From 83ca8d75e21d286096c749b7608f847220260b77 Mon Sep 17 00:00:00 2001
From: piotr <piotr@piotr-desktop.(none)>
Date: Mon, 1 Jun 2009 22:14:14 +0200
Subject: program now works for osr from 2,3,4,5,6 and almost for osr==7)

---
 src/lib/gsm_constants.h    |  9 +++--
 src/lib/gsm_receiver_cf.cc | 93 ++++++++++++++++++++++++----------------------
 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;
-- 
cgit v1.2.3