gr-gsm/lib/misc_utils/extract_system_info_impl.cc

236 lines
7.8 KiB
C++

/* -*- c++ -*- */
/*
* @file
* @author Piotr Krysik <ptrkrysik@gmail.com>
* @section LICENSE
*
* Gr-gsm is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* Gr-gsm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with gr-gsm; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include <grgsm/gsmtap.h>
#include <unistd.h>
#include <set>
#include <iterator>
#include <algorithm>
#include <iostream>
#include "extract_system_info_impl.h"
namespace gr {
namespace gsm {
boost::mutex extract_mutex;
void extract_system_info_impl::process_bursts(pmt::pmt_t msg)
{
pmt::pmt_t burst = pmt::cdr(msg);
int8_t * burst_elements = (int8_t *)pmt::blob_data(burst);
size_t burst_len=pmt::blob_length(burst);
pmt::pmt_t header_blob = pmt::car(msg);
gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
chan_info info;
info.id = header->arfcn;
info.pwr_db = header->signal_dbm;
std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
boost::mutex::scoped_lock lock(extract_mutex);
if(iter != d_c0_channels.end()){
info.lac = iter->lac;
info.cell_id = iter->cell_id;
info.mnc = iter->mnc;
d_c0_channels.erase(iter);
d_c0_channels.insert(info);
}
d_c0_channels.insert(info);
}
void extract_system_info_impl::process_sysinfo(pmt::pmt_t msg){
pmt::pmt_t msg_blob = pmt::cdr(msg);
uint8_t * msg_elements = (uint8_t *)pmt::blob_data(msg_blob);
if(msg_elements[2]==0x1b){
//wyciągnij arfcn
pmt::pmt_t header_blob = pmt::car(msg);
gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
chan_info info;
info.id = header->arfcn;
info.pwr_db = header->signal_dbm;
info.cell_id = (msg_elements[3]<<8)+msg_elements[4]; //wyciągnij cell id
info.lac = (msg_elements[8]<<8)+msg_elements[9]; //wyciągnij lac
info.mnc = (msg_elements[7]>>4); //wyciągnij id operatora
std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
boost::mutex::scoped_lock lock(extract_mutex);
if(iter != d_c0_channels.end()){
d_c0_channels.erase(iter);
}
d_c0_channels.insert(info);
}
else if(msg_elements[2]==0x1c){
pmt::pmt_t header_blob = pmt::car(msg);
gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_blob);
chan_info info;
info.id = header->arfcn;
info.pwr_db = header->signal_dbm;
info.lac = (msg_elements[6]<<8)+msg_elements[7]; //wyciągnij lac
info.mnc = (msg_elements[5]>>4); //wyciągnij id operatora
std::set<chan_info, compare_id>::iterator iter = d_c0_channels.find(info);
boost::mutex::scoped_lock lock(extract_mutex);
if(iter != d_c0_channels.end()){
d_c0_channels.erase(iter);
if(iter->cell_id!=0){
info.cell_id=iter->cell_id;
}
}
d_c0_channels.insert(info);
}
}
void extract_system_info_impl::show(){
std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
std::vector<chan_info>::iterator iter;
//std::sort(chans.begin(), chans.end(), compare_pwr());
for(iter=chans.begin(); iter != chans.end(); ++iter){
std::cout << static_cast<int>((*iter).id) << "(" << static_cast<int>((*iter).pwr_db) << ") ";
}
std::cout << std::endl;
}
std::vector<int> extract_system_info_impl::get_chans()
{
std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
std::vector<int> chans_ids(chans.size(),-1);
//std::sort(chans.begin(), chans.end(), compare_pwr());
for(int ii; ii < chans.size(); ++ii){
chans_ids[ii] = chans[ii].id;
}
return chans_ids;
}
std::vector<int> extract_system_info_impl::get_lac()
{
std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
std::vector<int> chans_ids(chans.size(),-1);
//std::sort(chans.begin(), chans.end(), compare_pwr());
for(int ii; ii < chans.size(); ++ii){
chans_ids[ii] = chans[ii].lac;
}
return chans_ids;
}
std::vector<int> extract_system_info_impl::get_mnc()
{
std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
std::vector<int> chans_ids(chans.size(),-1);
//std::sort(chans.begin(), chans.end(), compare_pwr());
for(int ii; ii < chans.size(); ++ii){
chans_ids[ii] = chans[ii].mnc;
}
return chans_ids;
}
std::vector<int> extract_system_info_impl::get_cell_id()
{
std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
std::vector<int> chans_ids(chans.size(),-1);
//std::sort(chans.begin(), chans.end(), compare_pwr());
for(int ii; ii < chans.size(); ++ii){
chans_ids[ii] = chans[ii].cell_id;
}
return chans_ids;
}
std::vector<int> extract_system_info_impl::get_pwrs()
{
std::vector<chan_info> chans(d_c0_channels.begin(), d_c0_channels.end());
std::vector<int> pwrs(chans.size(),-1);
//std::sort(chans.begin(), chans.end(), compare_pwr());
for(int ii; ii < chans.size(); ++ii){
pwrs[ii] = chans[ii].pwr_db;
}
return pwrs;
}
void extract_system_info_impl::reset()
{
std::set<chan_info, compare_id>::iterator iter;
chan_info info;
for(iter = d_c0_channels.begin(); iter != d_c0_channels.end(); iter++){
info.id = iter->id;
info.cell_id = iter->cell_id; //wyciągnij cell id
info.lac = iter->lac; //wyciągnij lac
info.mnc = iter->mnc;
info.pwr_db = -111;
d_c0_channels.erase(iter);
d_c0_channels.insert(info);
}
// d_c0_channels.clear();
if(!empty_p(pmt::mp("bursts"))){
delete_head_blocking(pmt::mp("bursts"));
}
}
extract_system_info::sptr
extract_system_info::make()
{
return gnuradio::get_initial_sptr
(new extract_system_info_impl());
}
/*
* The private constructor
*/
extract_system_info_impl::extract_system_info_impl()
: gr::block("extract_system_info",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)),
after_reset(false)
{
message_port_register_in(pmt::mp("bursts"));
set_msg_handler(pmt::mp("bursts"), boost::bind(&extract_system_info_impl::process_bursts, this, _1));
message_port_register_in(pmt::mp("msgs"));
set_msg_handler(pmt::mp("msgs"), boost::bind(&extract_system_info_impl::process_sysinfo, this, _1));
}
/*
* Our virtual destructor.
*/
extract_system_info_impl::~extract_system_info_impl()
{
}
} /* namespace gsm */
} /* namespace gr */