aboutsummaryrefslogtreecommitdiffstats
path: root/lib/receiver/receiver_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/receiver/receiver_impl.cc')
-rw-r--r--lib/receiver/receiver_impl.cc250
1 files changed, 139 insertions, 111 deletions
diff --git a/lib/receiver/receiver_impl.cc b/lib/receiver/receiver_impl.cc
index 0917f1e..de3438c 100644
--- a/lib/receiver/receiver_impl.cc
+++ b/lib/receiver/receiver_impl.cc
@@ -38,7 +38,9 @@
#include <iomanip>
#include <assert.h>
#include <boost/scoped_ptr.hpp>
-//#include "plotting/plotting.hpp"
+
+#include "plotting/plotting.hpp"
+#include <pthread.h>
#define SYNC_SEARCH_RANGE 30
@@ -64,7 +66,7 @@ receiver::make(int osr, int arfcn)
*/
receiver_impl::receiver_impl(int osr, int arfcn)
: gr::sync_block("receiver",
- gr::io_signature::make(1, 1, sizeof(gr_complex)),
+ gr::io_signature::make(1, -1, sizeof(gr_complex)),
gr::io_signature::make(0, 0, 0)),
d_OSR(osr),
d_chan_imp_length(CHAN_IMP_RESP_LENGTH),
@@ -104,7 +106,8 @@ receiver_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
- const gr_complex *input = (const gr_complex *) input_items[0];
+// std::vector<const gr_complex *> iii = (std::vector<const gr_complex *>) input_items; // jak zrobić to rzutowanie poprawnie
+ gr_complex * input = (gr_complex *) input_items[0];
std::vector<tag_t> freq_offset_tags;
uint64_t start = nitems_read(0);
uint64_t stop = start + noutput_items;
@@ -122,7 +125,6 @@ receiver_impl::work(int noutput_items,
if(d_state == synchronized && b_type == fcch_burst){
uint64_t last_sample_nr = ceil((GUARD_PERIOD + 2.0 * TAIL_BITS + 156.25) * d_OSR) + 1;
if(tag_offset < last_sample_nr){
- DCOUT("Freq change inside FCCH burst!!!!!!!!!!!!!!");
freq_offset_tag_in_fcch = true;
}
d_freq_offset_setting = pmt::to_double(freq_offset_tag.value);
@@ -134,9 +136,8 @@ receiver_impl::work(int noutput_items,
switch (d_state)
{
//bootstrapping
- case fcch_search: //this state is used because it takes some time (a bunch of buffered samples)
+ case fcch_search:
{
- DCOUT("FCCH search");
double freq_offset_tmp;
if (find_fcch_burst(input, noutput_items,freq_offset_tmp))
{
@@ -154,7 +155,6 @@ receiver_impl::work(int noutput_items,
case sch_search:
{
- DCOUT("SCH search");
vector_complex channel_imp_resp(CHAN_IMP_RESP_LENGTH*d_OSR);
int t1, t2, t3;
int burst_start = 0;
@@ -166,8 +166,6 @@ receiver_impl::work(int noutput_items,
detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); //detect bits using MLSE detection
if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) //decode SCH burst
{
- DCOUT("sch burst_start: " << burst_start);
- DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3);
d_burst_nr.set(t1, t2, t3, 0); //set counter of bursts value
d_burst_nr++;
@@ -188,109 +186,157 @@ receiver_impl::work(int noutput_items,
//in this state receiver is synchronized and it processes bursts according to burst type for given burst number
case synchronized:
{
- DCOUT("Synchronized");
vector_complex channel_imp_resp(CHAN_IMP_RESP_LENGTH*d_OSR);
- int burst_start;
int offset = 0;
int to_consume = 0;
unsigned char output_binary[BURST_SIZE];
- burst_type b_type = d_channel_conf.get_burst_type(d_burst_nr); //get burst type for given burst number
- double signal_pwr = 0;
- for(int ii=0;ii<noutput_items;ii++)
- {
- signal_pwr += abs(input[ii])*abs(input[ii]);
- }
- d_signal_dbm=static_cast<int8_t>(round(10*log10(signal_pwr/50/noutput_items)));
+ burst_type b_type;
- switch (b_type)
- {
- case fcch_burst: //if it's FCCH burst
- {
- const unsigned first_sample = ceil((GUARD_PERIOD + 2 * TAIL_BITS) * d_OSR) + 1;
- const unsigned last_sample = first_sample + USEFUL_BITS * d_OSR - TAIL_BITS * d_OSR;
- double freq_offset_tmp = compute_freq_offset(input, first_sample, last_sample); //extract frequency offset from it
-
- send_burst(d_burst_nr, fc_fb, b_type);
-
- pmt::pmt_t msg = pmt::make_tuple(pmt::mp("freq_offset"),pmt::from_double(freq_offset_tmp-d_freq_offset_setting),pmt::mp("synchronized"));
- message_port_pub(pmt::mp("measurements"), msg);
- }
- break;
- case sch_burst: //if it's SCH burst
+ for(int input_nr=0;input_nr<input_items.size();input_nr++)
{
- int t1, t2, t3, d_ncc, d_bcc;
- burst_start = get_sch_chan_imp_resp(input, &channel_imp_resp[0]); //get channel impulse response
+ double signal_pwr = 0;
+ input = (gr_complex *)input_items[input_nr];
- detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); //MLSE detection of bits
- send_burst(d_burst_nr, output_binary, b_type);
- if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) //and decode SCH data
+ for(int ii=GUARD_PERIOD;ii<TS_BITS;ii++)
{
- // d_burst_nr.set(t1, t2, t3, 0); //but only to check if burst_start value is correct
- d_failed_sch = 0;
- DCOUT("bcc: " << d_bcc << " ncc: " << d_ncc << " t1: " << t1 << " t2: " << t2 << " t3: " << t3);
- offset = burst_start - floor((GUARD_PERIOD) * d_OSR); //compute offset from burst_start - burst should start after a guard period
- DCOUT("offset: "<<offset);
- to_consume += offset; //adjust with offset number of samples to be consumed
+ signal_pwr += abs(input[ii])*abs(input[ii]);
}
- else
+ signal_pwr = signal_pwr/(TS_BITS);
+ d_signal_dbm = round(10*log10(signal_pwr/50));
+ if(input_nr==0){
+ d_c0_signal_dbm = d_signal_dbm;
+ }
+
+ if(input_nr==0) //for c0 channel burst type is controlled by channel configuration
+ {
+ b_type = d_channel_conf.get_burst_type(d_burst_nr); //get burst type for given burst number
+ }
+ else
+ {
+ b_type = normal_or_noise; //for the rest it can be only normal burst or noise (at least at this moment of development)
+ }
+
+ switch (b_type)
{
- d_failed_sch++;
- if (d_failed_sch >= MAX_SCH_ERRORS)
+ case fcch_burst: //if it's FCCH burst
+ {
+ const unsigned first_sample = ceil((GUARD_PERIOD + 2 * TAIL_BITS) * d_OSR) + 1;
+ const unsigned last_sample = first_sample + USEFUL_BITS * d_OSR - TAIL_BITS * d_OSR;
+ double freq_offset_tmp = compute_freq_offset(input, first_sample, last_sample); //extract frequency offset from it
+
+ send_burst(d_burst_nr, fc_fb, b_type);
+
+ pmt::pmt_t msg = pmt::make_tuple(pmt::mp("freq_offset"),pmt::from_double(freq_offset_tmp-d_freq_offset_setting),pmt::mp("synchronized"));
+ message_port_pub(pmt::mp("measurements"), msg);
+ break;
+ }
+ case sch_burst: //if it's SCH burst
+ {
+ int t1, t2, t3, d_ncc, d_bcc;
+ d_c0_burst_start = get_sch_chan_imp_resp(input, &channel_imp_resp[0]); //get channel impulse response
+
+ detect_burst(input, &channel_imp_resp[0], d_c0_burst_start, output_binary); //MLSE detection of bits
+ send_burst(d_burst_nr, output_binary, b_type);
+ if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) //and decode SCH data
+ {
+ // d_burst_nr.set(t1, t2, t3, 0); //but only to check if burst_start value is correct
+ d_failed_sch = 0;
+ offset = d_c0_burst_start - floor((GUARD_PERIOD) * d_OSR); //compute offset from burst_start - burst should start after a guard period
+ to_consume += offset; //adjust with offset number of samples to be consumed
+ }
+ else
{
- d_state = fcch_search;
- pmt::pmt_t msg = pmt::make_tuple(pmt::mp("freq_offset"),pmt::from_double(0.0),pmt::mp("sync_loss"));
- message_port_pub(pmt::mp("measurements"), msg);
- COUT("Re-Synchronization!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+ d_failed_sch++;
+ if (d_failed_sch >= MAX_SCH_ERRORS)
+ {
+ d_state = fcch_search;
+ pmt::pmt_t msg = pmt::make_tuple(pmt::mp("freq_offset"),pmt::from_double(0.0),pmt::mp("sync_loss"));
+ message_port_pub(pmt::mp("measurements"), msg);
+ DCOUT("Re-Synchronization!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+ }
}
+ break;
}
- }
- break;
-
- case normal_burst:
- {
- float normal_corr_max; //if it's normal burst
- burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, d_bcc); //get channel impulse response for given training sequence number - d_bcc
- detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); //MLSE detection of bits
- send_burst(d_burst_nr, output_binary, b_type);
- break;
- }
- case dummy_or_normal:
- {
- unsigned int normal_burst_start;
- float dummy_corr_max, normal_corr_max;
- get_norm_chan_imp_resp(input, &channel_imp_resp[0], &dummy_corr_max, TS_DUMMY);
- normal_burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, d_bcc);
-
- DCOUT("normal_corr_max: " << normal_corr_max << " dummy_corr_max:" << dummy_corr_max);
- if (normal_corr_max > dummy_corr_max)
+ case normal_burst:
{
- detect_burst(input, &channel_imp_resp[0], normal_burst_start, output_binary);
- send_burst(d_burst_nr, output_binary, b_type);
+ float normal_corr_max; //if it's normal burst
+ d_c0_burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, d_bcc); //get channel impulse response for given training sequence number - d_bcc
+ detect_burst(input, &channel_imp_resp[0], d_c0_burst_start, output_binary); //MLSE detection of bits
+ send_burst(d_burst_nr, output_binary, b_type);
+ break;
}
- else
+ case dummy_or_normal:
{
+ unsigned int normal_burst_start, dummy_burst_start;
+ float dummy_corr_max, normal_corr_max;
+
+ dummy_burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &dummy_corr_max, TS_DUMMY);
+ normal_burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, d_bcc);
+
+ if (normal_corr_max > dummy_corr_max)
+ {
+ d_c0_burst_start = normal_burst_start;
+ detect_burst(input, &channel_imp_resp[0], normal_burst_start, output_binary);
+ send_burst(d_burst_nr, output_binary, b_type);
+ }
+ else
+ {
+ d_c0_burst_start = dummy_burst_start;
+ send_burst(d_burst_nr, dummy_burst, b_type);
+ }
+ break;
+ }
+ case rach_burst:
+ break;
+ case dummy:
send_burst(d_burst_nr, dummy_burst, b_type);
+ break;
+ case normal_or_noise:
+ {
+ unsigned int burst_start;
+ float normal_corr_max_tmp;
+ float normal_corr_max=-1e6;
+ int max_tn;
+ std::vector<gr_complex> v(input, input + noutput_items);
+ if(d_signal_dbm>=d_c0_signal_dbm-13)
+ {
+ plot(v);
+
+ burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, 7);
+// if(abs(d_c0_burst_start-burst_start)<=2){
+ if((normal_corr_max/sqrt(signal_pwr))>=0.9){
+ std::cout << static_cast<int>(d_signal_dbm) << std::endl;
+ COUT("d_c0_burst_start: " << d_c0_burst_start);
+ COUT("burst_start: " << burst_start);
+ std::cout << "corr max to signal ratio: " << (normal_corr_max/sqrt(signal_pwr)) << std::endl;
+ usleep(4e6);
+ }
+ detect_burst(input, &channel_imp_resp[0], burst_start, output_binary);
+ send_burst(d_burst_nr, output_binary, b_type);
+ }
+ break;
}
+ case empty: //if it's empty burst
+ break; //do nothing
+ }
+
+ if(input_nr==0)
+ {
+ d_burst_nr++; //go to next burst
+ to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset(); //consume samples of the burst up to next guard period
+ }
+
+ if(input_nr==input_items.size()-1)
+ {
+ consume_each(to_consume);
+ }
+ //and add offset which is introduced by
+ //0.25 fractional part of a guard period
}
- case rach_burst:
- break;
- case dummy:
- send_burst(d_burst_nr, dummy_burst, b_type);
- break;
- case empty: //if it's empty burst
- break; //do nothing
- }
-
- d_burst_nr++; //go to next burst
- to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset(); //consume samples of the burst up to next guard period
- //and add offset which is introduced by
- //0.25 fractional part of a guard period
- consume_each(to_consume);
}
break;
}
-
return 0;
}
@@ -432,7 +478,6 @@ bool receiver_impl::find_fcch_burst(const gr_complex *input, const int nitems, d
case fcch_found:
{
- DCOUT("fcch found on position: " << d_counter + start_pos);
to_consume = start_pos + FCCH_HITS_NEEDED * d_OSR + 1; //consume one FCCH burst
d_fcch_start_pos = d_counter + start_pos;
@@ -531,7 +576,6 @@ int receiver_impl::get_sch_chan_imp_resp(const gr_complex *input, gr_complex * c
correlation_buffer.push_back(correlation);
power_buffer.push_back(std::pow(abs(correlation), 2));
}
- //plot(power_buffer);
//compute window energies
vector_float::iterator iter = power_buffer.begin();
bool loop_end = false;
@@ -693,14 +737,13 @@ int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex *
// int search_start_pos = search_center - d_chan_imp_length * d_OSR;
int search_stop_pos = search_center + d_chan_imp_length * d_OSR + 5 * d_OSR;
- for (int ii = search_start_pos; ii < search_stop_pos; ii++)
+ for(int ii = search_start_pos; ii < search_stop_pos; ii++)
{
gr_complex correlation = correlate_sequence(&d_norm_training_seq[bcc][TRAIN_BEGINNING], N_TRAIN_BITS - 10, &input[ii]);
-
correlation_buffer.push_back(correlation);
power_buffer.push_back(std::pow(abs(correlation), 2));
}
-
+ //plot(power_buffer);
//compute window energies
vector_float::iterator iter = power_buffer.begin();
bool loop_end = false;
@@ -748,10 +791,10 @@ int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex *
*corr_max = max_correlation;
- DCOUT("strongest_window_nr_new: " << strongest_window_nr);
+ //DCOUT("strongest_window_nr_new: " << strongest_window_nr);
burst_start = search_start_pos + strongest_window_nr - TRAIN_POS * d_OSR; //compute first sample posiiton which corresponds to the first sample of the impulse response
- DCOUT("burst_start: " << burst_start);
+ //DCOUT("burst_start: " << burst_start);
return burst_start;
}
@@ -785,21 +828,6 @@ void receiver_impl::configure_receiver()
d_channel_conf.set_burst_types(TIMESLOT0, FCCH_FRAMES, sizeof(FCCH_FRAMES) / sizeof(unsigned), fcch_burst);
d_channel_conf.set_burst_types(TIMESLOT0, SCH_FRAMES, sizeof(SCH_FRAMES) / sizeof(unsigned), sch_burst);
- // d_channel_conf.set_multiframe_type(TIMESLOT1, multiframe_26);
- // d_channel_conf.set_burst_types(TIMESLOT1, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
- // d_channel_conf.set_multiframe_type(TIMESLOT2, multiframe_26);
- // d_channel_conf.set_burst_types(TIMESLOT2, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
- // d_channel_conf.set_multiframe_type(TIMESLOT3, multiframe_26);
- // d_channel_conf.set_burst_types(TIMESLOT3, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
- // d_channel_conf.set_multiframe_type(TIMESLOT4, multiframe_26);
- // d_channel_conf.set_burst_types(TIMESLOT4, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
- // d_channel_conf.set_multiframe_type(TIMESLOT5, multiframe_26);
- // d_channel_conf.set_burst_types(TIMESLOT5, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
- // d_channel_conf.set_multiframe_type(TIMESLOT6, multiframe_26);
- // d_channel_conf.set_burst_types(TIMESLOT6, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
- // d_channel_conf.set_multiframe_type(TIMESLOT7, multiframe_26);
- // d_channel_conf.set_burst_types(TIMESLOT7, TRAFFIC_CHANNEL_F, sizeof(TRAFFIC_CHANNEL_F) / sizeof(unsigned), dummy_or_normal);
-
d_channel_conf.set_multiframe_type(TIMESLOT1, multiframe_51);
d_channel_conf.set_burst_types(TIMESLOT1, TEST51, sizeof(TEST51) / sizeof(unsigned), dummy_or_normal);
d_channel_conf.set_multiframe_type(TIMESLOT2, multiframe_51);