Add control channels demappers tests

3GPP TS 45.002 version 15.1.0 Release 15
Table 3 : Mapping of logical channels onto physical channels (see subclauses 6.3, 6.4, 6.5)
Table 4 : Mapping of logical channels onto physical channels (see subclauses 6.3, 6.4, 6.5)
Figure 8a: TDMA frame mapping for FCCH + SCH + BCCH + CCCH
Figure 8b: TDMA frame mapping for FCCH + SCH + BCCH + CCCH + SDCCH/4(0...3) + SACCH/4(0...3)

Five of the six tests currently fail and are marked with
@unittest.expectedFailure. Fixes in subsequent commits.

Change-Id: I33b0948832a0c2506bffd389cc134c3236c74d27
This commit is contained in:
Vasil Velichkov 2019-07-20 23:33:08 +03:00
parent 54580d148d
commit ff88ba41ec
11 changed files with 653 additions and 3 deletions

View File

@ -54,6 +54,8 @@ namespace gr {
virtual std::vector<int> get_timeslots() = 0;
virtual std::vector<std::string> get_burst_data() = 0;
virtual pmt::pmt_t get_bursts() = 0;
virtual std::vector<uint8_t> get_sub_types() = 0;
virtual std::vector<uint8_t> get_sub_slots() = 0;
};
} // namespace gsm
} // namespace gr

View File

@ -54,6 +54,7 @@ namespace gr {
virtual void set_framenumbers(const std::vector<int> &framenumbers) = 0;
virtual void set_timeslots(const std::vector<int> &timeslots) = 0;
virtual void set_burst_data(const std::vector<std::string> &burst_data) = 0;
virtual void set_arfcn(uint16_t arfcn) = 0;
};
} // namespace gsm

View File

@ -90,6 +90,8 @@ namespace gr {
d_framenumbers.push_back(frame_nr);
d_timeslots.push_back(header->timeslot);
d_burst_data.push_back(burst_str.str());
d_sub_types.push_back(header->sub_type);
d_sub_slots.push_back(header->sub_slot);
}
std::vector<int> burst_sink_impl::get_framenumbers()
@ -110,6 +112,14 @@ namespace gr {
{
return d_bursts;
}
std::vector<uint8_t> burst_sink_impl::get_sub_types()
{
return d_sub_types;
}
std::vector<uint8_t> burst_sink_impl::get_sub_slots()
{
return d_sub_slots;
}
} /* namespace gsm */
} /* namespace gr */

View File

@ -36,6 +36,8 @@ namespace gr {
std::vector<int> d_timeslots;
std::vector<std::string> d_burst_data;
pmt::pmt_t d_bursts;
std::vector<uint8_t> d_sub_types;
std::vector<uint8_t> d_sub_slots;
public:
burst_sink_impl();
~burst_sink_impl();
@ -44,6 +46,8 @@ namespace gr {
virtual std::vector<int> get_timeslots();
virtual std::vector<std::string> get_burst_data();
virtual pmt::pmt_t get_bursts();
virtual std::vector<uint8_t> get_sub_types();
virtual std::vector<uint8_t> get_sub_slots();
};
} // namespace gsm

View File

