blob: f48129403cfccc98a82dcc07811e2dbdb6b160fc [file] [log] [blame]
piotrfaacc722014-07-20 23:48:32 +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>
David Holm98806532014-12-01 21:19:18 +010026#include <gsm/endian.h>
piotrfaacc722014-07-20 23:48:32 +020027#include <gsm/gsmtap.h>
28#include "get_bcch_or_ccch_bursts_impl.h"
29
30namespace gr {
31 namespace gsm {
32
33 get_bcch_or_ccch_bursts::sptr
piotrdf304592014-08-04 11:22:47 +020034 get_bcch_or_ccch_bursts::make(unsigned int fn51_start)
piotrfaacc722014-07-20 23:48:32 +020035 {
36 return gnuradio::get_initial_sptr
piotrdf304592014-08-04 11:22:47 +020037 (new get_bcch_or_ccch_bursts_impl(fn51_start));
piotrfaacc722014-07-20 23:48:32 +020038 }
39
40 /*
41 * The private constructor
42 */
piotrdf304592014-08-04 11:22:47 +020043 get_bcch_or_ccch_bursts_impl::get_bcch_or_ccch_bursts_impl(unsigned int fn51_start)
piotrfaacc722014-07-20 23:48:32 +020044 : gr::block("get_bcch_or_ccch_bursts",
45 gr::io_signature::make(0, 0, 0),
piotrdf304592014-08-04 11:22:47 +020046 gr::io_signature::make(0, 0, 0)),
47 d_fn51_start(fn51_start)
piotrfaacc722014-07-20 23:48:32 +020048 {
49 message_port_register_in(pmt::mp("bursts"));
50 set_msg_handler(pmt::mp("bursts"), boost::bind(&get_bcch_or_ccch_bursts_impl::filter_ccch, this, _1));
51 message_port_register_out(pmt::mp("bursts"));
52 }
53
54 /*
55 * Our virtual destructor.
56 */
57 get_bcch_or_ccch_bursts_impl::~get_bcch_or_ccch_bursts_impl()
58 {
59 }
60
61 void get_bcch_or_ccch_bursts_impl::filter_ccch(pmt::pmt_t msg)
62 {
ptrkrysik617ba032014-11-21 10:11:05 +010063 pmt::pmt_t header_plus_burst = pmt::cdr(msg);
64 gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst);
ptrkrysik6f6d46d2014-11-12 22:50:18 +010065 uint32_t frame_nr = be32toh(header->frame_number);
piotrfaacc722014-07-20 23:48:32 +020066
ptrkrysik6f6d46d2014-11-12 22:50:18 +010067 uint32_t fn_mod51 = frame_nr % 51;
piotrdf304592014-08-04 11:22:47 +020068 int fn51_stop = d_fn51_start+3;
piotrfaacc722014-07-20 23:48:32 +020069
70 if(header->timeslot==0){
piotrdf304592014-08-04 11:22:47 +020071 if(fn_mod51>=d_fn51_start && fn_mod51<=fn51_stop){
72 uint32_t ii = fn_mod51-d_fn51_start;
ptrkrysik6f6d46d2014-11-12 22:50:18 +010073 d_frame_numbers[ii]=frame_nr;
piotrfaacc722014-07-20 23:48:32 +020074 d_bursts[ii] = msg;
75 }
76
77 if(fn_mod51==fn51_stop){
78 //check for a situation where some BCCH bursts were lost
79 //in this situation frame numbers won't be consecutive
80 bool frames_are_consecutive = true;
81 for(int jj=1; jj<4; jj++)
82 {
83 if((d_frame_numbers[jj]-d_frame_numbers[jj-1])!=1){
84 frames_are_consecutive = false;
85 }
86 }
87 if(frames_are_consecutive)
88 {
89 //send bursts to the output
90 for(int jj=0; jj<4; jj++)
91 {
92 message_port_pub(pmt::mp("bursts"), d_bursts[jj]);
93 }
94 }
95 }
96 }
97 }
98 } /* namespace gsm */
99} /* namespace gr */
100