blob: c4cfa1e88a34182691236ffbbd7a31c4085cc89b [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>
28#include <gsm/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 {
42 pmt::pmt_t burst = pmt::cdr(msg);
43 int8_t * burst_elements = (int8_t *)pmt::blob_data(burst);
44 size_t burst_len=pmt::blob_length(burst);
45
46 pmt::pmt_t header_blob = pmt::car(msg);
47 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
48 chan_info info;
49 info.id = header->arfcn;
50 info.pwr_db = header->signal_dbm;
51
52 std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
53
54 boost::mutex::scoped_lock lock(extract_mutex);
55 if(iter != d_c0_channels.end()){
56 info.lac = iter->lac;
57 info.cell_id = iter->cell_id;
58 info.mnc = iter->mnc;
59 d_c0_channels.erase(iter);
60 d_c0_channels.insert(info);
61 }
62 d_c0_channels.insert(info);
63 }
64
65 void extract_system_info_impl::process_sysinfo(pmt::pmt_t msg){
66 pmt::pmt_t msg_blob = pmt::cdr(msg);
67 uint8_t * msg_elements = (uint8_t *)pmt::blob_data(msg_blob);
68
69 if(msg_elements[2]==0x1b){
70 //wyciągnij arfcn
71 pmt::pmt_t header_blob = pmt::car(msg);
72 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
73 chan_info info;
74 info.id = header->arfcn;
75 info.pwr_db = header->signal_dbm;
76 info.cell_id = (msg_elements[3]<<8)+msg_elements[4]; //wyciągnij cell id
77 info.lac = (msg_elements[8]<<8)+msg_elements[9]; //wyciągnij lac
78 info.mnc = (msg_elements[7]>>4); //wyciągnij id operatora
79
80 std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
81 boost::mutex::scoped_lock lock(extract_mutex);
82 if(iter != d_c0_channels.end()){
83 d_c0_channels.erase(iter);
84 }
85 d_c0_channels.insert(info);
86 }
87 else if(msg_elements[2]==0x1c){
88 pmt::pmt_t header_blob = pmt::car(msg);
89 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
90 chan_info info;
91 info.id = header->arfcn;
92 info.pwr_db = header->signal_dbm;
93 info.lac = (msg_elements[6]<<8)+msg_elements[7]; //wyciągnij lac
94 info.mnc = (msg_elements[5]>>4); //wyciągnij id operatora
95
piotrdda22272014-08-04 11:31:54 +020096 std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
97 boost::mutex::scoped_lock lock(extract_mutex);
98 if(iter != d_c0_channels.end()){
99 d_c0_channels.erase(iter);
100 if(iter->cell_id!=0){
101 info.cell_id=iter->cell_id;
102 }
103 }
104 d_c0_channels.insert(info);
105 }
106 }
107
108 void extract_system_info_impl::show(){
109 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
110 std::vector<chan_info>::iterator iter;
111 //std::sort(chans.begin(), chans.end(), compare_pwr());
112 for(iter=chans.begin(); iter != chans.end(); ++iter){
113 std::cout << static_cast<int>((*iter).id) << "(" << static_cast<int>((*iter).pwr_db) << ") ";
114 }
115 std::cout << std::endl;
116 }
117
118 std::vector<int> extract_system_info_impl::get_chans()
119 {
120 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
121 std::vector<int> chans_ids(chans.size(),-1);
122 //std::sort(chans.begin(), chans.end(), compare_pwr());
123
124 for(int ii; ii < chans.size(); ++ii){
125 chans_ids[ii] = chans[ii].id;
126 }
127
128 return chans_ids;
129 }
130
131 std::vector<int> extract_system_info_impl::get_lac()
132 {
133 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
134 std::vector<int> chans_ids(chans.size(),-1);
135 //std::sort(chans.begin(), chans.end(), compare_pwr());
136
137 for(int ii; ii < chans.size(); ++ii){
138 chans_ids[ii] = chans[ii].lac;
139 }
140
141 return chans_ids;
142 }
143 std::vector<int> extract_system_info_impl::get_mnc()
144 {
145 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
146 std::vector<int> chans_ids(chans.size(),-1);
147 //std::sort(chans.begin(), chans.end(), compare_pwr());
148
149 for(int ii; ii < chans.size(); ++ii){
150 chans_ids[ii] = chans[ii].mnc;
151 }
152
153 return chans_ids;
154 }
155 std::vector<int> extract_system_info_impl::get_cell_id()
156 {
157 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
158 std::vector<int> chans_ids(chans.size(),-1);
159 //std::sort(chans.begin(), chans.end(), compare_pwr());
160
161 for(int ii; ii < chans.size(); ++ii){
162 chans_ids[ii] = chans[ii].cell_id;
163 }
164
165 return chans_ids;
166 }
167
168 std::vector<int> extract_system_info_impl::get_pwrs()
169 {
170 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
171 std::vector<int> pwrs(chans.size(),-1);
172 //std::sort(chans.begin(), chans.end(), compare_pwr());
173
174 for(int ii; ii < chans.size(); ++ii){
175 pwrs[ii] = chans[ii].pwr_db;
176 }
177
178 return pwrs;
179 }
180
181 void extract_system_info_impl::reset()
182 {
Piotr K66bb3cd2014-08-13 19:04:57 +0200183 std::set<chan_info, compare_id>::iterator iter;
184
185 chan_info info;
186
187 for(iter = d_c0_channels.begin(); iter != d_c0_channels.end(); iter++){
188 info.id = iter->id;
189 info.cell_id = iter->cell_id; //wyciągnij cell id
190 info.lac = iter->lac; //wyciągnij lac
191 info.mnc = iter->mnc;
192 info.pwr_db = -111;
193 d_c0_channels.erase(iter);
194 d_c0_channels.insert(info);
195 }
196// d_c0_channels.clear();
197
piotrdda22272014-08-04 11:31:54 +0200198 if(!empty_p(pmt::mp("bursts"))){
199 delete_head_blocking(pmt::mp("bursts"));
200 }
201 }
202
203 extract_system_info::sptr
204 extract_system_info::make()
205 {
206 return gnuradio::get_initial_sptr
207 (new extract_system_info_impl());
208 }
209
210 /*
211 * The private constructor
212 */
213 extract_system_info_impl::extract_system_info_impl()
214 : gr::block("extract_system_info",
215 gr::io_signature::make(0, 0, 0),
216 gr::io_signature::make(0, 0, 0)),
217 after_reset(false)
218 {
219 message_port_register_in(pmt::mp("bursts"));
220 set_msg_handler(pmt::mp("bursts"), boost::bind(&extract_system_info_impl::process_bursts, this, _1));
221 message_port_register_in(pmt::mp("msgs"));
222 set_msg_handler(pmt::mp("msgs"), boost::bind(&extract_system_info_impl::process_sysinfo, this, _1));
223 }
224
225 /*
226 * Our virtual destructor.
227 */
228 extract_system_info_impl::~extract_system_info_impl()
229 {
230 }
231
232
233 } /* namespace gsm */
234} /* namespace gr */
235