2017-08-03 13:51:57 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2018-03-12 18:09:56 +00:00
|
|
|
# TRX Toolkit
|
2017-11-21 11:35:24 +00:00
|
|
|
# DATA interface implementation
|
2017-08-03 13:51:57 +00:00
|
|
|
#
|
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
2019-07-08 03:14:10 +00:00
|
|
|
# (C) 2017-2019 by Vadim Yanitskiy <axilirator@gmail.com>
|
2017-08-03 13:51:57 +00:00
|
|
|
#
|
|
|
|
# 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.
|
|
|
|
|
2018-12-15 14:07:00 +00:00
|
|
|
import logging as log
|
|
|
|
|
2017-08-03 13:51:57 +00:00
|
|
|
from udp_link import UDPLink
|
2018-01-27 14:47:31 +00:00
|
|
|
from data_msg import *
|
2017-08-03 13:51:57 +00:00
|
|
|
|
|
|
|
class DATAInterface(UDPLink):
|
2019-01-14 00:54:18 +00:00
|
|
|
def __init__(self, *udp_link_args):
|
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
2019-07-08 03:14:10 +00:00
|
|
|
# Default header version (legacy)
|
|
|
|
self._hdr_ver = 0x00
|
|
|
|
|
2019-01-14 00:54:18 +00:00
|
|
|
UDPLink.__init__(self, *udp_link_args)
|
2019-01-14 20:47:57 +00:00
|
|
|
log.debug("Init TRXD interface (%s)" % self.desc_link())
|
2019-01-14 00:54:18 +00:00
|
|
|
|
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
2019-07-08 03:14:10 +00:00
|
|
|
def set_hdr_ver(self, ver):
|
2021-04-28 00:05:15 +00:00
|
|
|
if not ver in Msg.KNOWN_VERSIONS:
|
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
2019-07-08 03:14:10 +00:00
|
|
|
return False
|
|
|
|
|
|
|
|
self._hdr_ver = ver
|
|
|
|
return True
|
|
|
|
|
trx_toolkit/ctrl_if_trx.py: implement TRXD header version negotiation
Messages on DATA interface may have different header formats, defined
by a version number, which can be negotiated on the control interface.
By default, the Transceiver will use the legacy header version (0).
The header format negotiation can be initiated by the L1 using the
'SETFORMAT' command. If the requested version is not supported by
the transceiver, status code of the response message should indicate
a preferred (basically, the latest) version. The format of this
message is the following:
L1 -> TRX: CMD SETFORMAT VER_REQ
L1 <- TRX: RSP SETFORMAT VER_RSP VER_REQ
where:
- VER_REQ is the requested version (suggested by the L1),
- VER_RSP is either the applied version if matches VER_REQ,
or a preferred version if VER_REQ is not supported.
If the transceiver indicates VER_RSP different than VER_REQ, the L1
is supposed to reinitiate the version negotiation using the suggested
VER_RSP. For example:
L1 -> TRX: CMD SETFORMAT 2
L1 <- TRX: RSP SETFORMAT 1 2
L1 -> TRX: CMD SETFORMAT 1
L1 <- TRX: RSP SETFORMAT 1 1
If no suitable VER_RSP is found, or the VER_REQ is incorrect,
the status code in the response shall be -1.
As soon as VER_RSP matches VER_REQ in the response, the process
of negotiation is complete. Changing the header version is
supposed to be done before POWERON, but can be also done after.
Change-Id: I8d441b2559863d2dbd680db371062e4f3a2f9ff9
Related: OS#4006
2019-07-08 01:54:50 +00:00
|
|
|
def pick_hdr_ver(self, ver_req):
|
|
|
|
# Pick a version that is lower or equal to ver_req
|
2021-04-28 00:05:15 +00:00
|
|
|
for ver in Msg.KNOWN_VERSIONS[::-1]:
|
trx_toolkit/ctrl_if_trx.py: implement TRXD header version negotiation
Messages on DATA interface may have different header formats, defined
by a version number, which can be negotiated on the control interface.
By default, the Transceiver will use the legacy header version (0).
The header format negotiation can be initiated by the L1 using the
'SETFORMAT' command. If the requested version is not supported by
the transceiver, status code of the response message should indicate
a preferred (basically, the latest) version. The format of this
message is the following:
L1 -> TRX: CMD SETFORMAT VER_REQ
L1 <- TRX: RSP SETFORMAT VER_RSP VER_REQ
where:
- VER_REQ is the requested version (suggested by the L1),
- VER_RSP is either the applied version if matches VER_REQ,
or a preferred version if VER_REQ is not supported.
If the transceiver indicates VER_RSP different than VER_REQ, the L1
is supposed to reinitiate the version negotiation using the suggested
VER_RSP. For example:
L1 -> TRX: CMD SETFORMAT 2
L1 <- TRX: RSP SETFORMAT 1 2
L1 -> TRX: CMD SETFORMAT 1
L1 <- TRX: RSP SETFORMAT 1 1
If no suitable VER_RSP is found, or the VER_REQ is incorrect,
the status code in the response shall be -1.
As soon as VER_RSP matches VER_REQ in the response, the process
of negotiation is complete. Changing the header version is
supposed to be done before POWERON, but can be also done after.
Change-Id: I8d441b2559863d2dbd680db371062e4f3a2f9ff9
Related: OS#4006
2019-07-08 01:54:50 +00:00
|
|
|
if ver <= ver_req:
|
|
|
|
return ver
|
|
|
|
|
|
|
|
# No suitable version found
|
|
|
|
return -1
|
|
|
|
|
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
2019-07-08 03:14:10 +00:00
|
|
|
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
|
|
|
|
|
2018-12-08 21:38:07 +00:00
|
|
|
def recv_raw_data(self):
|
|
|
|
data, _ = self.sock.recvfrom(512)
|
|
|
|
return data
|
|
|
|
|
2021-04-28 00:05:15 +00:00
|
|
|
def recv_tx_msg(self):
|
2018-12-08 21:38:07 +00:00
|
|
|
# Read raw data from socket
|
|
|
|
data = self.recv_raw_data()
|
|
|
|
|
2021-04-28 00:05:15 +00:00
|
|
|
# Attempt to parse a TRXD Tx message
|
2018-12-08 21:38:07 +00:00
|
|
|
try:
|
2021-04-28 00:05:15 +00:00
|
|
|
msg = TxMsg()
|
2018-12-08 21:38:07 +00:00
|
|
|
msg.parse_msg(bytearray(data))
|
|
|
|
except:
|
2021-04-28 00:05:15 +00:00
|
|
|
log.error("Failed to parse a TRXD Tx message "
|
2018-12-08 21:38:07 +00:00
|
|
|
"from R:%s:%u" % (self.remote_addr, self.remote_port))
|
|
|
|
return None
|
|
|
|
|
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
2019-07-08 03:14:10 +00:00
|
|
|
# Make sure the header version matches
|
|
|
|
# the configured one (self._hdr_ver)
|
|
|
|
if not self.match_hdr_ver(msg):
|
|
|
|
return None
|
|
|
|
|
2018-12-08 21:38:07 +00:00
|
|
|
return msg
|
|
|
|
|
2021-04-28 00:05:15 +00:00
|
|
|
def recv_rx_msg(self):
|
2018-12-08 21:38:07 +00:00
|
|
|
# Read raw data from socket
|
|
|
|
data = self.recv_raw_data()
|
|
|
|
|
2021-04-28 00:05:15 +00:00
|
|
|
# Attempt to parse a TRXD Rx message
|
2018-12-08 21:38:07 +00:00
|
|
|
try:
|
2021-04-28 00:05:15 +00:00
|
|
|
msg = RxMsg()
|
2018-12-08 21:38:07 +00:00
|
|
|
msg.parse_msg(bytearray(data))
|
|
|
|
except:
|
2021-04-28 00:05:15 +00:00
|
|
|
log.error("Failed to parse a TRXD Rx message "
|
2018-12-08 21:38:07 +00:00
|
|
|
"from R:%s:%u" % (self.remote_addr, self.remote_port))
|
|
|
|
return None
|
|
|
|
|
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
2019-07-08 03:14:10 +00:00
|
|
|
# Make sure the header version matches
|
|
|
|
# the configured one (self._hdr_ver)
|
|
|
|
if not self.match_hdr_ver(msg):
|
|
|
|
return None
|
|
|
|
|
2018-12-08 21:38:07 +00:00
|
|
|
return msg
|
2017-08-03 13:51:57 +00:00
|
|
|
|
2018-12-09 15:13:44 +00:00
|
|
|
def send_msg(self, msg, legacy = False):
|
2020-07-26 19:58:13 +00:00
|
|
|
try:
|
2021-04-28 00:05:15 +00:00
|
|
|
# Validate and encode a TRXD message
|
2020-07-26 19:58:13 +00:00
|
|
|
payload = msg.gen_msg(legacy)
|
|
|
|
except ValueError as e:
|
2021-04-28 00:05:15 +00:00
|
|
|
log.error("Failed to encode a TRXD message ('%s') "
|
2020-07-26 19:58:13 +00:00
|
|
|
"due to error: %s" % (msg.desc_hdr(), e))
|
|
|
|
# TODO: we may want to send a NOPE.ind here
|
|
|
|
return
|
2017-08-03 13:51:57 +00:00
|
|
|
|
|
|
|
# Send message
|
2018-01-27 14:47:31 +00:00
|
|
|
self.send(payload)
|