blob: cc72f99c7e7a5a2617e4348b3c102115fb6db514 [file] [log] [blame]
Roman Khassraf8b64d872015-08-06 17:30:04 +02001/* -*- c++ -*- */
2/* @file
Piotr Krysika6268a52017-08-23 16:02:19 +02003 * @author (C) 2015 by Roman Khassraf <rkhassraf@gmail.com>
Roman Khassraf8b64d872015-08-06 17:30:04 +02004 * @section LICENSE
5 *
6 * Gr-gsm is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
10 *
11 * Gr-gsm is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with gr-gsm; see the file COPYING. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include <gnuradio/io_signature.h>
28#include "burst_sdcch_subslot_filter_impl.h"
29#include <stdio.h>
30#include <grgsm/endian.h>
31#include <grgsm/gsmtap.h>
32
Roman Khassraf8b64d872015-08-06 17:30:04 +020033namespace gr {
34 namespace gsm {
35
36 burst_sdcch_subslot_filter::sptr
37 burst_sdcch_subslot_filter::make(subslot_filter_mode mode, unsigned int subslot)
38 {
39 return gnuradio::get_initial_sptr
40 (new burst_sdcch_subslot_filter_impl(mode, subslot));
41 }
42
43 /*
44 * The private constructor
45 */
46 burst_sdcch_subslot_filter_impl::burst_sdcch_subslot_filter_impl(subslot_filter_mode mode, unsigned int subslot)
47 : gr::block("burst_sdcch_subslot_filter",
48 gr::io_signature::make(0, 0, 0),
49 gr::io_signature::make(0, 0, 0)),
Piotr Krysik4ea1b922016-02-28 11:25:52 +010050 d_mode(mode),
Vadim Yanitskiy04536ab2017-07-21 10:59:51 +070051 d_subslot(subslot),
52 d_filter_policy(FILTER_POLICY_DEFAULT)
Roman Khassraf8b64d872015-08-06 17:30:04 +020053 {
54 message_port_register_in(pmt::mp("in"));
55 message_port_register_out(pmt::mp("out"));
56
57 set_msg_handler(pmt::mp("in"), boost::bind(&burst_sdcch_subslot_filter_impl::process_burst, this, _1));
58 }
59
60 /*
61 * Our virtual destructor.
62 */
63 burst_sdcch_subslot_filter_impl::~burst_sdcch_subslot_filter_impl() {}
64
65 void burst_sdcch_subslot_filter_impl::process_burst(pmt::pmt_t msg)
Piotr Krysik4ea1b922016-02-28 11:25:52 +010066 {
Steve Glassc8edec52015-09-27 16:14:33 +100067 // hardcoded subslots of the channels, both SDCCH and the associated SACCH
68 // -1 means that the particular position in the frame is not SDCCH
69 static const int8_t subslots_sdcch4[102] = {
Piotr Krysik4ea1b922016-02-28 11:25:52 +010070 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 1, 1, 1, 1,-1,-1, 2, 2, 2, 2, 3, 3, 3, 3,-1,-1, 0, 0, 0, 0, 1, 1, 1, 1,-1,
71 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 1, 1, 1, 1,-1,-1, 2, 2, 2, 2, 3, 3, 3, 3,-1,-1, 2, 2, 2, 2, 3, 3, 3, 3,-1
Steve Glassc8edec52015-09-27 16:14:33 +100072 };
73 static const int8_t subslots_sdcch8[102] = {
Piotr Krysik4ea1b922016-02-28 11:25:52 +010074 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,-1,-1,-1,
75 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,-1,-1,-1
Steve Glassc8edec52015-09-27 16:14:33 +100076 };
Vadim Yanitskiy04536ab2017-07-21 10:59:51 +070077
78 if (d_filter_policy == FILTER_POLICY_DROP_ALL)
79 return;
80
81 if (d_filter_policy == FILTER_POLICY_PASS_ALL) {
82 message_port_pub(pmt::mp("out"), msg);
83 return;
84 }
Piotr Krysik4ea1b922016-02-28 11:25:52 +010085
Roman Khassraf8b64d872015-08-06 17:30:04 +020086 pmt::pmt_t header_plus_burst = pmt::cdr(msg);
87 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst);
88
89 uint32_t frame_nr = be32toh(header->frame_number);
90 uint32_t fn_mod102 = frame_nr % 102;
91
92 int8_t subslot;
93
94 if (d_mode == SS_FILTER_SDCCH8)
95 {
Steve Glassc8edec52015-09-27 16:14:33 +100096 subslot = subslots_sdcch8[fn_mod102];
Roman Khassraf8b64d872015-08-06 17:30:04 +020097 }
98 else if (d_mode == SS_FILTER_SDCCH4)
99 {
Steve Glassc8edec52015-09-27 16:14:33 +1000100 subslot = subslots_sdcch4[fn_mod102];
Roman Khassraf8b64d872015-08-06 17:30:04 +0200101 }
102
103 if ((subslot == -1) || (d_mode == SS_FILTER_SDCCH4 && subslot > 3))
104 {
105 return;
106 }
107
108 if (subslot == d_subslot)
109 {
110 message_port_pub(pmt::mp("out"), msg);
111 }
112 }
Vadim Yanitskiyfbfd8362017-07-21 07:18:05 +0700113
114 /* External API */
115 unsigned int
116 burst_sdcch_subslot_filter_impl::get_ss(void)
117 {
118 return d_subslot;
119 }
120
121 unsigned int
122 burst_sdcch_subslot_filter_impl::set_ss(unsigned int ss)
123 {
124 if ((d_mode == SS_FILTER_SDCCH8 && ss < 8)
125 || (d_mode == SS_FILTER_SDCCH4 && ss < 4))
126 d_subslot = ss;
127
128 return d_subslot;
129 }
130
131
132 subslot_filter_mode
133 burst_sdcch_subslot_filter_impl::get_mode(void)
134 {
135 return d_mode;
136 }
137
138 subslot_filter_mode
139 burst_sdcch_subslot_filter_impl::set_mode(subslot_filter_mode mode)
140 {
141 d_mode = mode;
142 return d_mode;
143 }
144
Vadim Yanitskiy04536ab2017-07-21 10:59:51 +0700145 /* Filtering policy */
146 filter_policy
147 burst_sdcch_subslot_filter_impl::get_policy(void)
148 {
149 return d_filter_policy;
150 }
151
152 filter_policy
153 burst_sdcch_subslot_filter_impl::set_policy(filter_policy policy)
154 {
155 d_filter_policy = policy;
156 return d_filter_policy;
157 }
158
Roman Khassraf8b64d872015-08-06 17:30:04 +0200159 } /* namespace gsm */
160} /* namespace gr */