diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/gsm_constants.h | 9 | ||||
| -rw-r--r-- | src/lib/gsm_receiver_cf.cc | 93 | ||||
| -rw-r--r-- | src/lib/gsm_receiver_cf.h | 36 | 
3 files changed, 83 insertions, 55 deletions
diff --git a/src/lib/gsm_constants.h b/src/lib/gsm_constants.h index d08df17..1e449b3 100644 --- a/src/lib/gsm_constants.h +++ b/src/lib/gsm_constants.h @@ -6,7 +6,9 @@  //Burst timing  #define TAIL_BITS         3 -#define GUARD_BITS        8.25 +#define GUARD_BITS        8 +#define GUARD_FRACTIONAL  0.25 //fractional part of guard period +#define GUARD_PERIOD      GUARD_BITS + GUARD_FRACTIONAL  #define DATA_BITS         58   //size of 1 data block in normal burst  #define N_TRAIN_BITS      26  #define N_SYNC_BITS       64 @@ -14,9 +16,9 @@  #define FCCH_BITS         USEFUL_BITS  #define BURST_SIZE        (USEFUL_BITS+2*TAIL_BITS) -#define TS_BITS           (TAIL_BITS+USEFUL_BITS+TAIL_BITS+GUARD_BITS)  //a full TS (156) +#define TS_BITS           (TAIL_BITS+USEFUL_BITS+TAIL_BITS+GUARD_BITS)  //a full TS (156 bits)  #define TS_PER_FRAME      8 -#define FRAME_BITS        (TS_PER_FRAME * TS_BITS)  +#define FRAME_BITS        (TS_PER_FRAME * TS_BITS + 2) // 156.25 * 8  #define FCCH_POS          TAIL_BITS  #define SYNC_POS          39  #define TRAIN_POS         58 @@ -24,6 +26,7 @@  #define FCCH_HITS_NEEDED        (USEFUL_BITS - 4)   #define FCCH_MAX_MISSES         1 +#define FCCH_MAX_FREQ_OFFSET    100  #define CHAN_IMP_RESP_LENGTH  5 diff --git a/src/lib/gsm_receiver_cf.cc b/src/lib/gsm_receiver_cf.cc index e4d2696..127c674 100644 --- a/src/lib/gsm_receiver_cf.cc +++ b/src/lib/gsm_receiver_cf.cc @@ -36,7 +36,7 @@  #include <sch.h>  #define FCCH_BUFFER_SIZE (FCCH_HITS_NEEDED) -#define SYNC_SEARCH_RANGE 60 +#define SYNC_SEARCH_RANGE 30  //TODO !! - move this methods to some else place @@ -70,7 +70,8 @@ gsm_receiver_cf::gsm_receiver_cf(gr_feval_dd *tuner, int osr)      d_counter(0),      d_fcch_start_pos(0),      d_freq_offset(0), -    d_state(first_fcch_search) +    d_state(first_fcch_search), +    d_burst_nr(osr)  //    d_fcch_count(0), //!!  //    d_x_temp(0),//!!  //    d_x2_temp(0)//!! @@ -128,19 +129,35 @@ gsm_receiver_cf::general_work(int noutput_items,        }        break; -    case sch_search: +    case sch_search: { +      gr_complex chan_imp_resp[CHAN_IMP_RESP_LENGTH*d_OSR]; +      int t1, t2, t3; +      int burst_start = 0; +      unsigned char output_binary[BURST_SIZE]; +        if (find_sch_burst(in, ninput_items[0], out)) { -        d_channel_conf.set_multiframe_type(0, multiframe_51); -        d_channel_conf.set_burst_types(0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); -        d_channel_conf.set_burst_types(0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); -        d_burst_nr++; -        d_state = synchronized; +        burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); +        detect_burst(in, chan_imp_resp, burst_start, output_binary); +        if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) { +          DCOUT("sch burst_start: " << burst_start); +          d_burst_nr.set(t1, t2, t3, 0); +          DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); +          d_channel_conf.set_multiframe_type(0, multiframe_51); +          d_channel_conf.set_burst_types(0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst); +          d_channel_conf.set_burst_types(0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst); +          d_burst_nr++; +          consume_each(burst_start + BURST_SIZE * d_OSR); +          d_state = synchronized; +        } else { +          d_state = next_fcch_search; +        }        } else {          d_state = sch_search;        }        break; +    } -      //in this state receiver is synchronized and it processes bursts according to burst type for given burst number +    //in this state receiver is synchronized and it processes bursts according to burst type for given burst number      case synchronized: {        gr_complex chan_imp_resp[100];//!!        burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); @@ -152,20 +169,20 @@ gsm_receiver_cf::general_work(int noutput_items,        switch (b_type) {          case fcch_burst: {            int ii; -          int first_sample = (GUARD_BITS+TAIL_BITS) *d_OSR; -          int last_sample = first_sample+USEFUL_BITS*d_OSR; +          int first_sample = ceil((GUARD_PERIOD + 2*TAIL_BITS) * d_OSR)+1; +          int last_sample = first_sample + USEFUL_BITS * d_OSR;            double phase_sum = 0;            for (ii = first_sample; ii < last_sample; ii++) { -            double phase_diff = compute_phase_diff(in[ii], in[ii-1]) * d_OSR; -//                   std::cout << "phase_diff: " << phase_diff << "\n"; +            double phase_diff = compute_phase_diff(in[ii], in[ii-1]) - (M_PI / 2) / d_OSR;              phase_sum += phase_diff;            } -          //std::cout << "phase_sum: " << phase_sum << "\n"; - -//               double freq_offset = compute_freq_offset(phase_sum, USEFUL_BITS-TAIL_BITS); -//               d_freq_offset -= freq_offset; -//               set_frequency(d_freq_offset); -//              std::cout << "freq_offset: " << d_freq_offset << "\n"; +          double freq_offset = compute_freq_offset(phase_sum, last_sample - first_sample); +          if(abs(freq_offset) > FCCH_MAX_FREQ_OFFSET){ +            d_freq_offset -= freq_offset; +            set_frequency(d_freq_offset); +            DCOUT("adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); +          } +                    }          break;          case sch_burst: { @@ -174,15 +191,15 @@ gsm_receiver_cf::general_work(int noutput_items,            detect_burst(in, chan_imp_resp, burst_start, output_binary);            if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) {  //                d_burst_nr.set(t1, t2, t3, 0); -            printf("bcc: %d, ncc: %d, t1: %d, t2: %d, t3: %d\n", d_bcc, d_ncc, t1, t2, t3); -            offset =  burst_start - GUARD_BITS * d_OSR; +            DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3); +            offset =  burst_start - floor((GUARD_PERIOD) * d_OSR); +            DCOUT(offset);              to_consume += offset;            } -          std::cout << offset << std::endl;          }          break;          case normal_burst: - +                      break;          case rach_burst: @@ -194,7 +211,8 @@ gsm_receiver_cf::general_work(int noutput_items,        }        d_burst_nr++; -      to_consume += floor(TS_BITS * d_OSR); + +      to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset();        consume_each(to_consume);      }      break; @@ -315,6 +333,7 @@ bool gsm_receiver_cf::find_fcch_burst(const gr_complex *in, const int nitems)          d_fcch_start_pos = d_counter + start_pos;          freq_offset = compute_freq_offset(best_sum, FCCH_HITS_NEEDED);          d_freq_offset -= freq_offset; +        DCOUT("freq_offset: " << d_freq_offset);          end = true;          result = true; @@ -345,7 +364,7 @@ double gsm_receiver_cf::compute_freq_offset(double best_sum, unsigned denominato  //   d_x2_temp += freq_offset * freq_offset;  //   d_mean = d_x_temp / d_fcch_count; -  DCOUT("freq_offset: " << freq_offset);   //" best_sum: " << best_sum +//   DCOUT("freq_offset: " << freq_offset);   //" best_sum: " << best_sum  //   DCOUT("wariance: " << sqrt((d_x2_temp / d_fcch_count - d_mean * d_mean)) << " fcch_count:" << d_fcch_count << " d_mean: " << d_mean);    return freq_offset; @@ -368,19 +387,16 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl    bool end = false;    bool result = false;    int sample_nr_near_sch_start = d_fcch_start_pos + (FRAME_BITS - SAFETY_MARGIN) * d_OSR; -  gr_complex chan_imp_resp[CHAN_IMP_RESP_LENGTH*d_OSR]; +  //   vector_complex correlation_buffer;  //   vector_float power_buffer;  //   vector_float window_energy_buffer;    enum states { -    start, reach_sch, find_sch_start, detect_and_decode_sch, search_not_finished, sch_found +    start, reach_sch, search_not_finished, sch_found    } sch_search_state;    sch_search_state = start; -  int t1, t2, t3; -  int burst_start = 0; -  unsigned char output_binary[BURST_SIZE];    while (!end) {      switch (sch_search_state) { @@ -389,7 +405,7 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl          if (d_counter < sample_nr_near_sch_start) {            sch_search_state = reach_sch;          } else { -          sch_search_state = find_sch_start; +          sch_search_state = sch_found;          }          break; @@ -402,26 +418,13 @@ bool gsm_receiver_cf::find_sch_burst(const gr_complex *in, const int nitems , fl          sch_search_state = search_not_finished;          break; -      case find_sch_start: -        burst_start = get_sch_chan_imp_resp(in, chan_imp_resp); -        sch_search_state = detect_and_decode_sch; -        break; -      case detect_and_decode_sch: -        detect_burst(in, chan_imp_resp, burst_start, output_binary); -        decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc); -        d_burst_nr.set(t1, t2, t3, 0); - -        printf("bcc: %d, ncc: %d, t1: %d, t2: %d, t3: %d\n", d_bcc, d_ncc, t1, t2, t3); -        to_consume += burst_start + BURST_SIZE * d_OSR; -        sch_search_state = sch_found; -        break; -        case search_not_finished:          result = false;          end = true;          break;        case sch_found: +        to_consume = 0;          result = true;          end = true;          break; diff --git a/src/lib/gsm_receiver_cf.h b/src/lib/gsm_receiver_cf.h index 98df34d..cc3fc15 100644 --- a/src/lib/gsm_receiver_cf.h +++ b/src/lib/gsm_receiver_cf.h @@ -32,6 +32,7 @@  //TODO !! - move this classes to some other place  #include <vector>  #include <algorithm> +#include <math.h>  typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy} burst_type;  typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; @@ -85,20 +86,30 @@ class multiframe_configuration  class burst_counter  {    private: +    const int d_OSR;      uint32_t d_t1, d_t2, d_t3, d_timeslot_nr; +    double d_first_sample_offset; +    double d_offset;    public: -    burst_counter(): +    burst_counter(int osr): +        d_OSR(osr),          d_t1(0),          d_t2(0),          d_t3(0), -        d_timeslot_nr(0) { +        d_timeslot_nr(0), +        d_first_sample_offset(0), +        d_offset(0) {      } -    burst_counter(uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr): +    burst_counter(int osr, uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr): +        d_OSR(osr),          d_t1(t1),          d_t2(t2),          d_t3(t3), -        d_timeslot_nr(timeslot_nr) { +        d_timeslot_nr(timeslot_nr), +        d_offset(0) { +      double first_sample_position = (get_frame_nr()*8+timeslot_nr)*TS_BITS; +      d_first_sample_offset = first_sample_position - floor(first_sample_position);      }      burst_counter & operator++(int) { @@ -113,6 +124,10 @@ class burst_counter          d_t2 = (d_t2 + 1) % 26;          d_t3 = (d_t3 + 1) % 51;        } +       +      d_first_sample_offset += GUARD_FRACTIONAL * d_OSR; +      d_offset = floor(d_first_sample_offset); +      d_first_sample_offset = d_first_sample_offset - d_offset;        return (*this);      } @@ -121,6 +136,9 @@ class burst_counter        d_t2 = t2;        d_t3 = t3;        d_timeslot_nr = timeslot_nr; +      double first_sample_position = (get_frame_nr()*8+timeslot_nr)*TS_BITS; +      d_first_sample_offset = first_sample_position - floor(first_sample_position); +      d_offset = 0;      }      uint32_t get_t1() { @@ -140,7 +158,11 @@ class burst_counter      }      uint32_t get_frame_nr() { -      return   (51 * 26 * d_t1) + (51 * (((d_t3 + 26) - d_t2) % 26)) + d_t3; +      return (51 * 26 * d_t1) + (51 * (((d_t3 + 26) - d_t2) % 26)) + d_t3; +    } +     +    unsigned get_offset(){ +       return (unsigned)d_offset;      }  }; @@ -180,7 +202,7 @@ 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(); @@ -227,7 +249,7 @@ class gsm_receiver_cf : public gr_block      gr_complex d_sch_training_seq[N_SYNC_BITS]; //encoded training sequence of a SCH burst      gr_feval_dd *d_tuner; -    int d_counter; +    unsigned d_counter;      //variables used to store result of the find_fcch_burst fuction      int d_fcch_start_pos;  | 
