blob: 6754e571c130e0158b4cc7652db7e1bb097eb8b1 [file] [log] [blame]
ptrkrysik6dded652014-11-19 11:32:05 +01001/* -*- c++ -*- */
ptrkrysik529895b2014-12-02 18:07:38 +01002/*
3 * @file
4 * @author Piotr Krysik <ptrkrysik@gmail.com>
5 * @section LICENSE
6 *
7 * Gr-gsm is free software; you can redistribute it and/or modify
ptrkrysik6dded652014-11-19 11:32:05 +01008 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
ptrkrysik529895b2014-12-02 18:07:38 +010011 *
12 * Gr-gsm is distributed in the hope that it will be useful,
ptrkrysik6dded652014-11-19 11:32:05 +010013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
ptrkrysik529895b2014-12-02 18:07:38 +010016 *
ptrkrysik6dded652014-11-19 11:32:05 +010017 * You should have received a copy of the GNU General Public License
ptrkrysik529895b2014-12-02 18:07:38 +010018 * along with gr-gsm; see the file COPYING. If not, write to
ptrkrysik6dded652014-11-19 11:32:05 +010019 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include <gnuradio/io_signature.h>
28#include "universal_ctrl_chans_demapper_impl.h"
ptrkrysik3be74a72014-12-13 10:11:00 +010029#include <grgsm/endian.h>
30#include <grgsm/gsmtap.h>
ptrkrysik42411c62015-07-08 10:50:41 +020031#include <set>
ptrkrysik6dded652014-11-19 11:32:05 +010032
iZsh66987932015-08-16 14:42:18 +020033#define BURST_SIZE 148
34
ptrkrysik6dded652014-11-19 11:32:05 +010035namespace gr {
36 namespace gsm {
37
38 universal_ctrl_chans_demapper::sptr
Piotr Krysik773a1942016-05-20 12:45:54 +020039 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> &downlink_subslots, const std::vector<int> &uplink_starts_fn_mod51, const std::vector<int> &uplink_channel_types, const std::vector<int> &uplink_subslots)
40 {
ptrkrysik6dded652014-11-19 11:32:05 +010041 return gnuradio::get_initial_sptr
Piotr Krysik773a1942016-05-20 12:45:54 +020042 (new universal_ctrl_chans_demapper_impl(timeslot_nr, downlink_starts_fn_mod51, downlink_channel_types, downlink_subslots, uplink_starts_fn_mod51, uplink_channel_types, uplink_subslots));
ptrkrysik6dded652014-11-19 11:32:05 +010043 }
44
45 /*
46 * The private constructor
47 */
Piotr Krysik773a1942016-05-20 12:45:54 +020048 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> &downlink_subslots, const std::vector<int> &uplink_starts_fn_mod51, const std::vector<int> &uplink_channel_types, const std::vector<int> &uplink_subslots)
ptrkrysik6dded652014-11-19 11:32:05 +010049 : gr::block("universal_ctrl_chans_demapper",
50 gr::io_signature::make(0, 0, 0),
ptrkrysikd8d4fbc2015-02-07 19:37:42 +010051 gr::io_signature::make(0, 0, 0)),
Piotr Krysik773a1942016-05-20 12:45:54 +020052 d_timeslot_nr(timeslot_nr),
53 d_downlink_starts_fn_mod51(51, 0),
54 d_downlink_channel_types(51, 0),
55 d_downlink_subslots(102, 0),
56 d_uplink_starts_fn_mod51(51, 0),
57 d_uplink_channel_types(51, 0),
58 d_uplink_subslots(102, 0)
ptrkrysik6dded652014-11-19 11:32:05 +010059 {
Piotr Krysikf517bea2016-05-21 09:02:12 +020060 if(downlink_starts_fn_mod51.size() != 51 ||
61 downlink_channel_types.size() != 51 ||
62 downlink_subslots.size() != 102 ||
63 uplink_starts_fn_mod51.size() != 51 ||
64 uplink_channel_types.size() != 51 ||
65 uplink_subslots.size() != 102 )
66 {
67 std::cout << "Check lengths of the vectors passed to the universal demapper - _starts_fn_mod15 and _sublots should have 51 elements, _subslots should have 102 elements" << std::endl;
68 std::runtime_error("Check lengths of the vectors passed to the universal demapper - _starts_fn_mod15 and _sublots should have 51 elements, _subslots should have 102 elements");
69 }
Piotr Krysik773a1942016-05-20 12:45:54 +020070 std::copy(downlink_starts_fn_mod51.begin(), downlink_starts_fn_mod51.end(), d_downlink_starts_fn_mod51.begin());
71 std::copy(downlink_channel_types.begin(), downlink_channel_types.end(), d_downlink_channel_types.begin());
72 std::copy(downlink_subslots.begin(), downlink_subslots.end(), d_downlink_subslots.begin());
73 std::copy(uplink_starts_fn_mod51.begin(), uplink_starts_fn_mod51.end(), d_uplink_starts_fn_mod51.begin());
74 std::copy(uplink_channel_types.begin(), uplink_channel_types.end(), d_uplink_channel_types.begin());
75 std::copy(uplink_subslots.begin(), uplink_subslots.end(), d_uplink_subslots.begin());
76
ptrkrysik6dded652014-11-19 11:32:05 +010077 message_port_register_in(pmt::mp("bursts"));
78 set_msg_handler(pmt::mp("bursts"), boost::bind(&universal_ctrl_chans_demapper_impl::filter_ctrl_chans, this, _1));
79 message_port_register_out(pmt::mp("bursts"));
80 }
81
82 /*
83 * Our virtual destructor.
84 */
85 universal_ctrl_chans_demapper_impl::~universal_ctrl_chans_demapper_impl()
86 {
87 }
88
89 void universal_ctrl_chans_demapper_impl::filter_ctrl_chans(pmt::pmt_t msg)
90 {
ptrkrysik617ba032014-11-21 10:11:05 +010091 pmt::pmt_t header_plus_burst = pmt::cdr(msg);
92 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst);
ptrkrysik6dded652014-11-19 11:32:05 +010093
Piotr Krysik773a1942016-05-20 12:45:54 +020094 if(header->timeslot==d_timeslot_nr)
95 {
96 int * starts_fn_mod51;
97 int * channel_types;
98 int * subslots;
99 uint32_t * frame_numbers;
100 pmt::pmt_t * bursts;
101
102 uint32_t frame_nr = be32toh(header->frame_number); //get frame number
103 uint32_t fn_mod51 = frame_nr % 51; //frame number modulo 51
104
105 //crate new message
iZsh66987932015-08-16 14:42:18 +0200106 int8_t new_msg[sizeof(gsmtap_hdr)+BURST_SIZE];
107 gsmtap_hdr * new_hdr = (gsmtap_hdr*)new_msg;
108 memcpy(new_msg, header, sizeof(gsmtap_hdr)+BURST_SIZE);
iZsh66987932015-08-16 14:42:18 +0200109 pmt::pmt_t msg_binary_blob = pmt::make_blob(new_msg,sizeof(gsmtap_hdr)+BURST_SIZE);
110 pmt::pmt_t msg_out = pmt::cons(pmt::PMT_NIL, msg_binary_blob);
Piotr Krysik9f723fd2015-08-06 10:23:52 +0200111
Piotr Krysik773a1942016-05-20 12:45:54 +0200112 //get information if burst is from uplink or downlink
113 bool uplink_burst = (be16toh(header->arfcn) & 0x4000) ? true : false;
114
115 //select right set of configuration and history for uplink or downlink
116 if(uplink_burst) {
117 starts_fn_mod51 = &d_uplink_starts_fn_mod51[0];
118 channel_types = &d_uplink_channel_types[0];
119 subslots = &d_uplink_subslots[0];
120 frame_numbers = d_uplink_frame_numbers;
121 bursts = d_uplink_bursts;
122 } else {
123 starts_fn_mod51 = &d_downlink_starts_fn_mod51[0];
124 channel_types = &d_downlink_channel_types[0];
125 subslots = &d_downlink_subslots[0];
126 frame_numbers = d_downlink_frame_numbers;
127 bursts = d_downlink_bursts;
Piotr Krysik9f723fd2015-08-06 10:23:52 +0200128 }
Piotr Krysik773a1942016-05-20 12:45:54 +0200129
130 uint32_t fn51_start = starts_fn_mod51[fn_mod51];
131 uint32_t fn51_stop = fn51_start + 3;
132 uint32_t ch_type = channel_types[fn_mod51];
Piotr Krysik9f723fd2015-08-06 10:23:52 +0200133
Piotr Krysik773a1942016-05-20 12:45:54 +0200134 if(ch_type != 0)
135 {
136 new_hdr->sub_type = ch_type;
137 }
138 new_hdr->sub_slot = subslots[fn_mod51 + (51 * (frame_nr % 2))];
139
140 if(fn_mod51>=fn51_start && fn_mod51<=fn51_stop)
141 {
142 uint32_t ii = fn_mod51 - fn51_start;
143 frame_numbers[ii] = frame_nr;
144 bursts[ii] = msg_out;
145 }
146
147 if(fn_mod51==fn51_stop)
148 {
149 //check for a situation where some bursts were lost
150 //in this situation frame numbers won't be consecutive
151 bool frames_are_consecutive = true;
152 for(int jj=1; jj<4; jj++)
Piotr Krysik9f723fd2015-08-06 10:23:52 +0200153 {
Piotr Krysik773a1942016-05-20 12:45:54 +0200154 if((frame_numbers[jj] - frame_numbers[jj-1])!=1)
Piotr Krysik9f723fd2015-08-06 10:23:52 +0200155 {
Piotr Krysik773a1942016-05-20 12:45:54 +0200156 frames_are_consecutive = false;
Piotr Krysik9f723fd2015-08-06 10:23:52 +0200157 }
Piotr Krysik9f723fd2015-08-06 10:23:52 +0200158 }
Piotr Krysik773a1942016-05-20 12:45:54 +0200159 if(frames_are_consecutive)
160 {
161 //send bursts to the output
162 for(int jj=0; jj<4; jj++)
163 {
164 message_port_pub(pmt::mp("bursts"), bursts[jj]);
165 }
166 }
ptrkrysik6dded652014-11-19 11:32:05 +0100167 }
168 }
169 }
170 } /* namespace gsm */
171} /* namespace gr */