@ -52,7 +52,8 @@ namespace gr {
: gr::block("burst_source",
gr::io_signature::make(0, 0, 0),
gr::io_signature::make(0, 0, 0)),
d_finished(false)
d_finished(false),
d_arfcn(0)
{
message_port_register_out(pmt::mp("out"));
set_framenumbers(framenumbers);
@ -85,6 +86,11 @@ namespace gr {
d_burst_data = burst_data;
}
void burst_source_impl::set_arfcn(uint16_t arfcn)
{
d_arfcn = arfcn;
}
bool burst_source_impl::start()
{
d_finished = false;
@ -122,7 +128,7 @@ namespace gr {
tap_header->timeslot = d_timeslots[i];
tap_header->frame_number = htobe32(d_framenumbers[i]);
tap_header->sub_type = GSMTAP_BURST_NORMAL;
tap_header->arfcn = 0;
tap_header->arfcn = d_arfcn;
tap_header->signal_dbm = 0;
tap_header->snr_db = 0;

View File

@ -40,6 +40,7 @@ namespace gr {
std::vector<int> d_timeslots;
std::vector<std::string> d_burst_data;
bool d_finished;
uint16_t d_arfcn;
void run();
public:
burst_source_impl(const std::vector<int> &framenumbers,
@ -49,6 +50,7 @@ namespace gr {
virtual void set_framenumbers(const std::vector<int> &framenumbers);
virtual void set_timeslots(const std::vector<int> &timeslots);
virtual void set_burst_data(const std::vector<std::string> &burst_data);
virtual void set_arfcn(uint16_t arfcn);
bool start();
bool stop();
bool finished();

View File

@ -45,7 +45,7 @@ GR_PYTHON_INSTALL(
include(GrTest)
set(GR_TEST_TARGET_DEPS gr-gsm)
set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig:${CMAKE_BINARY_DIR}/python/misc_utils)
set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig:${CMAKE_BINARY_DIR}/python/misc_utils:${CMAKE_BINARY_DIR}/python/receiver:${CMAKE_BINARY_DIR}/python/demapping:${CMAKE_BINARY_DIR}/python/transmitter)
GR_ADD_TEST(qa_arfcn ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_arfcn.py)
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)
@ -61,6 +61,9 @@ GR_ADD_TEST(qa_tch_f_decoder ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa
GR_ADD_TEST(qa_tch_h_decoder ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_tch_h_decoder.py)
GR_ADD_TEST(qa_tch_f_chans_demapper ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_tch_f_chans_demapper.py)
GR_ADD_TEST(qa_tch_h_chans_demapper ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_tch_h_chans_demapper.py)
GR_ADD_TEST(qa_gsm_bcch_ccch_demapper ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_gsm_bcch_ccch_demapper.py)
GR_ADD_TEST(qa_gsm_bcch_ccch_sdcch4_demapper ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_gsm_bcch_ccch_sdcch4_demapper.py)
GR_ADD_TEST(qa_gsm_sdcch8_demapper ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_gsm_sdcch8_demapper.py)
#GR_ADD_TEST(qa_msg_to_tag ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_msg_to_tag.py)
#GR_ADD_TEST(qa_controlled_fractional_resampler_cc ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_controlled_fractional_resampler_cc.py)
#GR_ADD_TEST(qa_uplink_downlink_splitter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_uplink_downlink_splitter.py)

View File

@ -0,0 +1,146 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @file
# @author (C) 2019 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.
#
#
import unittest
import numpy as np
from gnuradio import gr, gr_unittest, blocks
import grgsm
import pmt
import qa_gsm_demapper_data as test_data
class qa_gsm_bcch_ccch_demapper (gr_unittest.TestCase):
def setUp (self):
self.tb = gr.top_block ()
self.maxDiff = None
def tearDown (self):
self.tb = None
def test_downlink (self):
"""
BCCH_CCCH demapper downlink test
"""
src = grgsm.burst_source(test_data.frames, test_data.timeslots, test_data.bursts)
src.set_arfcn(0); # downlink
demapper = grgsm.gsm_bcch_ccch_demapper(timeslot_nr=0)
dst = grgsm.burst_sink()
self.tb.msg_connect(src, "out", demapper, "bursts")
self.tb.msg_connect(demapper, "bursts", dst, "in")
self.tb.run ()
b = test_data.bursts
self.assertEqual([
b[ 2], b[ 3], b[ 4], b[ 5], #BCCH
b[ 6], b[ 7], b[ 8], b[ 9], #CCCH skip 10-11
b[ 12], b[ 13], b[ 14], b[ 15],
b[ 16], b[ 17], b[ 18], b[ 19], #skip 20-21
b[ 22], b[ 23], b[ 24], b[ 25],
b[ 26], b[ 27], b[ 28], b[ 29], #skip 30-31
b[ 32], b[ 33], b[ 34], b[ 35],
b[ 36], b[ 37], b[ 38], b[ 39], #skip 40-41
b[ 42], b[ 43], b[ 44], b[ 45],
b[ 46], b[ 47], b[ 48], b[ 49], #skip 50-52
b[ 53], b[ 54], b[ 55], b[ 56], #BCCH
b[ 57], b[ 58], b[ 59], b[ 60], #CCCH skip 61-62
b[ 63], b[ 64], b[ 65], b[ 66],
b[ 67], b[ 68], b[ 69], b[ 70], #skip 71-72
b[ 73], b[ 74], b[ 75], b[ 76],
b[ 77], b[ 78], b[ 79], b[ 80], #skip 81-82
b[ 83], b[ 84], b[ 85], b[ 86],
b[ 87], b[ 88], b[ 89], b[ 90], #skip 91-92
b[ 93], b[ 94], b[ 95], b[ 96],
b[ 97], b[ 98], b[ 99], b[100], #skip 101-103
b[104], b[105], b[106], b[107] #BCCH
], list(dst.get_burst_data()))
self.assertEqual([
1, 1, 1, 1, #BCCH
2, 2, 2, 2, #CCCH
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
1, 1, 1, 1, #BCCH
2, 2, 2, 2, #CCCH
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
2, 2, 2, 2,
1, 1, 1, 1, #BCCH
], list(dst.get_sub_types()))
self.assertEqual([
0, 0, 0, 0, #BCCH
0, 0, 0, 0, #CCCH 0
1, 1, 1, 1,
2, 2, 2, 2,
3, 3, 3, 3,
4, 4, 4, 4,
5, 5, 5, 5,
6, 6, 6, 6,
7, 7, 7, 7,
8, 8, 8, 8, #CCCH 8
0, 0, 0, 0, #BCCH
0, 0, 0, 0, #CCCH 0
1, 1, 1, 1,
2, 2, 2, 2,
3, 3, 3, 3,
4, 4, 4, 4,
5, 5, 5, 5,
6, 6, 6, 6,
7, 7, 7, 7,
8, 8, 8, 8, #CCCH 8
0, 0, 0, 0, #BCCH
], list(dst.get_sub_slots()))
@unittest.expectedFailure
def test_uplink (self):
"""
BCCH_CCCH demapper uplink test
"""
src = grgsm.burst_source(test_data.frames, test_data.timeslots, test_data.bursts)
src.set_arfcn(0x2240); #uplink flag is 40
demapper = grgsm.gsm_bcch_ccch_demapper(timeslot_nr=0)
dst = grgsm.burst_sink()
self.tb.msg_connect(src, "out", demapper, "bursts")
self.tb.msg_connect(demapper, "bursts", dst, "in")
self.tb.run ()
b = test_data.bursts
self.assertEqual(b, list(dst.get_burst_data()))
self.assertEqual([3]*len(b), list(dst.get_sub_types()))
self.assertEqual([0]*len(b), list(dst.get_sub_slots()))
if __name__ == '__main__':
gr_unittest.run(qa_gsm_bcch_ccch_demapper, "qa_gsm_bcch_ccch_demapper.xml")

View File

@ -0,0 +1,211 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @file
# @author (C) 2019 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.
#
#
import unittest
import numpy as np
from gnuradio import gr, gr_unittest, blocks
import grgsm
import pmt
import qa_gsm_demapper_data as test_data
class qa_bcch_ccch_sdcch4_demapper (gr_unittest.TestCase):
def setUp (self):
self.tb = gr.top_block ()
self.maxDiff = None
def tearDown (self):
self.tb = None
@unittest.expectedFailure
def test_downlink (self):
"""
BCCH_CCCH_SDCCH4 demapper downlink test
"""
src = grgsm.burst_source(test_data.frames, test_data.timeslots, test_data.bursts)
src.set_arfcn(0); # downlink
demapper = grgsm.gsm_bcch_ccch_sdcch4_demapper(timeslot_nr=0)
dst = grgsm.burst_sink()
self.tb.msg_connect(src, "out", demapper, "bursts")
self.tb.msg_connect(demapper, "bursts", dst, "in")
self.tb.run ()
b = test_data.bursts
self.assertEqual([
b[ 2], b[ 3], b[ 4], b[ 5], #BCCH
b[ 6], b[ 7], b[ 8], b[ 9], #CCCH skip 2
b[ 12], b[ 13], b[ 14], b[ 15], #CCCH
b[ 16], b[ 17], b[ 18], b[ 19], #CCCH skip 2
b[ 22], b[ 23], b[ 24], b[ 25], #SDCCH 0
b[ 26], b[ 27], b[ 28], b[ 29], #SDCCH 1 skip 2
b[ 32], b[ 33], b[ 34], b[ 35], #SDCCH 2
b[ 36], b[ 37], b[ 38], b[ 39], #SDCCH 3 skip 2
b[ 42], b[ 43], b[ 44], b[ 45], #SACCH 0
b[ 46], b[ 47], b[ 48], b[ 49], #SACCH 1 skip 3
b[ 53], b[ 54], b[ 55], b[ 56], #BCCH
b[ 57], b[ 58], b[ 59], b[ 60], #CCCH skip 2
b[ 63], b[ 64], b[ 65], b[ 66], #CCCH
b[ 67], b[ 68], b[ 69], b[ 70], #CCCH skip 2
b[ 73], b[ 74], b[ 75], b[ 76], #SDCCH 0
b[ 77], b[ 78], b[ 79], b[ 80], #SDCCH 1 skip 2
b[ 83], b[ 84], b[ 85], b[ 86], #SDCCH 2
b[ 87], b[ 88], b[ 89], b[ 90], #SDCCH 3 skip 2
b[ 93], b[ 94], b[ 95], b[ 96], #SACCH 1
b[ 97], b[ 98], b[ 99], b[100], #SACCH 2 skip 3
b[104], b[105], b[106], b[107] #BCCH
], list(dst.get_burst_data()))
self.assertEqual([
1, 1, 1, 1, #BCCH
2, 2, 2, 2, #CCCH
2, 2, 2, 2, #CCCH
2, 2, 2, 2, #CCCH
7, 7, 7, 7, #SDCCH 0
7, 7, 7, 7, #SDCCH 1
7, 7, 7, 7, #SDCCH 2
7, 7, 7, 7, #SDCCH 3
135, 135, 135, 135, #SACCH 0
135, 135, 135, 135, #SACCH 1
1, 1, 1, 1, #BCCH
2, 2, 2, 2, #CCCH
2, 2, 2, 2, #CCCH
2, 2, 2, 2, #CCCH
7, 7, 7, 7, #SDCCH 0
7, 7, 7, 7, #SDCCH 1
7, 7, 7, 7, #SDCCH 2
7, 7, 7, 7, #SDCCH 3
135, 135, 135, 135, #SACCH 2
135, 135, 135, 135, #SACCH 3
1, 1, 1, 1, #BCCH
], list(dst.get_sub_types()))
self.assertEqual([
0, 0, 0, 0, #BCCH
0, 0, 0, 0, #CCCH
1, 1, 1, 1, #CCCH
2, 2, 2, 2, #CCCH
0, 0, 0, 0, #SDCCH 0
1, 1, 1, 1, #SDCCH 1
2, 2, 2, 2, #SDCCH 2
3, 3, 3, 3, #SDCCH 3
0, 0, 0, 0, #SACCH 0
1, 1, 1, 1, #SACCH 1
0, 0, 0, 0, #BCCH
0, 0, 0, 0, #CCCH
1, 1, 1, 1, #CCCH
2, 2, 2, 2, #CCCH
0, 0, 0, 0, #SDCCH 0
1, 1, 1, 1, #SDCCH 1
2, 2, 2, 2, #SDCCH 2
3, 3, 3, 3, #SDCCH 3
2, 2, 2, 2, #SACCH 2
3, 3, 3, 3, #SACCH 3
0, 0, 0, 0, #BCCH
], list(dst.get_sub_slots()))
@unittest.expectedFailure
def test_uplink (self):
"""
BCCH_CCCH_SDCCH4 demapper uplink test
"""
src = grgsm.burst_source(test_data.frames, test_data.timeslots, test_data.bursts)
src.set_arfcn(0x2240); #uplink flag is 40
demapper = grgsm.gsm_bcch_ccch_sdcch4_demapper(timeslot_nr=0)
dst = grgsm.burst_sink()
self.tb.msg_connect(src, "out", demapper, "bursts")
self.tb.msg_connect(demapper, "bursts", dst, "in")
self.tb.run ()
b = test_data.bursts
self.assertEqual(b, list(dst.get_burst_data()))
self.assertEqual([
7, 7, 7, 7, #SDCCH 3
3, 3, #RACCH
135, 135, 135, 135, #SACCH 2
135, 135, 135, 135, #SACCH 3
3, 3, 3, 3, #RACCH
3, 3, 3, 3, #RACCH
3, 3, 3, 3, #RACCH
3, 3, 3, 3, #RACCH
3, 3, 3, 3, #RACCH
3, 3, 3, #RACCH
7, 7, 7, 7, #SDCCH 0
7, 7, 7, 7, #SDCCH 1
3, 3, #RACCH
7, 7, 7, 7, #SDCCH 2
7, 7, 7, 7, #SDCCH 3
3, 3, #RACCH
135, 135, 135, 135, #SACCH 0
135, 135, 135, 135, #SACCH 1
3, 3, 3, 3, #RACCH
3, 3, 3, 3, #RACCH
3, 3, 3, 3, #RACCH
3, 3, 3, 3, #RACCH
3, 3, 3, 3, #RACCH
3, 3, 3, #RACCH
7, 7, 7, 7, #SDCCH 0
7, 7, 7, 7, #SDCCH 1
3, 3, #RACCH
7, 7, 7, 7, #SDCCH 2
7, 7, 7, 7, #SDCCH 3
3, 3, #RACCH
], list(dst.get_sub_types()))
self.assertEqual([
3, 3, 3, 3, #SDCCH 3
0, 0, #RACCH
2, 2, 2, 2, #SACCH 2
3, 3, 3, 3, #SACCH 3
0, 0, 0, 0, #RACCH
0, 0, 0, 0, #RACCH
0, 0, 0, 0, #RACCH
0, 0, 0, 0, #RACCH
0, 0, 0, 0, #RACCH
0, 0, 0, #RACCH
0, 0, 0, 0, #SDCCH 0
1, 1, 1, 1, #SDCCH 1
0, 0, #RACCH
2, 2, 2, 2, #SDCCH 2
3, 3, 3, 3, #SDCCH 3
0, 0, #RACCH
0, 0, 0, 0, #SACCH 0
1, 1, 1, 1, #SACCH 1
0, 0, 0, 0, #RACCH
0, 0, 0, 0, #RACCH
0, 0, 0, 0, #RACCH
0, 0, 0, 0, #RACCH
0, 0, 0, 0, #RACCH
0, 0, 0, #RACCH
0, 0, 0, 0, #SDCCH 0
1, 1, 1, 1, #SDCCH 1
0, 0, #RACCH
2, 2, 2, 2, #SDCCH 2
3, 3, 3, 3, #SDCCH 3
0, 0, #RACCH
], list(dst.get_sub_slots()))
if __name__ == '__main__':
gr_unittest.run(qa_bcch_ccch_sdcch4_demapper, "qa_bcch_ccch_sdcch4_demapper.xml")

View File

@ -0,0 +1,26 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @file
# @author (C) 2019 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.
#
#
bursts = [format((2**(i+1))-1, '0<148b') for i in range(0,108)]
frames = range(0, 108)
timeslots = [0] * len(frames)

View File

@ -0,0 +1,239 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @file
# @author (C) 2019 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.
#
#
import unittest
import numpy as np
from gnuradio import gr, gr_unittest, blocks
import grgsm
import pmt
import qa_gsm_demapper_data as test_data
class qa_gsm_sdcch8_demapper (gr_unittest.TestCase):
def setUp (self):
self.tb = gr.top_block ()
self.maxDiff = None
def tearDown (self):
self.tb = None
@unittest.expectedFailure
def test_downlink (self):
"""
SDCCH8 demapper downlink test
"""
src = grgsm.burst_source(test_data.frames, test_data.timeslots, test_data.bursts)
src.set_arfcn(0); # downlink
demapper = grgsm.gsm_sdcch8_demapper(timeslot_nr=0)
dst = grgsm.burst_sink()
self.tb.msg_connect(src, "out", demapper, "bursts")
self.tb.msg_connect(demapper, "bursts", dst, "in")
self.tb.run ()
b = test_data.bursts
self.assertEqual([
b[ 0], b[ 1], b[ 2], b[ 3], #SDCCH 0
b[ 4], b[ 5], b[ 6], b[ 7], #SDCCH 1
b[ 8], b[ 9], b[ 10], b[ 11], #SDCCH 2
b[ 12], b[ 13], b[ 14], b[ 15], #SDCCH 3
b[ 16], b[ 17], b[ 18], b[ 19], #SDCCH 4
b[ 20], b[ 21], b[ 22], b[ 23], #SDCCH 5
b[ 24], b[ 25], b[ 26], b[ 27], #SDCCH 6
b[ 28], b[ 29], b[ 30], b[ 31], #SDCCH 7
b[ 32], b[ 33], b[ 34], b[ 35], #SACCH 0
b[ 36], b[ 37], b[ 38], b[ 39], #SACCH 1
b[ 40], b[ 41], b[ 42], b[ 43], #SACCH 2
b[ 44], b[ 45], b[ 46], b[ 47], #SACCH 3 #skip 48-50
b[ 51], b[ 52], b[ 53], b[ 54], #SDCCH 0
b[ 55], b[ 56], b[ 57], b[ 58], #SDCCH 1
b[ 59], b[ 60], b[ 61], b[ 62], #SDCCH 2
b[ 63], b[ 64], b[ 65], b[ 66], #SDCCH 3
b[ 67], b[ 68], b[ 69], b[ 70], #SDCCH 4
b[ 71], b[ 72], b[ 73], b[ 74], #SDCCH 5
b[ 75], b[ 76], b[ 77], b[ 78], #SDCCH 6
b[ 79], b[ 80], b[ 81], b[ 82], #SDCCH 7
b[ 83], b[ 84], b[ 85], b[ 86], #SACCH 4
b[ 87], b[ 88], b[ 89], b[ 90], #SACCH 5
b[ 91], b[ 92], b[ 93], b[ 94], #SACCH 6
b[ 95], b[ 96], b[ 97], b[ 98], #SACCH 7 #skip 99-101
b[102], b[103], b[104], b[105], #SDCCH
], list(dst.get_burst_data()))
self.assertEqual([
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
136, 136, 136, 136,
136, 136, 136, 136,
136, 136, 136, 136,
136, 136, 136, 136,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
136, 136, 136, 136,
136, 136, 136, 136,
136, 136, 136, 136,
136, 136, 136, 136,
8, 8, 8, 8,
], list(dst.get_sub_types()))
self.assertEqual([
0, 0, 0, 0,
1, 1, 1, 1,
2, 2, 2, 2,
3, 3, 3, 3,
4, 4, 4, 4,
5, 5, 5, 5,
6, 6, 6, 6,
7, 7, 7, 7,
0, 0, 0, 0, #SACCH 0
1, 1, 1, 1, #SACCH 1
2, 2, 2, 2, #SACCH 2
3, 3, 3, 3, #SACCH 3
0, 0, 0, 0,
1, 1, 1, 1,
2, 2, 2, 2,
3, 3, 3, 3,
4, 4, 4, 4,
5, 5, 5, 5,
6, 6, 6, 6,
7, 7, 7, 7,
4, 4, 4, 4, #SACCH 4
5, 5, 5, 5, #SACCH 5
6, 6, 6, 6, #SACCH 6
7, 7, 7, 7, #SACCH 7
0, 0, 0, 0,
], list(dst.get_sub_slots()))
@unittest.expectedFailure
def test_uplink (self):
"""
BCCH_CCCH_SDCCH4 demapper uplink test
"""
src = grgsm.burst_source(test_data.frames, test_data.timeslots, test_data.bursts)
src.set_arfcn(0x2240); #uplink flag is 40
demapper = grgsm.gsm_sdcch8_demapper(timeslot_nr=0)
dst = grgsm.burst_sink()
self.tb.msg_connect(src, "out", demapper, "bursts")
self.tb.msg_connect(demapper, "bursts", dst, "in")
self.tb.run ()
b = test_data.bursts
self.assertEqual([
b[ 0], b[ 1], b[ 2], b[ 3], #SACCH 5
b[ 4], b[ 5], b[ 6], b[ 7], #SACCH 6
b[ 8], b[ 9], b[ 10], b[ 11], #SACCH 7 #skip 12-14
b[ 15], b[ 16], b[ 17], b[ 18], #SDCCH 0
b[ 19], b[ 20], b[ 21], b[ 22], #SDCCH 1
b[ 23], b[ 24], b[ 25], b[ 26], #SDCCH 2
b[ 27], b[ 28], b[ 29], b[ 30], #SDCCH 3
b[ 31], b[ 32], b[ 33], b[ 34], #SDCCH 4
b[ 35], b[ 36], b[ 37], b[ 38], #SDCCH 5
b[ 39], b[ 40], b[ 41], b[ 42], #SDCCH 6
b[ 43], b[ 44], b[ 45], b[ 46], #SDCCH 7
b[ 47], b[ 48], b[ 49], b[ 50], #SACCH 0
b[ 51], b[ 52], b[ 53], b[ 54], #SACCH 1
b[ 55], b[ 56], b[ 57], b[ 58], #SACCH 2
b[ 59], b[ 60], b[ 61], b[ 62], #SACCH 3 #skip 63-65
b[ 66], b[ 67], b[ 68], b[ 69], #SDCCH 0
b[ 70], b[ 71], b[ 72], b[ 73], #SDCCH 1
b[ 74], b[ 75], b[ 76], b[ 77], #SDCCH 2
b[ 78], b[ 79], b[ 80], b[ 81], #SDCCH 3
b[ 82], b[ 83], b[ 84], b[ 85], #SDCCH 4
b[ 86], b[ 87], b[ 88], b[ 89], #SDCCH 5
b[ 90], b[ 91], b[ 92], b[ 93], #SDCCH 6
b[ 94], b[ 95], b[ 96], b[ 97], #SDCCH 7
b[ 98], b[ 99], b[100], b[101], #SACCH 4
b[102], b[103], b[104], b[105], #SACCH 5
], list(dst.get_burst_data()))
self.assertEqual([
136, 136, 136, 136,
136, 136, 136, 136,
136, 136, 136, 136,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
136, 136, 136, 136,
136, 136, 136, 136,
136, 136, 136, 136,
136, 136, 136, 136,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
8, 8, 8, 8,
136, 136, 136, 136,
136, 136, 136, 136,
], list(dst.get_sub_types()))
self.assertEqual([
5, 5, 5, 5, #SACCH 5
6, 6, 6, 6, #SACCH 6
7, 7, 7, 7, #SACCH 7
0, 0, 0, 0,
1, 1, 1, 1,
2, 2, 2, 2,
3, 3, 3, 3,
4, 4, 4, 4,
5, 5, 5, 5,
6, 6, 6, 6,
7, 7, 7, 7,
0, 0, 0, 0, #SACCH 0
1, 1, 1, 1, #SACCH 1
2, 2, 2, 2, #SACCH 2
3, 3, 3, 3, #SACCH 3
0, 0, 0, 0,
1, 1, 1, 1,
2, 2, 2, 2,
3, 3, 3, 3,
4, 4, 4, 4,
5, 5, 5, 5,
6, 6, 6, 6,
7, 7, 7, 7,
4, 4, 4, 4, #SACCH 4
5, 5, 5, 5,
], list(dst.get_sub_slots()))
if __name__ == '__main__':
gr_unittest.run(qa_gsm_sdcch8_demapper, "qa_gsm_sdcch8_demapper.xml")