blob: 29511731ef74f7e380fb997b46acedb80719aa5a [file] [log] [blame]
piotrdda22272014-08-04 11:31:54 +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
piotrdda22272014-08-04 11:31:54 +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,
piotrdda22272014-08-04 11:31:54 +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 *
piotrdda22272014-08-04 11:31:54 +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
piotrdda22272014-08-04 11:31:54 +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>
ptrkrysik402c1fa2014-12-03 22:09:29 +010029#include <unistd.h>
30#include <set>
piotrdda22272014-08-04 11:31:54 +020031#include <iterator>
32#include <algorithm>
piotrdda22272014-08-04 11:31:54 +020033#include <iostream>
34
ptrkrysik402c1fa2014-12-03 22:09:29 +010035#include "extract_system_info_impl.h"
36
piotrdda22272014-08-04 11:31:54 +020037namespace gr {
38 namespace gsm {
39 boost::mutex extract_mutex;
40 void extract_system_info_impl::process_bursts(pmt::pmt_t msg)
41 {
ptrkrysika31a4812014-12-15 09:10:01 +010042 pmt::pmt_t burst_plus_header_blob = pmt::cdr(msg);
43 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(burst_plus_header_blob);
piotrdda22272014-08-04 11:31:54 +020044
piotrdda22272014-08-04 11:31:54 +020045 chan_info info;
46 info.id = header->arfcn;
47 info.pwr_db = header->signal_dbm;
piotrdda22272014-08-04 11:31:54 +020048 std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
49
50 boost::mutex::scoped_lock lock(extract_mutex);
51 if(iter != d_c0_channels.end()){
52 info.lac = iter->lac;
53 info.cell_id = iter->cell_id;
54 info.mnc = iter->mnc;
55 d_c0_channels.erase(iter);
56 d_c0_channels.insert(info);
57 }
58 d_c0_channels.insert(info);
59 }
60
61 void extract_system_info_impl::process_sysinfo(pmt::pmt_t msg){
ptrkrysika31a4812014-12-15 09:10:01 +010062 pmt::pmt_t message_plus_header_blob = pmt::cdr(msg);
63 uint8_t * message_plus_header = (uint8_t *)pmt::blob_data(message_plus_header_blob);
64 gsmtap_hdr * header = (gsmtap_hdr *)message_plus_header;
65 uint8_t * msg_elements = (uint8_t *)(message_plus_header+sizeof(gsmtap_hdr));
piotrdda22272014-08-04 11:31:54 +020066
67 if(msg_elements[2]==0x1b){
68 //wyciągnij arfcn
69 pmt::pmt_t header_blob = pmt::car(msg);
70 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
71 chan_info info;
72 info.id = header->arfcn;
73 info.pwr_db = header->signal_dbm;
ptrkrysika31a4812014-12-15 09:10:01 +010074 info.cell_id = (msg_elements[3]<<8)+msg_elements[4]; //take cell id
75 info.lac = (msg_elements[8]<<8)+msg_elements[9]; //take lac
76 info.mnc = (msg_elements[7]>>4); //take mnc
piotrdda22272014-08-04 11:31:54 +020077
78 std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
79 boost::mutex::scoped_lock lock(extract_mutex);
80 if(iter != d_c0_channels.end()){
81 d_c0_channels.erase(iter);
82 }
83 d_c0_channels.insert(info);
84 }
85 else if(msg_elements[2]==0x1c){
86 pmt::pmt_t header_blob = pmt::car(msg);
87 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
88 chan_info info;
89 info.id = header->arfcn;
90 info.pwr_db = header->signal_dbm;
ptrkrysika31a4812014-12-15 09:10:01 +010091 info.lac = (msg_elements[6]<<8)+msg_elements[7]; //take lac
92 info.mnc = (msg_elements[5]>>4); //take mnc
piotrdda22272014-08-04 11:31:54 +020093
piotrdda22272014-08-04 11:31:54 +020094 std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
95 boost::mutex::scoped_lock lock(extract_mutex);
96 if(iter != d_c0_channels.end()){
97 d_c0_channels.erase(iter);
98 if(iter->cell_id!=0){
99 info.cell_id=iter->cell_id;
100 }
101 }
102 d_c0_channels.insert(info);
103 }
104 }
105
106 void extract_system_info_impl::show(){
107 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
108 std::vector<chan_info>::iterator iter;
109 //std::sort(chans.begin(), chans.end(), compare_pwr());
110 for(iter=chans.begin(); iter != chans.end(); ++iter){
111 std::cout << static_cast<int>((*iter).id) << "(" << static_cast<int>((*iter).pwr_db) << ") ";
112 }
113 std::cout << std::endl;
114 }
115
116 std::vector<int> extract_system_info_impl::get_chans()
117 {
118 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
119 std::vector<int> chans_ids(chans.size(),-1);
120 //std::sort(chans.begin(), chans.end(), compare_pwr());
121
122 for(int ii; ii < chans.size(); ++ii){
123 chans_ids[ii] = chans[ii].id;
124 }
125
126 return chans_ids;
127 }
128
129 std::vector<int> extract_system_info_impl::get_lac()
130 {
131 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
132 std::vector<int> chans_ids(chans.size(),-1);
133 //std::sort(chans.begin(), chans.end(), compare_pwr());
134
135 for(int ii; ii < chans.size(); ++ii){
136 chans_ids[ii] = chans[ii].lac;
137 }
138
139 return chans_ids;
140 }
141 std::vector<int> extract_system_info_impl::get_mnc()
142 {
143 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
144 std::vector<int> chans_ids(chans.size(),-1);
145 //std::sort(chans.begin(), chans.end(), compare_pwr());
146
147 for(int ii; ii < chans.size(); ++ii){
148 chans_ids[ii] = chans[ii].mnc;
149 }
150
151 return chans_ids;
152 }
153 std::vector<int> extract_system_info_impl::get_cell_id()
154 {
155 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
156 std::vector<int> chans_ids(chans.size(),-1);
157 //std::sort(chans.begin(), chans.end(), compare_pwr());
158
159 for(int ii; ii < chans.size(); ++ii){
160 chans_ids[ii] = chans[ii].cell_id;
161 }
162
163 return chans_ids;
164 }
165
166 std::vector<int> extract_system_info_impl::get_pwrs()
167 {
168 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
169 std::vector<int> pwrs(chans.size(),-1);
170 //std::sort(chans.begin(), chans.end(), compare_pwr());
171
172 for(int ii; ii < chans.size(); ++ii){
173 pwrs[ii] = chans[ii].pwr_db;
174 }
175
176 return pwrs;
177 }
178
179 void extract_system_info_impl::reset()
180 {
Piotr K66bb3cd2014-08-13 19:04:57 +0200181 std::set<chan_info, compare_id>::iterator iter;
182
183 chan_info info;
184
185 for(iter = d_c0_channels.begin(); iter != d_c0_channels.end(); iter++){
186 info.id = iter->id;
ptrkrysika31a4812014-12-15 09:10:01 +0100187 info.cell_id = iter->cell_id;
188 info.lac = iter->lac;
189 info.mnc = iter->mnc;
Piotr K66bb3cd2014-08-13 19:04:57 +0200190 info.pwr_db = -111;
191 d_c0_channels.erase(iter);
192 d_c0_channels.insert(info);
193 }
194// d_c0_channels.clear();
195
piotrdda22272014-08-04 11:31:54 +0200196 if(!empty_p(pmt::mp("bursts"))){
197 delete_head_blocking(pmt::mp("bursts"));
198 }
199 }
200
201 extract_system_info::sptr
202 extract_system_info::make()
203 {
204 return gnuradio::get_initial_sptr
205 (new extract_system_info_impl());
206 }
207
208 /*
209 * The private constructor
210 */
211 extract_system_info_impl::extract_system_info_impl()
212 : gr::block("extract_system_info",
213 gr::io_signature::make(0, 0, 0),
214 gr::io_signature::make(0, 0, 0)),
215 after_reset(false)
216 {
217 message_port_register_in(pmt::mp("bursts"));
218 set_msg_handler(pmt::mp("bursts"), boost::bind(&extract_system_info_impl::process_bursts, this, _1));
219 message_port_register_in(pmt::mp("msgs"));
220 set_msg_handler(pmt::mp("msgs"), boost::bind(&extract_system_info_impl::process_sysinfo, this, _1));
221 }
222
223 /*
224 * Our virtual destructor.
225 */
226 extract_system_info_impl::~extract_system_info_impl()
227 {
228 }
229
230
231 } /* namespace gsm */
232} /* namespace gr */
233