Merge branch 'fixeria/trx' of https://github.com/axilirator/gr-gsm into fixeria_trx
# Resolved conflicts: # apps/grgsm_trx # python/trx/radio_if.py # swig/grgsm_swig.i
This commit is contained in:
commit
2471052cfe
|
@ -42,11 +42,11 @@ class Application:
|
||||||
base_port = 5700
|
base_port = 5700
|
||||||
|
|
||||||
# PHY specific
|
# PHY specific
|
||||||
phy_sample_rate = 4*1625000/6
|
phy_sample_rate = 4 * 1625000 / 6
|
||||||
phy_tx_antenna = "TX/RX"
|
phy_tx_antenna = "TX/RX"
|
||||||
phy_rx_antenna = "RX2"
|
phy_rx_antenna = "RX2"
|
||||||
phy_rx_gain = 30
|
phy_rx_gain = 30
|
||||||
phy_tx_gain = 40
|
phy_tx_gain = 10
|
||||||
phy_args = ""
|
phy_args = ""
|
||||||
phy_ppm = 0
|
phy_ppm = 0
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ class Application:
|
||||||
# PHY specific
|
# PHY specific
|
||||||
s += " Radio interface specific\n" \
|
s += " Radio interface specific\n" \
|
||||||
" -a --device-args Set device arguments\n" \
|
" -a --device-args Set device arguments\n" \
|
||||||
" -s --sample-rate Set sample rate (default 2000000)\n" \
|
" -s --sample-rate Set sample rate\n" \
|
||||||
" -g --rx-gain Set RX gain (default 30)\n" \
|
" -g --rx-gain Set RX gain (default 30)\n" \
|
||||||
" -G --tx-gain Set TX gain (default 10)\n" \
|
" -G --tx-gain Set TX gain (default 10)\n" \
|
||||||
" --rx-antenna Set RX antenna (default RX2)\n" \
|
" --rx-antenna Set RX antenna (default RX2)\n" \
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<block>
|
<block>
|
||||||
<name>Burst to fn_time</name>
|
<name>Burst to FN time</name>
|
||||||
<key>gsm_burst_to_fn_time</key>
|
<key>gsm_burst_to_fn_time</key>
|
||||||
<import>import grgsm</import>
|
<import>import grgsm</import>
|
||||||
<make>grgsm.burst_to_fn_time()</make>
|
<make>grgsm.gsm_burst_to_fn_time()</make>
|
||||||
|
|
||||||
<sink>
|
<sink>
|
||||||
<name>bursts_in</name>
|
<name>bursts_in</name>
|
||||||
|
|
|
@ -36,6 +36,7 @@ install(FILES
|
||||||
tmsi_dumper.h
|
tmsi_dumper.h
|
||||||
msg_to_tag.h
|
msg_to_tag.h
|
||||||
trx_burst_if.h
|
trx_burst_if.h
|
||||||
|
burst_to_fn_time.h
|
||||||
controlled_fractional_resampler_cc.h
|
controlled_fractional_resampler_cc.h
|
||||||
time_spec.h
|
time_spec.h
|
||||||
fn_time.h DESTINATION include/grgsm/misc_utils
|
fn_time.h DESTINATION include/grgsm/misc_utils
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* -*- 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_BURST_TO_FN_TIME_H
|
||||||
|
#define INCLUDED_GRGSM_BURST_TO_FN_TIME_H
|
||||||
|
|
||||||
|
#include <grgsm/api.h>
|
||||||
|
#include <gnuradio/block.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief <+description of block+>
|
||||||
|
* \ingroup gsm
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class GRGSM_API burst_to_fn_time : virtual public gr::block
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::shared_ptr<burst_to_fn_time> sptr;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return a shared_ptr to a new instance of grgsm::burst_to_fn_time.
|
||||||
|
*
|
||||||
|
* To avoid accidental use of raw pointers, grgsm::burst_to_fn_time's
|
||||||
|
* constructor is in a private implementation
|
||||||
|
* class. grgsm::burst_to_fn_time::make is the public interface for
|
||||||
|
* creating new instances.
|
||||||
|
*/
|
||||||
|
static sptr make();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GRGSM_BURST_TO_FN_TIME_H */
|
|
@ -37,5 +37,6 @@ add_sources(
|
||||||
fn_time.cc
|
fn_time.cc
|
||||||
udp_socket.cc
|
udp_socket.cc
|
||||||
trx_burst_if_impl.cc
|
trx_burst_if_impl.cc
|
||||||
|
burst_to_fn_time_impl.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/* -*- 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 "burst_to_fn_time_impl.h"
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
burst_to_fn_time::sptr
|
||||||
|
burst_to_fn_time::make(void)
|
||||||
|
{
|
||||||
|
return gnuradio::get_initial_sptr
|
||||||
|
(new burst_to_fn_time_impl());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The private constructor
|
||||||
|
*/
|
||||||
|
burst_to_fn_time_impl::burst_to_fn_time_impl(void)
|
||||||
|
: gr::block("burst_to_fn_time",
|
||||||
|
gr::io_signature::make(0, 0, 0),
|
||||||
|
gr::io_signature::make(0, 0, 0))
|
||||||
|
{
|
||||||
|
// Register I/O ports
|
||||||
|
message_port_register_in(pmt::mp("bursts_in"));
|
||||||
|
message_port_register_out(pmt::mp("fn_time_out"));
|
||||||
|
|
||||||
|
// Bind a port handler
|
||||||
|
set_msg_handler(pmt::mp("bursts_in"),
|
||||||
|
boost::bind(&burst_to_fn_time_impl::handle_burst, this, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Our virtual destructor.
|
||||||
|
*/
|
||||||
|
burst_to_fn_time_impl::~burst_to_fn_time_impl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
burst_to_fn_time_impl::handle_burst(pmt::pmt_t msg_in)
|
||||||
|
{
|
||||||
|
// Obtain fn_time tag from message
|
||||||
|
pmt::pmt_t blob = pmt::car(msg_in);
|
||||||
|
pmt::pmt_t fn_time = pmt::dict_ref(blob,
|
||||||
|
pmt::intern("fn_time"), pmt::PMT_NIL);
|
||||||
|
|
||||||
|
// Drop messages without required tag
|
||||||
|
if (fn_time == pmt::PMT_NIL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Compose and send a new message
|
||||||
|
pmt::pmt_t msg_out = pmt::dict_add(pmt::make_dict(),
|
||||||
|
pmt::intern("fn_time"), fn_time);
|
||||||
|
message_port_pub(pmt::mp("fn_time_out"), msg_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace gsm */
|
||||||
|
} /* namespace gr */
|
|
@ -0,0 +1,45 @@
|
||||||
|
/* -*- 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_BURST_TO_FN_TIME_IMPL_H
|
||||||
|
#define INCLUDED_GRGSM_BURST_TO_FN_TIME_IMPL_H
|
||||||
|
|
||||||
|
#include <grgsm/misc_utils/burst_to_fn_time.h>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
namespace gsm {
|
||||||
|
|
||||||
|
class burst_to_fn_time_impl : public burst_to_fn_time
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void handle_burst(pmt::pmt_t msg_in);
|
||||||
|
|
||||||
|
public:
|
||||||
|
burst_to_fn_time_impl(void);
|
||||||
|
~burst_to_fn_time_impl(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gsm
|
||||||
|
} // namespace gr
|
||||||
|
|
||||||
|
#endif /* INCLUDED_GRGSM_BURST_TO_FN_TIME_IMPL_H */
|
|
@ -90,15 +90,14 @@ namespace gr {
|
||||||
|
|
||||||
void txtime_setter_impl::process_fn_time_reference(pmt::pmt_t msg)
|
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;
|
pmt::pmt_t fn_time, time_hint;
|
||||||
|
|
||||||
fn_time = pmt::dict_ref(msg,
|
fn_time = pmt::dict_ref(msg,
|
||||||
pmt::intern("fn_time"), not_found);
|
pmt::intern("fn_time"), pmt::PMT_NIL);
|
||||||
time_hint = pmt::dict_ref(msg,
|
time_hint = pmt::dict_ref(msg,
|
||||||
pmt::intern("fn_time"), not_found);
|
pmt::intern("time_hint"), pmt::PMT_NIL);
|
||||||
|
|
||||||
if (fn_time != not_found) {
|
if (fn_time != pmt::PMT_NIL) {
|
||||||
uint32_t fn_ref = static_cast<uint32_t>
|
uint32_t fn_ref = static_cast<uint32_t>
|
||||||
(pmt::to_uint64(pmt::car(pmt::car(fn_time))));
|
(pmt::to_uint64(pmt::car(pmt::car(fn_time))));
|
||||||
uint32_t ts = static_cast<uint32_t>
|
uint32_t ts = static_cast<uint32_t>
|
||||||
|
@ -109,7 +108,7 @@ namespace gr {
|
||||||
pmt::cdr(pmt::cdr(fn_time)));
|
pmt::cdr(pmt::cdr(fn_time)));
|
||||||
|
|
||||||
set_fn_time_reference(fn_ref, ts, time_secs, time_fracs);
|
set_fn_time_reference(fn_ref, ts, time_secs, time_fracs);
|
||||||
} else if (time_hint != not_found) {
|
} else if (time_hint != pmt::PMT_NIL) {
|
||||||
set_time_hint(pmt::to_uint64(pmt::car(fn_time)),
|
set_time_hint(pmt::to_uint64(pmt::car(fn_time)),
|
||||||
pmt::to_double(pmt::cdr(fn_time)));
|
pmt::to_double(pmt::cdr(fn_time)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,6 @@ from gsm_sdcch8_demapper import gsm_sdcch8_demapper
|
||||||
from gsm_gmsk_mod import gsm_gmsk_mod
|
from gsm_gmsk_mod import gsm_gmsk_mod
|
||||||
from fn_time import *
|
from fn_time import *
|
||||||
from txtime_bursts_tagger import *
|
from txtime_bursts_tagger import *
|
||||||
from burst_to_fn_time import *
|
|
||||||
import arfcn
|
import arfcn
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,5 @@ GR_PYTHON_INSTALL(
|
||||||
clock_offset_corrector_tagged.py
|
clock_offset_corrector_tagged.py
|
||||||
hier_block.py
|
hier_block.py
|
||||||
fn_time.py
|
fn_time.py
|
||||||
burst_to_fn_time.py
|
|
||||||
DESTINATION ${GR_PYTHON_DIR}/grgsm
|
DESTINATION ${GR_PYTHON_DIR}/grgsm
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
"""
|
|
||||||
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)
|
|
|
@ -62,6 +62,7 @@ class ctrl_if_bb(ctrl_if):
|
||||||
if self.tb.trx_started:
|
if self.tb.trx_started:
|
||||||
print("[i] Stopping transceiver...")
|
print("[i] Stopping transceiver...")
|
||||||
self.tb.trx_started = False
|
self.tb.trx_started = False
|
||||||
|
self.tb.set_ta(0)
|
||||||
self.tb.stop()
|
self.tb.stop()
|
||||||
self.tb.wait()
|
self.tb.wait()
|
||||||
|
|
||||||
|
@ -144,6 +145,19 @@ class ctrl_if_bb(ctrl_if):
|
||||||
|
|
||||||
return (0, [meas_dbm])
|
return (0, [meas_dbm])
|
||||||
|
|
||||||
|
# Timing Advance control
|
||||||
|
elif self.verify_cmd(request, "SETTA", 1):
|
||||||
|
print("[i] Recv SETTA cmd")
|
||||||
|
|
||||||
|
# Check TA range
|
||||||
|
ta = int(request[1])
|
||||||
|
if ta < 0 or ta > 63:
|
||||||
|
print("[!] TA value must be in range: 0..63")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
self.tb.set_ta(ta)
|
||||||
|
return 0
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
elif self.verify_cmd(request, "ECHO", 0):
|
elif self.verify_cmd(request, "ECHO", 0):
|
||||||
print("[i] Recv ECHO cmd")
|
print("[i] Recv ECHO cmd")
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# GR-GSM based transceiver
|
# GR-GSM based transceiver
|
||||||
# Extending a GRC flowgraph gr-gsm/examples/trx_radio_if/radio_if_grc.grc
|
# Follow graph implementation
|
||||||
#
|
#
|
||||||
# (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>
|
# (C) 2016-2017 by Vadim Yanitskiy <axilirator@gmail.com>
|
||||||
# (C) 2017 by Piotr Krysik <ptrkrysik@gmail.com>
|
# (C) 2017 by Piotr Krysik <ptrkrysik@gmail.com>
|
||||||
|
@ -23,37 +23,267 @@
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
from grgsm.trx import radio_if_grc
|
import pmt
|
||||||
|
import time
|
||||||
|
import grgsm
|
||||||
|
import osmosdr
|
||||||
|
|
||||||
|
from math import pi
|
||||||
|
|
||||||
|
from gnuradio import digital
|
||||||
|
from gnuradio import blocks
|
||||||
|
from gnuradio import uhd
|
||||||
|
from gnuradio import gr
|
||||||
|
|
||||||
|
from gnuradio import filter
|
||||||
|
from gnuradio.filter import firdes
|
||||||
|
|
||||||
|
|
||||||
|
# HACK: should be implemented in C++!
|
||||||
|
class dict_toggle_sign(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(pmt.intern("dict_in"))
|
||||||
|
self.message_port_register_out(pmt.intern("dict_out"))
|
||||||
|
self.set_msg_handler(pmt.intern("dict_in"), self.change_sign)
|
||||||
|
|
||||||
|
def change_sign(self, msg):
|
||||||
|
if pmt.is_dict(msg):
|
||||||
|
d = pmt.to_python(msg)
|
||||||
|
for key, value in d.items():
|
||||||
|
d[key] *= -1
|
||||||
|
self.message_port_pub(pmt.intern("dict_out"), pmt.to_pmt(d))
|
||||||
|
|
||||||
|
class radio_if(gr.top_block):
|
||||||
|
# PHY specific variables
|
||||||
|
rx_freq = 935e6
|
||||||
|
tx_freq = 890e6
|
||||||
|
osr = 4
|
||||||
|
|
||||||
class radio_if(radio_if_grc):
|
|
||||||
# Application state flags
|
# Application state flags
|
||||||
trx_started = False
|
trx_started = False
|
||||||
|
|
||||||
|
# GSM timings (in microseconds [uS])
|
||||||
|
# One timeslot duration is 576.9 μs = 15/26 ms,
|
||||||
|
# or 156.25 symbol periods (a symbol period is 48/13 μs)
|
||||||
|
GSM_SYM_PERIOD_uS = 48.0 / 13.0
|
||||||
|
GSM_TS_PERIOD_uS = GSM_SYM_PERIOD_uS * 156.25
|
||||||
|
GSM_UL_DL_SHIFT_uS = -(GSM_TS_PERIOD_uS * 3)
|
||||||
|
|
||||||
|
# FIXME: shall be measured (automatically?) for
|
||||||
|
# particular device and particular clock rate.
|
||||||
|
# The current value is measured for USRP B2X0 at 26e6.
|
||||||
|
delay_correction = (285.616 + 2 * GSM_SYM_PERIOD_uS) * 1e-6
|
||||||
|
|
||||||
def __init__(self, phy_args, phy_sample_rate,
|
def __init__(self, phy_args, phy_sample_rate,
|
||||||
phy_rx_gain, phy_tx_gain, phy_ppm,
|
phy_rx_gain, phy_tx_gain, phy_ppm,
|
||||||
phy_rx_antenna, phy_tx_antenna,
|
phy_rx_antenna, phy_tx_antenna,
|
||||||
trx_remote_addr, trx_base_port,
|
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")
|
print("[i] Init Radio interface")
|
||||||
|
|
||||||
radio_if_grc.__init__(self,
|
# PHY specific variables
|
||||||
samp_rate=phy_sample_rate,
|
self.sample_rate = phy_sample_rate
|
||||||
tx_gain=phy_tx_gain, rx_gain=phy_rx_gain,
|
self.rx_gain = phy_rx_gain
|
||||||
tx_freq=phy_tx_freq, rx_freq=phy_rx_freq,
|
self.tx_gain = phy_tx_gain
|
||||||
osr=4, ppm=phy_ppm,
|
self.ppm = phy_ppm
|
||||||
trx_base_port=str(trx_base_port),
|
|
||||||
trx_remote_addr=trx_remote_addr,
|
gr.top_block.__init__(self, "GR-GSM TRX")
|
||||||
delay_correction=delay_correction,
|
|
||||||
uplink_shift=uplink_shift,
|
# TRX Burst Interface
|
||||||
timing_advance=timing_advance)
|
self.trx_burst_if = grgsm.trx_burst_if(
|
||||||
|
trx_remote_addr, str(trx_base_port))
|
||||||
|
|
||||||
|
|
||||||
|
# RX path definition
|
||||||
|
self.phy_src = uhd.usrp_source(phy_args,
|
||||||
|
uhd.stream_args(cpu_format="fc32",
|
||||||
|
channels=range(1)))
|
||||||
|
|
||||||
|
self.phy_src.set_clock_rate(26e6, uhd.ALL_MBOARDS)
|
||||||
|
self.phy_src.set_center_freq(self.rx_freq, 0)
|
||||||
|
self.phy_src.set_antenna(phy_rx_antenna, 0)
|
||||||
|
self.phy_src.set_samp_rate(phy_sample_rate)
|
||||||
|
self.phy_src.set_bandwidth(650e3, 0)
|
||||||
|
self.phy_src.set_gain(phy_rx_gain)
|
||||||
|
|
||||||
|
self.msg_to_tag_src = grgsm.msg_to_tag()
|
||||||
|
|
||||||
|
self.rotator_src = grgsm.controlled_rotator_cc(
|
||||||
|
self.calc_phase_inc(self.rx_freq))
|
||||||
|
|
||||||
|
self.lpf = filter.fir_filter_ccf(1, firdes.low_pass(
|
||||||
|
1, phy_sample_rate, 125e3, 5e3, firdes.WIN_HAMMING, 6.76))
|
||||||
|
|
||||||
|
self.gsm_receiver = grgsm.receiver(self.osr, ([0]), ([]))
|
||||||
|
|
||||||
|
self.ts_filter = grgsm.burst_timeslot_filter(0)
|
||||||
|
self.ts_filter.set_policy(grgsm.FILTER_POLICY_DROP_ALL)
|
||||||
|
|
||||||
|
# Connections
|
||||||
|
self.connect(
|
||||||
|
(self.phy_src, 0),
|
||||||
|
(self.msg_to_tag_src, 0))
|
||||||
|
|
||||||
|
self.connect(
|
||||||
|
(self.msg_to_tag_src, 0),
|
||||||
|
(self.rotator_src, 0))
|
||||||
|
|
||||||
|
self.connect(
|
||||||
|
(self.rotator_src, 0),
|
||||||
|
(self.lpf, 0))
|
||||||
|
|
||||||
|
self.connect(
|
||||||
|
(self.lpf, 0),
|
||||||
|
(self.gsm_receiver, 0))
|
||||||
|
|
||||||
|
self.msg_connect(
|
||||||
|
(self.gsm_receiver, 'C0'),
|
||||||
|
(self.ts_filter, 'in'))
|
||||||
|
|
||||||
|
self.msg_connect(
|
||||||
|
(self.ts_filter, 'out'),
|
||||||
|
(self.trx_burst_if, 'bursts'))
|
||||||
|
|
||||||
|
|
||||||
|
# TX Path Definition
|
||||||
|
self.phy_sink = uhd.usrp_sink(phy_args,
|
||||||
|
uhd.stream_args(cpu_format="fc32",
|
||||||
|
channels=range(1)), "packet_len")
|
||||||
|
|
||||||
|
self.phy_sink.set_clock_rate(26e6, uhd.ALL_MBOARDS)
|
||||||
|
self.phy_sink.set_antenna(phy_tx_antenna, 0)
|
||||||
|
self.phy_sink.set_samp_rate(phy_sample_rate)
|
||||||
|
self.phy_sink.set_center_freq(self.tx_freq, 0)
|
||||||
|
self.phy_sink.set_gain(self.tx_gain)
|
||||||
|
|
||||||
|
self.tx_time_setter = grgsm.txtime_setter(
|
||||||
|
0xffffffff, 0, 0, 0, 0, 0,
|
||||||
|
self.delay_correction + self.GSM_UL_DL_SHIFT_uS * 1e-6)
|
||||||
|
|
||||||
|
self.tx_burst_proc = grgsm.preprocess_tx_burst()
|
||||||
|
|
||||||
|
self.pdu_to_tagged_stream = blocks.pdu_to_tagged_stream(
|
||||||
|
blocks.byte_t, 'packet_len')
|
||||||
|
|
||||||
|
self.gmsk_mod = grgsm.gsm_gmsk_mod(
|
||||||
|
BT = 0.3, pulse_duration = 4, sps = self.osr)
|
||||||
|
|
||||||
|
self.burst_shaper = digital.burst_shaper_cc(
|
||||||
|
(firdes.window(firdes.WIN_HANN, 16, 0)),
|
||||||
|
0, 20, False, "packet_len")
|
||||||
|
|
||||||
|
self.msg_to_tag_sink = grgsm.msg_to_tag()
|
||||||
|
|
||||||
|
self.rotator_sink = grgsm.controlled_rotator_cc(
|
||||||
|
-self.calc_phase_inc(self.tx_freq))
|
||||||
|
|
||||||
|
# Connections
|
||||||
|
self.msg_connect(
|
||||||
|
(self.trx_burst_if, 'bursts'),
|
||||||
|
(self.tx_time_setter, 'bursts_in'))
|
||||||
|
|
||||||
|
self.msg_connect(
|
||||||
|
(self.tx_time_setter, 'bursts_out'),
|
||||||
|
(self.tx_burst_proc, 'bursts_in'))
|
||||||
|
|
||||||
|
self.msg_connect(
|
||||||
|
(self.tx_burst_proc, 'bursts_out'),
|
||||||
|
(self.pdu_to_tagged_stream, 'pdus'))
|
||||||
|
|
||||||
|
self.connect(
|
||||||
|
(self.pdu_to_tagged_stream, 0),
|
||||||
|
(self.gmsk_mod, 0))
|
||||||
|
|
||||||
|
self.connect(
|
||||||
|
(self.gmsk_mod, 0),
|
||||||
|
(self.burst_shaper, 0))
|
||||||
|
|
||||||
|
self.connect(
|
||||||
|
(self.burst_shaper, 0),
|
||||||
|
(self.msg_to_tag_sink, 0))
|
||||||
|
|
||||||
|
self.connect(
|
||||||
|
(self.msg_to_tag_sink, 0),
|
||||||
|
(self.rotator_sink, 0))
|
||||||
|
|
||||||
|
self.connect(
|
||||||
|
(self.rotator_sink, 0),
|
||||||
|
(self.phy_sink, 0))
|
||||||
|
|
||||||
|
|
||||||
|
# RX & TX synchronization
|
||||||
|
self.bt_filter = grgsm.burst_type_filter([3])
|
||||||
|
self.burst_to_fn_time = grgsm.burst_to_fn_time()
|
||||||
|
|
||||||
|
# Connections
|
||||||
|
self.msg_connect(
|
||||||
|
(self.gsm_receiver, 'C0'),
|
||||||
|
(self.bt_filter, 'bursts_in'))
|
||||||
|
|
||||||
|
self.msg_connect(
|
||||||
|
(self.bt_filter, 'bursts_out'),
|
||||||
|
(self.burst_to_fn_time, 'bursts_in'))
|
||||||
|
|
||||||
|
self.msg_connect(
|
||||||
|
(self.burst_to_fn_time, 'fn_time_out'),
|
||||||
|
(self.tx_time_setter, 'fn_time'))
|
||||||
|
|
||||||
|
|
||||||
|
# AFC (Automatic Frequency Correction)
|
||||||
|
self.gsm_clck_ctrl = grgsm.clock_offset_control(
|
||||||
|
self.rx_freq, phy_sample_rate, osr = self.osr)
|
||||||
|
|
||||||
|
self.dict_toggle_sign = dict_toggle_sign()
|
||||||
|
|
||||||
|
# Connections
|
||||||
|
self.msg_connect(
|
||||||
|
(self.gsm_receiver, 'measurements'),
|
||||||
|
(self.gsm_clck_ctrl, 'measurements'))
|
||||||
|
|
||||||
|
self.msg_connect(
|
||||||
|
(self.gsm_clck_ctrl, 'ctrl'),
|
||||||
|
(self.msg_to_tag_src, 'msg'))
|
||||||
|
|
||||||
|
self.msg_connect(
|
||||||
|
(self.gsm_clck_ctrl, 'ctrl'),
|
||||||
|
(self.dict_toggle_sign, 'dict_in'))
|
||||||
|
|
||||||
|
self.msg_connect(
|
||||||
|
(self.dict_toggle_sign, 'dict_out'),
|
||||||
|
(self.msg_to_tag_sink, 'msg'))
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
print("[i] Shutdown Radio interface")
|
print("[i] Shutdown Radio interface")
|
||||||
self.stop()
|
self.stop()
|
||||||
self.wait()
|
self.wait()
|
||||||
|
|
||||||
|
def calc_phase_inc(self, fc):
|
||||||
|
return self.ppm / 1.0e6 * 2 * pi * fc / self.sample_rate
|
||||||
|
|
||||||
|
def set_rx_freq(self, fc):
|
||||||
|
self.phy_src.set_center_freq(fc, 0)
|
||||||
|
self.rotator_src.set_phase_inc(self.calc_phase_inc(fc))
|
||||||
|
self.rx_freq = fc
|
||||||
|
|
||||||
|
def set_tx_freq(self, fc):
|
||||||
|
self.phy_sink.set_center_freq(fc, 0)
|
||||||
|
self.rotator_sink.set_phase_inc(-self.calc_phase_inc(fc))
|
||||||
|
self.tx_freq = fc
|
||||||
|
|
||||||
|
def set_rx_gain(self, gain):
|
||||||
|
self.phy_src.set_gain(gain, 0)
|
||||||
|
self.rx_gain = gain
|
||||||
|
|
||||||
|
def set_tx_gain(self, gain):
|
||||||
|
self.phy_sink.set_gain(gain, 0)
|
||||||
|
self.tx_gain = gain
|
||||||
|
|
||||||
|
def set_ta(self, ta):
|
||||||
|
print("[i] Setting TA value %d" % ta)
|
||||||
|
advance_time_sec = ta * self.GSM_SYM_PERIOD_uS * 1e-6
|
||||||
|
self.tx_time_setter.set_timing_advance(advance_time_sec)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* -*- c++ -*- */
|
/* -*- c++ -*- */
|
||||||
/*
|
/*
|
||||||
* @file
|
* @file
|
||||||
* @author (C) 2014 by Piotr Krysik <ptrkrysik@gmail.com>
|
* @author (C) 2014-2017 by Piotr Krysik <ptrkrysik@gmail.com>
|
||||||
* @section LICENSE
|
* @section LICENSE
|
||||||
*
|
*
|
||||||
* Gr-gsm is free software; you can redistribute it and/or modify
|
* Gr-gsm is free software; you can redistribute it and/or modify
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
#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/burst_to_fn_time.h"
|
||||||
#include "grgsm/misc_utils/fn_time.h"
|
#include "grgsm/misc_utils/fn_time.h"
|
||||||
#include "grgsm/transmitter/txtime_setter.h"
|
#include "grgsm/transmitter/txtime_setter.h"
|
||||||
#include "grgsm/transmitter/preprocess_tx_burst.h"
|
#include "grgsm/transmitter/preprocess_tx_burst.h"
|
||||||
|
@ -148,6 +148,10 @@ GR_SWIG_BLOCK_MAGIC2(gsm, controlled_fractional_resampler_cc);
|
||||||
GR_SWIG_BLOCK_MAGIC2(gsm, extract_cmc);
|
GR_SWIG_BLOCK_MAGIC2(gsm, extract_cmc);
|
||||||
%include "grgsm/misc_utils/extract_assignment_cmd.h"
|
%include "grgsm/misc_utils/extract_assignment_cmd.h"
|
||||||
GR_SWIG_BLOCK_MAGIC2(gsm, extract_assignment_cmd);
|
GR_SWIG_BLOCK_MAGIC2(gsm, extract_assignment_cmd);
|
||||||
|
%include "grgsm/misc_utils/trx_burst_if.h"
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(gsm, trx_burst_if);
|
||||||
|
%include "grgsm/misc_utils/burst_to_fn_time.h"
|
||||||
|
GR_SWIG_BLOCK_MAGIC2(gsm, burst_to_fn_time);
|
||||||
|
|
||||||
%include "grgsm/qa_utils/burst_sink.h"
|
%include "grgsm/qa_utils/burst_sink.h"
|
||||||
GR_SWIG_BLOCK_MAGIC2(gsm, burst_sink);
|
GR_SWIG_BLOCK_MAGIC2(gsm, burst_sink);
|
||||||
|
@ -158,37 +162,10 @@ 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/misc_utils/fn_time.h"
|
||||||
|
|
||||||
%include "grgsm/transmitter/txtime_setter.h"
|
%include "grgsm/transmitter/txtime_setter.h"
|
||||||
GR_SWIG_BLOCK_MAGIC2(gsm, txtime_setter);
|
GR_SWIG_BLOCK_MAGIC2(gsm, txtime_setter);
|
||||||
%include "grgsm/transmitter/preprocess_tx_burst.h"
|
%include "grgsm/transmitter/preprocess_tx_burst.h"
|
||||||
GR_SWIG_BLOCK_MAGIC2(gsm, preprocess_tx_burst);
|
GR_SWIG_BLOCK_MAGIC2(gsm, preprocess_tx_burst);
|
||||||
|
|
||||||
%include "grgsm/transmitter/gen_test_ab.h"
|
%include "grgsm/transmitter/gen_test_ab.h"
|
||||||
GR_SWIG_BLOCK_MAGIC2(gsm, gen_test_ab);
|
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