blob: 71695e2eef9d1d485bcb1a7ab700073c390c9245 [file] [log] [blame]
piotrfaacc722014-07-20 23:48:32 +02001/* -*- 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
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 {
38 int i;
39
40 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 }
51
52 return count;
53 }
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 {
ptrkrysik7f61c642014-10-30 08:57:27 +010071 //setup input/output ports
piotrfaacc722014-07-20 23:48:32 +020072 message_port_register_in(pmt::mp("bursts"));
73 set_msg_handler(pmt::mp("bursts"), boost::bind(&control_channels_decoder_impl::decode, this, _1));
piotrb529a592014-08-04 11:30:43 +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 Krysikb516e6d2016-09-28 11:53:26 +020083 ubit_t bursts_u[116 * 4];
84 sbit_t bursts_s[116 * 4];
Piotr Krysikb8d33d92016-10-02 18:54:46 +020085 uint8_t result[23];
86 int n_errors, n_bits_total;
87 int8_t header_plus_data[sizeof(gsmtap_hdr)+DATA_BYTES];
88
piotrfaacc722014-07-20 23:48:32 +020089 d_bursts[d_collected_bursts_num] = msg;
90 d_collected_bursts_num++;
Piotr Krysikb8d33d92016-10-02 18:54:46 +020091
piotrfaacc722014-07-20 23:48:32 +020092 //get convecutive bursts
piotrfaacc722014-07-20 23:48:32 +020093 if(d_collected_bursts_num==4)
94 {
95 d_collected_bursts_num=0;
Piotr Krysikb8d33d92016-10-02 18:54:46 +020096 //reorganize data from input bursts
piotrfaacc722014-07-20 23:48:32 +020097 for(int ii = 0; ii < 4; ii++)
98 {
ptrkrysik617ba032014-11-21 10:11:05 +010099 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 Krysikb516e6d2016-09-28 11:53:26 +0200102 memcpy(&bursts_u[ii*116], &burst_bits[3],58);
Piotr Krysikb8d33d92016-10-02 18:54:46 +0200103 memcpy(&bursts_u[ii*116+58], &burst_bits[3+57+1+26],58);
piotrfaacc722014-07-20 23:48:32 +0200104 }
Piotr Krysikb516e6d2016-09-28 11:53:26 +0200105 //convert to soft bits
106 ubits2sbits(bursts_u, bursts_s, 116 * 4);
107 //decode
108 gsm0503_xcch_decode(result, bursts_s, &n_errors, &n_bits_total);
piotrfaacc722014-07-20 23:48:32 +0200109
Piotr Krysikb8d33d92016-10-02 18:54:46 +0200110 //extract header of the first burst of the four bursts
ptrkrysik617ba032014-11-21 10:11:05 +0100111 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);
Piotr Krysikb8d33d92016-10-02 18:54:46 +0200113 //copy header and data
iZsh66987932015-08-16 14:42:18 +0200114 memcpy(header_plus_data, header, sizeof(gsmtap_hdr));
Piotr Krysikb516e6d2016-09-28 11:53:26 +0200115 memcpy(header_plus_data+sizeof(gsmtap_hdr), result, DATA_BYTES);
Piotr Krysikb8d33d92016-10-02 18:54:46 +0200116 //set data type in the header
iZsh66987932015-08-16 14:42:18 +0200117 ((gsmtap_hdr*)header_plus_data)->type = GSMTAP_TYPE_UM;
Piotr Krysikb8d33d92016-10-02 18:54:46 +0200118 //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
piotrb529a592014-08-04 11:30:43 +0200121 message_port_pub(pmt::mp("msgs"), msg_out);
piotrfaacc722014-07-20 23:48:32 +0200122 }
123 return;
124 }
125 } /* namespace gsm */
126} /* namespace gr */
127