blob: 267f6b4e8643dfce7497aa8922b142e3fe123735 [file] [log] [blame]
Roman Khassrafa1eb1882015-08-05 12:30:29 +02001/* -*- c++ -*- */
2/* @file
Piotr Krysika6268a52017-08-23 16:02:19 +02003 * @author (C) 2015 by Roman Khassraf <rkhassraf@gmail.com>
Roman Khassrafa1eb1882015-08-05 12:30:29 +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_splitter_impl.h"
29#include <stdio.h>
30#include <grgsm/endian.h>
31#include <grgsm/gsmtap.h>
32
Roman Khassrafa1eb1882015-08-05 12:30:29 +020033namespace gr {
34 namespace gsm {
35
36 burst_sdcch_subslot_splitter::sptr
37 burst_sdcch_subslot_splitter::make(splitter_mode mode)
38 {
39 return gnuradio::get_initial_sptr
40 (new burst_sdcch_subslot_splitter_impl(mode));
41 }
42
43 /*
44 * The private constructor
45 */
46 burst_sdcch_subslot_splitter_impl::burst_sdcch_subslot_splitter_impl(splitter_mode mode)
47 : gr::block("burst_sdcch_subslot_splitter",
48 gr::io_signature::make(0, 0, 0),
49 gr::io_signature::make(0, 0, 0)),
50 d_mode(mode)
51 {
52 message_port_register_in(pmt::mp("in"));
53
54 message_port_register_out(pmt::mp("out0"));
55 message_port_register_out(pmt::mp("out1"));
56 message_port_register_out(pmt::mp("out2"));
57 message_port_register_out(pmt::mp("out3"));
58 if (d_mode == SPLITTER_SDCCH8)
59 {
60 message_port_register_out(pmt::mp("out4"));
61 message_port_register_out(pmt::mp("out5"));
62 message_port_register_out(pmt::mp("out6"));
63 message_port_register_out(pmt::mp("out7"));
64 }
65
66 set_msg_handler(pmt::mp("in"), boost::bind(&burst_sdcch_subslot_splitter_impl::process_burst, this, _1));
67 }
68
69 /*
70 * Our virtual destructor.
71 */
72 burst_sdcch_subslot_splitter_impl::~burst_sdcch_subslot_splitter_impl() {}
73
74 void burst_sdcch_subslot_splitter_impl::process_burst(pmt::pmt_t msg)
75 {
Steve Glassc8edec52015-09-27 16:14:33 +100076 // hardcoded subslots of the channels, both SDCCH and the associated SACCH
77 // -1 means that the particular position in the frame is not SDCCH
78 static const int8_t subslots_sdcch4[102] = {
Piotr Krysik4ea1b922016-02-28 11:25:52 +010079 -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,
80 -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 +100081 };
82 static const int8_t subslots_sdcch8[102] = {
Piotr Krysik4ea1b922016-02-28 11:25:52 +010083 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,
84 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 +100085 };
Piotr Krysik4ea1b922016-02-28 11:25:52 +010086
Roman Khassrafa1eb1882015-08-05 12:30:29 +020087 pmt::pmt_t header_plus_burst = pmt::cdr(msg);
88 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst);
89
90 uint32_t frame_nr = be32toh(header->frame_number);
91 uint32_t fn_mod102 = frame_nr % 102;
92
93 int8_t subslot;
Piotr Krysik4ea1b922016-02-28 11:25:52 +010094
Roman Khassrafa1eb1882015-08-05 12:30:29 +020095 if (d_mode == SPLITTER_SDCCH8)
96 {
Steve Glassc8edec52015-09-27 16:14:33 +100097 subslot = subslots_sdcch8[fn_mod102];
Roman Khassrafa1eb1882015-08-05 12:30:29 +020098 }
99 else if (d_mode == SPLITTER_SDCCH4)
100 {
Steve Glassc8edec52015-09-27 16:14:33 +1000101 subslot = subslots_sdcch4[fn_mod102];
Roman Khassrafa1eb1882015-08-05 12:30:29 +0200102 }
103
104 if ((subslot == -1) || (d_mode == SPLITTER_SDCCH4 && subslot > 3))
105 {
106 return;
107 }
108
109 std::string port("out");
110
111 switch (subslot)
112 {
113 case 0:
114 port.append("0");
115 break;
116 case 1:
117 port.append("1");
118 break;
119 case 2:
120 port.append("2");
121 break;
122 case 3:
123 port.append("3");
124 break;
125 case 4:
126 port.append("4");
127 break;
128 case 5:
129 port.append("5");
130 break;
131 case 6:
132 port.append("6");
133 break;
134 case 7:
135 port.append("7");
136 break;
137 default:
138 port.append("0");
139 break;
140 }
141
142 message_port_pub(pmt::mp(port), msg);
143 }
Vadim Yanitskiy6ee2c162017-07-21 07:23:06 +0700144
145 /* External API */
146 splitter_mode
147 burst_sdcch_subslot_splitter_impl::get_mode(void)
148 {
149 return d_mode;
150 }
151
152 splitter_mode
153 burst_sdcch_subslot_splitter_impl::set_mode(splitter_mode mode)
154 {
155 d_mode = mode;
156 return d_mode;
157 }
158
Roman Khassrafa1eb1882015-08-05 12:30:29 +0200159 } /* namespace gsm */
160} /* namespace gr */