burst_file_source: Fix reading longer bursts

- Read bursts with pmt::deserialize directly from the std::filebuf
- Remove the unused unserialized variable
- Add tests

Since df978693 when the rx_time tags are present in the incomming stream
the gsm receiver adds fm_time to the burst's PMT and the bursts that
burst file sink writes becomes longer because of the additional field.

The burst file source block was expecting all burst to be 147 bytes long
and reading files with longer bursts was failing with an unhandled exception.

terminate called after throwing an instance of 'pmt::exception'
thread[thread-per-block[5]: <block dummy_burst_filter (2)>]: pmt_cdr: wrong_type : #f
  what():  pmt::deserialize: malformed input stream, tag value = : 115

Change-Id: I989b0d6a6b214088b7880e5cbf7bb6725492dbfc
This commit is contained in:
Vasil Velichkov 2018-09-11 14:15:53 +03:00 committed by Piotr Krysik
parent 7379e341b0
commit 89585b374b
4 changed files with 109 additions and 13 deletions

View File

@ -28,8 +28,6 @@
#include "burst_file_source_impl.h"
#include "stdio.h"
#define PMT_SIZE 174
namespace gr {
namespace gsm {
@ -86,16 +84,13 @@ namespace gr {
void burst_file_source_impl::run()
{
char *unserialized = (char*)malloc(sizeof(char) * PMT_SIZE);
while (d_input_file.read(unserialized, PMT_SIZE) && !d_finished)
std::filebuf* pbuf = d_input_file.rdbuf();
while (!d_finished)
{
if (d_input_file.bad())
{
pmt::pmt_t burst = pmt::deserialize(*pbuf);
if (pmt::is_eof_object(burst)) {
break;
}
std::string s(unserialized, PMT_SIZE);
pmt::pmt_t burst = pmt::deserialize_str(s);
message_port_pub(pmt::mp("out"), burst);
}
d_input_file.close();

View File

@ -31,8 +31,6 @@
#include <grgsm/gsmtap.h>
#include <grgsm/endian.h>
#define PMT_SIZE 174
namespace gr {
namespace gsm {
@ -110,8 +108,6 @@ namespace gr {
void burst_source_impl::run()
{
char *unserialized = (char*)malloc(sizeof(char) * PMT_SIZE);
for (int i=0; i<d_burst_data.size(); i++)
{
if (d_burst_data[i].length() == BURST_SIZE &&

View File

@ -50,6 +50,7 @@ GR_ADD_TEST(qa_arfcn ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_arfcn.p
GR_ADD_TEST(qa_decryption ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_decryption.py)
GR_ADD_TEST(qa_burst_printer ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_printer.py)
GR_ADD_TEST(qa_message_printer ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_message_printer.py)
GR_ADD_TEST(qa_burst_file_source ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_file_source.py)
GR_ADD_TEST(qa_burst_timeslot_splitter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_timeslot_splitter.py)
GR_ADD_TEST(qa_burst_sdcch_subslot_splitter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_sdcch_subslot_splitter.py)
GR_ADD_TEST(qa_burst_timeslot_filter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_timeslot_filter.py)

View File

@ -0,0 +1,104 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @file
# @author (C) 2018 by Vasil Velichkov <vvvelichkov@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.
#
#
from gnuradio import gr, gr_unittest, blocks
import grgsm_swig as grgsm
import tempfile
class qa_burst_file_sink (gr_unittest.TestCase):
def setUp (self):
self.tb = gr.top_block ()
def tearDown (self):
self.tb = None
def test_blob_only (self):
# prepare the input burst file
temp = tempfile.NamedTemporaryFile()
handle = open(temp.name, "wb")
handle.write(bytearray([
0x07, 0x06, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x01, 0x00, 0x02, 0x04, 0x03, 0x01, 0x00, 0x6f,
0xcd, 0x00, 0x00, 0x25, 0xc9, 0x82, 0x06, 0x1c, 0xf5, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00,
0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01,
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01,
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,
0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01
]))
handle.flush();
src = grgsm.burst_file_source(temp.name);
dst = grgsm.burst_sink();
self.tb.msg_connect(src, "out", dst, "in")
self.tb.run ()
self.assertEqual([2476418], list(dst.get_framenumbers()))
self.assertEqual([1], list(dst.get_timeslots()))
self.assertEqual([
"0000001000000101010111111110101000000000010101010111101010101001011011101111000101101111100000000001010101111010101010000000010101011101111010101001"],
list(dst.get_burst_data()))
def test_fn_time (self):
# prepare the input burst file
temp = tempfile.NamedTemporaryFile()
handle = open(temp.name, "wb")
handle.write(bytearray([
0x07,
# the additional fn_time field - 51 bytes
0x07, 0x07, 0x02, 0x00, 0x07, 0x66, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x07, 0x07, 0x0b,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x3b, 0x73, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x07, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3f, 0xe4, 0x99, 0x45,
0xbe, 0x81, 0xc0, 0xf4,
# the 173 original 173 bytes
0x06, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x01, 0x00, 0x02, 0x04, 0x03, 0x01, 0x00, 0x6f,
0xcd, 0x00, 0x00, 0x25, 0xc9, 0x82, 0x06, 0x1c, 0xf5, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00,
0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01,
0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01,
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,
0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01
]))
handle.flush();
src = grgsm.burst_file_source(temp.name);
dst = grgsm.burst_sink();
self.tb.msg_connect(src, "out", dst, "in")
self.tb.run ()
self.assertEqual([2476418], list(dst.get_framenumbers()))
self.assertEqual([1], list(dst.get_timeslots()))
self.assertEqual([
"0000001000000101010111111110101000000000010101010111101010101001011011101111000101101111100000000001010101111010101010000000010101011101111010101001"],
list(dst.get_burst_data()))
if __name__ == '__main__':
gr_unittest.run(qa_burst_file_sink, "qa_burst_file_sink.xml")