aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorptrkrysik <ptrkrysik@gmail.com>2014-10-30 09:05:15 +0100
committerptrkrysik <ptrkrysik@gmail.com>2014-10-30 09:05:15 +0100
commit58213797c17bc5fe397f067152363eb95f596b92 (patch)
treef5dd0366da5c7ccf31f5d402696235b99e345c2e
parenta25bb7030ba3b16a14346c2a04f1db6a6bddd237 (diff)
First step to add multichannel capability to the GSM receiver. At this moment it might still contain debuging code. The training sequence number for non C0 channels is embedded in the code.
-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
*