piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 1 | /* -*- c++ -*- */ |
ptrkrysik | 529895b | 2014-12-02 18:07:38 +0100 | [diff] [blame] | 2 | /* |
| 3 | * @file |
Piotr Krysik | a6268a5 | 2017-08-23 16:02:19 +0200 | [diff] [blame] | 4 | * @author (C) 2014 by Piotr Krysik <ptrkrysik@gmail.com> |
ptrkrysik | 529895b | 2014-12-02 18:07:38 +0100 | [diff] [blame] | 5 | * @section LICENSE |
| 6 | * |
| 7 | * Gr-gsm is free software; you can redistribute it and/or modify |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 8 | * 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. |
ptrkrysik | 529895b | 2014-12-02 18:07:38 +0100 | [diff] [blame] | 11 | * |
| 12 | * Gr-gsm is distributed in the hope that it will be useful, |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 13 | * 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. |
ptrkrysik | 529895b | 2014-12-02 18:07:38 +0100 | [diff] [blame] | 16 | * |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 17 | * You should have received a copy of the GNU General Public License |
ptrkrysik | 529895b | 2014-12-02 18:07:38 +0100 | [diff] [blame] | 18 | * along with gr-gsm; see the file COPYING. If not, write to |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 19 | * 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> |
ptrkrysik | 3be74a7 | 2014-12-13 10:11:00 +0100 | [diff] [blame] | 28 | #include <grgsm/gsmtap.h> |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 29 | #include "control_channels_decoder_impl.h" |
| 30 | |
ptrkrysik | 617ba03 | 2014-11-21 10:11:05 +0100 | [diff] [blame] | 31 | #define DATA_BYTES 23 |
| 32 | |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 33 | namespace gr { |
| 34 | namespace gsm { |
| 35 | |
Piotr Krysik | b516e6d | 2016-09-28 11:53:26 +0200 | [diff] [blame] | 36 | static int ubits2sbits(ubit_t *ubits, sbit_t *sbits, int count) |
| 37 | { |
Piotr Krysik | e24860f | 2018-04-06 15:22:51 +0200 | [diff] [blame] | 38 | int i; |
Piotr Krysik | b516e6d | 2016-09-28 11:53:26 +0200 | [diff] [blame] | 39 | |
Piotr Krysik | e24860f | 2018-04-06 15:22:51 +0200 | [diff] [blame] | 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 | } |
Piotr Krysik | b516e6d | 2016-09-28 11:53:26 +0200 | [diff] [blame] | 51 | |
Piotr Krysik | e24860f | 2018-04-06 15:22:51 +0200 | [diff] [blame] | 52 | return count; |
Piotr Krysik | b516e6d | 2016-09-28 11:53:26 +0200 | [diff] [blame] | 53 | } |
| 54 | |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 55 | 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 | /* |
ptrkrysik | 7f61c64 | 2014-10-30 08:57:27 +0100 | [diff] [blame] | 63 | * Constructor |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 64 | */ |
| 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 Krysik | e24860f | 2018-04-06 15:22:51 +0200 | [diff] [blame] | 71 | //setup input/output ports |
| 72 | message_port_register_in(pmt::mp("bursts")); |
| 73 | set_msg_handler(pmt::mp("bursts"), boost::bind(&control_channels_decoder_impl::decode, this, _1)); |
| 74 | message_port_register_out(pmt::mp("msgs")); |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 75 | } |
| 76 | |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 77 | control_channels_decoder_impl::~control_channels_decoder_impl() |
| 78 | { |
| 79 | } |
| 80 | |
| 81 | void control_channels_decoder_impl::decode(pmt::pmt_t msg) |
| 82 | { |
Piotr Krysik | e24860f | 2018-04-06 15:22:51 +0200 | [diff] [blame] | 83 | 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 Krysik | b8d33d9 | 2016-10-02 18:54:46 +0200 | [diff] [blame] | 88 | |
Piotr Krysik | e24860f | 2018-04-06 15:22:51 +0200 | [diff] [blame] | 89 | d_bursts[d_collected_bursts_num] = msg; |
| 90 | d_collected_bursts_num++; |
Piotr Krysik | b8d33d9 | 2016-10-02 18:54:46 +0200 | [diff] [blame] | 91 | |
Piotr Krysik | e24860f | 2018-04-06 15:22:51 +0200 | [diff] [blame] | 92 | //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++) |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 98 | { |
Piotr Krysik | e24860f | 2018-04-06 15:22:51 +0200 | [diff] [blame] | 99 | 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 Krysik | b8d33d9 | 2016-10-02 18:54:46 +0200 | [diff] [blame] | 101 | |
Piotr Krysik | e24860f | 2018-04-06 15:22:51 +0200 | [diff] [blame] | 102 | memcpy(&bursts_u[ii*116], &burst_bits[3],58); |
| 103 | memcpy(&bursts_u[ii*116+58], &burst_bits[3+57+1+26],58); |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 104 | } |
Piotr Krysik | e24860f | 2018-04-06 15:22:51 +0200 | [diff] [blame] | 105 | //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 | } |
piotr | faacc72 | 2014-07-20 23:48:32 +0200 | [diff] [blame] | 124 | } |
| 125 | } /* namespace gsm */ |
| 126 | } /* namespace gr */ |
| 127 | |