From 0a452fcc8e030f5bdb7187e1db7182cfc488aa31 Mon Sep 17 00:00:00 2001 From: Piotr Krysik Date: Thu, 28 May 2009 19:39:56 +0200 Subject: cleanup of unneeded test code, separation of longer parts of fch_search into two functions, addidion of 'synchronized' state and reading of sch in this state --- src/lib/gsm_receiver_cf.h | 203 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 186 insertions(+), 17 deletions(-) (limited to 'src/lib/gsm_receiver_cf.h') diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 20d66da..2bad50e 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -29,19 +29,176 @@ #include +//TODO !! - move this classes to some other place +#include +#include +typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy} burst_type; +typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; + +class multiframe_configuration +{ + private: + multiframe_type d_type; + std::vector d_burst_types; + public: + multiframe_configuration() { + d_type = unknown; + fill(d_burst_types.begin(), d_burst_types.end(), empty); + } + +// multiframe_configuration(multiframe_type type, const std::vector & burst_types): +// d_type(type) { +// d_burst_types.resize(burst_types.size()); +// copy(burst_types.begin(), burst_types.end(), d_burst_types.begin()); +// } + +// multiframe_configuration(multiframe_configuration & conf) { +// d_type = conf.d_type; +// copy(conf.d_burst_types.begin(), conf.d_burst_types.end(), d_burst_types.begin()); +// } + + ~multiframe_configuration() {} + + void set_type(multiframe_type type) { + if (type == multiframe_26) { + d_burst_types.resize(26); + } else { + d_burst_types.resize(51); + } + + d_type = type; + } + + void set_burst_type(int nr, burst_type type) { + d_burst_types[nr] = type; + } + + multiframe_type get_type() { + return d_type; + } + + burst_type get_burst_type(int nr) { + return d_burst_types[nr]; + } +}; + +class burst_counter +{ + private: + uint32_t d_t1, d_t2, d_t3, d_timeslot_nr; + public: + burst_counter(): + d_t1(0), + d_t2(0), + d_t3(0), + d_timeslot_nr(0) { + } + + burst_counter(uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr): + d_t1(t1), + d_t2(t2), + d_t3(t3), + d_timeslot_nr(timeslot_nr) { + } + + burst_counter & operator++(int) { + d_timeslot_nr++; + if (d_timeslot_nr == TS_PER_FRAME) { + d_timeslot_nr = 0; + + if ((d_t2 == 25) && (d_t3 == 50)) { + d_t1 = (d_t1 + 1) % (1 << 11); + } + + d_t2 = (d_t2 + 1) % 26; + d_t3 = (d_t3 + 1) % 51; + } + return (*this); + } + + void set(uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr) { + d_t1 = t1; + d_t2 = t2; + d_t3 = t3; + d_timeslot_nr = timeslot_nr; + } + + uint32_t get_t1() { + return d_t1; + } + + uint32_t get_t2() { + return d_t2; + } + + uint32_t get_t3() { + return d_t3; + } + + uint32_t get_timeslot_nr() { + return d_timeslot_nr; + } + + uint32_t get_frame_nr() { + return (51 * 26 * d_t1) + (51 * (((d_t3 + 26) - d_t2) % 26)) + d_t3; + } +}; + +class channel_configuration +{ + private: + multiframe_configuration d_timeslots_descriptions[TS_PER_FRAME]; + public: + channel_configuration() { + for (int i = 0; i < TS_PER_FRAME; i++) { + d_timeslots_descriptions[i].set_type(unknown); + } + } +// void set_timeslot_desc(int timeslot_nr, multiframe_configuration conf){ +// d_timeslots_descriptions[timeslot_nr] = conf; +// } + void set_multiframe_type(int timeslot_nr, multiframe_type type) { + d_timeslots_descriptions[timeslot_nr].set_type(type); + } + + void set_burst_types(int timeslot_nr, const unsigned mapping[], unsigned mapping_size, burst_type b_type) { + unsigned i; + for (i = 0; i < mapping_size; i++) { + d_timeslots_descriptions[timeslot_nr].set_burst_type(mapping[i], b_type); + } + } + + void set_single_burst_type(int timeslot_nr, int burst_nr, burst_type b_type) { + d_timeslots_descriptions[timeslot_nr].set_burst_type(burst_nr, b_type); + } + + burst_type get_burst_type(burst_counter burst_nr); +}; + +burst_type channel_configuration::get_burst_type(burst_counter burst_nr) +{ + uint32_t timeslot_nr = burst_nr.get_timeslot_nr(); + multiframe_type m_type = d_timeslots_descriptions[timeslot_nr].get_type(); + uint32_t nr; + + switch (m_type) { + case multiframe_26: + nr = burst_nr.get_t2(); + break; + case multiframe_51: + nr = burst_nr.get_t3(); + break; + default: + nr = 0; + break; + } + + return d_timeslots_descriptions[timeslot_nr].get_burst_type(nr); +} +// move it to some other place !! + class gsm_receiver_cf; -/* - * We use boost::shared_ptr's instead of raw pointers for all access - * to gr_blocks (and many other data structures). The shared_ptr gets - * us transparent reference counting, which greatly simplifies storage - * management issues. This is especially helpful in our hybrid - * C++ / Python system. - * - * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm - * - * As a convention, the _sptr suffix indicates a boost::shared_ptr - */ typedef boost::shared_ptr gsm_receiver_cf_sptr; typedef std::vector vector_complex; @@ -65,6 +222,8 @@ class gsm_receiver_cf : public gr_block private: const int d_OSR; + const int d_chan_imp_length; + gr_complex d_sch_training_seq[N_SYNC_BITS]; //encoded training sequence of a SCH burst gr_feval_dd *d_tuner; @@ -74,14 +233,22 @@ class gsm_receiver_cf : public gr_block int d_fcch_start_pos; float d_freq_offset; double d_best_sum; - - int d_fcch_count; //!!! - double d_x_temp, d_x2_temp, d_mean;//!! - + +// int d_fcch_count; //!!! +// double d_x_temp, d_x2_temp, d_mean;//!! + + burst_counter d_burst_nr; + channel_configuration d_channel_conf; + vector_complex d_channel_imp_resp; + int d_ncc; + int d_bcc; + enum states { - first_fcch_search, next_fcch_search, sch_search, read_bcch + //synchronization search part + first_fcch_search, next_fcch_search, sch_search, synchronized + // } d_state; friend gsm_receiver_cf_sptr gsm_make_receiver_cf(gr_feval_dd *tuner, int osr); @@ -91,8 +258,10 @@ class gsm_receiver_cf : public gr_block double compute_freq_offset(); void set_frequency(double freq_offset); inline float compute_phase_diff(gr_complex val1, gr_complex val2); - + bool find_sch_burst(const gr_complex *in, const int nitems , float *out); + int get_sch_chan_imp_resp(const gr_complex *in, gr_complex * chan_imp_resp); + void detect_burst(const gr_complex * in, gr_complex * chan_imp_resp, int burst_start, unsigned char * output_binary); void gmsk_mapper(const int * input, gr_complex * gmsk_output, int ninput); gr_complex correlate_sequence(const gr_complex * sequence, const gr_complex * input_signal, int ninput); inline void autocorrelation(const gr_complex * input, gr_complex * out, int length); -- cgit v1.2.3