blob: 6f65888bd76f41427961af2ac032dd962d7a479d [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){
piotrdda22272014-08-04 11:31:54 +020068 chan_info info;
ptrkrysik2f0f4c32015-01-12 22:59:05 +010069 info.id = header->arfcn; //take arfcn
piotrdda22272014-08-04 11:31:54 +020070 info.pwr_db = header->signal_dbm;
ptrkrysika31a4812014-12-15 09:10:01 +010071 info.cell_id = (msg_elements[3]<<8)+msg_elements[4]; //take cell id
72 info.lac = (msg_elements[8]<<8)+msg_elements[9]; //take lac
73 info.mnc = (msg_elements[7]>>4); //take mnc
piotrdda22272014-08-04 11:31:54 +020074
75 std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
76 boost::mutex::scoped_lock lock(extract_mutex);
77 if(iter != d_c0_channels.end()){
78 d_c0_channels.erase(iter);
79 }
80 d_c0_channels.insert(info);
81 }
82 else if(msg_elements[2]==0x1c){
piotrdda22272014-08-04 11:31:54 +020083 chan_info info;
ptrkrysik2f0f4c32015-01-12 22:59:05 +010084 info.id = header->arfcn; //take arfcn
piotrdda22272014-08-04 11:31:54 +020085 info.pwr_db = header->signal_dbm;
ptrkrysika31a4812014-12-15 09:10:01 +010086 info.lac = (msg_elements[6]<<8)+msg_elements[7]; //take lac
87 info.mnc = (msg_elements[5]>>4); //take mnc
piotrdda22272014-08-04 11:31:54 +020088
piotrdda22272014-08-04 11:31:54 +020089 std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
90 boost::mutex::scoped_lock lock(extract_mutex);
91 if(iter != d_c0_channels.end()){
92 d_c0_channels.erase(iter);
93 if(iter->cell_id!=0){
94 info.cell_id=iter->cell_id;
95 }
96 }
97 d_c0_channels.insert(info);
98 }
99 }
100
101 void extract_system_info_impl::show(){
102 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
103 std::vector<chan_info>::iterator iter;
104 //std::sort(chans.begin(), chans.end(), compare_pwr());
105 for(iter=chans.begin(); iter != chans.end(); ++iter){
106 std::cout << static_cast<int>((*iter).id) << "(" << static_cast<int>((*iter).pwr_db) << ") ";
107 }
108 std::cout << std::endl;
109 }
110
111 std::vector<int> extract_system_info_impl::get_chans()
112 {
113 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
114 std::vector<int> chans_ids(chans.size(),-1);
115 //std::sort(chans.begin(), chans.end(), compare_pwr());
116
117 for(int ii; ii < chans.size(); ++ii){
118 chans_ids[ii] = chans[ii].id;
119 }
120
121 return chans_ids;
122 }
123
124 std::vector<int> extract_system_info_impl::get_lac()
125 {
126 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
127 std::vector<int> chans_ids(chans.size(),-1);
128 //std::sort(chans.begin(), chans.end(), compare_pwr());
129
130 for(int ii; ii < chans.size(); ++ii){
131 chans_ids[ii] = chans[ii].lac;
132 }
133
134 return chans_ids;
135 }
136 std::vector<int> extract_system_info_impl::get_mnc()
137 {
138 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
139 std::vector<int> chans_ids(chans.size(),-1);
140 //std::sort(chans.begin(), chans.end(), compare_pwr());
141
142 for(int ii; ii < chans.size(); ++ii){
143 chans_ids[ii] = chans[ii].mnc;
144 }
145
146 return chans_ids;
147 }
148 std::vector<int> extract_system_info_impl::get_cell_id()
149 {
150 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
151 std::vector<int> chans_ids(chans.size(),-1);
152 //std::sort(chans.begin(), chans.end(), compare_pwr());
153
154 for(int ii; ii < chans.size(); ++ii){
155 chans_ids[ii] = chans[ii].cell_id;
156 }
157
158 return chans_ids;
159 }
160
161 std::vector<int> extract_system_info_impl::get_pwrs()
162 {
163 std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
164 std::vector<int> pwrs(chans.size(),-1);
165 //std::sort(chans.begin(), chans.end(), compare_pwr());
166
167 for(int ii; ii < chans.size(); ++ii){
168 pwrs[ii] = chans[ii].pwr_db;
169 }
170
171 return pwrs;
172 }
173
174 void extract_system_info_impl::reset()
175 {
Piotr K66bb3cd2014-08-13 19:04:57 +0200176 std::set<chan_info, compare_id>::iterator iter;
177
178 chan_info info;
179
180 for(iter = d_c0_channels.begin(); iter != d_c0_channels.end(); iter++){
181 info.id = iter->id;
ptrkrysika31a4812014-12-15 09:10:01 +0100182 info.cell_id = iter->cell_id;
183 info.lac = iter->lac;
184 info.mnc = iter->mnc;
Piotr K66bb3cd2014-08-13 19:04:57 +0200185 info.pwr_db = -111;
186 d_c0_channels.erase(iter);
187 d_c0_channels.insert(info);
188 }
189// d_c0_channels.clear();
190
piotrdda22272014-08-04 11:31:54 +0200191 if(!empty_p(pmt::mp("bursts"))){
192 delete_head_blocking(pmt::mp("bursts"));
193 }
194 }
195
196 extract_system_info::sptr
197 extract_system_info::make()
198 {
199 return gnuradio::get_initial_sptr
200 (new extract_system_info_impl());
201 }
202
203 /*
204 * The private constructor
205 */
206 extract_system_info_impl::extract_system_info_impl()
207 : gr::block("extract_system_info",
208 gr::io_signature::make(0, 0, 0),
209 gr::io_signature::make(0, 0, 0)),
210 after_reset(false)
211 {
212 message_port_register_in(pmt::mp("bursts"));
213 set_msg_handler(pmt::mp("bursts"), boost::bind(&extract_system_info_impl::process_bursts, this, _1));
214 message_port_register_in(pmt::mp("msgs"));
215 set_msg_handler(pmt::mp("msgs"), boost::bind(&extract_system_info_impl::process_sysinfo, this, _1));
216 }
217
218 /*
219 * Our virtual destructor.
220 */
221 extract_system_info_impl::~extract_system_info_impl()
222 {
223 }
224
225
226 } /* namespace gsm */
227} /* namespace gr */
228