diff options
author | Piotr Krysik <ptrkrysik@gmail.com> | 2016-05-14 19:37:14 +0200 |
---|---|---|
committer | Piotr Krysik <ptrkrysik@gmail.com> | 2016-05-14 19:37:14 +0200 |
commit | 8630fac60ca3b1609725498348267e66602d2067 (patch) | |
tree | 7d275e2455ca3efa11e86f90a036d9ff859e5723 | |
parent | cdff492ff7f318dc452b6270a4845b8df6d9e025 (diff) | |
parent | 5d6ae655574947444b713f1d34fab85167554b8c (diff) |
Merged uplink-decoding branch (with complete support for control channels decoding on uplink)
# Conflicts:
# examples
# lib/demapping/universal_ctrl_chans_demapper_impl.cc
# lib/receiver/receiver_impl.cc
-rw-r--r-- | grc/demapping/gsm_bcch_ccch_demapper.xml | 26 | ||||
-rw-r--r-- | grc/demapping/gsm_bcch_ccch_sdcch4_demapper.xml | 26 | ||||
-rw-r--r-- | grc/demapping/gsm_sdcch8_demapper.xml | 28 | ||||
-rw-r--r-- | grc/demapping/gsm_universal_ctrl_chans_demapper.xml | 29 | ||||
-rw-r--r-- | grc/gsm_block_tree.xml | 1 | ||||
-rw-r--r-- | grc/receiver/CMakeLists.txt | 1 | ||||
-rw-r--r-- | grc/receiver/gsm_receiver.xml | 2 | ||||
-rw-r--r-- | grc/receiver/gsm_receiver_with_uplink.xml | 71 | ||||
-rw-r--r-- | include/grgsm/demapping/universal_ctrl_chans_demapper.h | 2 | ||||
-rw-r--r-- | include/grgsm/receiver/receiver.h | 2 | ||||
-rw-r--r-- | lib/demapping/universal_ctrl_chans_demapper_impl.cc | 268 | ||||
-rw-r--r-- | lib/demapping/universal_ctrl_chans_demapper_impl.h | 17 | ||||
-rw-r--r-- | lib/receiver/receiver_config.cc | 27 | ||||
-rw-r--r-- | lib/receiver/receiver_config.h | 4 | ||||
-rw-r--r-- | lib/receiver/receiver_impl.cc | 35 | ||||
-rw-r--r-- | lib/receiver/receiver_impl.h | 3 |
16 files changed, 423 insertions, 119 deletions
diff --git a/grc/demapping/gsm_bcch_ccch_demapper.xml b/grc/demapping/gsm_bcch_ccch_demapper.xml index f027f8e..b295ce1 100644 --- a/grc/demapping/gsm_bcch_ccch_demapper.xml +++ b/grc/demapping/gsm_bcch_ccch_demapper.xml @@ -3,7 +3,7 @@ <name>BCCH + CCCH demapper</name> <key>gsm_bcch_ccch_demapper</key> <import>import grgsm</import> - <make>grgsm.universal_ctrl_chans_demapper($timeslot_nr, $starts_fn_mod51, $channel_types)</make> + <make>grgsm.universal_ctrl_chans_demapper($timeslot_nr, $downlink_starts_fn_mod51, $downlink_channel_types, $uplink_starts_fn_mod51, $uplink_channel_types)</make> <param> <name>Timeslot</name> @@ -14,21 +14,37 @@ </param> <param> - <name>starts_fn_mod51</name> - <key>starts_fn_mod51</key> + <name>downlink_starts_fn_mod51</name> + <key>downlink_starts_fn_mod51</key> <value>[2,6,12,16,22,26,32,36,42,46]</value> <type>int_vector</type> <hide>all</hide> </param> <param> - <name>channel_types</name> - <key>channel_types</key> + <name>downlink_channel_types</name> + <key>downlink_channel_types</key> <value>[1,2,2,2,2,2,2,2,2,2]</value> <type>int_vector</type> <hide>all</hide> </param> + <param> + <name>uplink_starts_fn_mod51</name> + <key>uplink_starts_fn_mod51</key> + <value>[]</value> + <type>int_vector</type> + <hide>all</hide> + </param> + + <param> + <name>uplink_channel_types</name> + <key>uplink_channel_types</key> + <value>[]</value> + <type>int_vector</type> + <hide>all</hide> + </param> + <sink> <name>bursts</name> <type>message</type> diff --git a/grc/demapping/gsm_bcch_ccch_sdcch4_demapper.xml b/grc/demapping/gsm_bcch_ccch_sdcch4_demapper.xml index 80e67d5..90b33ce 100644 --- a/grc/demapping/gsm_bcch_ccch_sdcch4_demapper.xml +++ b/grc/demapping/gsm_bcch_ccch_sdcch4_demapper.xml @@ -3,7 +3,7 @@ <name>BCCH + CCCH + SDCCH/4 demapper</name> <key>gsm_bcch_ccch_sdcch4_demapper</key> <import>import grgsm</import> - <make>grgsm.universal_ctrl_chans_demapper($timeslot_nr, $starts_fn_mod51, $channel_types)</make> + <make>grgsm.universal_ctrl_chans_demapper($timeslot_nr, $downlink_starts_fn_mod51, $downlink_channel_types, $uplink_starts_fn_mod51, $uplink_channel_types)</make> <param> <name>Timeslot</name> @@ -14,21 +14,37 @@ </param> <param> - <name>starts_fn_mod51</name> - <key>starts_fn_mod51</key> + <name>downlink_starts_fn_mod51</name> + <key>downlink_starts_fn_mod51</key> <value>[2,6,12,16,22,26,32,36,42,46]</value> <type>int_vector</type> <hide>all</hide> </param> <param> - <name>channel_types</name> - <key>channel_types</key> + <name>downlink_channel_types</name> + <key>downlink_channel_types</key> <value>[1,2,2,2,7,7,7,7,135,135]</value> <type>int_vector</type> <hide>all</hide> </param> + <param> + <name>uplink_starts_fn_mod51</name> + <key>uplink_starts_fn_mod51</key> + <value>[0,6,10,37,41,47]</value> + <type>int_vector</type> + <hide>all</hide> + </param> + + <param> + <name>uplink_channel_types</name> + <key>uplink_channel_types</key> + <value>[7,135,135,7,7,7]</value> + <type>int_vector</type> + <hide>all</hide> + </param> + <sink> <name>bursts</name> <type>message</type> diff --git a/grc/demapping/gsm_sdcch8_demapper.xml b/grc/demapping/gsm_sdcch8_demapper.xml index 38a8112..c81032a 100644 --- a/grc/demapping/gsm_sdcch8_demapper.xml +++ b/grc/demapping/gsm_sdcch8_demapper.xml @@ -3,7 +3,7 @@ <name>SDCCH/8 demapper</name> <key>gsm_sdcch8_demapper</key> <import>import grgsm</import> - <make>grgsm.universal_ctrl_chans_demapper($timeslot_nr, $starts_fn_mod51, $channel_types)</make> + <make>grgsm.universal_ctrl_chans_demapper($timeslot_nr, $downlink_starts_fn_mod51, $downlink_channel_types, $uplink_starts_fn_mod51, $uplink_channel_types)</make> <param> <name>Timeslot</name> @@ -14,16 +14,32 @@ </param> <param> - <name>starts_fn_mod51</name> - <key>starts_fn_mod51</key> + <name>downlink_starts_fn_mod51</name> + <key>downlink_starts_fn_mod51</key> <value>[0,4,8,12,16,20,24,28,32,36,40,44]</value> <type>int_vector</type> <hide>all</hide> </param> <param> - <name>channel_types</name> - <key>channel_types</key> + <name>downlink_channel_types</name> + <key>downlink_channel_types</key> + <value>[8,8,8,8,8,8,8,8,136,136,136,136]</value> + <type>int_vector</type> + <hide>all</hide> + </param> + + <param> + <name>uplink_starts_fn_mod51</name> + <key>uplink_starts_fn_mod51</key> + <value>[15,19,23,27,31,35,39,43,47,0,4,8]</value> + <type>int_vector</type> + <hide>all</hide> + </param> + + <param> + <name>uplink_channel_types</name> + <key>uplink_channel_types</key> <value>[8,8,8,8,8,8,8,8,136,136,136,136]</value> <type>int_vector</type> <hide>all</hide> @@ -42,4 +58,4 @@ Demapper for SDCCH/8 + SACCH/C8 control channels. This corresponds to channel combination vii specified in GSM 05.02, section 6.4 </doc> -</block>
\ No newline at end of file +</block> diff --git a/grc/demapping/gsm_universal_ctrl_chans_demapper.xml b/grc/demapping/gsm_universal_ctrl_chans_demapper.xml index 1d8d202..3b522be 100644 --- a/grc/demapping/gsm_universal_ctrl_chans_demapper.xml +++ b/grc/demapping/gsm_universal_ctrl_chans_demapper.xml @@ -3,7 +3,7 @@ <name>Universal ctrl chans demapper</name> <key>gsm_universal_ctrl_chans_demapper</key> <import>import grgsm</import> - <make>grgsm.universal_ctrl_chans_demapper($timeslot_nr, $starts_fn_mod51, $channel_types)</make> + <make>grgsm.universal_ctrl_chans_demapper($timeslot_nr, $downlink_starts_fn_mod51, $downlink_channel_types, $uplink_starts_fn_mod51, $uplink_channel_types)</make> <param> <name>timeslot_nr</name> @@ -14,21 +14,37 @@ </param> <param> - <name>starts_fn_mod51</name> - <key>starts_fn_mod51</key> + <name>downlink_starts_fn_mod51</name> + <key>downlink_starts_fn_mod51</key> <value>[2,6,12,16,22,26,32,36,42,46]</value> <type>int_vector</type> <hide>part</hide> </param> <param> - <name>channel_types</name> - <key>channel_types</key> + <name>downlink_channel_types</name> + <key>downlink_channel_types</key> <value>[1,2,2,2,2,2,2,2,2,2]</value> <type>int_vector</type> <hide>part</hide> </param> + <param> + <name>uplink_starts_fn_mod51</name> + <key>uplink_starts_fn_mod51</key> + <value>[0,6,10,37,41,47]</value> + <type>int_vector</type> + <hide>part</hide> + </param> + + <param> + <name>uplink_channel_types</name> + <key>uplink_channel_types</key> + <value>[2,2,2,2,2,2]</value> + <type>int_vector</type> + <hide>part</hide> + </param> + <sink> <name>bursts</name> <type>message</type> @@ -37,4 +53,7 @@ <name>bursts</name> <type>message</type> </source> + <doc> + Universal demapper for control channels. + </doc> </block> diff --git a/grc/gsm_block_tree.xml b/grc/gsm_block_tree.xml index f49f055..0b15562 100644 --- a/grc/gsm_block_tree.xml +++ b/grc/gsm_block_tree.xml @@ -13,6 +13,7 @@ <cat> <name>Receiver</name> <block>gsm_receiver</block> + <block>gsm_receiver_with_uplink</block> <block>gsm_cx_channel_hopper</block> <block>gsm_fcch_burst_tagger</block> <block>gsm_sch_detector</block> diff --git a/grc/receiver/CMakeLists.txt b/grc/receiver/CMakeLists.txt index af7042d..bbc086f 100644 --- a/grc/receiver/CMakeLists.txt +++ b/grc/receiver/CMakeLists.txt @@ -21,6 +21,7 @@ install(FILES gsm_input.xml gsm_wideband_input.xml gsm_receiver.xml + gsm_receiver_with_uplink.xml gsm_fcch_burst_tagger.xml gsm_sch_detector.xml gsm_fcch_detector.xml diff --git a/grc/receiver/gsm_receiver.xml b/grc/receiver/gsm_receiver.xml index 2119fd2..2988243 100644 --- a/grc/receiver/gsm_receiver.xml +++ b/grc/receiver/gsm_receiver.xml @@ -3,7 +3,7 @@ <name>GSM Receiver</name> <key>gsm_receiver</key> <import>import grgsm</import> - <make>grgsm.receiver($osr, $cell_allocation, $tseq_nums)</make> + <make>grgsm.receiver($osr, $cell_allocation, $tseq_nums, False)</make> <param> <name>Oversampling ratio</name> diff --git a/grc/receiver/gsm_receiver_with_uplink.xml b/grc/receiver/gsm_receiver_with_uplink.xml new file mode 100644 index 0000000..4b68336 --- /dev/null +++ b/grc/receiver/gsm_receiver_with_uplink.xml @@ -0,0 +1,71 @@ +<?xml version="1.0"?> +<block> + <name>GSM Receiver (with uplink)</name> + <key>gsm_receiver_with_uplink</key> + <import>import grgsm</import> + <make>grgsm.receiver($osr, $cell_allocation, $tseq_nums, True)</make> + + <param> + <name>Oversampling ratio</name> + <key>osr</key> + <value>4</value> + <type>int</type> + </param> + + <param> + <name>Cell allocation</name> + <key>cell_allocation</key> + <value>[0]</value> + <type>float_vector</type> + <hide>part</hide> + </param> + + <param> + <name>TSEQ numbers</name> + <key>tseq_nums</key> + <value>[]</value> + <type>int_vector</type> + <hide>part</hide> + </param> + + <param> + <name>Num Streams</name> + <key>num_streams</key> + <value>1</value> + <type>int</type> + <hide>part</hide> + </param> + + <check>$num_streams >= 0</check> + + <sink> + <name>C</name> + <type>complex</type> + <nports>$num_streams</nports> + </sink> + + + <sink> + <name>C_up</name> + <type>complex</type> + <nports>$num_streams</nports> + </sink> + + <source> + <name>C0</name> + <type>message</type> + <optional>1</optional> + </source> + + <source> + <name>CX</name> + <type>message</type> + <optional>1</optional> + </source> + + <source> + <name>measurements</name> + <type>message</type> + <optional>1</optional> + </source> +</block> diff --git a/include/grgsm/demapping/universal_ctrl_chans_demapper.h b/include/grgsm/demapping/universal_ctrl_chans_demapper.h index d8114f7..9d7240c 100644 --- a/include/grgsm/demapping/universal_ctrl_chans_demapper.h +++ b/include/grgsm/demapping/universal_ctrl_chans_demapper.h @@ -49,7 +49,7 @@ namespace gr { * class. gsm::universal_ctrl_chans_demapper::make is the public interface for * creating new instances. */ - static sptr make(unsigned int timeslot_nr, const std::vector<int> &starts_fn_mod51, const std::vector<int> &channel_types); + static sptr make(unsigned int timeslot_nr, const std::vector<int> &downlink_starts_fn_mod51, const std::vector<int> &downlink_channel_types, const std::vector<int> &uplink_starts_fn_mod51, const std::vector<int> &uplink_channel_types); }; } // namespace gsm diff --git a/include/grgsm/receiver/receiver.h b/include/grgsm/receiver/receiver.h index 80124f7..00e749e 100644 --- a/include/grgsm/receiver/receiver.h +++ b/include/grgsm/receiver/receiver.h @@ -51,7 +51,7 @@ namespace gr { * class. gsm::receiver::make is the public interface for * creating new instances. */ - static sptr make(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &seq_nums); + static sptr make(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &seq_nums, bool process_uplink); virtual void set_cell_allocation(const std::vector<int> &cell_allocation) = 0; virtual void set_tseq_nums(const std::vector<int> & tseq_nums) = 0; diff --git a/lib/demapping/universal_ctrl_chans_demapper_impl.cc b/lib/demapping/universal_ctrl_chans_demapper_impl.cc index c711928..cbbbc32 100644 --- a/lib/demapping/universal_ctrl_chans_demapper_impl.cc +++ b/lib/demapping/universal_ctrl_chans_demapper_impl.cc @@ -36,16 +36,16 @@ namespace gr { namespace gsm { universal_ctrl_chans_demapper::sptr - universal_ctrl_chans_demapper::make(unsigned int timeslot_nr, const std::vector<int> &starts_fn_mod51, const std::vector<int> &channel_types) + universal_ctrl_chans_demapper::make(unsigned int timeslot_nr, const std::vector<int> &downlink_starts_fn_mod51, const std::vector<int> &downlink_channel_types, const std::vector<int> &uplink_starts_fn_mod51, const std::vector<int> &uplink_channel_types) { return gnuradio::get_initial_sptr - (new universal_ctrl_chans_demapper_impl(timeslot_nr, starts_fn_mod51, channel_types)); + (new universal_ctrl_chans_demapper_impl(timeslot_nr, downlink_starts_fn_mod51, downlink_channel_types, uplink_starts_fn_mod51, uplink_channel_types)); } /* * The private constructor */ - universal_ctrl_chans_demapper_impl::universal_ctrl_chans_demapper_impl(unsigned int timeslot_nr, const std::vector<int> &starts_fn_mod51, const std::vector<int> &channel_types) + universal_ctrl_chans_demapper_impl::universal_ctrl_chans_demapper_impl(unsigned int timeslot_nr, const std::vector<int> &downlink_starts_fn_mod51, const std::vector<int> &downlink_channel_types, const std::vector<int> &uplink_starts_fn_mod51, const std::vector<int> &uplink_channel_types) : gr::block("universal_ctrl_chans_demapper", gr::io_signature::make(0, 0, 0), gr::io_signature::make(0, 0, 0)), @@ -56,75 +56,137 @@ namespace gr { for(int ii=0; ii<51; ii++) { - d_starts_fn_mod51[ii]=0; - d_channel_types[ii]=0; - d_subslots[ii] = 0; - d_subslots[ii+51] = 0; + d_downlink_starts_fn_mod51[ii]=0; + d_downlink_channel_types[ii]=0; + d_downlink_subslots[ii] = 0; + d_downlink_subslots[ii+51] = 0; + + d_uplink_starts_fn_mod51[ii]=0; + d_uplink_channel_types[ii]=0; + d_uplink_subslots[ii] = 0; + d_uplink_subslots[ii+51] = 0; } std::vector<int>::const_iterator s; std::vector<int>::const_iterator ch_type; - for(s=starts_fn_mod51.begin(), ch_type=channel_types.begin();s != starts_fn_mod51.end(); s++) + for(s=downlink_starts_fn_mod51.begin(), ch_type=downlink_channel_types.begin();s != downlink_starts_fn_mod51.end(); s++) + { + if((*s >= 0) and (*s <= (51-4))) + { + for(int ii=0; ii<4; ii++){ + d_downlink_starts_fn_mod51[*s+ii] = *s; + if(ch_type!=downlink_channel_types.end()) + { + d_downlink_channel_types[*s+ii] = *ch_type; + } + } + if(ch_type!=downlink_channel_types.end()) + { + ch_type++; + } + } + } + + for(s=uplink_starts_fn_mod51.begin(), ch_type=uplink_channel_types.begin();s != uplink_starts_fn_mod51.end(); s++) { if((*s >= 0) and (*s <= (51-4))) { for(int ii=0; ii<4; ii++){ - d_starts_fn_mod51[*s+ii] = *s; - if(ch_type!=channel_types.end()) + d_uplink_starts_fn_mod51[*s+ii] = *s; + if(ch_type!=uplink_channel_types.end()) { - d_channel_types[*s+ii] = *ch_type; + d_uplink_channel_types[*s+ii] = *ch_type; } } - if(ch_type!=channel_types.end()) + if(ch_type!=uplink_channel_types.end()) { ch_type++; } } } - std::set<int> distinct_channels(channel_types.begin(), channel_types.end()); - std::set<int>::iterator it; + std::set<int> distinct_downlink_channels(downlink_channel_types.begin(), downlink_channel_types.end()); + std::set<int>::iterator it; unsigned int subslot; - - for (it=distinct_channels.begin(); it != distinct_channels.end(); it++) - { - subslot = 0; - for(s=starts_fn_mod51.begin();s != starts_fn_mod51.end(); s++) - { - if ((d_channel_types[*s] == *it) and (*s >= 0) and (*s <= (51-4))) - { - for(int ii=0; ii<4; ii++) - { - d_subslots[*s+ii] = subslot; - d_subslots[*s+ii+51] = subslot; - } - subslot++; - } - } - - if (*it == GSMTAP_CHANNEL_ACCH or - *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_SDCCH) or - *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_SDCCH4) or - *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_SDCCH8) or - *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_TCH_F) or - *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_TCH_H) - ) - { - for(s=starts_fn_mod51.begin();s != starts_fn_mod51.end(); s++) - { - if ((d_channel_types[*s] == *it) and (*s >= 0) and (*s <= (51-4))) - { - for(int ii=0; ii<4; ii++) - { - d_subslots[*s+ii+51] = subslot; - } - subslot++; - } - } - } - } + for (it=distinct_downlink_channels.begin(); it != distinct_downlink_channels.end(); it++) + { + subslot = 0; + for(s=downlink_starts_fn_mod51.begin();s != downlink_starts_fn_mod51.end(); s++) + { + if ((d_downlink_channel_types[*s] == *it) and (*s >= 0) and (*s <= (51-4))) + { + for(int ii=0; ii<4; ii++) + { + d_downlink_subslots[*s+ii] = subslot; + d_downlink_subslots[*s+ii+51] = subslot; + } + subslot++; + } + } + + if (*it == GSMTAP_CHANNEL_ACCH or + *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_SDCCH) or + *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_SDCCH4) or + *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_SDCCH8) or + *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_TCH_F) or + *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_TCH_H) + ) + { + for(s=downlink_starts_fn_mod51.begin();s != downlink_starts_fn_mod51.end(); s++) + { + if ((d_downlink_channel_types[*s] == *it) and (*s >= 0) and (*s <= (51-4))) + { + for(int ii=0; ii<4; ii++) + { + d_downlink_subslots[*s+ii+51] = subslot; + } + subslot++; + } + } + } + } + + std::set<int> distinct_uplink_channels(uplink_channel_types.begin(), uplink_channel_types.end()); + for (it=distinct_uplink_channels.begin(); it != distinct_uplink_channels.end(); it++) + { + subslot = 0; + for(s=uplink_starts_fn_mod51.begin();s != uplink_starts_fn_mod51.end(); s++) + { + if ((d_uplink_channel_types[*s] == *it) and (*s >= 0) and (*s <= (51-4))) + { + for(int ii=0; ii<4; ii++) + { + d_uplink_subslots[*s+ii] = subslot; + d_uplink_subslots[*s+ii+51] = subslot; + } + subslot++; + } + } + + if (*it == GSMTAP_CHANNEL_ACCH or + *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_SDCCH) or + *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_SDCCH4) or + *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_SDCCH8) or + *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_TCH_F) or + *it == (GSMTAP_CHANNEL_ACCH|GSMTAP_CHANNEL_TCH_H) + ) + { + for(s=uplink_starts_fn_mod51.begin();s != uplink_starts_fn_mod51.end(); s++) + { + if ((d_uplink_channel_types[*s] == *it) and (*s >= 0) and (*s <= (51-4))) + { + for(int ii=0; ii<4; ii++) + { + d_uplink_subslots[*s+ii+51] = subslot; + } + subslot++; + } + } + } + } + message_port_register_in(pmt::mp("bursts")); set_msg_handler(pmt::mp("bursts"), boost::bind(&universal_ctrl_chans_demapper_impl::filter_ctrl_chans, this, _1)); @@ -142,52 +204,102 @@ namespace gr { { pmt::pmt_t header_plus_burst = pmt::cdr(msg); gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst); - + uint32_t frame_nr = be32toh(header->frame_number); uint32_t fn_mod51 = frame_nr % 51; - uint32_t fn51_start = d_starts_fn_mod51[fn_mod51]; - uint32_t fn51_stop = fn51_start + 3; - uint32_t ch_type = d_channel_types[fn_mod51]; + bool uplink_burst = (be16toh(header->arfcn) & 0x4000) ? true : false; + if(header->timeslot==d_timeslot){ int8_t new_msg[sizeof(gsmtap_hdr)+BURST_SIZE]; gsmtap_hdr * new_hdr = (gsmtap_hdr*)new_msg; memcpy(new_msg, header, sizeof(gsmtap_hdr)+BURST_SIZE); - new_hdr->sub_type = ch_type; - new_hdr->sub_slot = d_subslots[fn_mod51 + (51 * (frame_nr % 2))]; pmt::pmt_t msg_binary_blob = pmt::make_blob(new_msg,sizeof(gsmtap_hdr)+BURST_SIZE); pmt::pmt_t msg_out = pmt::cons(pmt::PMT_NIL, msg_binary_blob); - if(fn_mod51>=fn51_start && fn_mod51<=fn51_stop) - { - uint32_t ii = fn_mod51 - fn51_start; - d_frame_numbers[ii] = frame_nr; - d_bursts[ii] = msg_out; - } - - if(fn_mod51==fn51_stop) + if(uplink_burst) { - //check for a situation where some bursts were lost - //in this situation frame numbers won't be consecutive - bool frames_are_consecutive = true; - for(int jj=1; jj<4; jj++) + uint32_t fn51_start = d_uplink_starts_fn_mod51[fn_mod51]; + uint32_t fn51_stop = fn51_start + 3; + uint32_t ch_type = d_uplink_channel_types[fn_mod51]; + + if(ch_type != 0) { - if((d_frame_numbers[jj]-d_frame_numbers[jj-1])!=1) + new_hdr->sub_type = ch_type; + } + new_hdr->sub_slot = d_uplink_subslots[fn_mod51 + (51 * (frame_nr % 2))]; + + if(fn_mod51>=fn51_start && fn_mod51<=fn51_stop) + { + uint32_t ii = fn_mod51 - fn51_start; + d_uplink_frame_numbers[ii] = frame_nr; + d_uplink_bursts[ii] = msg_out; + } + + if(fn_mod51==fn51_stop) + { + //check for a situation where some bursts were lost + //in this situation frame numbers won't be consecutive + bool frames_are_consecutive = true; + for(int jj=1; jj<4; jj++) { - frames_are_consecutive = false; + if((d_uplink_frame_numbers[jj]-d_uplink_frame_numbers[jj-1])!=1) + { + frames_are_consecutive = false; + } } + if(frames_are_consecutive) + { + //send bursts to the output + for(int jj=0; jj<4; jj++) + { + message_port_pub(pmt::mp("bursts"), d_uplink_bursts[jj]); + } + } } - if(frames_are_consecutive) + } + else + { + uint32_t fn51_start = d_downlink_starts_fn_mod51[fn_mod51]; + uint32_t fn51_stop = fn51_start + 3; + uint32_t ch_type = d_downlink_channel_types[fn_mod51]; + + if(ch_type != 0) + { + new_hdr->sub_type = ch_type; + } + new_hdr->sub_slot = d_downlink_subslots[fn_mod51 + (51 * (frame_nr % 2))]; + + if(fn_mod51>=fn51_start && fn_mod51<=fn51_stop) + { + uint32_t ii = fn_mod51 - fn51_start; + d_downlink_frame_numbers[ii] = frame_nr; + d_downlink_bursts[ii] = msg_out; + } + + if(fn_mod51==fn51_stop) { - //send bursts to the output - for(int jj=0; jj<4; jj++) + //check for a situation where some bursts were lost + //in this situation frame numbers won't be consecutive + bool frames_are_consecutive = true; + for(int jj=1; jj<4; jj++) { - message_port_pub(pmt::mp("bursts"), d_bursts[jj]); + if((d_downlink_frame_numbers[jj]-d_downlink_frame_numbers[jj-1])!=1) + { + frames_are_consecutive = false; + } } - } + if(frames_are_consecutive) + { + //send bursts to the output + for(int jj=0; jj<4; jj++) + { + message_port_pub(pmt::mp("bursts"), d_downlink_bursts[jj]); + } + } + } } } } } /* namespace gsm */ } /* namespace gr */ - diff --git a/lib/demapping/universal_ctrl_chans_demapper_impl.h b/lib/demapping/universal_ctrl_chans_demapper_impl.h index d4e1440..0316bf4 100644 --- a/lib/demapping/universal_ctrl_chans_demapper_impl.h +++ b/lib/demapping/universal_ctrl_chans_demapper_impl.h @@ -32,14 +32,19 @@ namespace gr { class universal_ctrl_chans_demapper_impl : public universal_ctrl_chans_demapper { private: - unsigned int d_starts_fn_mod51[51]; - unsigned int d_channel_types[51]; - unsigned int d_subslots[102]; + unsigned int d_downlink_starts_fn_mod51[51]; + unsigned int d_uplink_starts_fn_mod51[51]; + unsigned int d_downlink_channel_types[51]; + unsigned int d_uplink_channel_types[51]; + unsigned int d_downlink_subslots[102]; + unsigned int d_uplink_subslots[102]; unsigned int d_timeslot; - uint32_t d_frame_numbers[4]; - pmt::pmt_t d_bursts[4]; + uint32_t d_downlink_frame_numbers[4]; + uint32_t d_uplink_frame_numbers[4]; + pmt::pmt_t d_downlink_bursts[4]; + pmt::pmt_t d_uplink_bursts[4]; public: - universal_ctrl_chans_demapper_impl(unsigned int timeslot_nr, const std::vector<int> &starts_fn_mod51, const std::vector<int> &channel_types); + universal_ctrl_chans_demapper_impl(unsigned int timeslot_nr, const std::vector<int> &downlink_starts_fn_mod51, const std::vector<int> &downlink_channel_types, const std::vector<int> &uplink_starts_fn_mod51, const std::vector<int> &uplink_channel_types); ~universal_ctrl_chans_demapper_impl(); void filter_ctrl_chans(pmt::pmt_t msg); diff --git a/lib/receiver/receiver_config.cc b/lib/receiver/receiver_config.cc index c8b85c7..0abf200 100644 --- a/lib/receiver/receiver_config.cc +++ b/lib/receiver/receiver_config.cc @@ -46,6 +46,33 @@ burst_counter & burst_counter::operator++(int) return (*this); } +burst_counter burst_counter::subtract_timeslots(unsigned int number_of_timeslots) +{ + int timeslot_nr = (int)d_timeslot_nr - (int)number_of_timeslots; + int t1,t2,t3; + if (timeslot_nr < 0) { + timeslot_nr = timeslot_nr + 8; + + t2 = (d_t2 - 1) % 26; + t3 = (d_t3 - 1) % 51; + + if ((d_t2 == 0) && (d_t3 == 0)) { + t1 = (d_t1 - 1) % (1 << 11); + } else + { + t1 = d_t1; + } + } + else + { + t1 = d_t1; + t2 = d_t2; + t3 = d_t3; + } + + return burst_counter(d_OSR, t1, t2, t3, timeslot_nr); +} + void burst_counter::set(uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr) { d_t1 = t1; diff --git a/lib/receiver/receiver_config.h b/lib/receiver/receiver_config.h index 496e1fe..17b98c8 100644 --- a/lib/receiver/receiver_config.h +++ b/lib/receiver/receiver_config.h @@ -89,12 +89,14 @@ class burst_counter d_t3(t3), d_timeslot_nr(timeslot_nr), d_offset_fractional(0.0), - d_offset_integer(0.0) { + d_offset_integer(0.0) + { d_offset_integer = 0; d_offset_fractional = 0; } burst_counter & operator++(int); + burst_counter subtract_timeslots(unsigned int number_of_timeslots); void set(uint32_t t1, uint32_t t2, uint32_t t3, uint32_t timeslot_nr); uint32_t get_t1() { diff --git a/lib/receiver/receiver_impl.cc b/lib/receiver/receiver_impl.cc index bd2b306..09a3703 100644 --- a/lib/receiver/receiver_impl.cc +++ b/lib/receiver/receiver_impl.cc @@ -52,20 +52,21 @@ namespace gr namespace gsm { receiver::sptr -receiver::make(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &tseq_nums) +receiver::make(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &tseq_nums, bool process_uplink) { return gnuradio::get_initial_sptr - (new receiver_impl(osr, cell_allocation, tseq_nums)); + (new receiver_impl(osr, cell_allocation, tseq_nums, process_uplink)); } /* * The private constructor */ -receiver_impl::receiver_impl(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &tseq_nums) +receiver_impl::receiver_impl(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &tseq_nums, bool process_uplink) : gr::sync_block("receiver", gr::io_signature::make(1, -1, sizeof(gr_complex)), gr::io_signature::make(0, 0, 0)), d_OSR(osr), + d_process_uplink(process_uplink), d_chan_imp_length(CHAN_IMP_RESP_LENGTH), d_counter(0), d_fcch_start_pos(0), @@ -172,7 +173,7 @@ receiver_impl::work(int noutput_items, { burst_start = get_sch_chan_imp_resp(input, &channel_imp_resp[0]); //get channel impulse response from it 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 + if (decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc) == 0) //decode SCH burst { d_burst_nr.set(t1, t2, t3, 0); //set counter of bursts value d_burst_nr++; @@ -198,10 +199,15 @@ receiver_impl::work(int noutput_items, int offset = 0; int to_consume = 0; unsigned char output_binary[BURST_SIZE]; - burst_type b_type; + unsigned int inputs_to_process=d_cell_allocation.size(); + + if(d_process_uplink) + { + inputs_to_process = 2*inputs_to_process; + } - for(int input_nr=0; input_nr<d_cell_allocation.size(); input_nr++) + for(int input_nr=0; input_nr<inputs_to_process; input_nr++) { double signal_pwr = 0; input = (gr_complex *)input_items[input_nr]; @@ -827,10 +833,21 @@ void receiver_impl::send_burst(burst_counter burst_nr, const unsigned char * bur tap_header->version = GSMTAP_VERSION; tap_header->hdr_len = sizeof(gsmtap_hdr)/4; tap_header->type = GSMTAP_TYPE_UM_BURST; - tap_header->timeslot = static_cast<uint8_t>(d_burst_nr.get_timeslot_nr()); - tap_header->frame_number = htobe32(d_burst_nr.get_frame_nr()); tap_header->sub_type = burst_type; - tap_header->arfcn = htobe16(d_cell_allocation[input_nr]) ; + bool uplink_burst = (input_nr >= d_cell_allocation.size()); + if(!uplink_burst) // downlink burst + { + tap_header->timeslot = static_cast<uint8_t>(d_burst_nr.get_timeslot_nr()); + tap_header->frame_number = htobe32(d_burst_nr.get_frame_nr()); + tap_header->arfcn = htobe16(d_cell_allocation[input_nr]) ; + } + else //uplink burst + { + tap_header->timeslot = static_cast<uint8_t>(d_burst_nr.subtract_timeslots(3).get_timeslot_nr()); + tap_header->frame_number = htobe32(d_burst_nr.subtract_timeslots(3).get_frame_nr()); + input_nr = input_nr - d_cell_allocation.size(); + tap_header->arfcn = htobe16(d_cell_allocation[input_nr] | 0x4000); + } tap_header->signal_dbm = static_cast<int8_t>(d_signal_dbm); tap_header->snr_db = 0; diff --git a/lib/receiver/receiver_impl.h b/lib/receiver/receiver_impl.h index d668e14..c8d71f9 100644 --- a/lib/receiver/receiver_impl.h +++ b/lib/receiver/receiver_impl.h @@ -39,6 +39,7 @@ namespace gr { /**@name Configuration of the receiver */ //@{ const int d_OSR; ///< oversampling ratio + bool d_process_uplink; const int d_chan_imp_length; ///< channel impulse length float d_signal_dbm; std::vector<int> d_tseq_nums; ///< stores training sequence numbers for channels different than C0 @@ -203,7 +204,7 @@ namespace gr { public: - receiver_impl(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &tseq_nums); + receiver_impl(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &tseq_nums, bool process_uplink); ~receiver_impl(); int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); |