blob: b49582f97249ea7c2fe1c8edb42faa72fe04c2a5 [file] [log] [blame]
piotrfaacc722014-07-20 23:48:32 +02001/* -*- c++ -*- */
ptrkrysik529895b2014-12-02 18:07:38 +01002/*
3 * @file
Piotr Krysika6268a52017-08-23 16:02:19 +02004 * @author (C) 2014 by Piotr Krysik <ptrkrysik@gmail.com>
ptrkrysik529895b2014-12-02 18:07:38 +01005 * @section LICENSE
6 *
7 * Gr-gsm is free software; you can redistribute it and/or modify
piotrfaacc722014-07-20 23:48:32 +02008 * 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,
piotrfaacc722014-07-20 23:48:32 +020013 * 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 *
piotrfaacc722014-07-20 23:48:32 +020017 * 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
piotrfaacc722014-07-20 23:48:32 +020019 * 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>
ptrkrysik3be74a72014-12-13 10:11:00 +010028#include <grgsm/gsmtap.h>
piotrfaacc722014-07-20 23:48:32 +020029#include "control_channels_decoder_impl.h"
30
ptrkrysik617ba032014-11-21 10:11:05 +010031#define DATA_BYTES 23
32
piotrfaacc722014-07-20 23:48:32 +020033namespace gr {
34 namespace gsm {
35
Piotr Krysikb516e6d2016-09-28 11:53:26 +020036 static int ubits2sbits(ubit_t *ubits, sbit_t *sbits, int count)
37 {
Piotr Krysike24860f2018-04-06 15:22:51 +020038 int i;
Piotr Krysikb516e6d2016-09-28 11:53:26 +020039
Piotr Krysike24860f2018-04-06 15:22:51 +020040 for (i = 0; i < count; i++) {
41 if (*ubits == 0x23) {
42 ubits++;
43 sbits++;
44 continue;
45 }
46 if ((*ubits++) & 1)
47 *sbits++ = -127;
48 else
49 *sbits++ = 127;
50 }
Piotr Krysikb516e6d2016-09-28 11:53:26 +020051
Piotr Krysike24860f2018-04-06 15:22:51 +020052 return count;
Piotr Krysikb516e6d2016-09-28 11:53:26 +020053 }
54
piotrfaacc722014-07-20 23:48:32 +020055 control_channels_decoder::sptr
56 control_channels_decoder::make()
57 {
58 return gnuradio::get_initial_sptr
59 (new control_channels_decoder_impl());
60 }
61
62 /*
ptrkrysik7f61c642014-10-30 08:57:27 +010063 * Constructor
piotrfaacc722014-07-20 23:48:32 +020064 */
65 control_channels_decoder_impl::control_channels_decoder_impl()
66 : gr::block("control_channels_decoder",
67 gr::io_signature::make(0, 0, 0),
68 gr::io_signature::make(0, 0, 0)),
69 d_collected_bursts_num(0)
70 {
Piotr Krysike24860f2018-04-06 15:22:51 +020071 //setup input/output ports
72 message_port_register_in(pmt::mp("bursts"));
Vadim Yanitskiya1169202021-05-03 19:00:43 +020073 set_msg_handler(pmt::mp("bursts"), boost::bind(&control_channels_decoder_impl::decode, this, boost::placeholders::_1));
Piotr Krysike24860f2018-04-06 15:22:51 +020074 message_port_register_out(pmt::mp("msgs"));
piotrfaacc722014-07-20 23:48:32 +020075 }
76
piotrfaacc722014-07-20 23:48:32 +020077 control_channels_decoder_impl::~control_channels_decoder_impl()
78 {
79 }
80
81 void control_channels_decoder_impl::decode(pmt::pmt_t msg)
82 {
Piotr Krysike24860f2018-04-06 15:22:51 +020083 ubit_t bursts_u[116 * 4];
84 sbit_t bursts_s[116 * 4];
85 uint8_t result[23];
86 int n_errors, n_bits_total;
87 int8_t header_plus_data[sizeof(gsmtap_hdr)+DATA_BYTES];
Piotr Krysikb8d33d92016-10-02 18:54:46 +020088
Piotr Krysike24860f2018-04-06 15:22:51 +020089 d_bursts[d_collected_bursts_num] = msg;
90 d_collected_bursts_num++;
Piotr Krysikb8d33d92016-10-02 18:54:46 +020091
Piotr Krysike24860f2018-04-06 15:22:51 +020092 //get convecutive bursts
93 if(d_collected_bursts_num==4)
94 {
95 d_collected_bursts_num=0;
96 //reorganize data from input bursts
97 for(int ii = 0; ii < 4; ii++)
piotrfaacc722014-07-20 23:48:32 +020098 {
Piotr Krysike24860f2018-04-06 15:22:51 +020099 pmt::pmt_t header_plus_burst = pmt::cdr(d_bursts[ii]);
100 int8_t * burst_bits = (int8_t *)(pmt::blob_data(header_plus_burst))+sizeof(gsmtap_hdr);
Piotr Krysikb8d33d92016-10-02 18:54:46 +0200101
Piotr Krysike24860f2018-04-06 15:22:51 +0200102 memcpy(&bursts_u[ii*116], &burst_bits[3],58);
103 memcpy(&bursts_u[ii*116+58], &burst_bits[3+57+1+26],58);
piotrfaacc722014-07-20 23:48:32 +0200104 }
Piotr Krysike24860f2018-04-06 15:22:51 +0200105 //convert to soft bits
106 ubits2sbits(bursts_u, bursts_s, 116 * 4);
107 //decode
108 if (gsm0503_xcch_decode(result, bursts_s, &n_errors, &n_bits_total) != -1)
109 {
110 //extract header of the first burst of the four bursts
111 pmt::pmt_t first_header_plus_burst = pmt::cdr(d_bursts[0]);
112 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(first_header_plus_burst);
113 //copy header and data
114 memcpy(header_plus_data, header, sizeof(gsmtap_hdr));
115 memcpy(header_plus_data+sizeof(gsmtap_hdr), result, DATA_BYTES);
116 //set data type in the header
117 ((gsmtap_hdr*)header_plus_data)->type = GSMTAP_TYPE_UM;
118 //prepare message
119 pmt::pmt_t msg_out = pmt::cons(pmt::PMT_NIL, pmt::make_blob(header_plus_data,DATA_BYTES+sizeof(gsmtap_hdr)));
120 //send message to the output
121 message_port_pub(pmt::mp("msgs"), msg_out);
122 }
123 }
piotrfaacc722014-07-20 23:48:32 +0200124 }
125 } /* namespace gsm */
126} /* namespace gr */
127