summaryrefslogtreecommitdiffstats
path: root/src/target
diff options
context:
space:
mode:
Diffstat (limited to 'src/target')
-rw-r--r--src/target/trx_toolkit/burst_fwd.py2
-rw-r--r--src/target/trx_toolkit/data_if.py32
-rwxr-xr-xsrc/target/trx_toolkit/fake_trx.py49
3 files changed, 78 insertions, 5 deletions
diff --git a/src/target/trx_toolkit/burst_fwd.py b/src/target/trx_toolkit/burst_fwd.py
index 164271fe..1d5dd7b8 100644
--- a/src/target/trx_toolkit/burst_fwd.py
+++ b/src/target/trx_toolkit/burst_fwd.py
@@ -84,4 +84,4 @@ class BurstForwarder:
if tx_msg.tn not in trx.ts_list:
continue
- trx.send_data_msg(src_trx, tx_msg)
+ trx.send_data_msg(src_trx, rx_msg, tx_msg)
diff --git a/src/target/trx_toolkit/data_if.py b/src/target/trx_toolkit/data_if.py
index 027fd854..10df4383 100644
--- a/src/target/trx_toolkit/data_if.py
+++ b/src/target/trx_toolkit/data_if.py
@@ -4,7 +4,7 @@
# TRX Toolkit
# DATA interface implementation
#
-# (C) 2017-2018 by Vadim Yanitskiy <axilirator@gmail.com>
+# (C) 2017-2019 by Vadim Yanitskiy <axilirator@gmail.com>
#
# All Rights Reserved
#
@@ -29,9 +29,29 @@ from data_msg import *
class DATAInterface(UDPLink):
def __init__(self, *udp_link_args):
+ # Default header version (legacy)
+ self._hdr_ver = 0x00
+
UDPLink.__init__(self, *udp_link_args)
log.debug("Init TRXD interface (%s)" % self.desc_link())
+ def set_hdr_ver(self, ver):
+ if not ver in DATAMSG.known_versions:
+ return False
+
+ self._hdr_ver = ver
+ return True
+
+ def match_hdr_ver(self, msg):
+ if msg.ver == self._hdr_ver:
+ return True
+
+ log.error("(%s) Rx DATA message (%s) with unexpected header "
+ "version %u (!= expected %u), ignoring..."
+ % (self.desc_link(), msg.desc_hdr(),
+ msg.ver, self._hdr_ver))
+ return False
+
def recv_raw_data(self):
data, _ = self.sock.recvfrom(512)
return data
@@ -49,6 +69,11 @@ class DATAInterface(UDPLink):
"from R:%s:%u" % (self.remote_addr, self.remote_port))
return None
+ # Make sure the header version matches
+ # the configured one (self._hdr_ver)
+ if not self.match_hdr_ver(msg):
+ return None
+
return msg
def recv_trx2l1_msg(self):
@@ -64,6 +89,11 @@ class DATAInterface(UDPLink):
"from R:%s:%u" % (self.remote_addr, self.remote_port))
return None
+ # Make sure the header version matches
+ # the configured one (self._hdr_ver)
+ if not self.match_hdr_ver(msg):
+ return None
+
return msg
def send_msg(self, msg, legacy = False):
diff --git a/src/target/trx_toolkit/fake_trx.py b/src/target/trx_toolkit/fake_trx.py
index 928333f6..de0e6ff0 100755
--- a/src/target/trx_toolkit/fake_trx.py
+++ b/src/target/trx_toolkit/fake_trx.py
@@ -35,9 +35,11 @@ import re
from app_common import ApplicationBase
from burst_fwd import BurstForwarder
from transceiver import Transceiver
+from data_msg import Modulation
from clck_gen import CLCKGen
from trx_list import TRXList
from fake_pm import FakePM
+from gsm_shared import *
class FakeTRX(Transceiver):
""" Fake transceiver with RF path (burst loss, RSSI, TA, ToA) simulation.
@@ -98,18 +100,21 @@ class FakeTRX(Transceiver):
TOA256_BASE_DEFAULT = 0
RSSI_BASE_DEFAULT = -60
+ CI_BASE_DEFAULT = 90
def __init__(self, *trx_args, **trx_kwargs):
Transceiver.__init__(self, *trx_args, **trx_kwargs)
- # Actual ToA / RSSI / TA values
+ # Actual ToA, RSSI, C/I, TA values
self.toa256_base = self.TOA256_BASE_DEFAULT
self.rssi_base = self.RSSI_BASE_DEFAULT
+ self.ci_base = self.CI_BASE_DEFAULT
self.ta = 0
- # ToA / RSSI randomization threshold
+ # ToA, RSSI, C/I randomization thresholds
self.toa256_rand_threshold = 0
self.rssi_rand_threshold = 0
+ self.ci_rand_threshold = 0
# Path loss simulation (burst dropping)
self.burst_drop_amount = 0
@@ -137,6 +142,17 @@ class FakeTRX(Transceiver):
rssi_max = self.rssi_base + self.rssi_rand_threshold
return random.randint(rssi_min, rssi_max)
+ @property
+ def ci(self):
+ # Check if randomization is required
+ if self.ci_rand_threshold is 0:
+ return self.ci_base
+
+ # Generate a random C/I value in required range
+ ci_min = self.ci_base - self.ci_rand_threshold
+ ci_max = self.ci_base + self.ci_rand_threshold
+ return random.randint(ci_min, ci_max)
+
# Path loss simulation: burst dropping
# Returns: True - drop, False - keep
def sim_burst_drop(self, msg):
@@ -152,14 +168,41 @@ class FakeTRX(Transceiver):
return False
+ def _handle_data_msg_v1(self, src_msg, msg):
+ # TODO: NOPE indications are not (yet) supported
+ msg.nope_ind = False
+
+ # C/I (Carrier-to-Interference ratio)
+ msg.ci = self.ci
+
+ # Pick modulation type by burst length
+ bl = len(src_msg.burst)
+ msg.mod_type = Modulation.pick_by_bl(bl)
+
+ # Pick TSC (Training Sequence Code) and TSC set
+ if msg.mod_type is Modulation.ModGMSK:
+ ss = TrainingSeqGMSK.pick(src_msg.burst)
+ msg.tsc = ss.tsc if ss is not None else 0
+ msg.tsc_set = ss.tsc_set if ss is not None else 0
+ else: # TODO: other modulation types (at least 8-PSK)
+ msg.tsc_set = 0
+ msg.tsc = 0
+
# Takes (partially initialized) TRX2L1 message,
# simulates RF path parameters (such as RSSI),
# and sends towards the L1
- def send_data_msg(self, src_trx, msg):
+ def send_data_msg(self, src_trx, src_msg, msg):
+ # Override header version
+ msg.ver = self.data_if._hdr_ver
+
# Complete message header
msg.toa256 = self.toa256
msg.rssi = self.rssi
+ # Version specific fields
+ if msg.ver >= 0x01:
+ self._handle_data_msg_v1(src_msg, msg)
+
# Apply optional Timing Advance
if src_trx.ta is not 0:
msg.toa256 -= src_trx.ta * 256