blob: 1d20d8d16020db14ac842669f6424ab2220686c1 [file] [log] [blame]
piotrdda22272014-08-04 11:31:54 +02001/* -*- c++ -*- */
2/*
3 * Copyright 2014 <+YOU OR YOUR COMPANY+>.
4 *
5 * This is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3, or (at your option)
8 * any later version.
9 *
10 * This software is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this software; see the file COPYING. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#ifdef HAVE_CONFIG_H
22#include "config.h"
23#endif
24
25#include <gnuradio/io_signature.h>
26#include <gsm/gsmtap.h>
27#include <iterator>
28#include <algorithm>
29#include "extract_system_info_impl.h"
30#include <unistd.h>
31
32#include <iostream>
33
34namespace gr {
35 namespace gsm {
36 boost::mutex extract_mutex;
37 void extract_system_info_impl::process_bursts(pmt::pmt_t msg)
38 {
39 pmt::pmt_t burst = pmt::cdr(msg);
40 int8_t * burst_elements = (int8_t *)pmt::blob_data(burst);
41 size_t burst_len=pmt::blob_length(burst);
42
43 pmt::pmt_t header_blob = pmt::car(msg);
44 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
45 chan_info info;
46 info.id = header->arfcn;
47 info.pwr_db = header->signal_dbm;
48
49 std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
50
51 boost::mutex::scoped_lock lock(extract_mutex);
52 if(iter != d_c0_channels.end()){
53 info.lac = iter->lac;
54 info.cell_id = iter->cell_id;
55 info.mnc = iter->mnc;
56 d_c0_channels.erase(iter);
57 d_c0_channels.insert(info);
58 }
59 d_c0_channels.insert(info);
60 }
61
62 void extract_system_info_impl::process_sysinfo(pmt::pmt_t msg){
63 pmt::pmt_t msg_blob = pmt::cdr(msg);
64 uint8_t * msg_elements = (uint8_t *)pmt::blob_data(msg_blob);
65
66 if(msg_elements[2]==0x1b){
67 //wyciągnij arfcn
68 pmt::pmt_t header_blob = pmt::car(msg);
69 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
70 chan_info info;
71 info.id = header->arfcn;
72 info.pwr_db = header->signal_dbm;
73 info.cell_id = (msg_elements[3]<<8)+msg_elements[4]; //wyciągnij cell id
74 info.lac = (msg_elements[8]<<8)+msg_elements[9]; //wyciągnij lac
75 info.mnc = (msg_elements[7]>>4); //wyciągnij id operatora
76
77 std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
78 boost::mutex::scoped_lock lock(extract_mutex);
79 if(iter != d_c0_channels.end()){
80 d_c0_channels.erase(iter);
81 }
82 d_c0_channels.insert(info);
83 }
84 else if(msg_elements[2]==0x1c){
85 pmt::pmt_t header_blob = pmt::car(msg);
86 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
87 chan_info info;
88 info.id = header->arfcn;
89 info.pwr_db = header->signal_dbm;
90 info.lac = (msg_elements[6]<<8)+msg_elements[7]; //wyciągnij lac
91 info.mnc = (msg_elements[5]>>4); //wyciągnij id operatora
92
93
94 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 {
181 d_c0_channels.clear();
182 if(!empty_p(pmt::mp("bursts"))){
183 delete_head_blocking(pmt::mp("bursts"));
184 }
185 }
186
187 extract_system_info::sptr
188 extract_system_info::make()
189 {
190 return gnuradio::get_initial_sptr
191 (new extract_system_info_impl());
192 }
193
194 /*
195 * The private constructor
196 */
197 extract_system_info_impl::extract_system_info_impl()
198 : gr::block("extract_system_info",
199 gr::io_signature::make(0, 0, 0),
200 gr::io_signature::make(0, 0, 0)),
201 after_reset(false)
202 {
203 message_port_register_in(pmt::mp("bursts"));
204 set_msg_handler(pmt::mp("bursts"), boost::bind(&extract_system_info_impl::process_bursts, this, _1));
205 message_port_register_in(pmt::mp("msgs"));
206 set_msg_handler(pmt::mp("msgs"), boost::bind(&extract_system_info_impl::process_sysinfo, this, _1));
207 }
208
209 /*
210 * Our virtual destructor.
211 */
212 extract_system_info_impl::~extract_system_info_impl()
213 {
214 }
215
216
217 } /* namespace gsm */
218} /* namespace gr */
219