blob: b7df803b6c52cd368b2eb083b18f8a97b4ecb724 [file] [log] [blame]
Roman Khassraf5bd14f22015-06-24 17:59:13 +02001/* -*- c++ -*- */
2/*
3 * @file
4 * @author Roman Khassraf <rkhassraf@gmail.com>
5 * @section LICENSE
6 *
7 * Gr-gsm is free software; you can redistribute it and/or modify
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.
11 *
12 * Gr-gsm is distributed in the hope that it will be useful,
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.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with gr-gsm; see the file COPYING. If not, write to
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>
28#include <grgsm/gsmtap.h>
29#include <unistd.h>
30#include <set>
31#include <iterator>
32#include <algorithm>
33#include <iostream>
34
35#include "extract_immediate_assignment_impl.h"
36
37namespace gr {
38 namespace gsm {
39 boost::mutex extract_immediate_assignment_mutex;
40
41 void extract_immediate_assignment_impl::process_message(pmt::pmt_t msg){
42 pmt::pmt_t message_plus_header_blob = pmt::cdr(msg);
43 uint8_t * message_plus_header = (uint8_t *)pmt::blob_data(message_plus_header_blob);
44 gsmtap_hdr * header = (gsmtap_hdr *)message_plus_header;
45 uint8_t * msg_elements = (uint8_t *)(message_plus_header+sizeof(gsmtap_hdr));
46 uint32_t frame_nr = be32toh(header->frame_number);
47
48 if(msg_elements[2]==0x3f)
49 {
50 std::cout << "\n------------------------------------------------------------------\n" << std::endl;
51 std::cout << "Immediate assignment found !" << std::endl;
52 std::cout << "FrameNr: " << (unsigned)frame_nr << std::endl;
53
54 uint8_t mode = msg_elements[3] & (1 << 4);
55
56 /*
57 channel description, see table 10.23 in GSM 04.08
58
59 msg_elements[4], octet 2 in specs
60
61 5 bits channel type
62 ignored in TBF
63 00001 TCH/F
64 0001T TCH/H, subchannel/TDMA offset T
65 001TT SDCCH/4, subchannel/TDMA offset TT
66 01TTT SDCCH/8, subchannel/TDMA offset TTT
67 3 bits timeslot number TN
68 */
69 uint8_t channeltype = (msg_elements[4] >> 3);
70 uint8_t timeslot = (msg_elements[4] & 7);
71 uint8_t subchannel;
72 std::string channel_type;
73
74 std::cout << "Timeslot: " << (unsigned)timeslot << std::endl;
75
76 if (mode == 0)
77 {
78 if (channeltype >= 8)
79 {
80 channel_type = "SDCCH/8";
81 subchannel = (channeltype & 7);
82 }
83 else if (channeltype >= 4 && channeltype <= 7)
84 {
85 channel_type = "SDCCH/4";
86 subchannel = (channeltype & 3);
87 }
88 else if (channeltype >= 2 && channeltype <= 3)
89 {
90 channel_type = "TCH/H";
91 subchannel = (channeltype & 1);
92 }
93 else
94 {
95 channel_type = "TCH/F";
96 subchannel = 0;
97 }
98
99 std::cout << "Channel type: " << channel_type << std::endl;
100 std::cout << "Subchannel: " << (unsigned)subchannel << std::endl;
101 }
102 else
103 {
104 std::cout << "Channel type: " << "GPRS - Temporary Block Flow TBF" << std::endl;
105 }
106
107 /*
108 msg_elements[5], msg_elements[6] are octets 3 and 4 in specs
109
110 3 bits training sequence (we dont process this for the moment)
111 1 bit hopping channel H
112
113 if H = 0:
114 2 bit spare
115 2 bit high part of single channel arfcn
116
117 8 bit low part of single channel arfcn
118
119 if H = 1:
120 4 bit high part of MAIO
121
122 2 bit low part of MAIO
123 6bit HSN
124 */
125 uint8_t hopping = (msg_elements[5] >> 4) & 1;
126
127 std::cout << "Hopping: " << (unsigned)hopping << std::endl;
128
129 if (hopping)
130 {
131 uint8_t maio = (msg_elements[5] & 0xf) << 2;
132 maio |= (msg_elements[6] >> 6);
133
134 uint8_t hsn = (msg_elements[6] & 0x3f);
135
136 std::cout << "MAIO: " << (unsigned)maio << std::endl;
137 std::cout << "HSN: " << (unsigned)hsn << std::endl;
138 }
139 else
140 {
141 uint16_t arfcn = (msg_elements[5] & 3) << 8;
142 arfcn |= msg_elements[6];
143
144 std::cout << "ARFCN: " << (unsigned)arfcn << std::endl;
145 }
146
147 // request reference as ID in set, so we get only one immediate assignment per reference
148 /*
149 msg_elements[7 - 9], octets 5 - 7 in specs : request reference, maybe later
150
151 msg_elements[10]: timing advance
152 */
153 uint8_t timing_advance = msg_elements[10];
154 std::cout << "TA: " << (unsigned)timing_advance << std::endl;
155
156 /*
157 msg_elements[11] - 20: mobile allocation, flexible length, see 10.5.2.21
158 */
159
160 uint8_t mobile_allocation_len = msg_elements[11];
161 if (mobile_allocation_len > 0)
162 {
163 uint8_t mobile_allocation[mobile_allocation_len];
164 for (int i=0; i<mobile_allocation_len; i++)
165 {
166 mobile_allocation[i] = msg_elements[12 + i];
167 std::cout << "MA: " << (unsigned)mobile_allocation[i] << std::endl;
168 }
169 }
170 }
171 }
172
173 extract_immediate_assignment::sptr
174 extract_immediate_assignment::make()
175 {
176 return gnuradio::get_initial_sptr
177 (new extract_immediate_assignment_impl());
178 }
179
180 /*
181 * The private constructor
182 */
183 extract_immediate_assignment_impl::extract_immediate_assignment_impl()
184 : gr::block("extract_immediate_assignment",
185 gr::io_signature::make(0, 0, 0),
186 gr::io_signature::make(0, 0, 0))
187 {
188 message_port_register_in(pmt::mp("msgs"));
189 set_msg_handler(pmt::mp("msgs"), boost::bind(&extract_immediate_assignment_impl::process_message, this, _1));
190 }
191
192 /*
193 * Our virtual destructor.
194 */
195 extract_immediate_assignment_impl::~extract_immediate_assignment_impl()
196 {
197 }
198 } /* namespace gsm */
199} /* namespace gr */
200