diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | examples/receiver_rtlsdr.grc | 690 | ||||
-rw-r--r-- | grc/receiver/gsm_receiver.xml | 10 | ||||
-rw-r--r-- | lib/receiver/gsm_constants.h | 2 | ||||
-rw-r--r-- | lib/receiver/receiver_impl.cc | 250 | ||||
-rw-r--r-- | lib/receiver/receiver_impl.h | 6 |
6 files changed, 500 insertions, 459 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 73a510c..572f87b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ cmake_minimum_required(VERSION 2.6) project(gr-gsm CXX C) enable_testing() +#set(CMAKE_BUILD_TYPE "Debug") #select the release build type by default to get optimization flags if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") diff --git a/examples/receiver_rtlsdr.grc b/examples/receiver_rtlsdr.grc index d7d4ccb..fb249bb 100644 --- a/examples/receiver_rtlsdr.grc +++ b/examples/receiver_rtlsdr.grc @@ -1,6 +1,6 @@ <?xml version='1.0' encoding='ASCII'?> <flow_graph> - <timestamp>Wed Aug 13 19:03:28 2014</timestamp> + <timestamp>Thu Aug 21 20:40:28 2014</timestamp> <block> <key>options</key> <param> @@ -210,58 +210,38 @@ </param> </block> <block> - <key>variable_qtgui_range</key> + <key>gsm_get_bcch_or_ccch_bursts</key> <param> <key>id</key> - <value>ppm</value> + <value>gsm_get_bcch_or_ccch_bursts_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>label</key> - <value>clock_correction</value> - </param> - <param> - <key>value</key> - <value>0</value> - </param> - <param> - <key>start</key> - <value>-50</value> - </param> - <param> - <key>stop</key> - <value>50</value> - </param> - <param> - <key>step</key> - <value>1</value> - </param> - <param> - <key>widget</key> - <value>counter</value> + <key>d_fn51_start</key> + <value>2</value> </param> <param> - <key>orient</key> - <value>Qt.Horizontal</value> + <key>alias</key> + <value></value> </param> <param> - <key>min_len</key> - <value>100</value> + <key>affinity</key> + <value></value> </param> <param> - <key>gui_hint</key> - <value></value> + <key>minoutbuf</key> + <value>0</value> </param> <param> - <key>alias</key> - <value></value> + <key>maxoutbuf</key> + <value>0</value> </param> <param> <key>_coordinate</key> - <value>(473, 10)</value> + <value>(660, 243)</value> </param> <param> <key>_rotation</key> @@ -269,232 +249,176 @@ </param> </block> <block> - <key>rtlsdr_source</key> + <key>blocks_tag_debug</key> <param> <key>id</key> - <value>rtlsdr_source_0</value> + <value>blocks_tag_debug_0</value> </param> <param> <key>_enabled</key> - <value>True</value> + <value>False</value> </param> <param> <key>type</key> - <value>fc32</value> + <value>complex</value> </param> <param> - <key>args</key> + <key>name</key> <value></value> </param> <param> - <key>nchan</key> - <value>1</value> - </param> - <param> - <key>sample_rate</key> - <value>samp_rate</value> - </param> - <param> - <key>freq0</key> - <value>fc</value> - </param> - <param> - <key>corr0</key> - <value>ppm</value> + <key>filter</key> + <value>""</value> </param> <param> - <key>dc_offset_mode0</key> - <value>0</value> + <key>num_inputs</key> + <value>1</value> </param> <param> - <key>iq_balance_mode0</key> - <value>0</value> + <key>vlen</key> + <value>1</value> </param> <param> - <key>gain_mode0</key> + <key>display</key> <value>True</value> </param> <param> - <key>gain0</key> - <value>g</value> - </param> - <param> - <key>if_gain0</key> - <value>20</value> - </param> - <param> - <key>bb_gain0</key> - <value>20</value> - </param> - <param> - <key>ant0</key> + <key>alias</key> <value></value> </param> <param> - <key>bw0</key> - <value>250e3</value> - </param> - <param> - <key>freq1</key> - <value>100e6</value> + <key>affinity</key> + <value></value> </param> <param> - <key>corr1</key> - <value>0</value> + <key>_coordinate</key> + <value>(456, 477)</value> </param> <param> - <key>dc_offset_mode1</key> + <key>_rotation</key> <value>0</value> </param> + </block> + <block> + <key>gsm_receiver_hier</key> <param> - <key>iq_balance_mode1</key> - <value>0</value> + <key>id</key> + <value>gsm_receiver_hier_0</value> </param> <param> - <key>gain_mode1</key> + <key>_enabled</key> <value>True</value> </param> <param> - <key>gain1</key> - <value>10</value> + <key>input_rate</key> + <value>samp_rate</value> </param> <param> - <key>if_gain1</key> - <value>20</value> + <key>osr</key> + <value>4</value> </param> <param> - <key>bb_gain1</key> - <value>20</value> + <key>arfcn</key> + <value>0</value> </param> <param> - <key>ant1</key> + <key>alias</key> <value></value> </param> <param> - <key>bw1</key> - <value>0</value> - </param> - <param> - <key>freq2</key> - <value>100e6</value> + <key>affinity</key> + <value></value> </param> <param> - <key>corr2</key> + <key>minoutbuf</key> <value>0</value> </param> <param> - <key>dc_offset_mode2</key> + <key>maxoutbuf</key> <value>0</value> </param> <param> - <key>iq_balance_mode2</key> - <value>0</value> + <key>_coordinate</key> + <value>(455, 244)</value> </param> <param> - <key>gain_mode2</key> - <value>True</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>gsm_control_channels_decoder</key> <param> - <key>gain2</key> - <value>10</value> + <key>id</key> + <value>gsm_control_channels_decoder_0</value> </param> <param> - <key>if_gain2</key> - <value>20</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>bb_gain2</key> - <value>20</value> + <key>alias</key> + <value></value> </param> <param> - <key>ant2</key> + <key>affinity</key> <value></value> </param> <param> - <key>bw2</key> + <key>minoutbuf</key> <value>0</value> </param> <param> - <key>freq3</key> - <value>100e6</value> - </param> - <param> - <key>corr3</key> + <key>maxoutbuf</key> <value>0</value> </param> <param> - <key>dc_offset_mode3</key> - <value>0</value> + <key>_coordinate</key> + <value>(920, 247)</value> </param> <param> - <key>iq_balance_mode3</key> + <key>_rotation</key> <value>0</value> </param> + </block> + <block> + <key>gsm_message_printer</key> <param> - <key>gain_mode3</key> - <value>True</value> - </param> - <param> - <key>gain3</key> - <value>10</value> - </param> - <param> - <key>if_gain3</key> - <value>20</value> + <key>id</key> + <value>gsm_message_printer_0</value> </param> <param> - <key>bb_gain3</key> - <value>20</value> + <key>_enabled</key> + <value>False</value> </param> <param> - <key>ant3</key> + <key>alias</key> <value></value> </param> <param> - <key>bw3</key> - <value>0</value> - </param> - <param> - <key>freq4</key> - <value>100e6</value> + <key>affinity</key> + <value></value> </param> <param> - <key>corr4</key> - <value>0</value> + <key>_coordinate</key> + <value>(1128, 169)</value> </param> <param> - <key>dc_offset_mode4</key> + <key>_rotation</key> <value>0</value> </param> + </block> + <block> + <key>gsm_message_printer</key> <param> - <key>iq_balance_mode4</key> - <value>0</value> + <key>id</key> + <value>gsm_message_printer_1</value> </param> <param> - <key>gain_mode4</key> + <key>_enabled</key> <value>True</value> </param> <param> - <key>gain4</key> - <value>10</value> - </param> - <param> - <key>if_gain4</key> - <value>20</value> - </param> - <param> - <key>bb_gain4</key> - <value>20</value> - </param> - <param> - <key>ant4</key> - <value></value> - </param> - <param> - <key>bw4</key> - <value>0</value> - </param> - <param> <key>alias</key> <value></value> </param> @@ -503,16 +427,8 @@ <value></value> </param> <param> - <key>minoutbuf</key> - <value>0</value> - </param> - <param> - <key>maxoutbuf</key> - <value>0</value> - </param> - <param> <key>_coordinate</key> - <value>(4, 171)</value> + <value>(1141, 247)</value> </param> <param> <key>_rotation</key> @@ -520,133 +436,85 @@ </param> </block> <block> - <key>qtgui_sink_x</key> + <key>blocks_message_debug</key> <param> <key>id</key> - <value>qtgui_sink_x_0</value> + <value>blocks_message_debug_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>complex</value> - </param> - <param> - <key>name</key> - <value>""</value> - </param> - <param> - <key>fftsize</key> - <value>1024</value> + <key>alias</key> + <value></value> </param> <param> - <key>wintype</key> - <value>firdes.WIN_BLACKMAN_hARRIS</value> + <key>affinity</key> + <value></value> </param> <param> - <key>fc</key> - <value>fc</value> + <key>_coordinate</key> + <value>(240, 405)</value> </param> <param> - <key>bw</key> - <value>samp_rate</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>variable_qtgui_range</key> <param> - <key>rate</key> - <value>10</value> + <key>id</key> + <value>ppm</value> </param> <param> - <key>showrf</key> + <key>_enabled</key> <value>True</value> </param> <param> - <key>plotfreq</key> - <value>True</value> + <key>label</key> + <value>clock_correction</value> </param> <param> - <key>plotwaterfall</key> - <value>True</value> + <key>value</key> + <value>84</value> </param> <param> - <key>plottime</key> - <value>True</value> + <key>start</key> + <value>-100</value> </param> <param> - <key>plotconst</key> - <value>True</value> + <key>stop</key> + <value>100</value> </param> <param> - <key>gui_hint</key> - <value></value> + <key>step</key> + <value>1</value> </param> <param> - <key>freqchangevar</key> - <value>None</value> + <key>widget</key> + <value>counter</value> </param> <param> - <key>showports</key> - <value>True</value> + <key>orient</key> + <value>Qt.Horizontal</value> </param> <param> - <key>alias</key> - <value></value> + <key>min_len</key> + <value>100</value> </param> <param> - <key>affinity</key> + <key>gui_hint</key> <value></value> </param> <param> - <key>minoutbuf</key> - <value>0</value> - </param> - <param> - <key>maxoutbuf</key> - <value>0</value> - </param> - <param> - <key>_coordinate</key> - <value>(455, 374)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> - <key>gsm_get_bcch_or_ccch_bursts</key> - <param> - <key>id</key> - <value>gsm_get_bcch_or_ccch_bursts_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>d_fn51_start</key> - <value>2</value> - </param> - <param> <key>alias</key> <value></value> </param> <param> - <key>affinity</key> - <value></value> - </param> - <param> - <key>minoutbuf</key> - <value>0</value> - </param> - <param> - <key>maxoutbuf</key> - <value>0</value> - </param> - <param> <key>_coordinate</key> - <value>(660, 243)</value> + <value>(473, 10)</value> </param> <param> <key>_rotation</key> @@ -748,141 +616,232 @@ </param> </block> <block> - <key>blocks_tag_debug</key> + <key>rtlsdr_source</key> <param> <key>id</key> - <value>blocks_tag_debug_0</value> + <value>rtlsdr_source_0</value> </param> <param> <key>_enabled</key> - <value>False</value> + <value>True</value> </param> <param> <key>type</key> - <value>complex</value> + <value>fc32</value> </param> <param> - <key>name</key> + <key>args</key> <value></value> </param> <param> - <key>filter</key> - <value>""</value> + <key>nchan</key> + <value>1</value> </param> <param> - <key>num_inputs</key> - <value>1</value> + <key>sample_rate</key> + <value>samp_rate</value> </param> <param> - <key>vlen</key> - <value>1</value> + <key>freq0</key> + <value>fc</value> </param> <param> - <key>display</key> + <key>corr0</key> + <value>ppm</value> + </param> + <param> + <key>dc_offset_mode0</key> + <value>0</value> + </param> + <param> + <key>iq_balance_mode0</key> + <value>0</value> + </param> + <param> + <key>gain_mode0</key> <value>True</value> </param> <param> - <key>alias</key> - <value></value> + <key>gain0</key> + <value>g</value> </param> <param> - <key>affinity</key> + <key>if_gain0</key> + <value>20</value> + </param> + <param> + <key>bb_gain0</key> + <value>20</value> + </param> + <param> + <key>ant0</key> <value></value> </param> <param> - <key>_coordinate</key> - <value>(456, 477)</value> + <key>bw0</key> + <value>250e3</value> </param> <param> - <key>_rotation</key> + <key>freq1</key> + <value>100e6</value> + </param> + <param> + <key>corr1</key> <value>0</value> </param> - </block> - <block> - <key>gsm_receiver_hier</key> <param> - <key>id</key> - <value>gsm_receiver_hier_0</value> + <key>dc_offset_mode1</key> + <value>0</value> </param> <param> - <key>_enabled</key> + <key>iq_balance_mode1</key> + <value>0</value> + </param> + <param> + <key>gain_mode1</key> <value>True</value> </param> <param> - <key>input_rate</key> - <value>samp_rate</value> + <key>gain1</key> + <value>10</value> </param> <param> - <key>osr</key> - <value>4</value> + <key>if_gain1</key> + <value>20</value> </param> <param> - <key>arfcn</key> - <value>0</value> + <key>bb_gain1</key> + <value>20</value> </param> <param> - <key>alias</key> + <key>ant1</key> <value></value> </param> <param> - <key>affinity</key> + <key>bw1</key> + <value>0</value> + </param> + <param> + <key>freq2</key> + <value>100e6</value> + </param> + <param> + <key>corr2</key> + <value>0</value> + </param> + <param> + <key>dc_offset_mode2</key> + <value>0</value> + </param> + <param> + <key>iq_balance_mode2</key> + <value>0</value> + </param> + <param> + <key>gain_mode2</key> + <value>True</value> + </param> + <param> + <key>gain2</key> + <value>10</value> + </param> + <param> + <key>if_gain2</key> + <value>20</value> + </param> + <param> + <key>bb_gain2</key> + <value>20</value> + </param> + <param> + <key>ant2</key> <value></value> </param> <param> - <key>minoutbuf</key> + <key>bw2</key> <value>0</value> </param> <param> - <key>maxoutbuf</key> + <key>freq3</key> + <value>100e6</value> + </param> + <param> + <key>corr3</key> <value>0</value> </param> <param> - <key>_coordinate</key> - <value>(455, 244)</value> + <key>dc_offset_mode3</key> + <value>0</value> </param> <param> - <key>_rotation</key> + <key>iq_balance_mode3</key> <value>0</value> </param> - </block> - <block> - <key>blocks_message_debug</key> <param> - <key>id</key> - <value>blocks_message_debug_0</value> + <key>gain_mode3</key> + <value>True</value> </param> <param> - <key>_enabled</key> - <value>False</value> + <key>gain3</key> + <value>10</value> </param> <param> - <key>alias</key> - <value></value> + <key>if_gain3</key> + <value>20</value> </param> <param> - <key>affinity</key> + <key>bb_gain3</key> + <value>20</value> + </param> + <param> + <key>ant3</key> <value></value> </param> <param> - <key>_coordinate</key> - <value>(240, 406)</value> + <key>bw3</key> + <value>0</value> </param> <param> - <key>_rotation</key> + <key>freq4</key> + <value>100e6</value> + </param> + <param> + <key>corr4</key> <value>0</value> </param> - </block> - <block> - <key>gsm_control_channels_decoder</key> <param> - <key>id</key> - <value>gsm_control_channels_decoder_0</value> + <key>dc_offset_mode4</key> + <value>0</value> </param> <param> - <key>_enabled</key> + <key>iq_balance_mode4</key> + <value>0</value> + </param> + <param> + <key>gain_mode4</key> <value>True</value> </param> <param> + <key>gain4</key> + <value>10</value> + </param> + <param> + <key>if_gain4</key> + <value>20</value> + </param> + <param> + <key>bb_gain4</key> + <value>20</value> + </param> + <param> + <key>ant4</key> + <value></value> + </param> + <param> + <key>bw4</key> + <value>0</value> + </param> + <param> <key>alias</key> <value></value> </param> @@ -900,7 +859,7 @@ </param> <param> <key>_coordinate</key> - <value>(920, 247)</value> + <value>(4, 171)</value> </param> <param> <key>_rotation</key> @@ -908,40 +867,73 @@ </param> </block> <block> - <key>gsm_message_printer</key> + <key>qtgui_sink_x</key> <param> <key>id</key> - <value>gsm_message_printer_0</value> + <value>qtgui_sink_x_0</value> </param> <param> <key>_enabled</key> - <value>False</value> + <value>True</value> </param> <param> - <key>alias</key> - <value></value> + <key>type</key> + <value>complex</value> </param> <param> - <key>affinity</key> - <value></value> + <key>name</key> + <value>""</value> </param> <param> - <key>_coordinate</key> - <value>(1128, 169)</value> + <key>fftsize</key> + <value>1024</value> </param> <param> - <key>_rotation</key> - <value>0</value> + <key>wintype</key> + <value>firdes.WIN_BLACKMAN_hARRIS</value> </param> - </block> - <block> - <key>gsm_message_printer</key> <param> - <key>id</key> - <value>gsm_message_printer_1</value> + <key>fc</key> + <value>fc</value> </param> <param> - <key>_enabled</key> + <key>bw</key> + <value>samp_rate</value> + </param> + <param> + <key>rate</key> + <value>10</value> + </param> + <param> + <key>showrf</key> + <value>True</value> + </param> + <param> + <key>plotfreq</key> + <value>True</value> + </param> + <param> + <key>plotwaterfall</key> + <value>True</value> + </param> + <param> + <key>plottime</key> + <value>True</value> + </param> + <param> + <key>plotconst</key> + <value>True</value> + </param> + <param> + <key>gui_hint</key> + <value></value> + </param> + <param> + <key>freqchangevar</key> + <value>None</value> + </param> + <param> + <key>showports</key> <value>True</value> </param> <param> @@ -953,8 +945,16 @@ <value></value> </param> <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> <key>_coordinate</key> - <value>(1141, 247)</value> + <value>(455, 374)</value> </param> <param> <key>_rotation</key> @@ -974,12 +974,6 @@ <sink_key>0</sink_key> </connection> <connection> - <source_block_id>clock_offset_corrector_0</source_block_id> - <sink_block_id>qtgui_sink_x_0</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> - <connection> <source_block_id>gsm_get_bcch_or_ccch_bursts_0</source_block_id> <sink_block_id>gsm_control_channels_decoder_0</sink_block_id> <source_key>bursts</source_key> @@ -1004,6 +998,18 @@ <sink_key>msgs</sink_key> </connection> <connection> + <source_block_id>gsm_control_channels_decoder_0</source_block_id> + <sink_block_id>gsm_message_printer_1</sink_block_id> + <source_key>msgs</source_key> + <sink_key>msgs</sink_key> + </connection> + <connection> + <source_block_id>gsm_clock_offset_control_0</source_block_id> + <sink_block_id>blocks_message_debug_0</sink_block_id> + <source_key>ppm</source_key> + <sink_key>print</sink_key> + </connection> + <connection> <source_block_id>gsm_clock_offset_control_0</source_block_id> <sink_block_id>clock_offset_corrector_0</sink_block_id> <source_key>ppm</source_key> @@ -1016,15 +1022,9 @@ <sink_key>0</sink_key> </connection> <connection> - <source_block_id>gsm_receiver_hier_0</source_block_id> - <sink_block_id>blocks_message_debug_0</sink_block_id> - <source_key>measurements</source_key> - <sink_key>print</sink_key> - </connection> - <connection> - <source_block_id>gsm_control_channels_decoder_0</source_block_id> - <sink_block_id>gsm_message_printer_1</sink_block_id> - <source_key>msgs</source_key> - <sink_key>msgs</sink_key> + <source_block_id>rtlsdr_source_0</source_block_id> + <sink_block_id>qtgui_sink_x_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> </connection> </flow_graph> diff --git a/grc/receiver/gsm_receiver.xml b/grc/receiver/gsm_receiver.xml index eb0db5f..4841568 100644 --- a/grc/receiver/gsm_receiver.xml +++ b/grc/receiver/gsm_receiver.xml @@ -20,10 +20,20 @@ <type>int</type> </param> + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>1</value> + <type>int</type> + </param> + <check>$num_streams >= 0</check> + <sink> <name>in</name> <type>complex</type> + <nports>$num_streams</nports> </sink> + <source> <name>bursts</name> <type>message</type> diff --git a/lib/receiver/gsm_constants.h b/lib/receiver/gsm_constants.h index 0308d96..01d089b 100644 --- a/lib/receiver/gsm_constants.h +++ b/lib/receiver/gsm_constants.h @@ -37,7 +37,7 @@ #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 {empty, fcch_burst, sch_burst, normal_burst, rach_burst, dummy, dummy_or_normal, normal_or_noise} burst_type; typedef enum {unknown, multiframe_26, multiframe_51} multiframe_type; static const unsigned char SYNC_BITS[] = { 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); diff --git a/lib/receiver/receiver_impl.h b/lib/receiver/receiver_impl.h index 3e962c7..08a2c44 100644 --- a/lib/receiver/receiver_impl.h +++ b/lib/receiver/receiver_impl.h @@ -34,16 +34,18 @@ namespace gr { class receiver_impl : public receiver { private: + unsigned int d_c0_burst_start; + float d_c0_signal_dbm; /**@name Configuration of the receiver */ //@{ const int d_OSR; ///< oversampling ratio const int d_chan_imp_length; ///< channel impulse length uint16_t d_arfcn; - int8_t d_signal_dbm; + float d_signal_dbm; //@} gr_complex d_sch_training_seq[N_SYNC_BITS]; ///<encoded training sequence of a SCH burst - gr_complex d_norm_training_seq[TRAIN_SEQ_NUM][N_TRAIN_BITS]; ///<encoded training sequences of a normal bursts and dummy bursts + gr_complex d_norm_training_seq[TRAIN_SEQ_NUM][N_TRAIN_BITS]; ///<encoded training sequences of a normal and dummy burst /** Counts samples consumed by the receiver * |