diff options
author | Vadim Yanitskiy <axilirator@gmail.com> | 2019-07-08 10:14:10 +0700 |
---|---|---|
committer | laforge <laforge@gnumonks.org> | 2019-07-16 04:07:34 +0000 |
commit | ebf676597b179e196eb27867725bf0ef7210b7aa (patch) | |
tree | ddd9f704dd82c33265ccf06f456bbd866c054260 /src/target/trx_toolkit/fake_trx.py | |
parent | 6780e47b6cdb9b470f0204fffbf3ecedae7f8a0e (diff) |
trx_toolkit/fake_trx.py: basic TRXD version 0x01 support
Since the new TRXD header format has been introduced, FakeTRX needs
to be able to fill it correctly. In particular, the following:
- Modulation, which can be determined from the burst length;
- Training Sequence Code (and set), which needs to be detected
by comparing the burst bits of L12TRX message against known
training sequences (only GMSK and the default TS set for now);
- C/I (Carrier-to-Interference ratio), which can be simulated
later on, as instructed on the TRXC interface ('FAKE_CI').
The actual TRXD header version is stored in the instance of class
DATAInterface. By default (at startup), legacy version 0 is used.
The version negotiation is supposed to be performed on the TRXC
interface, and to be implemented in a follow-up change.
Different Transceivers may use different header versions, thus in
FakeTRX.send_data_msg() we need to override the original version
of the L12TRX message, and generate the corresponding PDU.
Limitations:
- NOPE / IDLE indications are not (yet) supported;
- TSC detection: GMSK modulation only.
Change-Id: I164f5ae4ce7694d6e324aab927a04e96d489ebd8
Related: OS#4006
Diffstat (limited to 'src/target/trx_toolkit/fake_trx.py')
-rwxr-xr-x | src/target/trx_toolkit/fake_trx.py | 49 |
1 files changed, 46 insertions, 3 deletions
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 |