diff options
-rw-r--r-- | grc/CMakeLists.txt | 4 | ||||
-rw-r--r-- | grc/gsm_receiver.xml | 38 | ||||
-rw-r--r-- | grc/gsm_receiver_hier.xml | 11 | ||||
-rw-r--r-- | include/gsm/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/gsm_constants.h | 2 | ||||
-rw-r--r-- | lib/receiver_impl.cc | 72 | ||||
-rw-r--r-- | lib/receiver_impl.h | 2 | ||||
-rwxr-xr-x | python/receiver_hier.py | 6 | ||||
-rw-r--r-- | swig/gsm_swig.i | 3 |
10 files changed, 61 insertions, 81 deletions
diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index c3f7dea..f2f4b75 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -18,6 +18,6 @@ # Boston, MA 02110-1301, USA. install(FILES - gsm_receiver.xml - gsm_receiver_hier.xml DESTINATION share/gnuradio/grc/blocks + gsm_receiver_hier.xml + gsm_bursts_printer.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/gsm_receiver.xml b/grc/gsm_receiver.xml deleted file mode 100644 index 7a0e3aa..0000000 --- a/grc/gsm_receiver.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0"?> -<block> - <name>receiver</name> - <key>gsm_receiver</key> - <category>gsm</category> - <import>import gsm</import> - <make>gsm.receiver($tuner, $osr)</make> - <!-- Make one 'param' node for every Parameter you want settable from the GUI. - Sub-nodes: - * name - * key (makes the value accessible as $keyname, e.g. in the make node) - * type --> - <param> - <name>...</name> - <key>...</key> - <type>...</type> - </param> - - <!-- Make one 'sink' node per input. Sub-nodes: - * name (an identifier for the GUI) - * type - * vlen - * optional (set to 1 for optional inputs) --> - <sink> - <name>in</name> - <type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type> - </sink> - - <!-- Make one 'source' node per output. Sub-nodes: - * name (an identifier for the GUI) - * type - * vlen - * optional (set to 1 for optional inputs) --> - <source> - <name>out</name> - <type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type> - </source> -</block> diff --git a/grc/gsm_receiver_hier.xml b/grc/gsm_receiver_hier.xml index 247cfcb..23eadc9 100644 --- a/grc/gsm_receiver_hier.xml +++ b/grc/gsm_receiver_hier.xml @@ -13,7 +13,7 @@ </param> <param> - <name>Oversampling ration</name> + <name>Oversampling ratio</name> <key>osr</key> <value>4</value> <type>int</type> @@ -23,10 +23,9 @@ <name>in</name> <type>complex</type> </sink> - <source> - <name>out</name> - <type>float</type> - <vlen>142</vlen> + <name>bursts</name> + <type>message</type> + <optional>1</optional> </source> -</block>
\ No newline at end of file +</block> diff --git a/include/gsm/CMakeLists.txt b/include/gsm/CMakeLists.txt index aad938f..c7f4fb3 100644 --- a/include/gsm/CMakeLists.txt +++ b/include/gsm/CMakeLists.txt @@ -22,5 +22,6 @@ ######################################################################## install(FILES api.h - receiver.h DESTINATION include/gsm + receiver.h + bursts_printer.h DESTINATION include/gsm ) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 8d4c721..1139353 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -30,6 +30,7 @@ list(APPEND gsm_sources receiver_config.cc viterbi_detector.cc sch.c + bursts_printer_impl.cc ) add_library(gnuradio-gsm SHARED ${gsm_sources}) diff --git a/lib/gsm_constants.h b/lib/gsm_constants.h index 11913f1..964c1cf 100644 --- a/lib/gsm_constants.h +++ b/lib/gsm_constants.h @@ -34,7 +34,7 @@ #define CHAN_IMP_RESP_LENGTH 5 -#define MAX_SCH_ERRORS 5 //maximum number of subsequent sch errors after which gsm receiver goes to find_next_fcch state +#define MAX_SCH_ERRORS 10 //maximum number of subsequent sch errors after which gsm receiver goes to find_next_fcch state typedef enum {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy, dummy_or_normal} burst_type; typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; diff --git a/lib/receiver_impl.cc b/lib/receiver_impl.cc index f11290c..90eccc2 100644 --- a/lib/receiver_impl.cc +++ b/lib/receiver_impl.cc @@ -64,7 +64,7 @@ receiver::make(feval_dd * tuner, int osr) receiver_impl::receiver_impl(feval_dd * tuner, int osr) : gr::block("receiver", gr::io_signature::make(1, 1, sizeof(gr_complex)), - gr::io_signature::make(0, 1, 142 * sizeof(float))), + gr::io_signature::make(0, 0, 0)), d_OSR(osr), d_chan_imp_length(CHAN_IMP_RESP_LENGTH), d_tuner(tuner), @@ -75,6 +75,7 @@ receiver_impl::receiver_impl(feval_dd * tuner, int osr) d_burst_nr(osr), d_failed_sch(0) { + int i; gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0, -1.0)); for (i = 0; i < TRAIN_SEQ_NUM; i++) @@ -92,6 +93,7 @@ receiver_impl::receiver_impl(feval_dd * tuner, int osr) gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], startpoint); } + message_port_register_out(pmt::mp("bursts")); } /* @@ -117,6 +119,7 @@ receiver_impl::general_work(int noutput_items, //float *out = (float *) output_items[0]; int produced_out = 0; //how many output elements were produced - this isn't used yet //probably the gsm receiver will be changed into sink so this variable won't be necessary + switch (d_state) { //bootstrapping @@ -145,7 +148,7 @@ receiver_impl::general_work(int noutput_items, if (abs(prev_freq_offset - d_freq_offset) > FCCH_MAX_FREQ_OFFSET) { //set_frequency(d_freq_offset); //call set_frequncy only frequency offset change is greater than some value - DCOUT("Freq offset " << d_freq_offset); + COUT("Freq offset " << d_freq_offset); } //produced_out = 0; d_state = sch_search; @@ -161,7 +164,7 @@ receiver_impl::general_work(int noutput_items, case sch_search: { - DCOUT("SCH search") ; + DCOUT("SCH search"); vector_complex channel_imp_resp(CHAN_IMP_RESP_LENGTH*d_OSR); int t1, t2, t3; int burst_start = 0; @@ -220,17 +223,17 @@ receiver_impl::general_work(int noutput_items, double freq_offset = compute_freq_offset(input, first_sample, last_sample); //extract frequency offset from it d_freq_offset_vals.push_front(freq_offset); - //process_normal_burst(d_burst_nr, fc_fb); + send_burst(d_burst_nr, fc_fb); if (d_freq_offset_vals.size() >= 10) { double sum = std::accumulate(d_freq_offset_vals.begin(), d_freq_offset_vals.end(), 0); double mean_offset = sum / d_freq_offset_vals.size(); //compute mean d_freq_offset_vals.clear(); + DCOUT("mean offset" << mean_offset); if (abs(mean_offset) > FCCH_MAX_FREQ_OFFSET) { - d_freq_offset -= mean_offset; //and adjust frequency if it have changed beyond + //d_freq_offset -= mean_offset; //and adjust frequency if it have changed beyond //set_frequency(d_freq_offset); //some limit - DCOUT("mean_offset: " << mean_offset); DCOUT("Adjusting frequency, new frequency offset: " << d_freq_offset << "\n"); } } @@ -241,14 +244,14 @@ receiver_impl::general_work(int noutput_items, int t1, t2, t3, d_ncc, d_bcc; burst_start = get_sch_chan_imp_resp(input, &channel_imp_resp[0]); //get channel impulse response detect_burst(input, &channel_imp_resp[0], burst_start, output_binary); //MLSE detection of bits - //process_normal_burst(d_burst_nr, output_binary); + send_burst(d_burst_nr, output_binary); 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; 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); + DCOUT("offset: "<<offset); to_consume += offset; //adjust with offset number of samples to be consumed } else @@ -259,8 +262,8 @@ receiver_impl::general_work(int noutput_items, d_state = first_fcch_search; //TODO: this isn't good, the receiver is going wild when it goes back to next_fcch_search from here d_freq_offset_vals.clear(); d_freq_offset=0; - set_frequency(0); - DCOUT("many sch decoding errors"); + //set_frequency(0); + DCOUT("Re-Synchronization"); } } } @@ -271,34 +274,33 @@ receiver_impl::general_work(int noutput_items, 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 - process_normal_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready + send_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready break; } case dummy_or_normal: { unsigned int normal_burst_start; float dummy_corr_max, normal_corr_max; + DCOUT("Dummy"); get_norm_chan_imp_resp(input, &channel_imp_resp[0], &dummy_corr_max, TS_DUMMY); + DCOUT("Normal"); normal_burst_start = get_norm_chan_imp_resp(input, &channel_imp_resp[0], &normal_corr_max, d_bcc); - //COUT("normal_corr_max: " << normal_corr_max << " dummy_corr_max:" << dummy_corr_max); + DCOUT("normal_corr_max: " << normal_corr_max << " dummy_corr_max:" << dummy_corr_max); if (normal_corr_max > dummy_corr_max) { detect_burst(input, &channel_imp_resp[0], normal_burst_start, output_binary); - //if (!output_binary[0] && !output_binary[1] && !output_binary[2]) { - // COUT("Normal burst"); - process_normal_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready - //} + send_burst(d_burst_nr, output_binary); //TODO: this shouldn't be here - remove it when gsm receiver's interface will be ready } else { - //process_normal_burst(d_burst_nr, dummy_burst); + send_burst(d_burst_nr, dummy_burst); } } case rach_burst: break; case dummy: - //process_normal_burst(d_burst_nr, dummy_burst); + send_burst(d_burst_nr, dummy_burst); break; case empty: //if it's empty burst break; //do nothing @@ -367,14 +369,14 @@ bool receiver_impl::find_fcch_burst(const gr_complex *input, const int nitems) break; - case search: // search for positive samples + case search: // search for positive samples sample_number++; if (sample_number > nitems - FCCH_HITS_NEEDED * d_OSR) //if it isn't possible to find FCCH because { - //there's too few samples left to look into, + //there's too few samples left to look into, to_consume = sample_number; //don't do anything with those samples which are left - //and consume only those which were checked + //and consume only those which were checked fcch_search_state = search_fail; } else @@ -725,7 +727,7 @@ int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex * float energy = 0; int search_center = (int)((TRAIN_POS + GUARD_PERIOD) * d_OSR); - int search_start_pos = search_center + 1; + int search_start_pos = search_center + 1 - 5*d_OSR; // int search_start_pos = search_center - d_chan_imp_length * d_OSR; int search_stop_pos = search_center + d_chan_imp_length * d_OSR + 2 * d_OSR; @@ -764,7 +766,7 @@ int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex * } //!why doesn't this work int strongest_window_nr_new = max_element(window_energy_buffer.begin(), window_energy_buffer.end()) - window_energy_buffer.begin(); - strongest_window_nr = 3; //! so I have to override it here + strongest_window_nr = strongest_window_nr_new-d_OSR; //! so I have to override it here max_correlation = 0; for (int ii = 0; ii < (d_chan_imp_length)*d_OSR; ii++) @@ -778,7 +780,7 @@ int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex * // d_channel_imp_resp.push_back(correlation); chan_imp_resp[ii] = correlation; } - + *corr_max = max_correlation; // We want to use the first sample of the impulse response, and the // corresponding samples of the received signal. @@ -796,20 +798,26 @@ int receiver_impl::get_norm_chan_imp_resp(const gr_complex *input, gr_complex * //COUT("Poczatek ###############################"); //std::cout << " burst_start: " << burst_start << " center: " << ((float)(search_start_pos + strongest_window_nr + chan_imp_resp_center)) / d_OSR << " stronegest window nr: " << strongest_window_nr << "\n"; //COUT("burst_start_new: " << (search_start_pos + strongest_window_nr_new - TRAIN_POS * d_OSR)); - burst_start=(search_start_pos + strongest_window_nr_new - TRAIN_POS * d_OSR); + DCOUT("strongest_window_nr_new: " << strongest_window_nr); + burst_start=(search_start_pos + strongest_window_nr - TRAIN_POS * d_OSR); + + DCOUT("burst_start: " << burst_start); return burst_start; } -void receiver_impl::process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary) +void receiver_impl::send_burst(burst_counter burst_nr, const unsigned char * burst_binary) { int ii; - //std::cout << "fn:" <<burst_nr.get_frame_nr() << " ts" << burst_nr.get_timeslot_nr() << " "; - for(ii=0; ii<148; ii++) - { - std::cout << std::setprecision(1) << static_cast<int>(burst_binary[ii]) << ""; - } - std::cout << std::endl; + + static const int nelements = 148; + pmt::pmt_t burst = pmt::make_s8vector(nelements, 0); // Initializes all 64 elements to 0 + + size_t vec_size; + int8_t *burst_elements = pmt::s8vector_writable_elements(burst, vec_size); // Returns pointer, vec_size is set to 64 + + memcpy(burst_elements, burst_binary, nelements); + message_port_pub(pmt::mp("bursts"), burst); } //TODO: this shouldn't be here also - the same reason void receiver_impl::configure_receiver() diff --git a/lib/receiver_impl.h b/lib/receiver_impl.h index 6fb1778..40ce91d 100644 --- a/lib/receiver_impl.h +++ b/lib/receiver_impl.h @@ -189,7 +189,7 @@ namespace gr { /** * */ - void process_normal_burst(burst_counter burst_nr, const unsigned char * burst_binary); + void send_burst(burst_counter burst_nr, const unsigned char * burst_binary); /** * diff --git a/python/receiver_hier.py b/python/receiver_hier.py index 1737d41..2b2f9ab 100755 --- a/python/receiver_hier.py +++ b/python/receiver_hier.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +import weakref import gsm from gnuradio.eng_option import eng_option from gnuradio import gr, gru, blocks @@ -22,6 +23,9 @@ class receiver_hier(gr.hier_block2): gr.io_signature(1, 1, 142*gr.sizeof_float)) #set rates gsm_symb_rate = 1625000/6.0 + + self.message_port_register_hier_in("bursts") + self.input_rate = input_rate self.osr = osr self.sps = input_rate / gsm_symb_rate / osr @@ -33,6 +37,8 @@ class receiver_hier(gr.hier_block2): self.interpolator = self._set_interpolator() self.receiver = self._set_receiver() self.connect(self, self.filtr, self.interpolator, self.receiver, self) + self.msg_connect(self.receiver, "bursts", weakref.proxy(self), "bursts") + def _set_filter(self): filter_cutoff = 125e3 diff --git a/swig/gsm_swig.i b/swig/gsm_swig.i index e1c3613..5aaf16d 100644 --- a/swig/gsm_swig.i +++ b/swig/gsm_swig.i @@ -9,8 +9,11 @@ %{ #include "gsm/receiver.h" +#include "gsm/bursts_printer.h" %} %include "gsm/receiver.h" GR_SWIG_BLOCK_MAGIC2(gsm, receiver); +%include "gsm/bursts_printer.h" +GR_SWIG_BLOCK_MAGIC2(gsm, bursts_printer); |