aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--examples/receiver_rtlsdr.grc690
-rw-r--r--grc/receiver/gsm_receiver.xml10
-rw-r--r--lib/receiver/gsm_constants.h2
-rw-r--r--lib/receiver/receiver_impl.cc250
-rw-r--r--lib/receiver/receiver_impl.h6
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 &gt;= 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
*