Merge branch 'ptrkrysik/trx' into development
This commit is contained in:
commit
8a8d41a583
|
@ -5,7 +5,7 @@ build
|
||||||
*.pyc
|
*.pyc
|
||||||
*.pyo
|
*.pyo
|
||||||
.unittests
|
.unittests
|
||||||
build/
|
build*/
|
||||||
debian/tmp/
|
debian/tmp/
|
||||||
debian/files
|
debian/files
|
||||||
.directory
|
.directory
|
||||||
|
|
|
@ -77,6 +77,7 @@ GR_PYTHON_INSTALL(
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/grgsm_livemon_headless
|
${CMAKE_CURRENT_BINARY_DIR}/grgsm_livemon_headless
|
||||||
grgsm_scanner
|
grgsm_scanner
|
||||||
grgsm_decode
|
grgsm_decode
|
||||||
|
grgsm_trx
|
||||||
DESTINATION bin
|
DESTINATION bin
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# GR-GSM based transceiver
|
||||||
|
#
|
||||||
|
# (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>
|
||||||
|
#
|
||||||
|
# All Rights Reserved
|
||||||
|
#
|
||||||
|
# This program 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 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
import signal
|
||||||
|
import getopt
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from grgsm.trx import ctrl_if_bb
|
||||||
|
from grgsm.trx import radio_if
|
||||||
|
from grgsm.trx import fake_pm
|
||||||
|
|
||||||
|
COPYRIGHT = \
|
||||||
|
"Copyright (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>\n" \
|
||||||
|
"License GPLv2+: GNU GPL version 2 or later " \
|
||||||
|
"<http://gnu.org/licenses/gpl.html>\n" \
|
||||||
|
"This is free software: you are free to change and redistribute it.\n" \
|
||||||
|
"There is NO WARRANTY, to the extent permitted by law.\n"
|
||||||
|
|
||||||
|
class Application:
|
||||||
|
# Application variables
|
||||||
|
remote_addr = "127.0.0.1"
|
||||||
|
base_port = 5700
|
||||||
|
|
||||||
|
# PHY specific
|
||||||
|
phy_sample_rate = 4*1625000/6
|
||||||
|
phy_tx_antenna = "TX/RX"
|
||||||
|
phy_rx_antenna = "RX2"
|
||||||
|
phy_rx_gain = 30
|
||||||
|
phy_tx_gain = 40
|
||||||
|
phy_args = ""
|
||||||
|
phy_ppm = 0
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.print_copyright()
|
||||||
|
self.parse_argv()
|
||||||
|
|
||||||
|
# Set up signal handlers
|
||||||
|
signal.signal(signal.SIGINT, self.sig_handler)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# Init Radio interface
|
||||||
|
self.radio = radio_if(self.phy_args, self.phy_sample_rate,
|
||||||
|
self.phy_rx_gain, self.phy_tx_gain, self.phy_ppm,
|
||||||
|
self.phy_rx_antenna, self.phy_tx_antenna,
|
||||||
|
self.remote_addr, self.base_port)
|
||||||
|
|
||||||
|
# Power measurement emulation
|
||||||
|
# Noise: -120 .. -105
|
||||||
|
# BTS: -75 .. -50
|
||||||
|
self.pm = fake_pm(-120, -105, -75, -50)
|
||||||
|
|
||||||
|
# Init TRX CTRL interface
|
||||||
|
self.server = ctrl_if_bb(self.remote_addr,
|
||||||
|
self.base_port + 101, self.base_port + 1,
|
||||||
|
self.radio, self.pm)
|
||||||
|
|
||||||
|
print("[i] Init complete")
|
||||||
|
|
||||||
|
# Enter main loop
|
||||||
|
while True:
|
||||||
|
self.server.loop()
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
print("[i] Shutting down...")
|
||||||
|
self.server.shutdown()
|
||||||
|
self.radio.shutdown()
|
||||||
|
|
||||||
|
def print_copyright(self):
|
||||||
|
print(COPYRIGHT)
|
||||||
|
|
||||||
|
def print_help(self):
|
||||||
|
s = " Usage: " + sys.argv[0] + " [options]\n\n" \
|
||||||
|
" Some help...\n" \
|
||||||
|
" -h --help this text\n\n"
|
||||||
|
|
||||||
|
# TRX specific
|
||||||
|
s += " TRX interface specific\n" \
|
||||||
|
" -i --remote-addr Set remote address (default 127.0.0.1)\n" \
|
||||||
|
" -p --base-port Set base port number (default 5700)\n\n"
|
||||||
|
|
||||||
|
# PHY specific
|
||||||
|
s += " Radio interface specific\n" \
|
||||||
|
" -a --device-args Set device arguments\n" \
|
||||||
|
" -s --sample-rate Set sample rate (default 2000000)\n" \
|
||||||
|
" -g --rx-gain Set RX gain (default 30)\n" \
|
||||||
|
" -G --tx-gain Set TX gain (default 10)\n" \
|
||||||
|
" --rx-antenna Set RX antenna (default RX2)\n" \
|
||||||
|
" --tx-antenna Set TX antenna (default TX/RX)\n" \
|
||||||
|
" --ppm Set frequency correction (default 0)\n"
|
||||||
|
|
||||||
|
print(s)
|
||||||
|
|
||||||
|
def parse_argv(self):
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(sys.argv[1:],
|
||||||
|
"i:p:a:s:g:G:h",
|
||||||
|
["help", "remote-addr=", "base-port=", "device-args=",
|
||||||
|
"sample-rate=", "rx-gain=", "tx-gain=", "ppm=",
|
||||||
|
"rx-antenna=", "tx-antenna="])
|
||||||
|
except getopt.GetoptError as err:
|
||||||
|
# Print(help and exit)
|
||||||
|
self.print_help()
|
||||||
|
print("[!] " + str(err))
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
for o, v in opts:
|
||||||
|
if o in ("-h", "--help"):
|
||||||
|
self.print_help()
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
# TRX specific
|
||||||
|
elif o in ("-i", "--remote-addr"):
|
||||||
|
self.remote_addr = v
|
||||||
|
elif o in ("-p", "--base-port"):
|
||||||
|
if int(v) >= 0 and int(v) <= 65535:
|
||||||
|
self.base_port = int(v)
|
||||||
|
else:
|
||||||
|
print("[!] The port number should be in range [0-65536]")
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
# PHY specific
|
||||||
|
elif o in ("-a", "--device-args"):
|
||||||
|
self.phy_args = v
|
||||||
|
elif o in ("-s", "--sample-rate"):
|
||||||
|
self.phy_sample_rate = int(v)
|
||||||
|
elif o in ("-g", "--rx-gain"):
|
||||||
|
self.phy_rx_gain = int(v)
|
||||||
|
elif o in ("-G", "--tx-gain"):
|
||||||
|
self.phy_tx_gain = int(v)
|
||||||
|
elif o in ("--rx-antenna"):
|
||||||
|
self.phy_rx_antenna = v
|
||||||
|
elif o in ("--tx-antenna"):
|
||||||
|
self.phy_tx_antenna = v
|
||||||
|
elif o in ("--ppm"):
|
||||||
|
self.phy_ppm = int(v)
|
||||||
|
|
||||||
|
def sig_handler(self, signum, frame):
|
||||||
|
print("Signal %d received" % signum)
|
||||||
|
if signum is signal.SIGINT:
|
||||||
|
self.shutdown()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app = Application()
|
||||||
|
app.run()
|
2
examples
2
examples
|
@ -1 +1 @@
|
||||||
Subproject commit e4e387dddc3d9b860ae0938902fd59c1a569138c
|
Subproject commit 32727fc905c78b151cbb1794db05383220d7e61b
|
|
@ -23,6 +23,7 @@ add_subdirectory(demapping)
|
||||||
add_subdirectory(receiver)
|
add_subdirectory(receiver)
|
||||||
add_subdirectory(flow_control)
|
add_subdirectory(flow_control)
|
||||||
add_subdirectory(misc_utils)
|
add_subdirectory(misc_utils)
|
||||||
|
add_subdirectory(transmitter)
|
||||||
install(FILES
|
install(FILES
|
||||||
gsm_block_tree.xml DESTINATION share/gnuradio/grc/blocks
|
gsm_block_tree.xml DESTINATION share/gnuradio/grc/blocks
|
||||||
)
|
)
|
||||||
|
|
|
@ -21,6 +21,7 @@ install(FILES
|
||||||
gsm_burst_timeslot_splitter.xml
|
gsm_burst_timeslot_splitter.xml
|
||||||
gsm_burst_fnr_filter.xml
|
gsm_burst_fnr_filter.xml
|
||||||
gsm_burst_timeslot_filter.xml
|
gsm_burst_timeslot_filter.xml
|
||||||
|
gsm_burst_type_filter.xml
|
||||||
gsm_dummy_burst_filter.xml
|
gsm_dummy_burst_filter.xml
|
||||||
gsm_burst_sdcch_subslot_splitter.xml
|
gsm_burst_sdcch_subslot_splitter.xml
|
||||||
gsm_burst_sdcch_subslot_filter.xml
|
gsm_burst_sdcch_subslot_filter.xml
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<block>
|
||||||
|
<name>Burst Type Filter</name>
|
||||||
|
<key>gsm_burst_type_filter</key>
|
||||||
|
<import>import grgsm</import>
|
||||||
|
<make>grgsm.burst_type_filter($selected_burst_types)</make>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>Selected burst types</name>
|
||||||
|
<key>selected_burst_types</key>
|
||||||
|
<value>[0,1,2,3,4,5,6,7]</value>
|
||||||
|
<type>int_vector</type>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<sink>
|
||||||
|
<name>bursts_in</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</sink>
|
||||||
|
|
||||||
|
<source>
|
||||||
|
<name>bursts_out</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</source>
|
||||||
|
|
||||||
|
<doc>
|
||||||
|
This block filters bursts based on their type.
|
||||||
|
|
||||||
|
For more information on burst types, see GSM 05.02.
|
||||||
|
</doc>
|
||||||
|
</block>
|
|
@ -21,6 +21,14 @@
|
||||||
<block>gsm_clock_offset_control</block>
|
<block>gsm_clock_offset_control</block>
|
||||||
<block>gsm_input</block>
|
<block>gsm_input</block>
|
||||||
</cat>
|
</cat>
|
||||||
|
<cat>
|
||||||
|
<name>Transmitter</name>
|
||||||
|
<block>gsm_txtime_bursts_tagger</block>
|
||||||
|
<block>gsm_txtime_setter</block>
|
||||||
|
<block>gsm_gmsk_mod</block>
|
||||||
|
<block>gsm_preprocess_tx_burst</block>
|
||||||
|
<block>gsm_gen_test_ab</block>
|
||||||
|
</cat>
|
||||||
<cat>
|
<cat>
|
||||||
<name>Logical channels demapping</name>
|
<name>Logical channels demapping</name>
|
||||||
<block>gsm_universal_ctrl_chans_demapper</block>
|
<block>gsm_universal_ctrl_chans_demapper</block>
|
||||||
|
@ -45,6 +53,7 @@
|
||||||
<block>gsm_burst_timeslot_filter</block>
|
<block>gsm_burst_timeslot_filter</block>
|
||||||
<block>gsm_burst_sdcch_subslot_filter</block>
|
<block>gsm_burst_sdcch_subslot_filter</block>
|
||||||
<block>gsm_burst_fnr_filter</block>
|
<block>gsm_burst_fnr_filter</block>
|
||||||
|
<block>gsm_burst_type_filter</block>
|
||||||
<block>gsm_dummy_burst_filter</block>
|
<block>gsm_dummy_burst_filter</block>
|
||||||
<block>gsm_uplink_downlink_splitter</block>
|
<block>gsm_uplink_downlink_splitter</block>
|
||||||
</cat>
|
</cat>
|
||||||
|
@ -66,6 +75,8 @@
|
||||||
<block>gsm_clock_offset_corrector_tagged</block>
|
<block>gsm_clock_offset_corrector_tagged</block>
|
||||||
<block>gsm_msg_to_tag.xml</block>
|
<block>gsm_msg_to_tag.xml</block>
|
||||||
<block>gsm_tmsi_dumper</block>
|
<block>gsm_tmsi_dumper</block>
|
||||||
|
<block>gsm_trx_burst_if</block>
|
||||||
|
<block>gsm_burst_to_fn_time</block>
|
||||||
</cat>
|
</cat>
|
||||||
</cat>
|
</cat>
|
||||||
</cat>
|
</cat>
|
||||||
|
|
|
@ -32,6 +32,9 @@ install(FILES
|
||||||
gsm_burst_file_source.xml
|
gsm_burst_file_source.xml
|
||||||
gsm_message_file_sink.xml
|
gsm_message_file_sink.xml
|
||||||
gsm_message_file_source.xml
|
gsm_message_file_source.xml
|
||||||
|
gsm_trx_burst_if.xml
|
||||||
gsm_msg_to_tag.xml
|
gsm_msg_to_tag.xml
|
||||||
gsm_controlled_fractional_resampler_cc.xml DESTINATION share/gnuradio/grc/blocks
|
gsm_controlled_fractional_resampler_cc.xml
|
||||||
|
gsm_burst_to_fn_time.xml
|
||||||
|
DESTINATION share/gnuradio/grc/blocks
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<block>
|
||||||
|
<name>Burst to fn_time</name>
|
||||||
|
<key>gsm_burst_to_fn_time</key>
|
||||||
|
<import>import grgsm</import>
|
||||||
|
<make>grgsm.burst_to_fn_time()</make>
|
||||||
|
|
||||||
|
<sink>
|
||||||
|
<name>bursts_in</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</sink>
|
||||||
|
|
||||||
|
<source>
|
||||||
|
<name>fn_time_out</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</source>
|
||||||
|
</block>
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<block>
|
||||||
|
<name>TRX Burst Interface</name>
|
||||||
|
<key>gsm_trx_burst_if</key>
|
||||||
|
<import>import grgsm</import>
|
||||||
|
<make>grgsm.trx_burst_if($remote_addr, $base_port)</make>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>base_port</name>
|
||||||
|
<key>base_port</key>
|
||||||
|
<value>5700</value>
|
||||||
|
<type>string</type>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>remote_addr</name>
|
||||||
|
<key>remote_addr</key>
|
||||||
|
<value>127.0.0.1</value>
|
||||||
|
<type>string</type>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<sink>
|
||||||
|
<name>bursts</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</sink>
|
||||||
|
|
||||||
|
<source>
|
||||||
|
<name>bursts</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</source>
|
||||||
|
|
||||||
|
<doc>
|
||||||
|
OsmoTRX like UDP burst interface for external applications.
|
||||||
|
|
||||||
|
There are two UDP connections, where each message carries
|
||||||
|
one radio burst with header. Give a base port B (5700 by default).
|
||||||
|
One connection at port P=B+100+2 is used for sending received bursts
|
||||||
|
to an external application. Another one at port P=B+2 is used to
|
||||||
|
obtain to be transmitted bursts.
|
||||||
|
|
||||||
|
Received burst format:
|
||||||
|
1 byte timeslot index
|
||||||
|
4 bytes GSM frame number, big endian
|
||||||
|
1 byte RSSI in -dBm
|
||||||
|
2 bytes correlator timing offset in 1/256 symbol steps,
|
||||||
|
2's-comp, big endian
|
||||||
|
148 bytes soft symbol estimates, 0 -> definite "0",
|
||||||
|
255 -> definite "1"
|
||||||
|
|
||||||
|
To be transmitted burst format:
|
||||||
|
1 byte timeslot index
|
||||||
|
4 bytes GSM frame number, big endian
|
||||||
|
1 byte transmit level wrt ARFCN max, -dB (attenuation)
|
||||||
|
148 bytes output symbol values, 0 & 1
|
||||||
|
</doc>
|
||||||
|
</block>
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Copyright 2011,2012 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is part of GNU Radio
|
||||||
|
#
|
||||||
|
# GNU Radio 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.
|
||||||
|
#
|
||||||
|
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
gsm_gmsk_mod.xml
|
||||||
|
gsm_txtime_bursts_tagger.xml
|
||||||
|
gsm_txtime_setter.xml
|
||||||
|
gsm_preprocess_tx_burst.xml
|
||||||
|
gsm_gen_test_ab.xml
|
||||||
|
DESTINATION share/gnuradio/grc/blocks
|
||||||
|
)
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<block>
|
||||||
|
<name>Gen Test AB</name>
|
||||||
|
<key>gsm_gen_test_ab</key>
|
||||||
|
<import>import grgsm</import>
|
||||||
|
<make>grgsm.gen_test_ab()</make>
|
||||||
|
|
||||||
|
<sink>
|
||||||
|
<name>bursts_in</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</sink>
|
||||||
|
|
||||||
|
<source>
|
||||||
|
<name>bursts_out</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</source>
|
||||||
|
</block>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<block>
|
||||||
|
<name>GMSK Modulator for GSM</name>
|
||||||
|
<key>gsm_gmsk_mod</key>
|
||||||
|
<import>from grgsm import gsm_gmsk_mod</import>
|
||||||
|
<make>gsm_gmsk_mod(
|
||||||
|
BT=$BT,
|
||||||
|
pulse_duration=$pulse_duration,
|
||||||
|
sps=$sps,
|
||||||
|
)</make>
|
||||||
|
<callback>set_BT($BT)</callback>
|
||||||
|
<callback>set_pulse_duration($pulse_duration)</callback>
|
||||||
|
<callback>set_sps($sps)</callback>
|
||||||
|
<param>
|
||||||
|
<name>3 dB Time-Bandwidth Product</name>
|
||||||
|
<key>BT</key>
|
||||||
|
<value>4</value>
|
||||||
|
<type>raw</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Pulse Duration</name>
|
||||||
|
<key>pulse_duration</key>
|
||||||
|
<value>4</value>
|
||||||
|
<type>raw</type>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>Samples/Symbol</name>
|
||||||
|
<key>sps</key>
|
||||||
|
<value>4</value>
|
||||||
|
<type>raw</type>
|
||||||
|
</param>
|
||||||
|
<sink>
|
||||||
|
<name>in</name>
|
||||||
|
<type>byte</type>
|
||||||
|
<vlen>1</vlen>
|
||||||
|
<optional>1</optional>
|
||||||
|
</sink>
|
||||||
|
<source>
|
||||||
|
<name>out</name>
|
||||||
|
<type>complex</type>
|
||||||
|
<vlen>1</vlen>
|
||||||
|
<optional>1</optional>
|
||||||
|
</source>
|
||||||
|
<doc>Piotr Krysik
|
||||||
|
GMSK Modulator for GSM
|
||||||
|
</doc>
|
||||||
|
<grc_source>gr-gsm/hier_blocks/transmitter/gsm_gmsk_mod.grc</grc_source>
|
||||||
|
</block>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<block>
|
||||||
|
<name>Preprocess Tx burst</name>
|
||||||
|
<key>gsm_preprocess_tx_burst</key>
|
||||||
|
<import>import grgsm</import>
|
||||||
|
<make>grgsm.preprocess_tx_burst()</make>
|
||||||
|
|
||||||
|
<sink>
|
||||||
|
<name>bursts_in</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</sink>
|
||||||
|
|
||||||
|
<source>
|
||||||
|
<name>bursts_out</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</source>
|
||||||
|
</block>
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<block>
|
||||||
|
<name>txtime_bursts_tagger</name>
|
||||||
|
<key>gsm_txtime_bursts_tagger</key>
|
||||||
|
<import>import grgsm</import>
|
||||||
|
<make>grgsm.txtime_bursts_tagger($init_fn, $init_time, $time_hint, $timing_advance, $delay_correction)</make>
|
||||||
|
<callback>set_fn_time_reference($init_fn, $init_time)</callback>
|
||||||
|
<callback>set_time_hint($time_hint)</callback>
|
||||||
|
<callback>set_timing_advance($timing_advance)</callback>
|
||||||
|
<callback>set_delay_correction($delay_correction)</callback>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>init_fn</name>
|
||||||
|
<key>init_fn</key>
|
||||||
|
<value>None</value>
|
||||||
|
<type>raw</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>init_time</name>
|
||||||
|
<key>init_time</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>float</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>time_hint</name>
|
||||||
|
<key>time_hint</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>float</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>timing_advance</name>
|
||||||
|
<key>timing_advance</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>float</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>delay_correction</name>
|
||||||
|
<key>delay_correction</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>float</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<sink>
|
||||||
|
<name>fn_time</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</sink>
|
||||||
|
|
||||||
|
<sink>
|
||||||
|
<name>bursts</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</sink>
|
||||||
|
|
||||||
|
<source>
|
||||||
|
<name>bursts</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</source>
|
||||||
|
</block>
|
|
@ -0,0 +1,84 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<block>
|
||||||
|
<name>txtime_setter</name>
|
||||||
|
<key>gsm_txtime_setter</key>
|
||||||
|
<import>import grgsm</import>
|
||||||
|
<make>grgsm.txtime_setter($init_fn if ($init_fn is not None) else 0xffffffff, $init_time_secs, $init_time_fracs, $time_hint_secs, $time_hint_fracs, $timing_advance, $delay_correction)</make>
|
||||||
|
|
||||||
|
<callback>set_fn_time_reference($init_fn, $init_time_secs, $init_time_fracs)</callback>
|
||||||
|
<callback>set_time_hint($time_hint_secs, $time_hint_secs)</callback>
|
||||||
|
<callback>set_timing_advance($timing_advance)</callback>
|
||||||
|
<callback>set_delay_correction($delay_correction)</callback>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>init_fn</name>
|
||||||
|
<key>init_fn</key>
|
||||||
|
<value>None</value>
|
||||||
|
<type>raw</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>init_time_secs</name>
|
||||||
|
<key>init_time_secs</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>int</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>init_time_fracs</name>
|
||||||
|
<key>init_time_fracs</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>float</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>time_hint_secs</name>
|
||||||
|
<key>time_hint_secs</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>int</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<name>time_hint_fracs</name>
|
||||||
|
<key>time_hint_fracs</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>float</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>timing_advance</name>
|
||||||
|
<key>timing_advance</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>float</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<param>
|
||||||
|
<name>delay_correction</name>
|
||||||
|
<key>delay_correction</key>
|
||||||
|
<value>0</value>
|
||||||
|
<type>float</type>
|
||||||
|
<hide>part</hide>
|
||||||
|
</param>
|
||||||
|
|
||||||
|
<sink>
|
||||||
|
<name>fn_time</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</sink>
|
||||||
|
|
||||||
|
<sink>
|
||||||
|
<name>bursts_in</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</sink>
|
||||||
|
|
||||||
|
<source>
|
||||||
|
<name>bursts_out</name>
|
||||||
|
<type>message</type>
|
||||||
|
<optional>1</optional>
|
||||||
|
</source>
|
||||||
|
</block>
|
|
@ -0,0 +1,621 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<?grc format='1' created='3.7.9'?>
|
||||||
|
<flow_graph>
|
||||||
|
<timestamp>Wed Sep 20 07:48:30 2017</timestamp>
|
||||||
|
<block>
|
||||||
|
<key>options</key>
|
||||||
|
<param>
|
||||||
|
<key>author</key>
|
||||||
|
<value>Piotr Krysik</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>window_size</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>category</key>
|
||||||
|
<value>Modulators</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>description</key>
|
||||||
|
<value>GMSK Modulator for GSM</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(8, 8)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>generate_options</key>
|
||||||
|
<value>hb</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>hier_block_src_path</key>
|
||||||
|
<value>.:</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>gsm_gmsk_mod</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>max_nouts</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>qt_qss_theme</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>realtime_scheduling</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>run_command</key>
|
||||||
|
<value>{python} -u {filename}</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>run_options</key>
|
||||||
|
<value>prompt</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>run</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>thread_safe_setters</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>title</key>
|
||||||
|
<value>GMSK Modulator for GSM</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>parameter</key>
|
||||||
|
<param>
|
||||||
|
<key>alias</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(504, 15)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>BT</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>label</key>
|
||||||
|
<value>3 dB Time-Bandwidth Product</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>short_id</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>type</key>
|
||||||
|
<value>eng_float</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>value</key>
|
||||||
|
<value>4</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>blocks_float_to_char</key>
|
||||||
|
<param>
|
||||||
|
<key>alias</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>affinity</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(472, 204)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>blocks_float_to_char_0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>maxoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>minoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>scale</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>vlen</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>blocks_tagged_stream_multiply_length</key>
|
||||||
|
<param>
|
||||||
|
<key>alias</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>affinity</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(848, 209)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>blocks_tagged_stream_multiply_length_0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>type</key>
|
||||||
|
<value>complex</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>c</key>
|
||||||
|
<value>sps</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>lengthtagname</key>
|
||||||
|
<value>packet_len</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>maxoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>minoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>vlen</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>digital_chunks_to_symbols_xx</key>
|
||||||
|
<param>
|
||||||
|
<key>alias</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>affinity</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>dimension</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(296, 197)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>digital_chunks_to_symbols_xx_0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>in_type</key>
|
||||||
|
<value>byte</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>maxoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>minoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>num_ports</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>out_type</key>
|
||||||
|
<value>float</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>symbol_table</key>
|
||||||
|
<value>[1,-1]</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>digital_diff_decoder_bb</key>
|
||||||
|
<param>
|
||||||
|
<key>alias</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>affinity</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(120, 204)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>digital_diff_decoder_bb_0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>maxoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>minoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>modulus</key>
|
||||||
|
<value>2</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>digital_gmskmod_bc</key>
|
||||||
|
<param>
|
||||||
|
<key>bt</key>
|
||||||
|
<value>BT</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>alias</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>affinity</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(616, 190)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>digital_gmskmod_bc_0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>maxoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>minoutbuf</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>L</key>
|
||||||
|
<value>pulse_duration</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>samples_per_symbol</key>
|
||||||
|
<value>sps</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>import</key>
|
||||||
|
<param>
|
||||||
|
<key>alias</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(712, 28)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>import_0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>import</key>
|
||||||
|
<value>from gnuradio.analog import cpm</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>pad_sink</key>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(1136, 220)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>pad_sink_0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>type</key>
|
||||||
|
<value>complex</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>label</key>
|
||||||
|
<value>out</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>num_streams</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>optional</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>vlen</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>pad_source</key>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(0, 204)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>pad_source_0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>label</key>
|
||||||
|
<value>in</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>num_streams</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>optional</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>type</key>
|
||||||
|
<value>byte</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>vlen</key>
|
||||||
|
<value>1</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>parameter</key>
|
||||||
|
<param>
|
||||||
|
<key>alias</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(376, 14)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>pulse_duration</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>label</key>
|
||||||
|
<value>Pulse Duration</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>short_id</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>type</key>
|
||||||
|
<value>eng_float</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>value</key>
|
||||||
|
<value>4</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<block>
|
||||||
|
<key>parameter</key>
|
||||||
|
<param>
|
||||||
|
<key>alias</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>comment</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_enabled</key>
|
||||||
|
<value>True</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_coordinate</key>
|
||||||
|
<value>(240, 15)</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>_rotation</key>
|
||||||
|
<value>0</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>id</key>
|
||||||
|
<value>sps</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>label</key>
|
||||||
|
<value>Samples/Symbol</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>short_id</key>
|
||||||
|
<value></value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>type</key>
|
||||||
|
<value>intx</value>
|
||||||
|
</param>
|
||||||
|
<param>
|
||||||
|
<key>value</key>
|
||||||
|
<value>4</value>
|
||||||
|
</param>
|
||||||
|
</block>
|
||||||
|
<connection>
|
||||||
|
<source_block_id>blocks_float_to_char_0</source_block_id>
|
||||||
|
<sink_block_id>digital_gmskmod_bc_0</sink_block_id>
|
||||||
|
<source_key>0</source_key>
|
||||||
|
<sink_key>0</sink_key>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<source_block_id>blocks_tagged_stream_multiply_length_0</source_block_id>
|
||||||
|
<sink_block_id>pad_sink_0</sink_block_id>
|
||||||
|
<source_key>0</source_key>
|
||||||
|
<sink_key>0</sink_key>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<source_block_id>digital_chunks_to_symbols_xx_0</source_block_id>
|
||||||
|
<sink_block_id>blocks_float_to_char_0</sink_block_id>
|
||||||
|
<source_key>0</source_key>
|
||||||
|
<sink_key>0</sink_key>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<source_block_id>digital_diff_decoder_bb_0</source_block_id>
|
||||||
|
<sink_block_id>digital_chunks_to_symbols_xx_0</sink_block_id>
|
||||||
|
<source_key>0</source_key>
|
||||||
|
<sink_key>0</sink_key>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<source_block_id>digital_gmskmod_bc_0</source_block_id>
|
||||||
|
<sink_block_id>blocks_tagged_stream_multiply_length_0</sink_block_id>
|
||||||
|
<source_key>0</source_key>
|
||||||
|
<sink_key>0</sink_key>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<source_block_id>pad_source_0</source_block_id>
|
||||||
|
<sink_block_id>digital_diff_decoder_bb_0</sink_block_id>
|
||||||
|
<source_key>0</source_key>
|
||||||
|
<sink_key>0</sink_key>
|
||||||
|
</connection>
|
||||||
|
</flow_graph>
|
|
@ -25,6 +25,7 @@ install(FILES
|
||||||
api.h
|
api.h
|
||||||
gsmtap.h
|
gsmtap.h
|
||||||
constants.h
|
constants.h
|
||||||
|
gsm_constants.h
|
||||||
DESTINATION include/grgsm
|
DESTINATION include/grgsm
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,3 +36,4 @@ add_subdirectory(receiver)
|
||||||
add_subdirectory(misc_utils)
|
add_subdirectory(misc_utils)
|
||||||
add_subdirectory(qa_utils)
|
add_subdirectory(qa_utils)
|
||||||
add_subdirectory(flow_control)
|
add_subdirectory(flow_control)
|
||||||
|
add_subdirectory(transmitter)
|
||||||
|
|
|
@ -27,6 +27,7 @@ install(FILES
|
||||||
burst_timeslot_filter.h
|
burst_timeslot_filter.h
|
||||||
burst_sdcch_subslot_filter.h
|
burst_sdcch_subslot_filter.h
|
||||||
burst_fnr_filter.h
|
burst_fnr_filter.h
|
||||||
|
burst_type_filter.h
|
||||||
dummy_burst_filter.h
|
dummy_burst_filter.h
|
||||||
uplink_downlink_splitter.h DESTINATION include/grgsm/flow_control
|
uplink_downlink_splitter.h DESTINATION include/grgsm/flow_control
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/* @file
|
||||||
|
* @author (C) 2017 by 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GSM_BURST_TYPE_FILTER_H
|
||||||
|
#define INCLUDED_GSM_BURST_TYPE_FILTER_H
|
||||||
|
|
||||||
|
#include <grgsm/api.h>
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
#include <grgsm/flow_control/common.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief <+description of block+>
|
||||||
|
* \ingroup gsm
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class GRGSM_API burst_type_filter : virtual public gr::block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::shared_ptr<burst_type_filter> sptr;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return a shared_ptr to a new instance of grgsm::burst_type_filter.
|
||||||
|
*
|
||||||
|
* To avoid accidental use of raw pointers, grgsm::burst_type_filter's
|
||||||
|
* constructor is in a private implementation
|
||||||
|
* class. grgsm::burst_type_filter::make is the public interface for
|
||||||
|
* creating new instances.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static sptr make(const std::vector<uint8_t> & selected_burst_types);
|
||||||
|
|
||||||
|
/* External API */
|
||||||
|
/* Filtering policy */
|
||||||
|
virtual filter_policy get_policy(void) = 0;
|
||||||
|
virtual filter_policy set_policy(filter_policy policy) = 0;
|
||||||
|
virtual void set_selected_burst_types(const std::vector<uint8_t> & selected_burst_types) = 0;
|
||||||
|
};
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GSM_BURST_TYPE_FILTER_H */
|
|
@ -28,7 +28,7 @@
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
namespace grgsm {
|
namespace gsm {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief <+description of block+>
|
* \brief <+description of block+>
|
||||||
|
@ -51,7 +51,7 @@ namespace gr {
|
||||||
static sptr make();
|
static sptr make();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace grgsm
|
} // namespace gsm
|
||||||
} // namespace gr
|
} // namespace gr
|
||||||
|
|
||||||
#endif /* INCLUDED_GRGSM_UPLINK_DOWNLINK_SPLITTER_H */
|
#endif /* INCLUDED_GRGSM_UPLINK_DOWNLINK_SPLITTER_H */
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#define USEFUL_BITS 142 //(2*(DATA_BITS+STEALING_BIT) + N_TRAIN_BITS )
|
#define USEFUL_BITS 142 //(2*(DATA_BITS+STEALING_BIT) + N_TRAIN_BITS )
|
||||||
#define FCCH_BITS USEFUL_BITS
|
#define FCCH_BITS USEFUL_BITS
|
||||||
#define BURST_SIZE (USEFUL_BITS+2*TAIL_BITS)
|
#define BURST_SIZE (USEFUL_BITS+2*TAIL_BITS)
|
||||||
|
#define ACCESS_BURST_SIZE 88
|
||||||
#define PROCESSED_CHUNK BURST_SIZE+2*GUARD_PERIOD
|
#define PROCESSED_CHUNK BURST_SIZE+2*GUARD_PERIOD
|
||||||
|
|
||||||
#define SCH_DATA_LEN 39
|
#define SCH_DATA_LEN 39
|
|
@ -35,5 +35,8 @@ install(FILES
|
||||||
message_printer.h
|
message_printer.h
|
||||||
tmsi_dumper.h
|
tmsi_dumper.h
|
||||||
msg_to_tag.h
|
msg_to_tag.h
|
||||||
controlled_fractional_resampler_cc.h DESTINATION include/grgsm/misc_utils
|
trx_burst_if.h
|
||||||
|
controlled_fractional_resampler_cc.h
|
||||||
|
time_spec.h
|
||||||
|
fn_time.h DESTINATION include/grgsm/misc_utils
|
||||||
)
|
)
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace gr {
|
||||||
virtual void set_resamp_ratio(float resamp_ratio) = 0;
|
virtual void set_resamp_ratio(float resamp_ratio) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace grgsm
|
} // namespace gsm
|
||||||
} // namespace gr
|
} // namespace gr
|
||||||
|
|
||||||
#endif /* INCLUDED_GRGSM_CONTROLLED_FRACTIONAL_RESAMPLER_CC_H */
|
#endif /* INCLUDED_GRGSM_CONTROLLED_FRACTIONAL_RESAMPLER_CC_H */
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/* @file
|
||||||
|
* @author Piotr Krysik <ptrkrysik@gmail.com>
|
||||||
|
* @author Vadim Yanitskiy <axilirator@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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GRGSM_FN_TIME_H
|
||||||
|
#define INCLUDED_GRGSM_FN_TIME_H
|
||||||
|
|
||||||
|
#include <grgsm/api.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes difference between reference frame number
|
||||||
|
* and a second frame number.
|
||||||
|
* @param fn_ref reference frame number modulo GSM_HYPER_FRAME
|
||||||
|
* @param fn second frame number modulo GSM_HYPER_FRAME
|
||||||
|
* @param time_ref precise timestamp of the first sample in the fn_ref
|
||||||
|
* @param time_hint coarse time for fn that is used as a hint to avoid
|
||||||
|
* ambiguities caused by modulo operation applied to
|
||||||
|
* frame numbers
|
||||||
|
* @return difference between fn_ref and fn
|
||||||
|
*/
|
||||||
|
typedef std::pair<unsigned long long, double> time_format;
|
||||||
|
|
||||||
|
GRGSM_API time_format fn_time_delta_cpp(uint32_t fn_ref, time_format time_ref, uint32_t fn_x,
|
||||||
|
time_format time_hint, uint32_t ts_num, uint32_t ts_ref);
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GRGSM_FN_TIME_H */
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace gr {
|
||||||
static sptr make();
|
static sptr make();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace grgsm
|
} // namespace gsm
|
||||||
} // namespace gr
|
} // namespace gr
|
||||||
|
|
||||||
#endif /* INCLUDED_GRGSM_MSG_TO_TAG_H */
|
#endif /* INCLUDED_GRGSM_MSG_TO_TAG_H */
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
//
|
||||||
|
// Copyright 2010-2012 Ettus Research LLC
|
||||||
|
//
|
||||||
|
// This program 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 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef INCLUDED_TYPES_TIME_SPEC_HPP
|
||||||
|
#define INCLUDED_TYPES_TIME_SPEC_HPP
|
||||||
|
|
||||||
|
#include <grgsm/api.h>
|
||||||
|
#include <boost/operators.hpp>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* A time_spec_t holds a seconds and a fractional seconds time value.
|
||||||
|
* Depending upon usage, the time_spec_t can represent absolute times,
|
||||||
|
* relative times, or time differences (between absolute times).
|
||||||
|
*
|
||||||
|
* The time_spec_t provides clock-domain independent time storage,
|
||||||
|
* but can convert fractional seconds to/from clock-domain specific units.
|
||||||
|
*
|
||||||
|
* The fractional seconds are stored as double precision floating point.
|
||||||
|
* This gives the fractional seconds enough precision to unambiguously
|
||||||
|
* specify a clock-tick/sample-count up to rates of several petahertz.
|
||||||
|
*/
|
||||||
|
class GRGSM_API time_spec_t : boost::additive<time_spec_t>, boost::totally_ordered<time_spec_t>{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Copy constructor
|
||||||
|
*/
|
||||||
|
time_spec_t(const time_spec_t & spec);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Create a time_spec_t from a real-valued seconds count.
|
||||||
|
* \param secs the real-valued seconds count (default = 0)
|
||||||
|
*/
|
||||||
|
time_spec_t(double secs = 0);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Create a time_spec_t from whole and fractional seconds.
|
||||||
|
* \param full_secs the whole/integer seconds count
|
||||||
|
* \param frac_secs the fractional seconds count (default = 0)
|
||||||
|
*/
|
||||||
|
time_spec_t(time_t full_secs, double frac_secs = 0);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Create a time_spec_t from whole seconds and fractional ticks.
|
||||||
|
* Translation from clock-domain specific units.
|
||||||
|
* \param full_secs the whole/integer seconds count
|
||||||
|
* \param tick_count the fractional seconds tick count
|
||||||
|
* \param tick_rate the number of ticks per second
|
||||||
|
*/
|
||||||
|
time_spec_t(time_t full_secs, long tick_count, double tick_rate);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Create a time_spec_t from a 64-bit tick count.
|
||||||
|
* Translation from clock-domain specific units.
|
||||||
|
* \param ticks an integer count of ticks
|
||||||
|
* \param tick_rate the number of ticks per second
|
||||||
|
*/
|
||||||
|
static time_spec_t from_ticks(long long ticks, double tick_rate);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Convert the fractional seconds to clock ticks.
|
||||||
|
* Translation into clock-domain specific units.
|
||||||
|
* \param tick_rate the number of ticks per second
|
||||||
|
* \return the fractional seconds tick count
|
||||||
|
*/
|
||||||
|
long get_tick_count(double tick_rate) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Convert the time spec into a 64-bit tick count.
|
||||||
|
* Translation into clock-domain specific units.
|
||||||
|
* \param tick_rate the number of ticks per second
|
||||||
|
* \return an integer number of ticks
|
||||||
|
*/
|
||||||
|
long long to_ticks(const double tick_rate) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get the time as a real-valued seconds count.
|
||||||
|
* Note: If this time_spec_t represents an absolute time,
|
||||||
|
* the precision of the fractional seconds may be lost.
|
||||||
|
* \return the real-valued seconds
|
||||||
|
*/
|
||||||
|
double get_real_secs(void) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get the whole/integer part of the time in seconds.
|
||||||
|
* \return the whole/integer seconds
|
||||||
|
*/
|
||||||
|
time_t get_full_secs(void) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get the fractional part of the time in seconds.
|
||||||
|
* \return the fractional seconds
|
||||||
|
*/
|
||||||
|
double get_frac_secs(void) const;
|
||||||
|
|
||||||
|
//! Implement addable interface
|
||||||
|
time_spec_t &operator+=(const time_spec_t &);
|
||||||
|
|
||||||
|
//! Implement subtractable interface
|
||||||
|
time_spec_t &operator-=(const time_spec_t &);
|
||||||
|
|
||||||
|
//private time storage details
|
||||||
|
private: time_t _full_secs; double _frac_secs;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Implement equality_comparable interface
|
||||||
|
bool operator==(const time_spec_t &, const time_spec_t &);
|
||||||
|
|
||||||
|
//! Implement less_than_comparable interface
|
||||||
|
bool operator<(const time_spec_t &, const time_spec_t &);
|
||||||
|
|
||||||
|
inline time_t time_spec_t::get_full_secs(void) const{
|
||||||
|
return this->_full_secs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double time_spec_t::get_frac_secs(void) const{
|
||||||
|
return this->_frac_secs;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace transceiver
|
||||||
|
} //namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_TYPES_TIME_SPEC_HPP */
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/* @file
|
||||||
|
* @author Vadim Yanitskiy <axilirator@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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GRGSM_TRX_BURST_IF_H
|
||||||
|
#define INCLUDED_GRGSM_TRX_BURST_IF_H
|
||||||
|
|
||||||
|
#include <grgsm/api.h>
|
||||||
|
#include <gnuradio/sync_block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief <+description of block+>
|
||||||
|
* \ingroup grgsm
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class GRGSM_API trx_burst_if : virtual public gr::block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::shared_ptr<trx_burst_if> sptr;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return a shared_ptr to a new instance of grgsm::trx_burst_if.
|
||||||
|
*
|
||||||
|
* To avoid accidental use of raw pointers, grgsm::trx_burst_if's
|
||||||
|
* constructor is in a private implementation
|
||||||
|
* class. grgsm::trx_burst_if::make is the public interface for
|
||||||
|
* creating new instances.
|
||||||
|
*/
|
||||||
|
static sptr make(
|
||||||
|
const std::string &remote_addr,
|
||||||
|
const std::string &base_port);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GRGSM_TRX_BURST_IF_H */
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include <grgsm/api.h>
|
#include <grgsm/api.h>
|
||||||
#include <gnuradio/block.h>
|
#include <gnuradio/block.h>
|
||||||
|
#include <pmt/pmt.h>
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
namespace gsm {
|
namespace gsm {
|
||||||
|
@ -52,6 +53,7 @@ namespace gr {
|
||||||
virtual std::vector<int> get_framenumbers() = 0;
|
virtual std::vector<int> get_framenumbers() = 0;
|
||||||
virtual std::vector<int> get_timeslots() = 0;
|
virtual std::vector<int> get_timeslots() = 0;
|
||||||
virtual std::vector<std::string> get_burst_data() = 0;
|
virtual std::vector<std::string> get_burst_data() = 0;
|
||||||
|
virtual pmt::pmt_t get_bursts() = 0;
|
||||||
};
|
};
|
||||||
} // namespace gsm
|
} // namespace gsm
|
||||||
} // namespace gr
|
} // namespace gr
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Copyright 2011,2012 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is part of GNU Radio
|
||||||
|
#
|
||||||
|
# GNU Radio 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.
|
||||||
|
#
|
||||||
|
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# Install public header files
|
||||||
|
########################################################################
|
||||||
|
install(FILES
|
||||||
|
txtime_setter.h
|
||||||
|
preprocess_tx_burst.h
|
||||||
|
gen_test_ab.h
|
||||||
|
DESTINATION include/grgsm/transmitter
|
||||||
|
)
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GSM_GEN_TEST_AB_H
|
||||||
|
#define INCLUDED_GSM_GEN_TEST_AB_H
|
||||||
|
|
||||||
|
#include <grgsm/api.h>
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief A block that does preprocessing tasks before sending bursts to modulator.
|
||||||
|
* \ingroup gsm
|
||||||
|
*
|
||||||
|
* Currently it removes GSMTAP header from a burst and puts it in first part of PDU
|
||||||
|
* pair and removes tailing zeros from Access Bursts coming from TRX interface.
|
||||||
|
*/
|
||||||
|
class GRGSM_API gen_test_ab : virtual public gr::block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::shared_ptr<gen_test_ab> sptr;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return a shared_ptr to a new instance of gsm::gen_test_ab.
|
||||||
|
*
|
||||||
|
* To avoid accidental use of raw pointers, gsm::gen_test_ab's
|
||||||
|
* constructor is in a private implementation
|
||||||
|
* class. gsm::gen_test_ab::make is the public interface for
|
||||||
|
* creating new instances.
|
||||||
|
*/
|
||||||
|
static sptr make();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GSM_GEN_TEST_AB_H */
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GSM_PREPROCESS_TX_BURST_H
|
||||||
|
#define INCLUDED_GSM_PREPROCESS_TX_BURST_H
|
||||||
|
|
||||||
|
#include <grgsm/api.h>
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief A block that does preprocessing tasks before sending bursts to modulator.
|
||||||
|
* \ingroup gsm
|
||||||
|
*
|
||||||
|
* Currently it removes GSMTAP header from a burst and puts it in first part of PDU
|
||||||
|
* pair and removes tailing zeros from Access Bursts coming from TRX interface.
|
||||||
|
*/
|
||||||
|
class GRGSM_API preprocess_tx_burst : virtual public gr::block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::shared_ptr<preprocess_tx_burst> sptr;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return a shared_ptr to a new instance of gsm::preprocess_tx_burst.
|
||||||
|
*
|
||||||
|
* To avoid accidental use of raw pointers, gsm::preprocess_tx_burst's
|
||||||
|
* constructor is in a private implementation
|
||||||
|
* class. gsm::preprocess_tx_burst::make is the public interface for
|
||||||
|
* creating new instances.
|
||||||
|
*/
|
||||||
|
static sptr make();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GSM_PREPROCESS_TX_BURST_H */
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GSM_TXTIME_SETTER_H
|
||||||
|
#define INCLUDED_GSM_TXTIME_SETTER_H
|
||||||
|
|
||||||
|
#include <grgsm/api.h>
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief <+description of block+>
|
||||||
|
* \ingroup gsm
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class GRGSM_API txtime_setter : virtual public gr::block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::shared_ptr<txtime_setter> sptr;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return a shared_ptr to a new instance of gsm::txtime_setter.
|
||||||
|
*
|
||||||
|
* To avoid accidental use of raw pointers, gsm::txtime_setter's
|
||||||
|
* constructor is in a private implementation
|
||||||
|
* class. gsm::txtime_setter::make is the public interface for
|
||||||
|
* creating new instances.
|
||||||
|
*/
|
||||||
|
static sptr make(uint32_t init_fn, uint64_t init_time_secs, double init_time_fracs, uint64_t time_hint_secs, double time_hint_fracs, double timing_advance, double delay_correction);
|
||||||
|
virtual void set_fn_time_reference(uint32_t fn, uint32_t ts, uint64_t time_secs, double time_fracs) = 0;
|
||||||
|
virtual void set_time_hint(uint64_t time_hint_secs, double time_hint_fracs) = 0;
|
||||||
|
virtual void set_delay_correction(double delay_correction) = 0;
|
||||||
|
virtual void set_timing_advance(double timing_advance) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GSM_TXTIME_SETTER_H */
|
||||||
|
|
|
@ -70,6 +70,7 @@ add_subdirectory(flow_control)
|
||||||
add_subdirectory(misc_utils)
|
add_subdirectory(misc_utils)
|
||||||
add_subdirectory(qa_utils)
|
add_subdirectory(qa_utils)
|
||||||
add_subdirectory(receiver)
|
add_subdirectory(receiver)
|
||||||
|
add_subdirectory(transmitter)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Setup library
|
# Setup library
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "gsm_constants.h"
|
#include <grgsm/gsm_constants.h>
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <osmocom/coding/gsm0503_coding.h>
|
#include <osmocom/coding/gsm0503_coding.h>
|
||||||
|
|
|
@ -23,6 +23,7 @@ add_sources(
|
||||||
burst_sdcch_subslot_splitter_impl.cc
|
burst_sdcch_subslot_splitter_impl.cc
|
||||||
burst_timeslot_filter_impl.cc
|
burst_timeslot_filter_impl.cc
|
||||||
burst_timeslot_splitter_impl.cc
|
burst_timeslot_splitter_impl.cc
|
||||||
|
burst_type_filter_impl.cc
|
||||||
dummy_burst_filter_impl.cc
|
dummy_burst_filter_impl.cc
|
||||||
uplink_downlink_splitter_impl.cc
|
uplink_downlink_splitter_impl.cc
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/* @file
|
||||||
|
* @author (C) 2017 by 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 "burst_type_filter_impl.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <grgsm/endian.h>
|
||||||
|
#include <grgsm/gsmtap.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
burst_type_filter::sptr
|
||||||
|
burst_type_filter::make(const std::vector<uint8_t> & selected_burst_types)
|
||||||
|
{
|
||||||
|
return gnuradio::get_initial_sptr
|
||||||
|
(new burst_type_filter_impl(selected_burst_types));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The private constructor
|
||||||
|
*/
|
||||||
|
burst_type_filter_impl::burst_type_filter_impl(const std::vector<uint8_t> & selected_burst_types)
|
||||||
|
: gr::block("burst_type_filter",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(0, 0, 0)),
|
||||||
|
d_filter_policy(FILTER_POLICY_DEFAULT)
|
||||||
|
{
|
||||||
|
set_selected_burst_types(selected_burst_types);
|
||||||
|
|
||||||
|
message_port_register_in(pmt::mp("bursts_in"));
|
||||||
|
message_port_register_out(pmt::mp("bursts_out"));
|
||||||
|
|
||||||
|
set_msg_handler(pmt::mp("bursts_in"), boost::bind(&burst_type_filter_impl::process_burst, this, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Our virtual destructor.
|
||||||
|
*/
|
||||||
|
burst_type_filter_impl::~burst_type_filter_impl() {}
|
||||||
|
|
||||||
|
void burst_type_filter_impl::process_burst(pmt::pmt_t msg)
|
||||||
|
{
|
||||||
|
if (d_filter_policy == FILTER_POLICY_DROP_ALL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (d_filter_policy == FILTER_POLICY_PASS_ALL) {
|
||||||
|
message_port_pub(pmt::mp("bursts_out"), msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(pmt::cdr(msg));
|
||||||
|
if (std::find(d_selected_burst_types.begin(), d_selected_burst_types.end(), header->sub_type) != d_selected_burst_types.end()) //check if burst type is listed in burst types to pass
|
||||||
|
{
|
||||||
|
message_port_pub(pmt::mp("bursts_out"), msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Filtering policy */
|
||||||
|
filter_policy
|
||||||
|
burst_type_filter_impl::get_policy(void)
|
||||||
|
{
|
||||||
|
return d_filter_policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter_policy
|
||||||
|
burst_type_filter_impl::set_policy(filter_policy policy)
|
||||||
|
{
|
||||||
|
d_filter_policy = policy;
|
||||||
|
return d_filter_policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
burst_type_filter_impl::set_selected_burst_types(const std::vector<uint8_t> & selected_burst_types)
|
||||||
|
{
|
||||||
|
d_selected_burst_types.assign(selected_burst_types.begin(), selected_burst_types.end());
|
||||||
|
}
|
||||||
|
} /* namespace gsm */
|
||||||
|
} /* namespace gr */
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/* @file
|
||||||
|
* @author (C) 2017 by 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GSM_BURST_TYPE_FILTER_IMPL_H
|
||||||
|
#define INCLUDED_GSM_BURST_TYPE_FILTER_IMPL_H
|
||||||
|
|
||||||
|
#define BURST_TYPE_LEN 148
|
||||||
|
|
||||||
|
#include <grgsm/flow_control/burst_type_filter.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
class burst_type_filter_impl : public burst_type_filter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
filter_policy d_filter_policy;
|
||||||
|
std::vector<uint8_t> d_selected_burst_types;
|
||||||
|
public:
|
||||||
|
burst_type_filter_impl(const std::vector<uint8_t> & selected_burst_types);
|
||||||
|
~burst_type_filter_impl();
|
||||||
|
void process_burst(pmt::pmt_t msg);
|
||||||
|
|
||||||
|
/* External API */
|
||||||
|
/* Filtering policy */
|
||||||
|
filter_policy get_policy(void);
|
||||||
|
filter_policy set_policy(filter_policy policy);
|
||||||
|
|
||||||
|
void set_selected_burst_types(const std::vector<uint8_t> & selected_burst_types);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GSM_BURST_TYPE_FILTER_IMPL_H */
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include <grgsm/endian.h>
|
#include <grgsm/endian.h>
|
||||||
#define BURST_SIZE 148
|
#define BURST_SIZE 148
|
||||||
namespace gr {
|
namespace gr {
|
||||||
namespace grgsm {
|
namespace gsm {
|
||||||
|
|
||||||
uplink_downlink_splitter::sptr
|
uplink_downlink_splitter::sptr
|
||||||
uplink_downlink_splitter::make()
|
uplink_downlink_splitter::make()
|
||||||
|
@ -71,6 +71,6 @@ namespace gr {
|
||||||
uplink_downlink_splitter_impl::~uplink_downlink_splitter_impl()
|
uplink_downlink_splitter_impl::~uplink_downlink_splitter_impl()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
} /* namespace grgsm */
|
} /* namespace gsm */
|
||||||
} /* namespace gr */
|
} /* namespace gr */
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <grgsm/flow_control/uplink_downlink_splitter.h>
|
#include <grgsm/flow_control/uplink_downlink_splitter.h>
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
namespace grgsm {
|
namespace gsm {
|
||||||
|
|
||||||
class uplink_downlink_splitter_impl : public uplink_downlink_splitter
|
class uplink_downlink_splitter_impl : public uplink_downlink_splitter
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,7 @@ namespace gr {
|
||||||
|
|
||||||
void process_msg(pmt::pmt_t msg);
|
void process_msg(pmt::pmt_t msg);
|
||||||
};
|
};
|
||||||
} // namespace grgsm
|
} // namespace gsm
|
||||||
} // namespace gr
|
} // namespace gr
|
||||||
|
|
||||||
#endif /* INCLUDED_GRGSM_UPLINK_DOWNLINK_SPLITTER_IMPL_H */
|
#endif /* INCLUDED_GRGSM_UPLINK_DOWNLINK_SPLITTER_IMPL_H */
|
||||||
|
|
|
@ -33,5 +33,9 @@ add_sources(
|
||||||
message_printer_impl.cc
|
message_printer_impl.cc
|
||||||
msg_to_tag_impl.cc
|
msg_to_tag_impl.cc
|
||||||
tmsi_dumper_impl.cc
|
tmsi_dumper_impl.cc
|
||||||
|
time_spec.cc
|
||||||
|
fn_time.cc
|
||||||
|
udp_socket.cc
|
||||||
|
trx_burst_if_impl.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,6 @@ namespace gr {
|
||||||
set_relative_rate(1.0 / resamp_ratio);
|
set_relative_rate(1.0 / resamp_ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace grgsm */
|
} /* namespace gsm */
|
||||||
} /* namespace gr */
|
} /* namespace gr */
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace gr {
|
||||||
void set_resamp_ratio(float resamp_ratio);
|
void set_resamp_ratio(float resamp_ratio);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace grgsm
|
} // namespace gsm
|
||||||
} // namespace gr
|
} // namespace gr
|
||||||
|
|
||||||
#endif /* INCLUDED_GRGSM_CONTROLLED_FRACTIONAL_RESAMPLER_CC_IMPL_H */
|
#endif /* INCLUDED_GRGSM_CONTROLLED_FRACTIONAL_RESAMPLER_CC_IMPL_H */
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/* @file
|
||||||
|
* @author Piotr Krysik <ptrkrysik@gmail.com>
|
||||||
|
* @author Vadim Yanitskiy <axilirator@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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grgsm/misc_utils/fn_time.h>
|
||||||
|
#include <grgsm/misc_utils/time_spec.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define GSM_HYPER_FRAME (26 * 51 * 2048)
|
||||||
|
#define GSM_SYM_RATE (13.0e6 / 48.0)
|
||||||
|
|
||||||
|
#define GSM_TS_PERIOD (156.25 / GSM_SYM_RATE)
|
||||||
|
#define GSM_FN_PERIOD (8 * GSM_TS_PERIOD)
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
/**
|
||||||
|
* Computes difference between two frame numbers modulo
|
||||||
|
* GSM_HYPER_FRAME / 2. The result is correct if difference
|
||||||
|
* between the frame numbers is not bigger than GSM_HYPER_FRAME / 2.
|
||||||
|
* @param fn1 first frame number
|
||||||
|
* @param fn2 second frame number
|
||||||
|
* @return computed difference
|
||||||
|
*/
|
||||||
|
static int fnmod_delta(uint32_t fn1, uint32_t fn2)
|
||||||
|
{
|
||||||
|
int delta, h2;
|
||||||
|
|
||||||
|
delta = (fn1 % GSM_HYPER_FRAME) - (fn2 % GSM_HYPER_FRAME);
|
||||||
|
|
||||||
|
h2 = GSM_HYPER_FRAME / 2;
|
||||||
|
|
||||||
|
if (delta >= h2) {
|
||||||
|
delta -= GSM_HYPER_FRAME;
|
||||||
|
} else if(delta < -h2) {
|
||||||
|
delta += GSM_HYPER_FRAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fn_time_diff_delta(uint32_t fn, uint32_t fn_ref,
|
||||||
|
time_spec_t time_diff_hint)
|
||||||
|
{
|
||||||
|
int frames_diff, fn_delta;
|
||||||
|
frames_diff = int(round(time_diff_hint.get_real_secs() / GSM_FN_PERIOD));
|
||||||
|
fn_delta = fnmod_delta(fn, fn_ref + frames_diff) + frames_diff;
|
||||||
|
|
||||||
|
return fn_delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes difference between reference frame number
|
||||||
|
* and a second frame number.
|
||||||
|
* @param fn_ref reference frame number modulo GSM_HYPER_FRAME
|
||||||
|
* @param fn second frame number modulo GSM_HYPER_FRAME
|
||||||
|
* @param time_ref precise timestamp of the first sample in the fn_ref
|
||||||
|
* @param time_hint coarse time for fn that is used as a hint to avoid
|
||||||
|
* ambiguities caused by modulo operation applied to
|
||||||
|
* frame numbers
|
||||||
|
* @return difference between fn_ref and fn
|
||||||
|
*/
|
||||||
|
time_format fn_time_delta_cpp(uint32_t fn_ref, time_format time_ref, uint32_t fn_x,
|
||||||
|
time_format time_hint, uint32_t ts_num, uint32_t ts_ref)
|
||||||
|
{
|
||||||
|
time_spec_t time_diff_hint = time_spec_t(time_hint.first, time_hint.second) - time_spec_t(time_ref.first, time_ref.second);
|
||||||
|
int fn_delta = fn_time_diff_delta(fn_x, fn_ref, time_diff_hint);
|
||||||
|
time_spec_t time_x_precise = fn_delta * GSM_FN_PERIOD + time_spec_t(time_ref.first, time_ref.second) + (static_cast<int>(ts_num) - static_cast<int>(ts_ref)) * GSM_TS_PERIOD;
|
||||||
|
|
||||||
|
return time_format(time_x_precise.get_full_secs(), time_x_precise.get_frac_secs());
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace gsm */
|
||||||
|
} /* namespace gr */
|
||||||
|
|
|
@ -94,6 +94,6 @@ namespace gr {
|
||||||
return noutput_items;
|
return noutput_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace grgsm */
|
} /* namespace gsm */
|
||||||
} /* namespace gr */
|
} /* namespace gr */
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace gr {
|
||||||
gr_vector_void_star &output_items);
|
gr_vector_void_star &output_items);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace grgsm
|
} // namespace gsm
|
||||||
} // namespace gr
|
} // namespace gr
|
||||||
|
|
||||||
#endif /* INCLUDED_GRGSM_MSG_TO_TAG_IMPL_H */
|
#endif /* INCLUDED_GRGSM_MSG_TO_TAG_IMPL_H */
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
//
|
||||||
|
// Copyright 2011-2013 Ettus Research LLC
|
||||||
|
//
|
||||||
|
// This program 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 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <grgsm/misc_utils/time_spec.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Time spec constructors
|
||||||
|
**********************************************************************/
|
||||||
|
#define time_spec_init(full, frac) { \
|
||||||
|
const time_t _full = time_t(full); \
|
||||||
|
const double _frac = double(frac); \
|
||||||
|
const int _frac_int = int(_frac); \
|
||||||
|
_full_secs = _full + _frac_int; \
|
||||||
|
_frac_secs = _frac - _frac_int; \
|
||||||
|
if (_frac_secs < 0) {\
|
||||||
|
_full_secs -= 1; \
|
||||||
|
_frac_secs += 1; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long long fast_llround(const double x){
|
||||||
|
return (long long)(x + 0.5); // assumption of non-negativity
|
||||||
|
}
|
||||||
|
|
||||||
|
time_spec_t::time_spec_t(const time_spec_t & spec){
|
||||||
|
time_spec_init(spec.get_full_secs(), spec.get_frac_secs());
|
||||||
|
}
|
||||||
|
|
||||||
|
time_spec_t::time_spec_t(double secs){
|
||||||
|
time_spec_init(0, secs);
|
||||||
|
}
|
||||||
|
|
||||||
|
time_spec_t::time_spec_t(time_t full_secs, double frac_secs){
|
||||||
|
time_spec_init(full_secs, frac_secs);
|
||||||
|
}
|
||||||
|
|
||||||
|
time_spec_t::time_spec_t(time_t full_secs, long tick_count, double tick_rate){
|
||||||
|
const double frac_secs = tick_count/tick_rate;
|
||||||
|
time_spec_init(full_secs, frac_secs);
|
||||||
|
}
|
||||||
|
|
||||||
|
time_spec_t time_spec_t::from_ticks(long long ticks, double tick_rate){
|
||||||
|
const long long rate_i = (long long)(tick_rate);
|
||||||
|
const double rate_f = tick_rate - rate_i;
|
||||||
|
const time_t secs_full = time_t(ticks/rate_i);
|
||||||
|
const long long ticks_error = ticks - (secs_full*rate_i);
|
||||||
|
const double ticks_frac = ticks_error - secs_full*rate_f;
|
||||||
|
return time_spec_t(secs_full, ticks_frac/tick_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Time spec accessors
|
||||||
|
**********************************************************************/
|
||||||
|
long time_spec_t::get_tick_count(double tick_rate) const{
|
||||||
|
return long(fast_llround(this->get_frac_secs()*tick_rate));
|
||||||
|
}
|
||||||
|
|
||||||
|
long long time_spec_t::to_ticks(double tick_rate) const{
|
||||||
|
const long long rate_i = (long long)(tick_rate);
|
||||||
|
const double rate_f = tick_rate - rate_i;
|
||||||
|
const long long ticks_full = this->get_full_secs()*rate_i;
|
||||||
|
const double ticks_error = this->get_full_secs()*rate_f;
|
||||||
|
const double ticks_frac = this->get_frac_secs()*tick_rate;
|
||||||
|
return ticks_full + fast_llround(ticks_error + ticks_frac);
|
||||||
|
}
|
||||||
|
|
||||||
|
double time_spec_t::get_real_secs(void) const{
|
||||||
|
return this->get_full_secs() + this->get_frac_secs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Time spec math overloads
|
||||||
|
**********************************************************************/
|
||||||
|
time_spec_t &time_spec_t::operator+=(const time_spec_t &rhs){
|
||||||
|
time_spec_init(
|
||||||
|
this->get_full_secs() + rhs.get_full_secs(),
|
||||||
|
this->get_frac_secs() + rhs.get_frac_secs()
|
||||||
|
);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_spec_t &time_spec_t::operator-=(const time_spec_t &rhs){
|
||||||
|
time_spec_init(
|
||||||
|
this->get_full_secs() - rhs.get_full_secs(),
|
||||||
|
this->get_frac_secs() - rhs.get_frac_secs()
|
||||||
|
);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const time_spec_t &lhs, const time_spec_t &rhs){
|
||||||
|
return
|
||||||
|
lhs.get_full_secs() == rhs.get_full_secs() and
|
||||||
|
lhs.get_frac_secs() == rhs.get_frac_secs()
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const time_spec_t &lhs, const time_spec_t &rhs){
|
||||||
|
return (
|
||||||
|
(lhs.get_full_secs() < rhs.get_full_secs()) or (
|
||||||
|
(lhs.get_full_secs() == rhs.get_full_secs()) and
|
||||||
|
(lhs.get_frac_secs() < rhs.get_frac_secs())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,231 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/* @file
|
||||||
|
* @author Vadim Yanitskiy <axilirator@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 <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include "udp_socket.h"
|
||||||
|
#include "trx_burst_if_impl.h"
|
||||||
|
|
||||||
|
#define BURST_SIZE 148
|
||||||
|
#define DATA_IF_MTU 160
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 41-bit RACH synchronization sequence
|
||||||
|
* GSM 05.02 Chapter 5.2.7 Access burst (AB)
|
||||||
|
*/
|
||||||
|
static uint8_t rach_synch_seq[] = {
|
||||||
|
0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0,
|
||||||
|
1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
trx_burst_if::sptr
|
||||||
|
trx_burst_if::make(
|
||||||
|
const std::string &remote_addr,
|
||||||
|
const std::string &base_port)
|
||||||
|
{
|
||||||
|
int base_port_int = boost::lexical_cast<int> (base_port);
|
||||||
|
|
||||||
|
return gnuradio::get_initial_sptr
|
||||||
|
(new trx_burst_if_impl(remote_addr, base_port_int));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The private constructor
|
||||||
|
*/
|
||||||
|
trx_burst_if_impl::trx_burst_if_impl(
|
||||||
|
const std::string &remote_addr,
|
||||||
|
int base_port
|
||||||
|
) : gr::block("trx_burst_if",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(0, 0, 0))
|
||||||
|
{
|
||||||
|
message_port_register_in(pmt::mp("bursts"));
|
||||||
|
message_port_register_out(pmt::mp("bursts"));
|
||||||
|
|
||||||
|
// Bind a port handler
|
||||||
|
set_msg_handler(pmt::mp("bursts"),
|
||||||
|
boost::bind(&trx_burst_if_impl::handle_dl_burst, this, _1));
|
||||||
|
|
||||||
|
// Prepare port numbers
|
||||||
|
std::string data_src_port = boost::lexical_cast<std::string> (base_port + 2);
|
||||||
|
std::string data_dst_port = boost::lexical_cast<std::string> (base_port + 102);
|
||||||
|
|
||||||
|
// Init DATA interface
|
||||||
|
d_data_sock = new udp_socket(remote_addr,
|
||||||
|
data_src_port, data_dst_port, DATA_IF_MTU);
|
||||||
|
|
||||||
|
// Bind DATA interface handler
|
||||||
|
d_data_sock->udp_rx_handler = boost::bind(
|
||||||
|
&trx_burst_if_impl::handle_ul_burst, this, _1, _2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Our virtual destructor.
|
||||||
|
*/
|
||||||
|
trx_burst_if_impl::~trx_burst_if_impl()
|
||||||
|
{
|
||||||
|
// Release all UDP sockets and free memory
|
||||||
|
delete d_data_sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if burst is a RACH burst
|
||||||
|
*/
|
||||||
|
bool trx_burst_if_impl::detect_rach(uint8_t *burst)
|
||||||
|
{
|
||||||
|
// Compare synchronization sequence
|
||||||
|
for (int i = 0; i < 41; i++)
|
||||||
|
if (burst[i + 8] != rach_synch_seq[i])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Make sure TB and GP are filled by 0x00
|
||||||
|
for (int i = 0; i < 63; i++)
|
||||||
|
if (burst[i + 85] != 0x00)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create an UDP payload with burst bits
|
||||||
|
* and some channel data.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
trx_burst_if_impl::burst_pack(pmt::pmt_t msg, uint8_t *buf)
|
||||||
|
{
|
||||||
|
pmt::pmt_t header_plus_burst = pmt::cdr(msg);
|
||||||
|
|
||||||
|
// Extract GSMTAP header from message
|
||||||
|
gsmtap_hdr *header = (gsmtap_hdr *)
|
||||||
|
pmt::blob_data(header_plus_burst);
|
||||||
|
|
||||||
|
// Pack timeslot index
|
||||||
|
buf[0] = header->timeslot;
|
||||||
|
|
||||||
|
// Extract frame number
|
||||||
|
uint32_t frame_nr = be32toh(header->frame_number);
|
||||||
|
|
||||||
|
// Pack frame number
|
||||||
|
buf[1] = (frame_nr >> 24) & 0xff;
|
||||||
|
buf[2] = (frame_nr >> 16) & 0xff;
|
||||||
|
buf[3] = (frame_nr >> 8) & 0xff;
|
||||||
|
buf[4] = (frame_nr >> 0) & 0xff;
|
||||||
|
|
||||||
|
// Pack RSSI (-dBm)
|
||||||
|
buf[5] = -(uint8_t) header->signal_dbm;
|
||||||
|
|
||||||
|
// Pack correlator timing offset (TOA)
|
||||||
|
// FIXME: where to find this value?
|
||||||
|
buf[6] = 0;
|
||||||
|
buf[7] = 0;
|
||||||
|
|
||||||
|
// Extract bits {0..1} from message
|
||||||
|
// Despite GR-GSM uses int8_t, they are not real sbits {-127..127}
|
||||||
|
uint8_t *burst = (uint8_t *)
|
||||||
|
(pmt::blob_data(header_plus_burst)) + sizeof(gsmtap_hdr);
|
||||||
|
|
||||||
|
// Convert to transceiver interface specific bits {255..0}
|
||||||
|
for (int i = 0; i < 148; i++)
|
||||||
|
buf[8 + i] = burst[i] ? 255 : 0;
|
||||||
|
|
||||||
|
// Fill two unused bytes
|
||||||
|
buf[156] = 0x00;
|
||||||
|
buf[157] = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
trx_burst_if_impl::handle_dl_burst(pmt::pmt_t msg)
|
||||||
|
{
|
||||||
|
// 8 bytes of header + 148 bytes of burst
|
||||||
|
// + two unused, but required bytes
|
||||||
|
// otherwise bursts would be rejected
|
||||||
|
uint8_t buf[158];
|
||||||
|
|
||||||
|
// Compose a new UDP payload with burst
|
||||||
|
burst_pack(msg, buf);
|
||||||
|
|
||||||
|
// Send a burst
|
||||||
|
d_data_sock->udp_send(buf, 158);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
trx_burst_if_impl::handle_ul_burst(uint8_t *payload, size_t len)
|
||||||
|
{
|
||||||
|
// Check length according to the protocol
|
||||||
|
if (len != 154)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Make sure TS index is correct */
|
||||||
|
if (payload[0] >= 8)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Unpack and check frame number */
|
||||||
|
uint32_t fn = (payload[1] << 24)
|
||||||
|
| (payload[2] << 16)
|
||||||
|
| (payload[3] << 8)
|
||||||
|
| payload[4];
|
||||||
|
|
||||||
|
if (fn >= 2715648)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Prepare a buffer for GSMTAP header and burst
|
||||||
|
uint8_t buf[sizeof(gsmtap_hdr) + BURST_SIZE];
|
||||||
|
|
||||||
|
// Set up pointer to GSMTAP header structure
|
||||||
|
struct gsmtap_hdr *header = (struct gsmtap_hdr *) buf;
|
||||||
|
memset(header, 0x00, sizeof(struct gsmtap_hdr));
|
||||||
|
|
||||||
|
// Fill in basic info
|
||||||
|
header->version = GSMTAP_VERSION;
|
||||||
|
header->hdr_len = sizeof(gsmtap_hdr) / 4;
|
||||||
|
header->type = GSMTAP_TYPE_UM_BURST;
|
||||||
|
|
||||||
|
// Set timeslot index and frame number
|
||||||
|
header->timeslot = payload[0];
|
||||||
|
header->frame_number = htobe32(fn);
|
||||||
|
|
||||||
|
// Check if one is a RACH burst
|
||||||
|
header->sub_type = detect_rach(payload + 6) ?
|
||||||
|
GSMTAP_BURST_ACCESS : GSMTAP_BURST_NORMAL;
|
||||||
|
|
||||||
|
// Copy burst bits (0 & 1) for source message
|
||||||
|
memcpy(buf + sizeof(gsmtap_hdr), payload + 6, BURST_SIZE);
|
||||||
|
|
||||||
|
// Create a pmt blob
|
||||||
|
pmt::pmt_t blob = pmt::make_blob(buf, sizeof(gsmtap_hdr) + BURST_SIZE);
|
||||||
|
pmt::pmt_t msg = pmt::cons(pmt::PMT_NIL, blob);
|
||||||
|
|
||||||
|
/* Send a message to the output */
|
||||||
|
message_port_pub(pmt::mp("bursts"), msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace gsm */
|
||||||
|
} /* namespace gr */
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/* @file
|
||||||
|
* @author Vadim Yanitskiy <axilirator@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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GRGSM_TRX_BURST_IF_IMPL_H
|
||||||
|
#define INCLUDED_GRGSM_TRX_BURST_IF_IMPL_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <grgsm/gsmtap.h>
|
||||||
|
#include <grgsm/misc_utils/trx_burst_if.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
class trx_burst_if_impl : public trx_burst_if
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
udp_socket *d_data_sock;
|
||||||
|
|
||||||
|
bool detect_rach(uint8_t *burst);
|
||||||
|
void burst_pack(pmt::pmt_t msg, uint8_t *buf);
|
||||||
|
|
||||||
|
public:
|
||||||
|
trx_burst_if_impl(const std::string &remote_addr, int base_port);
|
||||||
|
~trx_burst_if_impl();
|
||||||
|
|
||||||
|
void handle_dl_burst(pmt::pmt_t msg);
|
||||||
|
void handle_ul_burst(uint8_t *payload, size_t len);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GRGSM_TRX_BURST_IF_IMPL_H */
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GNU Radio
|
||||||
|
*
|
||||||
|
* GNU Radio 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.
|
||||||
|
*
|
||||||
|
* GNU Radio 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 GNU Radio; 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/thread/thread.h>
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include <gnuradio/blocks/pdu.h>
|
||||||
|
#include <pmt/pmt.h>
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include "udp_socket.h"
|
||||||
|
|
||||||
|
using boost::asio::ip::udp;
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
udp_socket::udp_socket(
|
||||||
|
const std::string &remote_addr,
|
||||||
|
const std::string &src_port,
|
||||||
|
const std::string &dst_port,
|
||||||
|
size_t mtu)
|
||||||
|
{
|
||||||
|
// Resize receive buffer according to MTU value
|
||||||
|
d_rxbuf.resize(mtu);
|
||||||
|
|
||||||
|
// Resolve remote host address
|
||||||
|
udp::resolver resolver(d_io_service);
|
||||||
|
|
||||||
|
udp::resolver::query rx_query(
|
||||||
|
udp::v4(), remote_addr, src_port,
|
||||||
|
boost::asio::ip::resolver_query_base::passive);
|
||||||
|
udp::resolver::query tx_query(
|
||||||
|
udp::v4(), remote_addr, dst_port,
|
||||||
|
boost::asio::ip::resolver_query_base::passive);
|
||||||
|
|
||||||
|
d_udp_endpoint_rx = *resolver.resolve(rx_query);
|
||||||
|
d_udp_endpoint_tx = *resolver.resolve(tx_query);
|
||||||
|
|
||||||
|
// Create a socket
|
||||||
|
d_udp_socket.reset(new udp::socket(d_io_service, d_udp_endpoint_rx));
|
||||||
|
|
||||||
|
// Setup read handler
|
||||||
|
d_udp_socket->async_receive_from(
|
||||||
|
boost::asio::buffer(d_rxbuf), d_udp_endpoint_rx,
|
||||||
|
boost::bind(&udp_socket::handle_udp_read, this,
|
||||||
|
boost::asio::placeholders::error,
|
||||||
|
boost::asio::placeholders::bytes_transferred));
|
||||||
|
|
||||||
|
// Start server
|
||||||
|
d_thread = gr::thread::thread(
|
||||||
|
boost::bind(&udp_socket::run_io_service, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
udp_socket::~udp_socket()
|
||||||
|
{
|
||||||
|
// Stop server
|
||||||
|
d_io_service.stop();
|
||||||
|
d_thread.interrupt();
|
||||||
|
d_thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
udp_socket::run_io_service(void)
|
||||||
|
{
|
||||||
|
d_io_service.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
udp_socket::udp_send(uint8_t *data, size_t len)
|
||||||
|
{
|
||||||
|
d_udp_socket->send_to(
|
||||||
|
boost::asio::buffer(data, len),
|
||||||
|
d_udp_endpoint_tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
udp_socket::handle_udp_read(
|
||||||
|
const boost::system::error_code& error,
|
||||||
|
size_t bytes_transferred)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Call incoming data handler
|
||||||
|
if (udp_rx_handler != NULL)
|
||||||
|
udp_rx_handler((uint8_t *) &d_rxbuf[0], bytes_transferred);
|
||||||
|
|
||||||
|
d_udp_socket->async_receive_from(
|
||||||
|
boost::asio::buffer(d_rxbuf), d_udp_endpoint_rx,
|
||||||
|
boost::bind(&udp_socket::handle_udp_read, this,
|
||||||
|
boost::asio::placeholders::error,
|
||||||
|
boost::asio::placeholders::bytes_transferred));
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace gsm */
|
||||||
|
}/* namespace gr */
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GNU Radio
|
||||||
|
*
|
||||||
|
* GNU Radio 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.
|
||||||
|
*
|
||||||
|
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GRGSM_TRX_UDP_SOCKET_H
|
||||||
|
#define INCLUDED_GRGSM_TRX_UDP_SOCKET_H
|
||||||
|
|
||||||
|
#include <gnuradio/thread/thread.h>
|
||||||
|
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <pmt/pmt.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
class udp_socket
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
boost::asio::io_service d_io_service;
|
||||||
|
std::vector<char> d_rxbuf;
|
||||||
|
gr::thread::thread d_thread;
|
||||||
|
bool d_started;
|
||||||
|
bool d_finished;
|
||||||
|
|
||||||
|
boost::asio::ip::udp::endpoint d_udp_endpoint_rx;
|
||||||
|
boost::asio::ip::udp::endpoint d_udp_endpoint_tx;
|
||||||
|
boost::shared_ptr<boost::asio::ip::udp::socket> d_udp_socket;
|
||||||
|
|
||||||
|
void handle_udp_read(const boost::system::error_code& error,
|
||||||
|
size_t bytes_transferred);
|
||||||
|
void run_io_service(void);
|
||||||
|
|
||||||
|
public:
|
||||||
|
udp_socket(
|
||||||
|
const std::string &remote_addr,
|
||||||
|
const std::string &src_port,
|
||||||
|
const std::string &dst_port,
|
||||||
|
size_t mtu);
|
||||||
|
~udp_socket();
|
||||||
|
|
||||||
|
void udp_send(uint8_t *data, size_t len);
|
||||||
|
boost::function<void (uint8_t *, size_t)> udp_rx_handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace gsm */
|
||||||
|
} /* namespace gr */
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GRGSM_TRX_UDP_SOCKET_H */
|
|
@ -47,7 +47,8 @@ namespace gr {
|
||||||
burst_sink_impl::burst_sink_impl()
|
burst_sink_impl::burst_sink_impl()
|
||||||
: gr::block("burst_sink",
|
: gr::block("burst_sink",
|
||||||
gr::io_signature::make(0, 0, 0),
|
gr::io_signature::make(0, 0, 0),
|
||||||
gr::io_signature::make(0, 0, 0))
|
gr::io_signature::make(0, 0, 0)),
|
||||||
|
d_bursts(pmt::PMT_NIL)
|
||||||
{
|
{
|
||||||
message_port_register_in(pmt::mp("in"));
|
message_port_register_in(pmt::mp("in"));
|
||||||
set_msg_handler(pmt::mp("in"), boost::bind(&burst_sink_impl::process_burst, this, _1));
|
set_msg_handler(pmt::mp("in"), boost::bind(&burst_sink_impl::process_burst, this, _1));
|
||||||
|
@ -105,7 +106,10 @@ namespace gr {
|
||||||
{
|
{
|
||||||
return d_burst_data;
|
return d_burst_data;
|
||||||
}
|
}
|
||||||
|
pmt::pmt_t burst_sink_impl::get_bursts()
|
||||||
|
{
|
||||||
|
return d_bursts;
|
||||||
|
}
|
||||||
} /* namespace gsm */
|
} /* namespace gsm */
|
||||||
} /* namespace gr */
|
} /* namespace gr */
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace gr {
|
||||||
std::vector<int> d_framenumbers;
|
std::vector<int> d_framenumbers;
|
||||||
std::vector<int> d_timeslots;
|
std::vector<int> d_timeslots;
|
||||||
std::vector<std::string> d_burst_data;
|
std::vector<std::string> d_burst_data;
|
||||||
|
pmt::pmt_t d_bursts;
|
||||||
public:
|
public:
|
||||||
burst_sink_impl();
|
burst_sink_impl();
|
||||||
~burst_sink_impl();
|
~burst_sink_impl();
|
||||||
|
@ -42,6 +43,7 @@ namespace gr {
|
||||||
virtual std::vector<int> get_framenumbers();
|
virtual std::vector<int> get_framenumbers();
|
||||||
virtual std::vector<int> get_timeslots();
|
virtual std::vector<int> get_timeslots();
|
||||||
virtual std::vector<std::string> get_burst_data();
|
virtual std::vector<std::string> get_burst_data();
|
||||||
|
virtual pmt::pmt_t get_bursts();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gsm
|
} // namespace gsm
|
||||||
|
|
|
@ -23,4 +23,5 @@ add_sources(
|
||||||
receiver_config.cc
|
receiver_config.cc
|
||||||
receiver_impl.cc
|
receiver_impl.cc
|
||||||
viterbi_detector.cc
|
viterbi_detector.cc
|
||||||
|
time_sample_ref.cc
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sch.h>
|
#include <sch.h>
|
||||||
#include <gsm_constants.h>
|
#include <grgsm/gsm_constants.h>
|
||||||
#include "clock_offset_control_impl.h"
|
#include "clock_offset_control_impl.h"
|
||||||
|
|
||||||
namespace gr
|
namespace gr
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <gsm_constants.h>
|
#include <grgsm/gsm_constants.h>
|
||||||
|
|
||||||
class multiframe_configuration
|
class multiframe_configuration
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,10 +73,13 @@ namespace gr
|
||||||
) : gr::sync_block("receiver",
|
) : gr::sync_block("receiver",
|
||||||
gr::io_signature::make(1, -1, sizeof(gr_complex)),
|
gr::io_signature::make(1, -1, sizeof(gr_complex)),
|
||||||
gr::io_signature::make(0, 0, 0)),
|
gr::io_signature::make(0, 0, 0)),
|
||||||
|
d_samples_consumed(0),
|
||||||
|
d_rx_time_received(false),
|
||||||
|
d_time_samp_ref(GSM_SYMBOL_RATE * osr),
|
||||||
d_OSR(osr),
|
d_OSR(osr),
|
||||||
d_process_uplink(process_uplink),
|
d_process_uplink(process_uplink),
|
||||||
d_chan_imp_length(CHAN_IMP_RESP_LENGTH),
|
d_chan_imp_length(CHAN_IMP_RESP_LENGTH),
|
||||||
d_counter(0),
|
d_counter(0), //TODO: use nitems_read instead of d_counter
|
||||||
d_fcch_start_pos(0),
|
d_fcch_start_pos(0),
|
||||||
d_freq_offset_setting(0),
|
d_freq_offset_setting(0),
|
||||||
d_state(fcch_search),
|
d_state(fcch_search),
|
||||||
|
@ -174,8 +177,13 @@ namespace gr
|
||||||
d_freq_offset_tag_in_fcch = tag_offset < last_sample_nr;
|
d_freq_offset_tag_in_fcch = tag_offset < last_sample_nr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Obtaining current time with use of rx_time tag provided i.e. by UHD devices */
|
||||||
|
/* And storing it in time_sample_ref for sample number to time conversion */
|
||||||
|
std::vector<tag_t> rx_time_tags;
|
||||||
|
|
||||||
/* Main state machine */
|
/* Main state machine */
|
||||||
|
d_samples_consumed = 0;
|
||||||
switch (d_state) {
|
switch (d_state) {
|
||||||
case fcch_search:
|
case fcch_search:
|
||||||
fcch_search_handler(input, noutput_items);
|
fcch_search_handler(input, noutput_items);
|
||||||
|
@ -188,7 +196,20 @@ namespace gr
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
get_tags_in_window(rx_time_tags, 0, 0, d_samples_consumed, pmt::string_to_symbol("rx_time"));
|
||||||
|
if(!rx_time_tags.empty()){
|
||||||
|
d_rx_time_received = true;
|
||||||
|
tag_t rx_time_tag = *(rx_time_tags.begin());
|
||||||
|
|
||||||
|
uint64_t rx_time_full_part = to_uint64(tuple_ref(rx_time_tag.value,0));
|
||||||
|
double rx_time_frac_part = to_double(tuple_ref(rx_time_tag.value,1));
|
||||||
|
|
||||||
|
time_spec_t current_rx_time = time_spec_t(rx_time_full_part, rx_time_frac_part);
|
||||||
|
uint64_t current_start_offset = rx_time_tag.offset;
|
||||||
|
d_time_samp_ref.update(current_rx_time, current_start_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return d_samples_consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -248,7 +269,9 @@ namespace gr
|
||||||
d_burst_nr++;
|
d_burst_nr++;
|
||||||
|
|
||||||
/* Consume samples up to the next guard period */
|
/* Consume samples up to the next guard period */
|
||||||
consume_each(burst_start + BURST_SIZE * d_OSR + 4 * d_OSR);
|
unsigned int to_consume = burst_start + BURST_SIZE * d_OSR + 4 * d_OSR;
|
||||||
|
// consume_each(to_consume);
|
||||||
|
d_samples_consumed += to_consume;
|
||||||
|
|
||||||
/* Update current state */
|
/* Update current state */
|
||||||
d_state = synchronized;
|
d_state = synchronized;
|
||||||
|
@ -320,7 +343,7 @@ namespace gr
|
||||||
|
|
||||||
case sch_burst:
|
case sch_burst:
|
||||||
{
|
{
|
||||||
int d_ncc, d_bcc;
|
int ncc, bcc;
|
||||||
int t1, t2, t3;
|
int t1, t2, t3;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -332,12 +355,8 @@ namespace gr
|
||||||
detect_burst(input, &channel_imp_resp[0],
|
detect_burst(input, &channel_imp_resp[0],
|
||||||
d_c0_burst_start, output_binary);
|
d_c0_burst_start, output_binary);
|
||||||
|
|
||||||
/* Compose a message with GSMTAP header and bits */
|
|
||||||
send_burst(d_burst_nr, output_binary,
|
|
||||||
GSMTAP_BURST_SCH, input_nr);
|
|
||||||
|
|
||||||
/* Attempt to decode SCH burst */
|
/* Attempt to decode SCH burst */
|
||||||
rc = decode_sch(&output_binary[3], &t1, &t2, &t3, &d_ncc, &d_bcc);
|
rc = decode_sch(&output_binary[3], &t1, &t2, &t3, &ncc, &bcc);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if (++d_failed_sch >= MAX_SCH_ERRORS) {
|
if (++d_failed_sch >= MAX_SCH_ERRORS) {
|
||||||
/* We have to resynchronize, change state */
|
/* We have to resynchronize, change state */
|
||||||
|
@ -352,6 +371,10 @@ namespace gr
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compose a message with GSMTAP header and bits */
|
||||||
|
send_burst(d_burst_nr, output_binary,
|
||||||
|
GSMTAP_BURST_SCH, input_nr, d_c0_burst_start);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decoding was successful, now
|
* Decoding was successful, now
|
||||||
* compute offset from burst_start,
|
* compute offset from burst_start,
|
||||||
|
@ -380,7 +403,7 @@ namespace gr
|
||||||
|
|
||||||
/* Compose a message with GSMTAP header and bits */
|
/* Compose a message with GSMTAP header and bits */
|
||||||
send_burst(d_burst_nr, output_binary,
|
send_burst(d_burst_nr, output_binary,
|
||||||
GSMTAP_BURST_NORMAL, input_nr);
|
GSMTAP_BURST_NORMAL, input_nr, d_c0_burst_start);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -404,13 +427,13 @@ namespace gr
|
||||||
|
|
||||||
/* Compose a message with GSMTAP header and bits */
|
/* Compose a message with GSMTAP header and bits */
|
||||||
send_burst(d_burst_nr, output_binary,
|
send_burst(d_burst_nr, output_binary,
|
||||||
GSMTAP_BURST_NORMAL, input_nr);
|
GSMTAP_BURST_NORMAL, input_nr, normal_burst_start);
|
||||||
} else {
|
} else {
|
||||||
d_c0_burst_start = dummy_burst_start;
|
d_c0_burst_start = dummy_burst_start;
|
||||||
|
|
||||||
/* Compose a message with GSMTAP header and bits */
|
/* Compose a message with GSMTAP header and bits */
|
||||||
send_burst(d_burst_nr, dummy_burst,
|
send_burst(d_burst_nr, dummy_burst,
|
||||||
GSMTAP_BURST_DUMMY, input_nr);
|
GSMTAP_BURST_DUMMY, input_nr, dummy_burst_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -462,7 +485,7 @@ namespace gr
|
||||||
burst_start, output_binary);
|
burst_start, output_binary);
|
||||||
|
|
||||||
/* Compose a message with GSMTAP header and bits */
|
/* Compose a message with GSMTAP header and bits */
|
||||||
send_burst(d_burst_nr, output_binary, GSMTAP_BURST_NORMAL, input_nr);
|
send_burst(d_burst_nr, output_binary, GSMTAP_BURST_NORMAL, input_nr, burst_start);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -483,7 +506,8 @@ namespace gr
|
||||||
|
|
||||||
/* Consume samples of the burst up to next guard period */
|
/* Consume samples of the burst up to next guard period */
|
||||||
to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset();
|
to_consume += TS_BITS * d_OSR + d_burst_nr.get_offset();
|
||||||
consume_each(to_consume);
|
// consume_each(to_consume);
|
||||||
|
d_samples_consumed += to_consume;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -674,7 +698,8 @@ namespace gr
|
||||||
}
|
}
|
||||||
|
|
||||||
d_counter += to_consume;
|
d_counter += to_consume;
|
||||||
consume_each(to_consume);
|
// consume_each(to_consume);
|
||||||
|
d_samples_consumed += to_consume;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -725,7 +750,8 @@ namespace gr
|
||||||
}
|
}
|
||||||
|
|
||||||
d_counter += to_consume;
|
d_counter += to_consume;
|
||||||
consume_each(to_consume);
|
// consume_each(to_consume);
|
||||||
|
d_samples_consumed += to_consume;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -979,7 +1005,7 @@ namespace gr
|
||||||
void
|
void
|
||||||
receiver_impl::send_burst(burst_counter burst_nr,
|
receiver_impl::send_burst(burst_counter burst_nr,
|
||||||
const unsigned char * burst_binary, uint8_t burst_type,
|
const unsigned char * burst_binary, uint8_t burst_type,
|
||||||
size_t input_nr)
|
size_t input_nr, unsigned int burst_start)
|
||||||
{
|
{
|
||||||
/* Buffer for GSMTAP header and burst */
|
/* Buffer for GSMTAP header and burst */
|
||||||
uint8_t buf[sizeof(gsmtap_hdr) + BURST_SIZE];
|
uint8_t buf[sizeof(gsmtap_hdr) + BURST_SIZE];
|
||||||
|
@ -1018,12 +1044,26 @@ namespace gr
|
||||||
tap_header->signal_dbm = static_cast<int8_t>(d_signal_dbm);
|
tap_header->signal_dbm = static_cast<int8_t>(d_signal_dbm);
|
||||||
tap_header->snr_db = 0; /* FIXME: Can we calculate this? */
|
tap_header->snr_db = 0; /* FIXME: Can we calculate this? */
|
||||||
|
|
||||||
|
pmt::pmt_t pdu_header = pmt::make_dict();
|
||||||
|
|
||||||
|
/* Add timestamp of the first sample - if available */
|
||||||
|
if(d_rx_time_received) {
|
||||||
|
time_spec_t time_spec_of_first_sample = d_time_samp_ref.offset_to_time(nitems_read(0)+burst_start);
|
||||||
|
uint64_t full = time_spec_of_first_sample.get_full_secs();
|
||||||
|
double frac = time_spec_of_first_sample.get_frac_secs();
|
||||||
|
pdu_header =
|
||||||
|
pmt::dict_add(pdu_header, pmt::mp("fn_time"),
|
||||||
|
pmt::cons(
|
||||||
|
pmt::cons(pmt::from_uint64(be32toh(frame_number)), pmt::from_uint64(tn)),
|
||||||
|
pmt::cons(pmt::from_uint64(full), pmt::from_double(frac))));
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy burst to the buffer */
|
/* Copy burst to the buffer */
|
||||||
memcpy(burst, burst_binary, BURST_SIZE);
|
memcpy(burst, burst_binary, BURST_SIZE);
|
||||||
|
|
||||||
/* Allocate a new message */
|
/* Allocate a new message */
|
||||||
pmt::pmt_t blob = pmt::make_blob(buf, sizeof(gsmtap_hdr) + BURST_SIZE);
|
pmt::pmt_t blob = pmt::make_blob(buf, sizeof(gsmtap_hdr) + BURST_SIZE);
|
||||||
pmt::pmt_t msg = pmt::cons(pmt::PMT_NIL, blob);
|
pmt::pmt_t msg = pmt::cons(pdu_header, blob);
|
||||||
|
|
||||||
/* Send message */
|
/* Send message */
|
||||||
if (input_nr == 0)
|
if (input_nr == 0)
|
||||||
|
@ -1092,6 +1132,5 @@ namespace gr
|
||||||
{
|
{
|
||||||
d_state = fcch_search;
|
d_state = fcch_search;
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace gsm */
|
} /* namespace gsm */
|
||||||
} /* namespace gr */
|
} /* namespace gr */
|
||||||
|
|
|
@ -25,16 +25,20 @@
|
||||||
|
|
||||||
#include <grgsm/receiver/receiver.h>
|
#include <grgsm/receiver/receiver.h>
|
||||||
#include <grgsm/gsmtap.h>
|
#include <grgsm/gsmtap.h>
|
||||||
#include <gsm_constants.h>
|
#include <grgsm/gsm_constants.h>
|
||||||
#include <receiver_config.h>
|
#include <receiver_config.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "time_sample_ref.h"
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
namespace gsm {
|
namespace gsm {
|
||||||
class receiver_impl : public receiver
|
class receiver_impl : public receiver
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
unsigned int d_c0_burst_start;
|
unsigned int d_samples_consumed;
|
||||||
|
bool d_rx_time_received;
|
||||||
|
time_sample_ref d_time_samp_ref;
|
||||||
|
int d_c0_burst_start;
|
||||||
float d_c0_signal_dbm;
|
float d_c0_signal_dbm;
|
||||||
|
|
||||||
/**@name Configuration of the receiver */
|
/**@name Configuration of the receiver */
|
||||||
|
@ -195,7 +199,7 @@ namespace gr {
|
||||||
* @param burst_binary - content of the burst
|
* @param burst_binary - content of the burst
|
||||||
* @b_type - type of the burst
|
* @b_type - type of the burst
|
||||||
*/
|
*/
|
||||||
void send_burst(burst_counter burst_nr, const unsigned char * burst_binary, uint8_t burst_type, size_t input_nr);
|
void send_burst(burst_counter burst_nr, const unsigned char * burst_binary, uint8_t burst_type, size_t input_nr, unsigned int burst_start=-1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures burst types in different channels
|
* Configures burst types in different channels
|
||||||
|
@ -209,13 +213,13 @@ namespace gr {
|
||||||
gr_vector_const_void_star &input_items, int noutput_items);
|
gr_vector_const_void_star &input_items, int noutput_items);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
receiver_impl(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &tseq_nums, bool process_uplink);
|
receiver_impl(int osr, const std::vector<int> &cell_allocation, const std::vector<int> &tseq_nums, bool process_uplink);
|
||||||
~receiver_impl();
|
~receiver_impl();
|
||||||
|
|
||||||
int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items);
|
||||||
virtual void set_cell_allocation(const std::vector<int> &cell_allocation);
|
virtual void set_cell_allocation(const std::vector<int> &cell_allocation);
|
||||||
virtual void set_tseq_nums(const std::vector<int> & tseq_nums);
|
virtual void set_tseq_nums(const std::vector<int> & tseq_nums);
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
};
|
};
|
||||||
} // namespace gsm
|
} // namespace gsm
|
||||||
} // namespace gr
|
} // namespace gr
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* @file
|
||||||
|
* @author (C) 2017 by 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include "time_sample_ref.h"
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
time_sample_ref::time_sample_ref(double samp_rate): d_samp_rate(samp_rate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
time_sample_ref::~time_sample_ref()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void time_sample_ref::update(time_spec_t last_rx_time, uint64_t current_start_offset)
|
||||||
|
{
|
||||||
|
d_last_rx_time = last_rx_time;
|
||||||
|
d_current_start_offset = current_start_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_spec_t time_sample_ref::offset_to_time(uint64_t offset)
|
||||||
|
{
|
||||||
|
uint64_t samples_from_last_rx_time = offset - d_current_start_offset;
|
||||||
|
time_spec_t time = time_spec_t(static_cast<double>(samples_from_last_rx_time)/d_samp_rate) + d_last_rx_time;
|
||||||
|
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t time_sample_ref::time_to_offset(time_spec_t time)
|
||||||
|
{
|
||||||
|
double samples_since_last_rx_time_tag = (time-d_last_rx_time).get_real_secs()*d_samp_rate;
|
||||||
|
// double fractional_part = round(samples_since_last_rx_time_tag) - samples_since_last_rx_time_tag;
|
||||||
|
uint64_t offset = static_cast<uint64_t>(round(samples_since_last_rx_time_tag)) + d_current_start_offset;
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/*
|
||||||
|
* @file
|
||||||
|
* @author (C) 2017 by 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_TIME_SAMPLE_REF_IMPL_H
|
||||||
|
#define INCLUDED_TIME_SAMPLE_REF_IMPL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <grgsm/misc_utils/time_spec.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
/*
|
||||||
|
Class for storing time reference and for conversions time<->sample number
|
||||||
|
*/
|
||||||
|
class time_sample_ref
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double d_samp_rate;
|
||||||
|
time_spec_t d_last_rx_time;
|
||||||
|
uint64_t d_current_start_offset;
|
||||||
|
public:
|
||||||
|
time_sample_ref(double samp_rate);
|
||||||
|
~time_sample_ref();
|
||||||
|
void update(time_spec_t last_rx_time, uint64_t current_start_offset);
|
||||||
|
time_spec_t offset_to_time(uint64_t offset);
|
||||||
|
uint64_t time_to_offset(time_spec_t time);
|
||||||
|
};
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
#endif// INCLUDED_TIME_SAMPLE_REF_IMPL_H
|
|
@ -56,7 +56,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gnuradio/gr_complex.h>
|
#include <gnuradio/gr_complex.h>
|
||||||
#include <gsm_constants.h>
|
#include <grgsm/gsm_constants.h>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#define PATHS_NUM (1 << (CHAN_IMP_RESP_LENGTH-1))
|
#define PATHS_NUM (1 << (CHAN_IMP_RESP_LENGTH-1))
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright 2011,2012 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is part of GNU Radio
|
||||||
|
#
|
||||||
|
# GNU Radio 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.
|
||||||
|
#
|
||||||
|
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
add_sources(
|
||||||
|
txtime_setter_impl.cc
|
||||||
|
preprocess_tx_burst_impl.cc
|
||||||
|
gen_test_ab_impl
|
||||||
|
)
|
|
@ -0,0 +1,107 @@
|
||||||
|
/* -*- 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 <grgsm/gsm_constants.h>
|
||||||
|
#include "gen_test_ab_impl.h"
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
static uint8_t rach_synch_seq[] = {
|
||||||
|
0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0 ,
|
||||||
|
1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t AB[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
// static uint8_t AB[] = {0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1};
|
||||||
|
// static uint8_t AB[] = { 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1};
|
||||||
|
// static uint8_t AB[] = {1,1,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,0,1,0,1,0,1,1,1,0,0,0,0,1,1,1,0,0,1,0,0,0,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
|
||||||
|
// ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
|
||||||
|
gen_test_ab::sptr
|
||||||
|
gen_test_ab::make()
|
||||||
|
{
|
||||||
|
return gnuradio::get_initial_sptr
|
||||||
|
(new gen_test_ab_impl());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The private constructor
|
||||||
|
*/
|
||||||
|
gen_test_ab_impl::gen_test_ab_impl()
|
||||||
|
: gr::block("gen_test_ab",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(0, 0, 0))
|
||||||
|
{
|
||||||
|
message_port_register_in(pmt::intern("bursts_in"));
|
||||||
|
message_port_register_out(pmt::intern("bursts_out"));
|
||||||
|
|
||||||
|
set_msg_handler(pmt::intern("bursts_in"), boost::bind(&gen_test_ab_impl::generate_ab, this, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Our virtual destructor.
|
||||||
|
*/
|
||||||
|
gen_test_ab_impl::~gen_test_ab_impl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_test_ab_impl::generate_ab(pmt::pmt_t burst)
|
||||||
|
{
|
||||||
|
uint8_t buf[sizeof(gsmtap_hdr) + 148];
|
||||||
|
struct gsmtap_hdr *tap_header = (struct gsmtap_hdr *) buf;
|
||||||
|
uint8_t *access_burst = buf + sizeof(gsmtap_hdr);
|
||||||
|
|
||||||
|
// memset(access_burst, 0, 8); /* TB */
|
||||||
|
// memcpy(access_burst + 8, rach_synch_seq, 41); /* sync seq */
|
||||||
|
// memcpy(access_burst + 49, AB, 36); /* payload */
|
||||||
|
// memset(access_burst + 85, 0, 63); /* TB + GP */
|
||||||
|
|
||||||
|
memcpy(access_burst, AB, 148);
|
||||||
|
|
||||||
|
gsmtap_hdr * header = (gsmtap_hdr *)(pmt::blob_data(pmt::cdr(burst)));
|
||||||
|
uint32_t frame_nr = be32toh(header->frame_number);
|
||||||
|
frame_nr = (frame_nr+51)% (26*51*2048);
|
||||||
|
|
||||||
|
tap_header->version = GSMTAP_VERSION;
|
||||||
|
tap_header->hdr_len = sizeof(gsmtap_hdr) / 4;
|
||||||
|
tap_header->type = GSMTAP_TYPE_UM_BURST;
|
||||||
|
tap_header->sub_type = GSMTAP_BURST_ACCESS;
|
||||||
|
tap_header->frame_number = htobe32(frame_nr);
|
||||||
|
tap_header->timeslot = header->timeslot;
|
||||||
|
tap_header->arfcn = 0;
|
||||||
|
|
||||||
|
pmt::pmt_t blob = pmt::make_blob(buf, sizeof(gsmtap_hdr) + BURST_SIZE);
|
||||||
|
pmt::pmt_t pdu_header = pmt::make_dict();
|
||||||
|
|
||||||
|
pmt::pmt_t new_msg = pmt::cons(pdu_header, blob);
|
||||||
|
message_port_pub(pmt::intern("bursts_out"), new_msg);
|
||||||
|
}
|
||||||
|
} /* namespace gsm */
|
||||||
|
} /* namespace gr */
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GSM_GEN_TEST_AB_IMPL_H
|
||||||
|
#define INCLUDED_GSM_GEN_TEST_AB_IMPL_H
|
||||||
|
|
||||||
|
#include <grgsm/transmitter/gen_test_ab.h>
|
||||||
|
#include <grgsm/misc_utils/time_spec.h>
|
||||||
|
#include <grgsm/misc_utils/fn_time.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
class gen_test_ab_impl : public gen_test_ab
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void generate_ab(pmt::pmt_t burst);
|
||||||
|
|
||||||
|
public:
|
||||||
|
gen_test_ab_impl();
|
||||||
|
~gen_test_ab_impl();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GSM_GEN_TEST_AB_IMPL_H */
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/* @file
|
||||||
|
* @author Piotr Krysik <ptrkrysik@gmail.com>
|
||||||
|
* @author Vadim Yanitskiy <axilirator@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 <assert.h>
|
||||||
|
|
||||||
|
#include <gnuradio/io_signature.h>
|
||||||
|
#include <grgsm/gsm_constants.h>
|
||||||
|
#include <grgsm/gsmtap.h>
|
||||||
|
|
||||||
|
#include "preprocess_tx_burst_impl.h"
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
preprocess_tx_burst::sptr
|
||||||
|
preprocess_tx_burst::make()
|
||||||
|
{
|
||||||
|
return gnuradio::get_initial_sptr
|
||||||
|
(new preprocess_tx_burst_impl());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The private constructor
|
||||||
|
*/
|
||||||
|
preprocess_tx_burst_impl::preprocess_tx_burst_impl()
|
||||||
|
: gr::block("preprocess_tx_burst",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(0, 0, 0))
|
||||||
|
{
|
||||||
|
message_port_register_in(pmt::mp("bursts_in"));
|
||||||
|
message_port_register_out(pmt::mp("bursts_out"));
|
||||||
|
|
||||||
|
set_msg_handler(pmt::mp("bursts_in"),
|
||||||
|
boost::bind(&preprocess_tx_burst_impl::process_burst, this, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Our virtual destructor.
|
||||||
|
*/
|
||||||
|
preprocess_tx_burst_impl::~preprocess_tx_burst_impl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void preprocess_tx_burst_impl::process_burst(pmt::pmt_t msg_in)
|
||||||
|
{
|
||||||
|
pmt::pmt_t blob_in = pmt::cdr(msg_in);
|
||||||
|
|
||||||
|
// Extract GSMTAP header from message
|
||||||
|
gsmtap_hdr *burst_hdr = (gsmtap_hdr *) pmt::blob_data(blob_in);
|
||||||
|
|
||||||
|
// Extract burst bits from message
|
||||||
|
uint8_t *burst_bits = (uint8_t *)
|
||||||
|
(pmt::blob_data(blob_in)) + sizeof(gsmtap_hdr);
|
||||||
|
|
||||||
|
// Determine and check burst length
|
||||||
|
size_t burst_len = pmt::blob_length(blob_in) - sizeof(gsmtap_hdr);
|
||||||
|
assert(burst_len == BURST_SIZE);
|
||||||
|
|
||||||
|
// The Access Burst last has reduced length
|
||||||
|
if (burst_hdr->sub_type == GSMTAP_BURST_ACCESS)
|
||||||
|
burst_len = ACCESS_BURST_SIZE;
|
||||||
|
|
||||||
|
// Prepare an output message
|
||||||
|
pmt::pmt_t blob_out = pmt::make_blob(burst_bits, burst_len);
|
||||||
|
pmt::pmt_t msg_out = pmt::cons(pmt::car(msg_in), blob_out);
|
||||||
|
|
||||||
|
/* Send a message to the output */
|
||||||
|
message_port_pub(pmt::mp("bursts_out"), msg_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace gsm */
|
||||||
|
} /* namespace gr */
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GSM_PREPROCESS_TX_BURST_IMPL_H
|
||||||
|
#define INCLUDED_GSM_PREPROCESS_TX_BURST_IMPL_H
|
||||||
|
|
||||||
|
#include <grgsm/transmitter/preprocess_tx_burst.h>
|
||||||
|
#include <grgsm/misc_utils/time_spec.h>
|
||||||
|
#include <grgsm/misc_utils/fn_time.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
class preprocess_tx_burst_impl : public preprocess_tx_burst
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void process_burst(pmt::pmt_t burst);
|
||||||
|
|
||||||
|
public:
|
||||||
|
preprocess_tx_burst_impl();
|
||||||
|
~preprocess_tx_burst_impl();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GSM_PREPROCESS_TX_BURST_IMPL_H */
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
/* -*- c++ -*- */
|
||||||
|
/* @file
|
||||||
|
* @author Piotr Krysik <ptrkrysik@gmail.com>
|
||||||
|
* @author Vadim Yanitskiy <axilirator@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 "txtime_setter_impl.h"
|
||||||
|
|
||||||
|
#define UNKNOWN_FN 0xffffffff
|
||||||
|
#define MAX_EARLY_TIME_DIFF 10.0
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
txtime_setter::sptr
|
||||||
|
txtime_setter::make(
|
||||||
|
uint32_t init_fn, uint64_t init_time_secs,
|
||||||
|
double init_time_fracs, uint64_t time_hint_secs,
|
||||||
|
double time_hint_fracs, double timing_advance,
|
||||||
|
double delay_correction)
|
||||||
|
{
|
||||||
|
return gnuradio::get_initial_sptr
|
||||||
|
(new txtime_setter_impl(init_fn, init_time_secs,
|
||||||
|
init_time_fracs, time_hint_secs, time_hint_fracs,
|
||||||
|
timing_advance, delay_correction));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The private constructor
|
||||||
|
*/
|
||||||
|
txtime_setter_impl::txtime_setter_impl(
|
||||||
|
uint32_t init_fn, uint64_t init_time_secs,
|
||||||
|
double init_time_fracs, uint64_t time_hint_secs,
|
||||||
|
double time_hint_fracs, double timing_advance,
|
||||||
|
double delay_correction
|
||||||
|
) : gr::block("txtime_setter",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(0, 0, 0)),
|
||||||
|
d_time_hint(time_hint_secs,time_hint_fracs),
|
||||||
|
d_time_ref(init_time_secs,init_time_fracs),
|
||||||
|
d_delay_correction(delay_correction),
|
||||||
|
d_timing_advance(timing_advance),
|
||||||
|
d_fn_ref(init_fn),
|
||||||
|
d_ts_ref(0)
|
||||||
|
{
|
||||||
|
// Register I/O ports
|
||||||
|
message_port_register_in(pmt::mp("fn_time"));
|
||||||
|
message_port_register_in(pmt::mp("bursts_in"));
|
||||||
|
message_port_register_out(pmt::mp("bursts_out"));
|
||||||
|
|
||||||
|
// Bind message handlers
|
||||||
|
set_msg_handler(pmt::mp("fn_time"),
|
||||||
|
boost::bind(&txtime_setter_impl::process_fn_time_reference,
|
||||||
|
this, _1));
|
||||||
|
set_msg_handler(pmt::mp("bursts_in"),
|
||||||
|
boost::bind(&txtime_setter_impl::process_txtime_of_burst,
|
||||||
|
this, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Our virtual destructor.
|
||||||
|
*/
|
||||||
|
txtime_setter_impl::~txtime_setter_impl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void txtime_setter_impl::process_fn_time_reference(pmt::pmt_t msg)
|
||||||
|
{
|
||||||
|
pmt::pmt_t not_found = pmt::intern("not_found");
|
||||||
|
pmt::pmt_t fn_time, time_hint;
|
||||||
|
|
||||||
|
fn_time = pmt::dict_ref(msg,
|
||||||
|
pmt::intern("fn_time"), not_found);
|
||||||
|
time_hint = pmt::dict_ref(msg,
|
||||||
|
pmt::intern("fn_time"), not_found);
|
||||||
|
|
||||||
|
if (fn_time != not_found) {
|
||||||
|
uint32_t fn_ref = static_cast<uint32_t>
|
||||||
|
(pmt::to_uint64(pmt::car(pmt::car(fn_time))));
|
||||||
|
uint32_t ts = static_cast<uint32_t>
|
||||||
|
(pmt::to_uint64(pmt::cdr(pmt::car(fn_time))));
|
||||||
|
uint64_t time_secs = pmt::to_uint64(
|
||||||
|
pmt::car(pmt::cdr(fn_time)));
|
||||||
|
double time_fracs = pmt::to_double(
|
||||||
|
pmt::cdr(pmt::cdr(fn_time)));
|
||||||
|
|
||||||
|
set_fn_time_reference(fn_ref, ts, time_secs, time_fracs);
|
||||||
|
} else if (time_hint != not_found) {
|
||||||
|
set_time_hint(pmt::to_uint64(pmt::car(fn_time)),
|
||||||
|
pmt::to_double(pmt::cdr(fn_time)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void txtime_setter_impl::process_txtime_of_burst(pmt::pmt_t msg_in)
|
||||||
|
{
|
||||||
|
if (d_fn_ref != UNKNOWN_FN)
|
||||||
|
{
|
||||||
|
pmt::pmt_t blob = pmt::cdr(msg_in);
|
||||||
|
|
||||||
|
// Extract GSMTAP header from message
|
||||||
|
gsmtap_hdr *header = (gsmtap_hdr *) pmt::blob_data(blob);
|
||||||
|
uint32_t frame_nr = be32toh(header->frame_number);
|
||||||
|
uint32_t ts_num = header->timeslot;
|
||||||
|
|
||||||
|
time_format txtime = fn_time_delta_cpp(d_fn_ref, d_time_ref,
|
||||||
|
frame_nr, d_time_hint, ts_num, d_ts_ref);
|
||||||
|
|
||||||
|
time_spec_t txtime_spec = time_spec_t(txtime.first, txtime.second);
|
||||||
|
txtime_spec -= d_delay_correction;
|
||||||
|
txtime_spec -= d_timing_advance;
|
||||||
|
|
||||||
|
time_spec_t current_time_estimate = time_spec_t(d_time_hint.first, d_time_hint.second);
|
||||||
|
|
||||||
|
if (txtime_spec <= current_time_estimate) { // Drop too late bursts
|
||||||
|
std::cout << "lB" << std::flush;
|
||||||
|
} else if (txtime_spec > current_time_estimate + MAX_EARLY_TIME_DIFF) { // Drop too early bursts
|
||||||
|
std::cout << "eB" << std::flush; //TODO: too early condition might happen when changing BTSes.
|
||||||
|
//Wrong fn_time is applied to new or old bursts in such situation.
|
||||||
|
//This solution is not perfect as MS might be blocked upto
|
||||||
|
//MAX_EARLY_TIME_DIFF seconds.
|
||||||
|
//Better solution would be to indentify fn_time and burst coming
|
||||||
|
//from given BTS (i.e. based on ARFCN) and dropping bursts for which
|
||||||
|
//the bts_id doesn't match with bts_id of fn_time.
|
||||||
|
} else { //process bursts that are in the right time-frame
|
||||||
|
pmt::pmt_t tags_dict = pmt::dict_add(
|
||||||
|
pmt::make_dict(),
|
||||||
|
pmt::intern("tx_time"),
|
||||||
|
pmt::make_tuple(
|
||||||
|
pmt::from_uint64(txtime_spec.get_full_secs()),
|
||||||
|
pmt::from_double(txtime_spec.get_frac_secs()))
|
||||||
|
);
|
||||||
|
|
||||||
|
tags_dict = pmt::dict_add(tags_dict,
|
||||||
|
pmt::intern("fn"), pmt::from_uint64(frame_nr));
|
||||||
|
tags_dict = pmt::dict_add(tags_dict,
|
||||||
|
pmt::intern("ts"), pmt::from_uint64(ts_num));
|
||||||
|
|
||||||
|
// Send a message to the output
|
||||||
|
pmt::pmt_t msg_out = pmt::cons(tags_dict, pmt::cdr(msg_in));
|
||||||
|
message_port_pub(pmt::mp("bursts_out"), msg_out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void txtime_setter_impl::set_fn_time_reference(
|
||||||
|
uint32_t fn, uint32_t ts, uint64_t time_secs,
|
||||||
|
double time_fracs)
|
||||||
|
{
|
||||||
|
d_fn_ref = fn;
|
||||||
|
d_ts_ref = ts;
|
||||||
|
d_time_ref = std::make_pair(time_secs, time_fracs);
|
||||||
|
set_time_hint(time_secs, time_fracs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void txtime_setter_impl::set_time_hint(
|
||||||
|
uint64_t time_hint_secs, double time_hint_fracs)
|
||||||
|
{
|
||||||
|
d_time_hint = std::make_pair(time_hint_secs, time_hint_fracs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void txtime_setter_impl::set_delay_correction(double delay_correction)
|
||||||
|
{
|
||||||
|
d_delay_correction = delay_correction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void txtime_setter_impl::set_timing_advance(double timing_advance)
|
||||||
|
{
|
||||||
|
d_timing_advance = timing_advance;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace gsm */
|
||||||
|
} /* namespace gr */
|
|
@ -0,0 +1,64 @@
|
||||||
|
/* -*- 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_GSM_TXTIME_SETTER_IMPL_H
|
||||||
|
#define INCLUDED_GSM_TXTIME_SETTER_IMPL_H
|
||||||
|
|
||||||
|
#include <grgsm/transmitter/txtime_setter.h>
|
||||||
|
#include <grgsm/misc_utils/time_spec.h>
|
||||||
|
#include <grgsm/misc_utils/fn_time.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
class txtime_setter_impl : public txtime_setter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
uint32_t d_fn_ref;
|
||||||
|
uint32_t d_ts_ref;
|
||||||
|
time_format d_time_ref;
|
||||||
|
time_format d_time_hint;
|
||||||
|
double d_timing_advance;
|
||||||
|
double d_delay_correction;
|
||||||
|
|
||||||
|
void process_fn_time_reference(pmt::pmt_t msg);
|
||||||
|
void process_txtime_of_burst(pmt::pmt_t msg);
|
||||||
|
|
||||||
|
public:
|
||||||
|
txtime_setter_impl(uint32_t init_fn, uint64_t init_time_secs,
|
||||||
|
double init_time_fracs, uint64_t time_hint_secs,
|
||||||
|
double time_hint_fracs, double timing_advance,
|
||||||
|
double delay_correction);
|
||||||
|
~txtime_setter_impl();
|
||||||
|
|
||||||
|
// Where all the action really happens
|
||||||
|
void set_fn_time_reference(uint32_t fn, uint32_t ts,
|
||||||
|
uint64_t time_secs, double time_fracs);
|
||||||
|
void set_time_hint(uint64_t time_hint_secs, double time_hint_fracs);
|
||||||
|
void set_delay_correction(double delay_correction);
|
||||||
|
void set_timing_advance(double timing_advance);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GSM_TXTIME_SETTER_IMPL_H */
|
|
@ -31,6 +31,8 @@ endif()
|
||||||
add_subdirectory(misc_utils)
|
add_subdirectory(misc_utils)
|
||||||
add_subdirectory(receiver)
|
add_subdirectory(receiver)
|
||||||
add_subdirectory(demapping)
|
add_subdirectory(demapping)
|
||||||
|
add_subdirectory(transmitter)
|
||||||
|
add_subdirectory(trx)
|
||||||
|
|
||||||
GR_PYTHON_INSTALL(
|
GR_PYTHON_INSTALL(
|
||||||
FILES
|
FILES
|
||||||
|
@ -58,3 +60,4 @@ GR_ADD_TEST(qa_tch_f_decoder ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa
|
||||||
#GR_ADD_TEST(qa_msg_to_tag ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_msg_to_tag.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_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)
|
#GR_ADD_TEST(qa_uplink_downlink_splitter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_uplink_downlink_splitter.py)
|
||||||
|
GR_ADD_TEST(qa_txtime_setter ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_txtime_setter.py)
|
||||||
|
|
|
@ -55,7 +55,10 @@ from gsm_input import gsm_input
|
||||||
from gsm_bcch_ccch_demapper import gsm_bcch_ccch_demapper
|
from gsm_bcch_ccch_demapper import gsm_bcch_ccch_demapper
|
||||||
from gsm_bcch_ccch_sdcch4_demapper import gsm_bcch_ccch_sdcch4_demapper
|
from gsm_bcch_ccch_sdcch4_demapper import gsm_bcch_ccch_sdcch4_demapper
|
||||||
from gsm_sdcch8_demapper import gsm_sdcch8_demapper
|
from gsm_sdcch8_demapper import gsm_sdcch8_demapper
|
||||||
|
from gsm_gmsk_mod import gsm_gmsk_mod
|
||||||
|
from fn_time import *
|
||||||
|
from txtime_bursts_tagger import *
|
||||||
|
from burst_to_fn_time import *
|
||||||
import arfcn
|
import arfcn
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,5 +22,7 @@ GR_PYTHON_INSTALL(
|
||||||
arfcn.py
|
arfcn.py
|
||||||
clock_offset_corrector_tagged.py
|
clock_offset_corrector_tagged.py
|
||||||
hier_block.py
|
hier_block.py
|
||||||
fn_time.py DESTINATION ${GR_PYTHON_DIR}/grgsm
|
fn_time.py
|
||||||
|
burst_to_fn_time.py
|
||||||
|
DESTINATION ${GR_PYTHON_DIR}/grgsm
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
"""
|
||||||
|
Embedded Python Blocks:
|
||||||
|
|
||||||
|
Each this file is saved, GRC will instantiate the first class it finds to get
|
||||||
|
ports and parameters of your block. The arguments to __init__ will be the
|
||||||
|
parameters. All of them are required to have default values!
|
||||||
|
"""
|
||||||
|
import numpy as np
|
||||||
|
from gnuradio import gr
|
||||||
|
import pmt
|
||||||
|
|
||||||
|
class burst_to_fn_time(gr.basic_block):
|
||||||
|
def __init__(self): # only default arguments here
|
||||||
|
gr.basic_block.__init__(
|
||||||
|
self,
|
||||||
|
name='Burst to fn_time',
|
||||||
|
in_sig=[],
|
||||||
|
out_sig=[]
|
||||||
|
)
|
||||||
|
self.message_port_register_in(pmt.intern("bursts_in"))
|
||||||
|
self.message_port_register_out(pmt.intern("fn_time_out"))
|
||||||
|
self.set_msg_handler(pmt.intern("bursts_in"), self.convert)
|
||||||
|
|
||||||
|
def convert(self, msg):
|
||||||
|
fn_time = pmt.dict_ref(pmt.car(msg),pmt.intern("fn_time"),pmt.PMT_NIL)
|
||||||
|
fn_time_msg = pmt.dict_add(pmt.make_dict(), pmt.intern("fn_time"), fn_time)
|
||||||
|
if pmt.to_python(fn_time) is not None:
|
||||||
|
self.message_port_pub(pmt.intern("fn_time_out"), fn_time_msg)
|
|
@ -22,6 +22,7 @@
|
||||||
#
|
#
|
||||||
from math import floor, ceil
|
from math import floor, ceil
|
||||||
from random import uniform
|
from random import uniform
|
||||||
|
from grgsm import fn_time_delta_cpp
|
||||||
|
|
||||||
__hyper_frame = 26*51*2048
|
__hyper_frame = 26*51*2048
|
||||||
__symb_rate = 13.0e6/48.0
|
__symb_rate = 13.0e6/48.0
|
||||||
|
@ -37,14 +38,21 @@ __frame_period = 8*__ts_period
|
||||||
def fnmod_delta(fn1, fn2):
|
def fnmod_delta(fn1, fn2):
|
||||||
h2 = __hyper_frame/2
|
h2 = __hyper_frame/2
|
||||||
delta = (fn1%__hyper_frame)-(fn2%__hyper_frame)
|
delta = (fn1%__hyper_frame)-(fn2%__hyper_frame)
|
||||||
|
|
||||||
if delta >= h2:
|
if delta >= h2:
|
||||||
delta = delta - __hyper_frame
|
delta = delta - __hyper_frame
|
||||||
elif delta < -h2:
|
elif delta < -h2:
|
||||||
delta = delta + __hyper_frame
|
delta = delta + __hyper_frame
|
||||||
|
|
||||||
return delta
|
return delta
|
||||||
|
|
||||||
|
def fn_time_diff_delta(fn_x, fn_ref, time_diff_hint=0):
|
||||||
|
frames_diff = int(round(time_diff_hint/__frame_period))
|
||||||
|
fn_ref_hint = (fn_ref + frames_diff)
|
||||||
|
fn_delta = fnmod_delta(fn_x,fn_ref_hint)+frames_diff
|
||||||
|
|
||||||
|
return fn_delta
|
||||||
|
|
||||||
#fn_time_delta computes difference between reference frame number and a second frame number. It also computes timestamp of the second frame number. The full list of parameters is following:
|
#fn_time_delta computes difference between reference frame number and a second frame number. It also computes timestamp of the second frame number. The full list of parameters is following:
|
||||||
#* fn_ref - reference frame number modulo __hyper_frame
|
#* fn_ref - reference frame number modulo __hyper_frame
|
||||||
#* time_ref - precise timestamp of the first sample in the frame fn_ref
|
#* time_ref - precise timestamp of the first sample in the frame fn_ref
|
||||||
|
@ -52,33 +60,33 @@ def fnmod_delta(fn1, fn2):
|
||||||
#* time_hint - coarse time for fn_x that is used as a hint to avoid ambiguities caused by modulo operation applied to frame numbers. The correct are values from range <time2_precise-__hiperframe/2, time2_precise+__hiperframe/2> (where time2_precise is exact time of the first sample in frame fn_x)
|
#* time_hint - coarse time for fn_x that is used as a hint to avoid ambiguities caused by modulo operation applied to frame numbers. The correct are values from range <time2_precise-__hiperframe/2, time2_precise+__hiperframe/2> (where time2_precise is exact time of the first sample in frame fn_x)
|
||||||
#* ts_num - number of timeslot in the frame
|
#* ts_num - number of timeslot in the frame
|
||||||
|
|
||||||
def fn_time_delta(fn_ref, time_ref, fn_x, time_hint=None, ts_num=None):
|
def fn_time_delta(fn_ref, time_ref, fn_x, time_hint=None, ts_num=0, ts_ref=0):
|
||||||
if time_hint is None:
|
if time_hint is None:
|
||||||
time_hint = time_ref
|
time_hint = time_ref
|
||||||
|
|
||||||
if ts_num is None:
|
time_diff_hint = time_hint-time_ref
|
||||||
ts_num = 0
|
fn_delta = fn_time_diff_delta(fn_x,fn_ref, time_diff_hint)
|
||||||
|
time_x_precise = fn_delta*__frame_period+time_ref+(ts_num-ts_ref)*__ts_period
|
||||||
time_diff = time_hint-time_ref
|
|
||||||
frames_diff = int(round(time_diff/__frame_period))
|
|
||||||
fn_ref = (fn_ref + frames_diff)
|
|
||||||
fn_delta = fnmod_delta(fn_x,fn_ref)+frames_diff
|
|
||||||
time2_precise = fn_delta*__frame_period+time_ref+ts_num*__ts_period
|
|
||||||
|
|
||||||
return fn_delta, time2_precise
|
return fn_delta, time_x_precise
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
fn1 = 10000
|
fn1 = 10000
|
||||||
time1 = 10
|
ts_ref = 4
|
||||||
for fn2 in xrange(__hyper_frame/2+fn1-10,__hyper_frame/2*10+fn1+10,10):
|
time1 = 10.5
|
||||||
time2 = time1 + (fn2-fn1)*__frame_period
|
for fn2 in xrange(__hyper_frame/2+fn1-10,__hyper_frame/2*10+fn1+100,10):
|
||||||
|
ts_x = int(uniform(0,8))
|
||||||
|
time2 = time1 + (fn2-fn1)*__frame_period + (ts_x-ts_ref)*__ts_period
|
||||||
error = uniform(-6200,6200)
|
error = uniform(-6200,6200)
|
||||||
time2_err = time2+error
|
time2_err = time2+error
|
||||||
fn_delta, time2_precise = fn_time_delta(fn1, time1, fn2, time2_err)
|
fn_delta, time2_precise = fn_time_delta(fn1, time1, fn2, time2_err, ts_x, ts_ref)
|
||||||
|
time2_precise_cpp = fn_time_delta_cpp(fn1, (int(time1),time1-int(time1)), fn2, (int(time2_err),time2_err-int(time2_err)), ts_x, ts_ref)
|
||||||
if fn_delta != fn2-fn1:
|
if fn_delta != fn2-fn1:
|
||||||
print "dupa:", fn2, error#, 'fn_delta:'+str(fn_delta), time2, error, frames_diff_h4, (time2-time1)/(__hyper_frame*__frame_period), time_diff_h4_prev, time_diff
|
print "bad fn:", fn2, error#, 'fn_delta:'+str(fn_delta), time2, error, frames_diff_h4, (time2-time1)/(__hyper_frame*__frame_period), time_diff_hint_h4_prev, time_diff_hint
|
||||||
time_diff = time2 - time2_precise
|
# time_diff_hint = time2 - time2_precise
|
||||||
if time_diff > 0.1:
|
time_diff_hint = time2_precise_cpp[0]+time2_precise_cpp[1] - time2_precise
|
||||||
print "dupa"
|
|
||||||
|
|
||||||
|
if abs(time_diff_hint) > 0.0001:
|
||||||
|
print "time2_precise_cpp",time2_precise_cpp," time2_precise",time2_precise," time_ref",time1," time_hint",time2_err
|
||||||
|
print ""
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# @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.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
from gnuradio import gr, gr_unittest
|
||||||
|
from gnuradio import blocks
|
||||||
|
from txtime_bursts_tagger import txtime_bursts_tagger
|
||||||
|
#from transmitter.txtime_bursts_tagger import txtime_bursts_tagger
|
||||||
|
from pmt import *
|
||||||
|
|
||||||
|
def make_time_hint_msg(time_hint):
|
||||||
|
return cons( dict_add(make_dict(), intern("time_hint"), from_double(time_hint)),PMT_NIL)
|
||||||
|
|
||||||
|
def make_fn_time_msg(fn_ref, time_ref):
|
||||||
|
return cons( dict_add(make_dict(), intern("fn_time"), cons(from_uint64(fn_ref), from_double(time_ref))),PMT_NIL)
|
||||||
|
|
||||||
|
class qa_txtime_bursts_tagger (gr_unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp (self):
|
||||||
|
self.tb = gr.top_block ()
|
||||||
|
|
||||||
|
def tearDown (self):
|
||||||
|
self.tb = None
|
||||||
|
|
||||||
|
def test_001_t (self):
|
||||||
|
tb = self.tb
|
||||||
|
time_ref = 0
|
||||||
|
fn_ref = 0
|
||||||
|
dut = txtime_bursts_tagger(fn_ref, time_ref)
|
||||||
|
|
||||||
|
framenumbers_input = [1259192, 1076346, 1076242, 235879, 1259218]
|
||||||
|
timeslots_input = [6, 3, 4, 3, 5]
|
||||||
|
bursts_input = [
|
||||||
|
"0001100001000111100111101111100101000100101011000010011110011101001111101100010100111111100000110100011111101011101100100111110011000100010001010000",
|
||||||
|
"0001000101000000001001111110000110010110110111110111101000001101001111101100010100111111001110001001110101110001010001000111011010010001011011000000",
|
||||||
|
"0001001101101101000111001000101011001101001110110001001100111101001111101100010100111111111001001010011010011111010010010101011001001011011100110000",
|
||||||
|
"0000010010100000001001101010100001011100010001101100111111101101001111101100010100111111101101001110100010101110010110101111100010010000110010110000",
|
||||||
|
]
|
||||||
|
|
||||||
|
src = grgsm.burst_source(framenumbers_input, timeslots_input, bursts_input)
|
||||||
|
sink = grgsm.burst_sink()
|
||||||
|
|
||||||
|
self.tb.msg_connect(src, "out", dut, "bursts")
|
||||||
|
self.tb.msg_connect(dut, "bursts", sink, "in")
|
||||||
|
|
||||||
|
tb.start()
|
||||||
|
tb.wait()
|
||||||
|
print "Dupa"
|
||||||
|
print sink
|
||||||
|
|
||||||
|
|
||||||
|
# msg1 = make_msg(1,"lol1")
|
||||||
|
# msg2 = make_msg(1,"lol2")
|
||||||
|
# msg3 = make_msg(2,"lol1")
|
||||||
|
# msg4 = make_msg(2,"lol1")
|
||||||
|
#
|
||||||
|
# port = intern("msgs")
|
||||||
|
|
||||||
|
# tb.msg_connect(g,"msgs",dbg,"store")
|
||||||
|
# #tb.msg_connect(g,"msgs",dbg,"print_pdu")
|
||||||
|
|
||||||
|
# tb.start()
|
||||||
|
|
||||||
|
# g.to_basic_block()._post(port, msg1)
|
||||||
|
# g.to_basic_block()._post(port, msg3)
|
||||||
|
# g.to_basic_block()._post(port, msg2)
|
||||||
|
# g.to_basic_block()._post(port, msg4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# while dbg.num_messages() < 4:
|
||||||
|
# time.sleep(0.1)
|
||||||
|
|
||||||
|
# tb.stop()
|
||||||
|
# tb.wait()
|
||||||
|
# print dbg.get_message(0)
|
||||||
|
# print get_id(dbg.get_message(0))
|
||||||
|
#
|
||||||
|
# self.assertEqual(get_id(dbg.get_message(0)),1)
|
||||||
|
# self.assertEqual(get_id(dbg.get_message(1)),1)
|
||||||
|
# self.assertEqual(get_id(dbg.get_message(2)),2)
|
||||||
|
# self.assertEqual(get_id(dbg.get_message(3)),2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
gr_unittest.run(qa_txtime_bursts_tagger, "qa_txtime_bursts_tagger.xml")
|
|
@ -0,0 +1,43 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# @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.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
from gnuradio import gr, gr_unittest
|
||||||
|
from gnuradio import blocks
|
||||||
|
import grgsm_swig as grgsm
|
||||||
|
|
||||||
|
class qa_txtime_setter (gr_unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp (self):
|
||||||
|
self.tb = gr.top_block ()
|
||||||
|
|
||||||
|
def tearDown (self):
|
||||||
|
self.tb = None
|
||||||
|
|
||||||
|
def test_001_t (self):
|
||||||
|
# set up fg
|
||||||
|
self.tb.run ()
|
||||||
|
# check data
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
gr_unittest.run(qa_txtime_setter, "qa_txtime_setter.xml")
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright 2011,2012 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is part of GNU Radio
|
||||||
|
#
|
||||||
|
# GNU Radio 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.
|
||||||
|
#
|
||||||
|
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
GR_PYTHON_INSTALL(
|
||||||
|
FILES
|
||||||
|
txtime_bursts_tagger.py
|
||||||
|
gsm_gmsk_mod.py DESTINATION ${GR_PYTHON_DIR}/grgsm
|
||||||
|
)
|
|
@ -0,0 +1,69 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##################################################
|
||||||
|
# GNU Radio Python Flow Graph
|
||||||
|
# Title: GMSK Modulator for GSM
|
||||||
|
# Author: Piotr Krysik
|
||||||
|
# Description: GMSK Modulator for GSM
|
||||||
|
# Generated: Wed Sep 20 21:12:04 2017
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
from gnuradio import blocks
|
||||||
|
from gnuradio import digital
|
||||||
|
from gnuradio import gr
|
||||||
|
from gnuradio.analog import cpm
|
||||||
|
from gnuradio.filter import firdes
|
||||||
|
import grgsm
|
||||||
|
|
||||||
|
class gsm_gmsk_mod(grgsm.hier_block):
|
||||||
|
|
||||||
|
def __init__(self, BT=4, pulse_duration=4, sps=4):
|
||||||
|
gr.hier_block2.__init__(
|
||||||
|
self, "GMSK Modulator for GSM",
|
||||||
|
gr.io_signature(1, 1, gr.sizeof_char*1),
|
||||||
|
gr.io_signature(1, 1, gr.sizeof_gr_complex*1),
|
||||||
|
)
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Parameters
|
||||||
|
##################################################
|
||||||
|
self.BT = BT
|
||||||
|
self.pulse_duration = pulse_duration
|
||||||
|
self.sps = sps
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Blocks
|
||||||
|
##################################################
|
||||||
|
self.digital_gmskmod_bc_0 = digital.gmskmod_bc(sps, pulse_duration, BT)
|
||||||
|
self.digital_diff_decoder_bb_0 = digital.diff_decoder_bb(2)
|
||||||
|
self.digital_chunks_to_symbols_xx_0 = digital.chunks_to_symbols_bf(([1,-1]), 1)
|
||||||
|
self.blocks_tagged_stream_multiply_length_0 = blocks.tagged_stream_multiply_length(gr.sizeof_gr_complex*1, "packet_len", sps)
|
||||||
|
self.blocks_float_to_char_0 = blocks.float_to_char(1, 1)
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Connections
|
||||||
|
##################################################
|
||||||
|
self.connect((self.blocks_float_to_char_0, 0), (self.digital_gmskmod_bc_0, 0))
|
||||||
|
self.connect((self.blocks_tagged_stream_multiply_length_0, 0), (self, 0))
|
||||||
|
self.connect((self.digital_chunks_to_symbols_xx_0, 0), (self.blocks_float_to_char_0, 0))
|
||||||
|
self.connect((self.digital_diff_decoder_bb_0, 0), (self.digital_chunks_to_symbols_xx_0, 0))
|
||||||
|
self.connect((self.digital_gmskmod_bc_0, 0), (self.blocks_tagged_stream_multiply_length_0, 0))
|
||||||
|
self.connect((self, 0), (self.digital_diff_decoder_bb_0, 0))
|
||||||
|
|
||||||
|
def get_BT(self):
|
||||||
|
return self.BT
|
||||||
|
|
||||||
|
def set_BT(self, BT):
|
||||||
|
self.BT = BT
|
||||||
|
|
||||||
|
def get_pulse_duration(self):
|
||||||
|
return self.pulse_duration
|
||||||
|
|
||||||
|
def set_pulse_duration(self, pulse_duration):
|
||||||
|
self.pulse_duration = pulse_duration
|
||||||
|
|
||||||
|
def get_sps(self):
|
||||||
|
return self.sps
|
||||||
|
|
||||||
|
def set_sps(self, sps):
|
||||||
|
self.sps = sps
|
||||||
|
self.blocks_tagged_stream_multiply_length_0.set_scalar(self.sps)
|
|
@ -0,0 +1,97 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# @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.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
from gnuradio import gr
|
||||||
|
from fn_time import fn_time_delta
|
||||||
|
import pmt
|
||||||
|
import numpy
|
||||||
|
|
||||||
|
class txtime_bursts_tagger(gr.basic_block):
|
||||||
|
"""
|
||||||
|
A block that adds txtime metadata to a burst
|
||||||
|
"""
|
||||||
|
def __init__(self, init_fn=0, init_time=0, time_hint=None, timing_advance=0, delay_correction=0):
|
||||||
|
gr.basic_block.__init__(self,
|
||||||
|
name="txtime_bursts_tagger",
|
||||||
|
in_sig=[],
|
||||||
|
out_sig=[])
|
||||||
|
self.set_fn_time_reference(init_fn, init_time)
|
||||||
|
if time_hint is not None:
|
||||||
|
self.set_time_hint(time_hint)
|
||||||
|
|
||||||
|
self.timing_advance = timing_advance
|
||||||
|
self.delay_correction = delay_correction
|
||||||
|
|
||||||
|
self.message_port_register_in(pmt.intern("fn_time"))
|
||||||
|
self.message_port_register_in(pmt.intern("bursts"))
|
||||||
|
self.message_port_register_out(pmt.intern("bursts"))
|
||||||
|
|
||||||
|
self.set_msg_handler(pmt.intern("fn_time"), self.process_fn_time_reference)
|
||||||
|
self.set_msg_handler(pmt.intern("bursts"), self.process_txtime_of_burst)
|
||||||
|
|
||||||
|
def process_fn_time_reference(self, msg):
|
||||||
|
time_hint = pmt.to_python(pmt.dict_ref(msg, pmt.intern("time_hint"), pmt.PMT_NIL))
|
||||||
|
fn_time = pmt.to_python(pmt.dict_ref(msg, pmt.intern("fn_time"), pmt.PMT_NIL))
|
||||||
|
|
||||||
|
if time_hint is not None:
|
||||||
|
self.time_hint = time_hint
|
||||||
|
elif fn_time is not None:
|
||||||
|
self.fn_ref = fn_time[0][0]
|
||||||
|
self.ts = fn_time[0][1]
|
||||||
|
full = fn_time[1][0]
|
||||||
|
frac = fn_time[1][1]
|
||||||
|
|
||||||
|
self.time_ref = full+frac
|
||||||
|
self.time_hint = self.time_ref
|
||||||
|
|
||||||
|
def process_txtime_of_burst(self, msg):
|
||||||
|
burst_with_header = pmt.to_python(pmt.cdr(msg))
|
||||||
|
fn = burst_with_header[11]+burst_with_header[10]*2**8+burst_with_header[9]*2**16+burst_with_header[8]*2**24
|
||||||
|
ts_num = burst_with_header[3]
|
||||||
|
if self.fn_ref is not None:
|
||||||
|
fn_delta, txtime = fn_time_delta(self.fn_ref, self.time_ref, fn, self.time_hint, ts_num)
|
||||||
|
txtime_corrected = txtime - self.delay_correction
|
||||||
|
txtime_final = txtime_corrected - self.timing_advance
|
||||||
|
|
||||||
|
txtime_secs = int(txtime_final)
|
||||||
|
txtime_fracs = txtime_final-int(txtime_final)
|
||||||
|
#print "txtime_secs",txtime_secs,"txtime_fracs",txtime_fracs
|
||||||
|
tags_dict = pmt.dict_add(pmt.make_dict(), pmt.intern("tx_time"), pmt.make_tuple(pmt.from_uint64(txtime_secs),pmt.from_double(txtime_fracs)))
|
||||||
|
tags_dict = pmt.dict_add(tags_dict, pmt.intern("fn"), pmt.from_uint64(fn))
|
||||||
|
new_msg = pmt.cons(tags_dict, pmt.cdr(msg))
|
||||||
|
self.message_port_pub(pmt.intern("bursts"), new_msg)
|
||||||
|
|
||||||
|
def set_fn_time_reference(self, init_fn, init_time):
|
||||||
|
self.fn_ref = init_fn
|
||||||
|
self.time_ref = init_time
|
||||||
|
self.set_time_hint(init_time)
|
||||||
|
|
||||||
|
def set_time_hint(self, time_hint):
|
||||||
|
self.time_hint = time_hint
|
||||||
|
|
||||||
|
def set_delay_correction(delay_correction):
|
||||||
|
self.delay_correction = delay_correction
|
||||||
|
|
||||||
|
def set_timing_advance(timing_advance):
|
||||||
|
self.timing_advance = timing_advance
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Copyright 2011,2012 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is part of GNU Radio
|
||||||
|
#
|
||||||
|
# GNU Radio 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.
|
||||||
|
#
|
||||||
|
# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
GR_PYTHON_INSTALL(
|
||||||
|
FILES
|
||||||
|
__init__.py
|
||||||
|
udp_link.py
|
||||||
|
ctrl_if.py
|
||||||
|
ctrl_if_bb.py
|
||||||
|
fake_pm.py
|
||||||
|
radio_if.py
|
||||||
|
radio_if_grc.py
|
||||||
|
change_sign_of_dict_elements.py
|
||||||
|
DESTINATION ${GR_PYTHON_DIR}/grgsm/trx
|
||||||
|
)
|
|
@ -0,0 +1,29 @@
|
||||||
|
#
|
||||||
|
# Copyright 2008,2009 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This application 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.
|
||||||
|
#
|
||||||
|
# This application 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
#
|
||||||
|
|
||||||
|
'''
|
||||||
|
This is a set of helper classes for the grgsm_trx application.
|
||||||
|
'''
|
||||||
|
|
||||||
|
from udp_link import udp_link
|
||||||
|
from ctrl_if import ctrl_if
|
||||||
|
from ctrl_if_bb import ctrl_if_bb
|
||||||
|
from fake_pm import fake_pm
|
||||||
|
from radio_if_grc import radio_if_grc
|
||||||
|
from radio_if import radio_if
|
||||||
|
from change_sign_of_dict_elements import change_sign_of_dict_elements
|
|
@ -0,0 +1,30 @@
|
||||||
|
"""
|
||||||
|
Embedded Python Blocks:
|
||||||
|
|
||||||
|
Each this file is saved, GRC will instantiate the first class it finds to get
|
||||||
|
ports and parameters of your block. The arguments to __init__ will be the
|
||||||
|
parameters. All of them are required to have default values!
|
||||||
|
"""
|
||||||
|
|
||||||
|
from gnuradio import gr
|
||||||
|
from pmt import *
|
||||||
|
|
||||||
|
class change_sign_of_dict_elements(gr.basic_block):
|
||||||
|
def __init__(self): # only default arguments here
|
||||||
|
gr.basic_block.__init__(
|
||||||
|
self,
|
||||||
|
name='Change sign of elts in dict',
|
||||||
|
in_sig=[],
|
||||||
|
out_sig=[]
|
||||||
|
)
|
||||||
|
self.message_port_register_in(intern("dict_in"))
|
||||||
|
self.message_port_register_out(intern("dict_out"))
|
||||||
|
self.set_msg_handler(intern("dict_in"), self.change_sign)
|
||||||
|
|
||||||
|
def change_sign(self, msg):
|
||||||
|
if is_dict(msg):
|
||||||
|
d = to_python(msg)
|
||||||
|
#print d
|
||||||
|
for key, value in d.items():
|
||||||
|
d[key] *= -1
|
||||||
|
self.message_port_pub(intern("dict_out"), to_pmt(d))
|
|
@ -0,0 +1,82 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# GR-GSM based transceiver
|
||||||
|
# CTRL interface implementation
|
||||||
|
#
|
||||||
|
# (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>
|
||||||
|
#
|
||||||
|
# All Rights Reserved
|
||||||
|
#
|
||||||
|
# This program 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 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
from grgsm.trx import udp_link
|
||||||
|
|
||||||
|
class ctrl_if(udp_link):
|
||||||
|
def handle_rx(self, data):
|
||||||
|
if self.verify_req(data):
|
||||||
|
request = self.prepare_req(data)
|
||||||
|
rc = self.parse_cmd(request)
|
||||||
|
|
||||||
|
if type(rc) is tuple:
|
||||||
|
self.send_response(request, rc[0], rc[1])
|
||||||
|
else:
|
||||||
|
self.send_response(request, rc)
|
||||||
|
else:
|
||||||
|
print("[!] Wrong data on CTRL interface")
|
||||||
|
|
||||||
|
def verify_req(self, data):
|
||||||
|
# Verify command signature
|
||||||
|
return data.startswith("CMD")
|
||||||
|
|
||||||
|
def prepare_req(self, data):
|
||||||
|
# Strip signature, paddings and \0
|
||||||
|
request = data[4:].strip().strip("\0")
|
||||||
|
# Split into a command and arguments
|
||||||
|
request = request.split(" ")
|
||||||
|
# Now we have something like ["TXTUNE", "941600"]
|
||||||
|
return request
|
||||||
|
|
||||||
|
def verify_cmd(self, request, cmd, argc):
|
||||||
|
# Check if requested command matches
|
||||||
|
if request[0] != cmd:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# And has enough arguments
|
||||||
|
if len(request) - 1 != argc:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Check if all arguments are numeric
|
||||||
|
for v in request[1:]:
|
||||||
|
if not v.isdigit():
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def send_response(self, request, response_code, params = None):
|
||||||
|
# Include status code, for example ["TXTUNE", "0", "941600"]
|
||||||
|
request.insert(1, str(response_code))
|
||||||
|
|
||||||
|
# Optionally append command specific parameters
|
||||||
|
if params is not None:
|
||||||
|
request += params
|
||||||
|
|
||||||
|
# Add the response signature, and join back to string
|
||||||
|
response = "RSP " + " ".join(request) + "\0"
|
||||||
|
# Now we have something like "RSP TXTUNE 0 941600"
|
||||||
|
self.send(response)
|
||||||
|
|
||||||
|
def parse_cmd(self, request):
|
||||||
|
raise NotImplementedError
|
|
@ -0,0 +1,155 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# GR-GSM based transceiver
|
||||||
|
# CTRL interface for OsmocomBB
|
||||||
|
#
|
||||||
|
# (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>
|
||||||
|
#
|
||||||
|
# All Rights Reserved
|
||||||
|
#
|
||||||
|
# This program 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 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
import grgsm
|
||||||
|
from ctrl_if import ctrl_if
|
||||||
|
|
||||||
|
class ctrl_if_bb(ctrl_if):
|
||||||
|
def __init__(self, remote_addr, remote_port, bind_port, tb, pm):
|
||||||
|
print("[i] Init CTRL interface")
|
||||||
|
ctrl_if.__init__(self, remote_addr, remote_port, bind_port)
|
||||||
|
|
||||||
|
# Set link to the follow graph (top block)
|
||||||
|
self.tb = tb
|
||||||
|
# Power measurement
|
||||||
|
self.pm = pm
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
print("[i] Shutdown CTRL interface")
|
||||||
|
ctrl_if.shutdown(self)
|
||||||
|
|
||||||
|
def parse_cmd(self, request):
|
||||||
|
# Power control
|
||||||
|
if self.verify_cmd(request, "POWERON", 0):
|
||||||
|
print("[i] Recv POWERON CMD")
|
||||||
|
|
||||||
|
# Ensure transceiver isn't working
|
||||||
|
if self.tb.trx_started:
|
||||||
|
print("[!] Transceiver already started")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
print("[i] Starting transceiver...")
|
||||||
|
self.tb.trx_started = True
|
||||||
|
self.tb.start()
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
elif self.verify_cmd(request, "POWEROFF", 0):
|
||||||
|
print("[i] Recv POWEROFF cmd")
|
||||||
|
|
||||||
|
# TODO: flush all buffers between blocks
|
||||||
|
if self.tb.trx_started:
|
||||||
|
print("[i] Stopping transceiver...")
|
||||||
|
self.tb.trx_started = False
|
||||||
|
self.tb.stop()
|
||||||
|
self.tb.wait()
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Gain control
|
||||||
|
elif self.verify_cmd(request, "SETRXGAIN", 1):
|
||||||
|
print("[i] Recv SETRXGAIN cmd")
|
||||||
|
|
||||||
|
# TODO: check gain value
|
||||||
|
gain = int(request[1])
|
||||||
|
self.tb.set_rx_gain(gain)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
elif self.verify_cmd(request, "SETTXGAIN", 1):
|
||||||
|
print("[i] Recv SETTXGAIN cmd")
|
||||||
|
|
||||||
|
# TODO: check gain value
|
||||||
|
gain = int(request[1])
|
||||||
|
self.tb.set_tx_gain(gain)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Tuning Control
|
||||||
|
elif self.verify_cmd(request, "RXTUNE", 1):
|
||||||
|
print("[i] Recv RXTUNE cmd")
|
||||||
|
|
||||||
|
# TODO: check freq range
|
||||||
|
freq = int(request[1]) * 1000
|
||||||
|
self.tb.set_rx_freq(freq)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
elif self.verify_cmd(request, "TXTUNE", 1):
|
||||||
|
print("[i] Recv TXTUNE cmd")
|
||||||
|
|
||||||
|
# TODO: check freq range
|
||||||
|
freq = int(request[1]) * 1000
|
||||||
|
self.tb.set_tx_freq(freq)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Timeslot management
|
||||||
|
elif self.verify_cmd(request, "SETSLOT", 2):
|
||||||
|
print("[i] Recv SETSLOT cmd")
|
||||||
|
|
||||||
|
# Obtain TS index
|
||||||
|
tn = int(request[1])
|
||||||
|
if tn not in range(0, 8):
|
||||||
|
print("[!] TS index should be in range: 0..7")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Ignore timeslot type for now
|
||||||
|
config = int(request[2])
|
||||||
|
print("[i] Configure timeslot filter to: %s"
|
||||||
|
% ("drop all" if config == 0 else "TS %d" % tn))
|
||||||
|
|
||||||
|
if config == 0:
|
||||||
|
# Value 0 means 'drop all'
|
||||||
|
self.tb.ts_filter.set_policy(
|
||||||
|
grgsm.FILTER_POLICY_DROP_ALL)
|
||||||
|
else:
|
||||||
|
self.tb.ts_filter.set_policy(
|
||||||
|
grgsm.FILTER_POLICY_DEFAULT)
|
||||||
|
self.tb.ts_filter.set_tn(tn)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Power measurement
|
||||||
|
elif self.verify_cmd(request, "MEASURE", 1):
|
||||||
|
print("[i] Recv MEASURE cmd")
|
||||||
|
|
||||||
|
# TODO: check freq range
|
||||||
|
meas_freq = int(request[1]) * 1000
|
||||||
|
|
||||||
|
# HACK: send fake low power values
|
||||||
|
# until actual power measurement is implemented
|
||||||
|
meas_dbm = str(self.pm.measure(meas_freq))
|
||||||
|
|
||||||
|
return (0, [meas_dbm])
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
elif self.verify_cmd(request, "ECHO", 0):
|
||||||
|
print("[i] Recv ECHO cmd")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Wrong / unknown command
|
||||||
|
else:
|
||||||
|
print("[!] Wrong request on CTRL interface")
|
||||||
|
return -1
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Virtual Um-interface (fake transceiver)
|
||||||
|
# Power measurement emulation for BB
|
||||||
|
#
|
||||||
|
# (C) 2017 by Vadim Yanitskiy <axilirator@gmail.com>
|
||||||
|
#
|
||||||
|
# All Rights Reserved
|
||||||
|
#
|
||||||
|
# This program 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 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
from random import randint
|
||||||
|
|
||||||
|
class fake_pm:
|
||||||
|
# Freq. list for good power level
|
||||||
|
bts_list = []
|
||||||
|
|
||||||
|
def __init__(self, noise_min, noise_max, bts_min, bts_max):
|
||||||
|
# Save power level ranges
|
||||||
|
self.noise_min = noise_min
|
||||||
|
self.noise_max = noise_max
|
||||||
|
self.bts_min = bts_min
|
||||||
|
self.bts_max = bts_max
|
||||||
|
|
||||||
|
def measure(self, bts):
|
||||||
|
if bts in self.bts_list:
|
||||||
|
return randint(self.bts_min, self.bts_max)
|
||||||
|
else:
|
||||||
|
return randint(self.noise_min, self.noise_max)
|
||||||
|
|
||||||
|
def update_bts_list(self, new_list):
|
||||||
|
self.bts_list = new_list
|
||||||
|
|
||||||
|
def add_bts_list(self, add_list):
|
||||||
|
self.bts_list += add_list
|
||||||
|
|
||||||
|
def del_bts_list(self, del_list):
|
||||||
|
for item in del_list:
|
||||||
|
if item in self.bts_list:
|
||||||
|
self.bts_list.remove(item)
|
|
@ -0,0 +1,59 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# GR-GSM based transceiver
|
||||||
|
# Extending a GRC flowgraph gr-gsm/examples/trx_radio_if/radio_if_grc.grc
|
||||||
|
#
|
||||||
|
# (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>
|
||||||
|
# (C) 2017 by Piotr Krysik <ptrkrysik@gmail.com>
|
||||||
|
#
|
||||||
|
# All Rights Reserved
|
||||||
|
#
|
||||||
|
# This program 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 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
from grgsm.trx import radio_if_grc
|
||||||
|
|
||||||
|
class radio_if(radio_if_grc):
|
||||||
|
# Application state flags
|
||||||
|
trx_started = False
|
||||||
|
|
||||||
|
def __init__(self, phy_args, phy_sample_rate,
|
||||||
|
phy_rx_gain, phy_tx_gain, phy_ppm,
|
||||||
|
phy_rx_antenna, phy_tx_antenna,
|
||||||
|
trx_remote_addr, trx_base_port,
|
||||||
|
phy_tx_freq=938900000,
|
||||||
|
phy_rx_freq=938900000-45e6,
|
||||||
|
delay_correction=285.616e-6,
|
||||||
|
uplink_shift=-(6.0/1625000*(156.25)*3),
|
||||||
|
timing_advance=0):
|
||||||
|
|
||||||
|
print("[i] Init Radio interface")
|
||||||
|
|
||||||
|
radio_if_grc.__init__(self,
|
||||||
|
samp_rate=phy_sample_rate,
|
||||||
|
tx_gain=phy_tx_gain, rx_gain=phy_rx_gain,
|
||||||
|
tx_freq=phy_tx_freq, rx_freq=phy_rx_freq,
|
||||||
|
osr=4, ppm=phy_ppm,
|
||||||
|
trx_base_port=str(trx_base_port),
|
||||||
|
trx_remote_addr=trx_remote_addr,
|
||||||
|
delay_correction=delay_correction,
|
||||||
|
uplink_shift=uplink_shift,
|
||||||
|
timing_advance=timing_advance)
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
print("[i] Shutdown Radio interface")
|
||||||
|
self.stop()
|
||||||
|
self.wait()
|
||||||
|
|
|
@ -0,0 +1,268 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##################################################
|
||||||
|
# GNU Radio Python Flow Graph
|
||||||
|
# Title: Trx radio interface
|
||||||
|
# Author: (C) Piotr Krysik 2017
|
||||||
|
# Description: Alpha version of trx radio interface
|
||||||
|
# Generated: Fri Dec 1 10:49:25 2017
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
from change_sign_of_dict_elements import change_sign_of_dict_elements
|
||||||
|
from gnuradio import blocks
|
||||||
|
from gnuradio import digital
|
||||||
|
from gnuradio import eng_notation
|
||||||
|
from gnuradio import filter
|
||||||
|
from gnuradio import gr
|
||||||
|
from gnuradio import uhd
|
||||||
|
from gnuradio.eng_option import eng_option
|
||||||
|
from gnuradio.filter import firdes
|
||||||
|
from grgsm import gsm_gmsk_mod
|
||||||
|
from optparse import OptionParser
|
||||||
|
import grgsm
|
||||||
|
import math
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
class radio_if_grc(gr.top_block):
|
||||||
|
|
||||||
|
def __init__(self, delay_correction=285.616e-6, osr=4, ppm=-0.799427, rx_freq=935e6+36*0.2e6, rx_gain=40, samp_rate=13e6/12.0, timing_advance=0, trx_base_port="5710", trx_remote_addr="127.0.0.1", tx_freq=935e6+36*0.2e6-45e6, tx_gain=40, uplink_shift=-(6.0/1625000*(156.25)*3)):
|
||||||
|
gr.top_block.__init__(self, "Trx radio interface")
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Parameters
|
||||||
|
##################################################
|
||||||
|
self.delay_correction = delay_correction
|
||||||
|
self.osr = osr
|
||||||
|
self.ppm = ppm
|
||||||
|
self.rx_freq = rx_freq
|
||||||
|
self.rx_gain = rx_gain
|
||||||
|
self.samp_rate = samp_rate
|
||||||
|
self.timing_advance = timing_advance
|
||||||
|
self.trx_base_port = trx_base_port
|
||||||
|
self.trx_remote_addr = trx_remote_addr
|
||||||
|
self.tx_freq = tx_freq
|
||||||
|
self.tx_gain = tx_gain
|
||||||
|
self.uplink_shift = uplink_shift
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Blocks
|
||||||
|
##################################################
|
||||||
|
self.uhd_usrp_source_0 = uhd.usrp_source(
|
||||||
|
",".join(("", "")),
|
||||||
|
uhd.stream_args(
|
||||||
|
cpu_format="fc32",
|
||||||
|
channels=range(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.uhd_usrp_source_0.set_clock_rate(26e6, uhd.ALL_MBOARDS)
|
||||||
|
self.uhd_usrp_source_0.set_samp_rate(samp_rate)
|
||||||
|
self.uhd_usrp_source_0.set_center_freq(rx_freq, 0)
|
||||||
|
self.uhd_usrp_source_0.set_gain(rx_gain, 0)
|
||||||
|
self.uhd_usrp_source_0.set_antenna("RX2", 0)
|
||||||
|
self.uhd_usrp_sink_0 = uhd.usrp_sink(
|
||||||
|
",".join(("", "")),
|
||||||
|
uhd.stream_args(
|
||||||
|
cpu_format="fc32",
|
||||||
|
channels=range(1),
|
||||||
|
),
|
||||||
|
"packet_len",
|
||||||
|
)
|
||||||
|
self.uhd_usrp_sink_0.set_clock_rate(26e6, uhd.ALL_MBOARDS)
|
||||||
|
self.uhd_usrp_sink_0.set_subdev_spec("A:B", 0)
|
||||||
|
self.uhd_usrp_sink_0.set_samp_rate(samp_rate)
|
||||||
|
self.uhd_usrp_sink_0.set_center_freq(tx_freq, 0)
|
||||||
|
self.uhd_usrp_sink_0.set_gain(tx_gain, 0)
|
||||||
|
self.uhd_usrp_sink_0.set_antenna("TX/RX", 0)
|
||||||
|
self.ts_filter = grgsm.burst_timeslot_filter(0)
|
||||||
|
self.low_pass_filter_0_0 = filter.fir_filter_ccf(1, firdes.low_pass(
|
||||||
|
1, samp_rate, 125e3, 5e3, firdes.WIN_HAMMING, 6.76))
|
||||||
|
self.gsm_txtime_setter_0 = grgsm.txtime_setter(None if (None is not None) else 0xffffffff, 0, 0, 0, 0, timing_advance, delay_correction+uplink_shift)
|
||||||
|
self.gsm_trx_burst_if_0 = grgsm.trx_burst_if(trx_remote_addr, trx_base_port)
|
||||||
|
self.gsm_receiver_0 = grgsm.receiver(4, ([0]), ([4]), False)
|
||||||
|
self.gsm_preprocess_tx_burst_0 = grgsm.preprocess_tx_burst()
|
||||||
|
self.gsm_msg_to_tag_0_0 = grgsm.msg_to_tag()
|
||||||
|
self.gsm_msg_to_tag_0 = grgsm.msg_to_tag()
|
||||||
|
self.gsm_gmsk_mod_0 = gsm_gmsk_mod(
|
||||||
|
BT=0.3,
|
||||||
|
pulse_duration=4,
|
||||||
|
sps=osr,
|
||||||
|
)
|
||||||
|
self.gsm_controlled_rotator_cc_0_0 = grgsm.controlled_rotator_cc(-ppm/1.0e6*2*math.pi*tx_freq/samp_rate)
|
||||||
|
self.gsm_controlled_rotator_cc_0 = grgsm.controlled_rotator_cc(ppm/1.0e6*2*math.pi*rx_freq/samp_rate)
|
||||||
|
self.gsm_clock_offset_control_0 = grgsm.clock_offset_control(rx_freq, samp_rate, osr)
|
||||||
|
self.gsm_burst_type_filter_0 = grgsm.burst_type_filter(([3]))
|
||||||
|
self.gsm_burst_to_fn_time_0 = grgsm.burst_to_fn_time()
|
||||||
|
self.digital_burst_shaper_xx_0 = digital.burst_shaper_cc((firdes.window(firdes.WIN_HANN, 16, 0)), 0, 20, False, "packet_len")
|
||||||
|
self.change_sign_of_dict_elements = change_sign_of_dict_elements()
|
||||||
|
self.blocks_pdu_to_tagged_stream_0_0 = blocks.pdu_to_tagged_stream(blocks.byte_t, "packet_len")
|
||||||
|
|
||||||
|
##################################################
|
||||||
|
# Connections
|
||||||
|
##################################################
|
||||||
|
self.msg_connect((self.change_sign_of_dict_elements, 'dict_out'), (self.gsm_msg_to_tag_0_0, 'msg'))
|
||||||
|
self.msg_connect((self.gsm_burst_to_fn_time_0, 'fn_time_out'), (self.gsm_txtime_setter_0, 'fn_time'))
|
||||||
|
self.msg_connect((self.gsm_burst_type_filter_0, 'bursts_out'), (self.gsm_burst_to_fn_time_0, 'bursts_in'))
|
||||||
|
self.msg_connect((self.gsm_clock_offset_control_0, 'ctrl'), (self.change_sign_of_dict_elements, 'dict_in'))
|
||||||
|
self.msg_connect((self.gsm_clock_offset_control_0, 'ctrl'), (self.gsm_msg_to_tag_0, 'msg'))
|
||||||
|
self.msg_connect((self.gsm_preprocess_tx_burst_0, 'bursts_out'), (self.blocks_pdu_to_tagged_stream_0_0, 'pdus'))
|
||||||
|
self.msg_connect((self.gsm_receiver_0, 'C0'), (self.gsm_burst_type_filter_0, 'bursts_in'))
|
||||||
|
self.msg_connect((self.gsm_receiver_0, 'measurements'), (self.gsm_clock_offset_control_0, 'measurements'))
|
||||||
|
self.msg_connect((self.gsm_receiver_0, 'C0'), (self.ts_filter, 'in'))
|
||||||
|
self.msg_connect((self.gsm_trx_burst_if_0, 'bursts'), (self.gsm_txtime_setter_0, 'bursts_in'))
|
||||||
|
self.msg_connect((self.gsm_txtime_setter_0, 'bursts_out'), (self.gsm_preprocess_tx_burst_0, 'bursts_in'))
|
||||||
|
self.msg_connect((self.ts_filter, 'out'), (self.gsm_trx_burst_if_0, 'bursts'))
|
||||||
|
self.connect((self.blocks_pdu_to_tagged_stream_0_0, 0), (self.gsm_gmsk_mod_0, 0))
|
||||||
|
self.connect((self.digital_burst_shaper_xx_0, 0), (self.gsm_msg_to_tag_0_0, 0))
|
||||||
|
self.connect((self.gsm_controlled_rotator_cc_0, 0), (self.low_pass_filter_0_0, 0))
|
||||||
|
self.connect((self.gsm_controlled_rotator_cc_0_0, 0), (self.uhd_usrp_sink_0, 0))
|
||||||
|
self.connect((self.gsm_gmsk_mod_0, 0), (self.digital_burst_shaper_xx_0, 0))
|
||||||
|
self.connect((self.gsm_msg_to_tag_0, 0), (self.gsm_controlled_rotator_cc_0, 0))
|
||||||
|
self.connect((self.gsm_msg_to_tag_0_0, 0), (self.gsm_controlled_rotator_cc_0_0, 0))
|
||||||
|
self.connect((self.low_pass_filter_0_0, 0), (self.gsm_receiver_0, 0))
|
||||||
|
self.connect((self.uhd_usrp_source_0, 0), (self.gsm_msg_to_tag_0, 0))
|
||||||
|
|
||||||
|
def get_delay_correction(self):
|
||||||
|
return self.delay_correction
|
||||||
|
|
||||||
|
def set_delay_correction(self, delay_correction):
|
||||||
|
self.delay_correction = delay_correction
|
||||||
|
self.gsm_txtime_setter_0.set_delay_correction(self.delay_correction+self.uplink_shift)
|
||||||
|
|
||||||
|
def get_osr(self):
|
||||||
|
return self.osr
|
||||||
|
|
||||||
|
def set_osr(self, osr):
|
||||||
|
self.osr = osr
|
||||||
|
self.gsm_gmsk_mod_0.set_sps(self.osr)
|
||||||
|
|
||||||
|
def get_ppm(self):
|
||||||
|
return self.ppm
|
||||||
|
|
||||||
|
def set_ppm(self, ppm):
|
||||||
|
self.ppm = ppm
|
||||||
|
self.gsm_controlled_rotator_cc_0.set_phase_inc(self.ppm/1.0e6*2*math.pi*self.rx_freq/self.samp_rate)
|
||||||
|
self.gsm_controlled_rotator_cc_0_0.set_phase_inc(-self.ppm/1.0e6*2*math.pi*self.tx_freq/self.samp_rate)
|
||||||
|
|
||||||
|
def get_rx_freq(self):
|
||||||
|
return self.rx_freq
|
||||||
|
|
||||||
|
def set_rx_freq(self, rx_freq):
|
||||||
|
self.rx_freq = rx_freq
|
||||||
|
self.gsm_controlled_rotator_cc_0.set_phase_inc(self.ppm/1.0e6*2*math.pi*self.rx_freq/self.samp_rate)
|
||||||
|
self.uhd_usrp_source_0.set_center_freq(self.rx_freq, 0)
|
||||||
|
|
||||||
|
def get_rx_gain(self):
|
||||||
|
return self.rx_gain
|
||||||
|
|
||||||
|
def set_rx_gain(self, rx_gain):
|
||||||
|
self.rx_gain = rx_gain
|
||||||
|
self.uhd_usrp_source_0.set_gain(self.rx_gain, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def get_samp_rate(self):
|
||||||
|
return self.samp_rate
|
||||||
|
|
||||||
|
def set_samp_rate(self, samp_rate):
|
||||||
|
self.samp_rate = samp_rate
|
||||||
|
self.gsm_controlled_rotator_cc_0.set_phase_inc(self.ppm/1.0e6*2*math.pi*self.rx_freq/self.samp_rate)
|
||||||
|
self.gsm_controlled_rotator_cc_0_0.set_phase_inc(-self.ppm/1.0e6*2*math.pi*self.tx_freq/self.samp_rate)
|
||||||
|
self.low_pass_filter_0_0.set_taps(firdes.low_pass(1, self.samp_rate, 125e3, 5e3, firdes.WIN_HAMMING, 6.76))
|
||||||
|
self.uhd_usrp_sink_0.set_samp_rate(self.samp_rate)
|
||||||
|
self.uhd_usrp_source_0.set_samp_rate(self.samp_rate)
|
||||||
|
|
||||||
|
def get_timing_advance(self):
|
||||||
|
return self.timing_advance
|
||||||
|
|
||||||
|
def set_timing_advance(self, timing_advance):
|
||||||
|
self.timing_advance = timing_advance
|
||||||
|
self.gsm_txtime_setter_0.set_timing_advance(self.timing_advance)
|
||||||
|
|
||||||
|
def get_trx_base_port(self):
|
||||||
|
return self.trx_base_port
|
||||||
|
|
||||||
|
def set_trx_base_port(self, trx_base_port):
|
||||||
|
self.trx_base_port = trx_base_port
|
||||||
|
|
||||||
|
def get_trx_remote_addr(self):
|
||||||
|
return self.trx_remote_addr
|
||||||
|
|
||||||
|
def set_trx_remote_addr(self, trx_remote_addr):
|
||||||
|
self.trx_remote_addr = trx_remote_addr
|
||||||
|
|
||||||
|
def get_tx_freq(self):
|
||||||
|
return self.tx_freq
|
||||||
|
|
||||||
|
def set_tx_freq(self, tx_freq):
|
||||||
|
self.tx_freq = tx_freq
|
||||||
|
self.gsm_controlled_rotator_cc_0_0.set_phase_inc(-self.ppm/1.0e6*2*math.pi*self.tx_freq/self.samp_rate)
|
||||||
|
self.uhd_usrp_sink_0.set_center_freq(self.tx_freq, 0)
|
||||||
|
|
||||||
|
def get_tx_gain(self):
|
||||||
|
return self.tx_gain
|
||||||
|
|
||||||
|
def set_tx_gain(self, tx_gain):
|
||||||
|
self.tx_gain = tx_gain
|
||||||
|
self.uhd_usrp_sink_0.set_gain(self.tx_gain, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def get_uplink_shift(self):
|
||||||
|
return self.uplink_shift
|
||||||
|
|
||||||
|
def set_uplink_shift(self, uplink_shift):
|
||||||
|
self.uplink_shift = uplink_shift
|
||||||
|
self.gsm_txtime_setter_0.set_delay_correction(self.delay_correction+self.uplink_shift)
|
||||||
|
|
||||||
|
|
||||||
|
def argument_parser():
|
||||||
|
parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
|
||||||
|
parser.add_option(
|
||||||
|
"", "--delay-correction", dest="delay_correction", type="eng_float", default=eng_notation.num_to_str(285.616e-6),
|
||||||
|
help="Set delay_correction [default=%default]")
|
||||||
|
parser.add_option(
|
||||||
|
"", "--osr", dest="osr", type="intx", default=4,
|
||||||
|
help="Set OSR [default=%default]")
|
||||||
|
parser.add_option(
|
||||||
|
"", "--ppm", dest="ppm", type="eng_float", default=eng_notation.num_to_str(-0.799427),
|
||||||
|
help="Set Clock offset correction [default=%default]")
|
||||||
|
parser.add_option(
|
||||||
|
"-d", "--rx-freq", dest="rx_freq", type="eng_float", default=eng_notation.num_to_str(935e6+36*0.2e6),
|
||||||
|
help="Set rx_freq [default=%default]")
|
||||||
|
parser.add_option(
|
||||||
|
"-g", "--rx-gain", dest="rx_gain", type="eng_float", default=eng_notation.num_to_str(40),
|
||||||
|
help="Set rx_gain [default=%default]")
|
||||||
|
parser.add_option(
|
||||||
|
"", "--samp-rate", dest="samp_rate", type="eng_float", default=eng_notation.num_to_str(13e6/12.0),
|
||||||
|
help="Set samp_rate [default=%default]")
|
||||||
|
parser.add_option(
|
||||||
|
"", "--timing-advance", dest="timing_advance", type="eng_float", default=eng_notation.num_to_str(0),
|
||||||
|
help="Set timing_advance [default=%default]")
|
||||||
|
parser.add_option(
|
||||||
|
"", "--trx-base-port", dest="trx_base_port", type="string", default="5710",
|
||||||
|
help="Set 5710 [default=%default]")
|
||||||
|
parser.add_option(
|
||||||
|
"", "--trx-remote-addr", dest="trx_remote_addr", type="string", default="127.0.0.1",
|
||||||
|
help="Set 127.0.0.1 [default=%default]")
|
||||||
|
parser.add_option(
|
||||||
|
"-u", "--tx-freq", dest="tx_freq", type="eng_float", default=eng_notation.num_to_str(935e6+36*0.2e6-45e6),
|
||||||
|
help="Set tx_freq [default=%default]")
|
||||||
|
parser.add_option(
|
||||||
|
"-r", "--tx-gain", dest="tx_gain", type="eng_float", default=eng_notation.num_to_str(40),
|
||||||
|
help="Set tx_gain [default=%default]")
|
||||||
|
parser.add_option(
|
||||||
|
"", "--uplink-shift", dest="uplink_shift", type="eng_float", default=eng_notation.num_to_str(-(6.0/1625000*(156.25)*3)),
|
||||||
|
help="Set uplink_shift [default=%default]")
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def main(top_block_cls=radio_if_grc, options=None):
|
||||||
|
if options is None:
|
||||||
|
options, _ = argument_parser().parse_args()
|
||||||
|
|
||||||
|
tb = top_block_cls(delay_correction=options.delay_correction, osr=options.osr, ppm=options.ppm, rx_freq=options.rx_freq, rx_gain=options.rx_gain, samp_rate=options.samp_rate, timing_advance=options.timing_advance, trx_base_port=options.trx_base_port, trx_remote_addr=options.trx_remote_addr, tx_freq=options.tx_freq, tx_gain=options.tx_gain, uplink_shift=options.uplink_shift)
|
||||||
|
tb.start()
|
||||||
|
tb.wait()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,56 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# GR-GSM based transceiver
|
||||||
|
# UDP link implementation
|
||||||
|
#
|
||||||
|
# (C) 2017 by Vadim Yanitskiy <axilirator@gmail.com>
|
||||||
|
#
|
||||||
|
# All Rights Reserved
|
||||||
|
#
|
||||||
|
# This program 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 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
import socket
|
||||||
|
import select
|
||||||
|
|
||||||
|
class udp_link:
|
||||||
|
def __init__(self, remote_addr, remote_port, bind_port):
|
||||||
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
self.sock.bind((remote_addr, bind_port))
|
||||||
|
self.sock.setblocking(0)
|
||||||
|
|
||||||
|
# Save remote info
|
||||||
|
self.remote_addr = remote_addr
|
||||||
|
self.remote_port = remote_port
|
||||||
|
|
||||||
|
def loop(self):
|
||||||
|
r_event, w_event, x_event = select.select([self.sock], [], [])
|
||||||
|
|
||||||
|
# Check for incoming data
|
||||||
|
if self.sock in r_event:
|
||||||
|
data, addr = self.sock.recvfrom(128)
|
||||||
|
self.handle_rx(data.decode())
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
self.sock.close();
|
||||||
|
|
||||||
|
def send(self, data):
|
||||||
|
if type(data) not in [bytearray, bytes]:
|
||||||
|
data = data.encode()
|
||||||
|
|
||||||
|
self.sock.sendto(data, (self.remote_addr, self.remote_port))
|
||||||
|
|
||||||
|
def handle_rx(self, data):
|
||||||
|
raise NotImplementedError
|
|
@ -23,6 +23,9 @@
|
||||||
|
|
||||||
#define GRGSM_API
|
#define GRGSM_API
|
||||||
|
|
||||||
|
%include <std_pair.i>
|
||||||
|
%template(pairud) std::pair<unsigned long long,double>;
|
||||||
|
|
||||||
%include "gnuradio.i" // the common stuff
|
%include "gnuradio.i" // the common stuff
|
||||||
|
|
||||||
//load generated python docstrings
|
//load generated python docstrings
|
||||||
|
@ -44,6 +47,7 @@
|
||||||
#include "grgsm/flow_control/burst_timeslot_filter.h"
|
#include "grgsm/flow_control/burst_timeslot_filter.h"
|
||||||
#include "grgsm/flow_control/burst_sdcch_subslot_filter.h"
|
#include "grgsm/flow_control/burst_sdcch_subslot_filter.h"
|
||||||
#include "grgsm/flow_control/burst_fnr_filter.h"
|
#include "grgsm/flow_control/burst_fnr_filter.h"
|
||||||
|
#include "grgsm/flow_control/burst_type_filter.h"
|
||||||
#include "grgsm/flow_control/dummy_burst_filter.h"
|
#include "grgsm/flow_control/dummy_burst_filter.h"
|
||||||
#include "grgsm/flow_control/uplink_downlink_splitter.h"
|
#include "grgsm/flow_control/uplink_downlink_splitter.h"
|
||||||
#include "grgsm/misc_utils/bursts_printer.h"
|
#include "grgsm/misc_utils/bursts_printer.h"
|
||||||
|
@ -65,6 +69,12 @@
|
||||||
#include "grgsm/misc_utils/message_file_source.h"
|
#include "grgsm/misc_utils/message_file_source.h"
|
||||||
#include "grgsm/misc_utils/msg_to_tag.h"
|
#include "grgsm/misc_utils/msg_to_tag.h"
|
||||||
#include "grgsm/misc_utils/controlled_fractional_resampler_cc.h"
|
#include "grgsm/misc_utils/controlled_fractional_resampler_cc.h"
|
||||||
|
//#include "grgsm/misc_utils/time_spec.h"
|
||||||
|
#include "grgsm/misc_utils/fn_time.h"
|
||||||
|
#include "grgsm/transmitter/txtime_setter.h"
|
||||||
|
#include "grgsm/transmitter/preprocess_tx_burst.h"
|
||||||
|
#include "grgsm/transmitter/gen_test_ab.h"
|
||||||
|
#include "grgsm/misc_utils/trx_burst_if.h"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%include "constants.i"
|
%include "constants.i"
|
||||||
|
@ -100,10 +110,12 @@ GR_SWIG_BLOCK_MAGIC2(gsm, burst_timeslot_filter);
|
||||||
GR_SWIG_BLOCK_MAGIC2(gsm, burst_sdcch_subslot_filter);
|
GR_SWIG_BLOCK_MAGIC2(gsm, burst_sdcch_subslot_filter);
|
||||||
%include "grgsm/flow_control/burst_fnr_filter.h"
|
%include "grgsm/flow_control/burst_fnr_filter.h"
|
||||||
GR_SWIG_BLOCK_MAGIC2(gsm, burst_fnr_filter);
|
GR_SWIG_BLOCK_MAGIC2(gsm, burst_fnr_filter);
|
||||||
|
%include "grgsm/flow_control/burst_type_filter.h"
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(gsm, burst_type_filter);
|
||||||
%include "grgsm/flow_control/dummy_burst_filter.h"
|
%include "grgsm/flow_control/dummy_burst_filter.h"
|
||||||
GR_SWIG_BLOCK_MAGIC2(gsm, dummy_burst_filter);
|
GR_SWIG_BLOCK_MAGIC2(gsm, dummy_burst_filter);
|
||||||
%include "grgsm/flow_control/uplink_downlink_splitter.h"
|
%include "grgsm/flow_control/uplink_downlink_splitter.h"
|
||||||
GR_SWIG_BLOCK_MAGIC2(grgsm, uplink_downlink_splitter);
|
GR_SWIG_BLOCK_MAGIC2(gsm, uplink_downlink_splitter);
|
||||||
|
|
||||||
|
|
||||||
%include "grgsm/misc_utils/bursts_printer.h"
|
%include "grgsm/misc_utils/bursts_printer.h"
|
||||||
|
@ -145,3 +157,38 @@ GR_SWIG_BLOCK_MAGIC2(gsm, burst_source);
|
||||||
GR_SWIG_BLOCK_MAGIC2(gsm, message_source);
|
GR_SWIG_BLOCK_MAGIC2(gsm, message_source);
|
||||||
%include "grgsm/qa_utils/message_sink.h"
|
%include "grgsm/qa_utils/message_sink.h"
|
||||||
GR_SWIG_BLOCK_MAGIC2(gsm, message_sink);
|
GR_SWIG_BLOCK_MAGIC2(gsm, message_sink);
|
||||||
|
|
||||||
|
//#pragma SWIG nowarn=319
|
||||||
|
//%include "grgsm/misc_utils/time_spec.h"
|
||||||
|
|
||||||
|
//%extend gr::gsm::time_spec_t{
|
||||||
|
// gr::gsm::time_spec_t __add__(const gr::gsm::time_spec_t &what)
|
||||||
|
// {
|
||||||
|
// gr::gsm::time_spec_t temp = *self;
|
||||||
|
// temp += what;
|
||||||
|
// return temp;
|
||||||
|
// }
|
||||||
|
// gr::gsm::time_spec_t __sub__(const gr::gsm::time_spec_t &what)
|
||||||
|
// {
|
||||||
|
// gr::gsm::time_spec_t temp = *self;
|
||||||
|
// temp -= what;
|
||||||
|
// return temp;
|
||||||
|
// }
|
||||||
|
// bool __eq__(const gr::gsm::time_spec_t &what)
|
||||||
|
// {
|
||||||
|
// return (what == *self);
|
||||||
|
// }
|
||||||
|
//};
|
||||||
|
|
||||||
|
%include "grgsm/misc_utils/fn_time.h"
|
||||||
|
|
||||||
|
%include "grgsm/transmitter/txtime_setter.h"
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(gsm, txtime_setter);
|
||||||
|
%include "grgsm/transmitter/preprocess_tx_burst.h"
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(gsm, preprocess_tx_burst);
|
||||||
|
|
||||||
|
%include "grgsm/transmitter/gen_test_ab.h"
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(gsm, gen_test_ab);
|
||||||
|
|
||||||
|
%include "grgsm/misc_utils/trx_burst_if.h"
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(gsm, trx_burst_if);
|
||||||
|
|
Loading…
Reference in New Issue