summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/gsm_constants.h9
-rw-r--r--src/lib/gsm_receiver_cf.cc93
-rw-r--r--src/lib/gsm_receiver_cf.h36
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;
personal git repositories of Harald Welte. Your mileage may vary