Commit Graph

32 Commits

Author SHA1 Message Date
Oliver Smith 1741372556 treewide: remove FSF address
Remove the paragraph about writing to the Free Software Foundation's
mailing address. The FSF has changed addresses in the past, and may do
so again. In 2021 this is not useful, let's rather have a bit less
boilerplate at the start of source files.

Change-Id: I73be012c01c0108fb6951dbff91d50eb19b40c51
2021-12-14 12:52:04 +00:00
Vadim Yanitskiy 00b70983a5 trx_toolkit: support setting artificial delay for TRXC
Change-Id: Idb1ef445bc14a6312f08a83ecacc3a938b0e1d70
Related: OS#5245
2021-10-03 14:13:51 +06:00
Vadim Yanitskiy 1b7b4ec7a4 trx_toolkit: use RxMsg/TxMsg instead of TRX2L1/L12TRX
I intentionally do not use 'Downlink' and 'Uplink' terms in this project
because both MS and BTS transmit and receive on the opposite directions.
A burst coming from demodulator may be a Downlink or an Uplink burst
depending on the context, so we definitely need more precise terms.

Back then when I started to work on TRX toolkit, I decided to use the
'TRX2L1' and 'L12TRX' for receive and transmit directions respectively.
Now I find them hard to read, so let's replace them with 'Rx' and 'Tx'.

Change-Id: I688f24a3c09dd7e1cc00b5530ec26c8e8cfd8f7c
Related: OS#4006, SYS#4895
2021-05-03 20:39:10 +02:00
Vadim Yanitskiy b988408166 trx_toolkit/fake_trx.py: use raw string notation for regex
This way there is no need to escape backslashes in regex.

Change-Id: I1b2b6675851275bd5285ffc287410535b22055ae
2021-05-03 20:35:46 +02:00
Pau Espin 1687d3dea3 fake_trx: Implement RFMUTE TRXC cmd
Change-Id: I67d16858cd70cb0527c1da77bd3787d5e53100b4
2020-08-26 18:04:57 +02:00
Vadim Yanitskiy d4ed09df57 Revert "trx_toolkit/transceiver.py: implement the transmit burst queue"
This reverts commit 6e1c82d298.
Unfortunately, solving one problem it introduced even more regressions.

Change-Id: If29b4f6718cbc8af18fe18a5e3eca3912e8af01e
Related: OS#4658
2020-07-22 19:59:06 +07:00
Vadim Yanitskiy 49673e4073 trx_toolkit: use python3 in shebang of executable scripts
TRX Toolkit is still backwards compatible with Python2, but Python3
does much better in terms of performance.  Also, on Debian Stretch
that is used as a base for our Docker images, Python 2.7 is still
the default.  Let's require Python3 in shebang.

Change-Id: I8a1d7c59d3b5d49ec2ed94a7c77905e02134f216
2020-07-16 13:46:19 +07:00
Vadim Yanitskiy 6e1c82d298 trx_toolkit/transceiver.py: implement the transmit burst queue
In order to reflect the UL/DL delay caused by the premature burst
scheduling (a.k.a. 'fn-advance') in a virtual environment, the
Transceiver implementation now queues all to be transmitted bursts,
so they remain in the queue until the appropriate time of transmission.

The API user is supposed to call recv_data_msg() in order to obtain
a L12TRX message on the TRXD (data) inteface, so it gets queued by
this function.  Then, to ensure the timeous transmission, the user
of this implementation needs to call clck_tick() on each TDMA
frame.  Both functions are thread-safe (queue mutex).

In a multi-trx configuration, the use of queue additionally ensures
proper burst aggregation on multiple TRXD connections, so all L12TRX
messages are guaranteed to be sent in the right order, i.e. with
monolithically-increasing TDMA frame numbers.

Of course, this change increases the overall CPU usage, given that
each transceiver gets its own queue, and we need to serve them all
on every TDMA frame.  According to my measurements, when running
test cases from ttcn3-bts-test, the average load is ~50% higher
than what it used to be.  Still not significantly high, though.

Change-Id: Ie66ef9667dc8d156ad578ce324941a816c07c105
Related: OS#4658, OS#4546
2020-07-14 17:21:14 +07:00
Vadim Yanitskiy e2aaeb59b3 trx_toolkit/fake_trx.py: move Rx burst handling to Transceiver
Change-Id: Ic1f44bfb21ac3173e9530a0a9966cd5e64b8bd48
2020-07-13 08:51:19 +00:00
Vadim Yanitskiy 37c81fea95 trx_toolkit/fake_trx.py: avoid using TRXList.__getitem__()
Running with cProfile shows that there are quite a lot calls:

  469896    0.254    0.000    0.254    0.000 trx_list.py:37(__getitem__)

Let's better avoid using it in performance critical parts.

Change-Id: I2bbc0a2af8218af0b9a02d8e16d4216cf602892a
2020-07-13 08:51:19 +00:00
Pau Espin 3ca971eb2e fake_trx: Support SETPOWER and NOMTXPOWER TRXC cmds
By default RSSI on the Rx side is computed based on transmitter's
tx power and then substracting the the Rx path loss.
If FAKE_RSSI is used, then the values in there are used instead.

A default hardcoded value of tx nominal power = 50 dBm is set to keep
old behavior of RSSI=-60dB after calculations.

Change-Id: I3ee1a32ca22c3272e66b3ca78e4f67d283844c80
2020-06-03 20:22:59 +02:00
Vadim Yanitskiy ae8e5ad648 trx_toolkit/fake_trx.py: send NOPE.ind in case of path loss simulation
Since TRXD header version 1, we should send NOPE indications to the
L1 side in absence of TRX2L1 bursts, and IDLE indications during
IDLE TDMA frames (basically noise measurements).

This change is the first step towards the goal: if a given burst
is to be dropped due to the path loss simulation (see FAKE_DROP),
mark the carrier TRX2L1 message as NOPE.ind and send anyway.

Change-Id: Iabd0af665e3108d23a908638f943a5b689986e2c
Related: OS#3428, OS#2975
2019-11-20 15:05:57 +00:00
Vadim Yanitskiy b1ae186c55 trx_toolkit/fake_trx.py: refactor L12TRX -> TRX2L1 burst transformation
The burst transformation in BurstForwarder.forward_msg() used to be
done only once, so then the resulting message was distributed over
the list of connected (and active) transceivers.

This approach limits the path loss simulation capabilities, because
a reference to the same message is passed to FakeTRX.send_data_msg().
If one transceiver changes (or removes) the burst bits, the other
transceivers would not receive the original message.

Let's do the transformation individually for each transceiver,
so the original message will always remain unchanged.

Change-Id: Ia016a3a9bb6e9f17182a7168aa5a501ae9b9978b
2019-11-20 15:05:57 +00:00
Vadim Yanitskiy 2605d96720 trx_toolkit: fix: do not use 'is' / 'is not' with string and numerical literals
Since version 3.8, Python warnins us that using the "is" and "is not"
operators with string and numerical literals is a bad idea. Let's
avoid this and use the classical '==' and '!=' operators instead.

Change-Id: Iaed86d630ac1e0b9b4f72bbf3c788e325783456d
Bug description: https://bugs.python.org/issue34850
2019-11-17 17:46:48 +07:00
Vadim Yanitskiy 88e1620502 trx_toolkit: fix compatibility with Python 3: 'is' vs '=='
Change-Id: I8ba05c04f206578cf61df58573c24cba1d6fba52
2019-07-24 05:44:19 +07:00
Alexander Couzens 998ed796c3 target/*.py: shebang: use /usr/bin/env python
Use the system default python instead of a hardcoded python2
Allow to use python2 and python3.

Change-Id: Iab185759b574eff1ca1b189dcbb4e1a3eec52132
2019-07-16 22:46:12 +00:00
Vadim Yanitskiy 3d9a1d6e48 trx_toolkit/fake_trx.py: introduce a TRXC command for C/I simulation
C/I (Carrier-to-Interference ratio) is a value in cB (centiBels),
computed from the training sequence of each received burst,
by comparing the "ideal" training sequence with the received one.

This change introduces a new command similar to FAKE_TOA and FAKE_RSSI,
so it can be used by TTCN-3 test case 'TC_pcu_data_ind_lqual_cb' to
verify that the link quality measurements are delivered to the PCU.

Change-Id: I7080effbbc1022d1884c6d6f0cb580eba8e514ff
Related: OS#1855
2019-07-16 14:52:24 +07:00
Vadim Yanitskiy ebf676597b 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-16 04:07:34 +00:00
Vadim Yanitskiy c09894924a trx_toolkit/transceiver.py: add optional transceiver name
Since fake_trx.py can handle multiple transceivers, it may be useful
to name transceivers. If transceiver has some name, it will appear
in logging messages, for example:

  [INFO] transceiver.py:104 Init transceiver 'BTS@127.0.0.1:5700'
  [INFO] transceiver.py:104 Init transceiver 'MS@127.0.0.1:6700'
  [INFO] transceiver.py:104 Init transceiver '127.0.0.1:5700/1'

This change additionally assigns names to the both default
transceivers, and extends the '--trx' option with ability
to specify some name, for example:

  --trx foo@127.0.0.1:5700 or --trx bar@127.0.0.1:5700/1
  --trx ipv6@[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:6700

Change-Id: I2f58f02e7819bb008b8aab1a8bf9e0adeb2e44ec
2019-01-14 23:52:31 +00:00
Vadim Yanitskiy ba28c3efc1 trx_toolkit/fake_trx.py: enrich TRX logging messages
Since fake_trx.py can handle multiple transceivers, it makes sense
to print some info in logging messages about transceivers they
belong to. This acvieved by defining __str__() for Transceiver.

Some examples:

  [DEBUG] ctrl_if_trx.py:83 (127.0.0.1:5700) Recv POWEROFF cmd
  [INFO] ctrl_if_trx.py:85 (127.0.0.1:5700) Stopping transceiver...

  [DEBUG] ctrl_if_trx.py:95 (127.0.0.1:5700/1) Recv RXTUNE cmd
  [DEBUG] ctrl_if_trx.py:102 (127.0.0.1:5700/1) Recv TXTUNE cmd
  [DEBUG] ctrl_if_trx.py:155 (127.0.0.1:5700/1) Ignore CMD SETTSC
  [DEBUG] ctrl_if_trx.py:155 (127.0.0.1:5700/1) Ignore CMD SETPOWER

Change-Id: I1f706790a2da226f1418f89d2cfbb55baa6ea624
2019-01-14 23:52:31 +00:00
Vadim Yanitskiy 71fee86391 trx_toolkit/fake_trx.py: move init code to __init__()
There should be no code in run() that does initialization,
__init__() is the best place for this. This change allows
to import the Application class from fake_trx.py, and
run it from script (e.g. for testing).

Change-Id: I84969630348a189d237cc98354e568421839a37b
2019-01-14 23:52:31 +00:00
Vadim Yanitskiy e4e3e6facd trx_toolkit/fake_trx.py: fix: update trx_list of FakePM
It seems in Ice44e2b22566b3652ef6d43896055963b13ab185 I forgot
to do this, so all measurements triggered by MEASURE command
were incorrect (always noise). Let's fix this!

Change-Id: I155f118b2d3e3b23eb148fe7e2630790f8fcd18c
2019-01-13 16:33:31 +07:00
Vadim Yanitskiy 786e97a0dc trx_toolkit/fake_trx.py: handle multiple transceivers
Since Ice44e2b22566b3652ef6d43896055963b13ab185 is merged, the class
hierarchy has become much more flexible, so it's possible to create
multiple Transceiver / FakeTRX instances and distribute bursts using
a single instance of BurstForwarder.

This change introduces a new command line option, that can be used
to specify additional transceivers. Please note that fake_trx.py
still initializes a pair of BTS and BB transceivers by default.

The new option has the following format:

  --trx REMOTE_ADDR:BASE_PORT[/TRX_NUM]

Some examples for IPv4 and IPv6:

  --trx 127.0.0.1:5703
  --trx [2001:0db8:85a3:0000:0000:8a2e:0370:7334]:6703

If optional TRX_NUM > 0 is specified, e.g.:

  --trx 127.0.0.1:5700/1

then this transceiver is considered as a child of another one.
See I7e97b7f32dde7ab74779133e9d7504f1d0fce60c for details.

Change-Id: Ibff31fb3a958a714c828d0dea7e87d47f778fd80
2019-01-13 16:33:12 +07:00
Vadim Yanitskiy 152a2da8d2 trx_toolkit/fake_trx.py: refactor global class hierarchy
This change is a big step towards handling of multiple transceivers
in a single process, i.e. multiple MS and multiple BTS connections.

The old class hierarchy wasn't flexible enough, because initially
fake_trx was designed as a bridge between OsmocomBB and OsmoBTS,
but not as the burst router. There were two separate, but 90%
similar implementations of the CTRL interface, two variations
of each simulation parameter - one for UL, another for DL.

The following new classes are introduced:

  - Transceiver - represents a single transceiver, that can be
    used as for the BTS side, as for the MS side. Each instance
    has its own CTRL, DATA, and (optionally) CLCK interfaces,
    among with basic state variables, such as both RX / TX freq.,
    power state (running or idle) and list of active timeslots.

  - CTRLInterfaceTRX - unified control interface handler for
    common transceiver management commands, such as POWERON,
    RXTUNE, and SETSLOT. Deprecates both CTRLInterface{BB|BTS}.

  - FakeTRX - basically, a child of Transceiver, extended with
    RF path (burst loss, RSSI, TA, ToA) simulation. Implements
    a custom CTRL command handler for CTRLInterfaceTRX.

The following classes were refactored:

  - BurstForwarder - still performs burst forwarding, but now
    it doesn't store any simulation parameters, and doesn't
    know who is BTS, and who is MS. Actually, BurstForwarder
    transforms each L12TRX message into a TRX2L1 message, and
    dispatches it between running transceivers with matching
    RX frequency and matching timeslot.

  - FakePM - still generates random RSSI values, but doesn't
    distinguish between MS and BTS anymore. As soon as a
    measurement request is received, it attempts to find
    at least one running TRX on a given frequency.

Please note that fake_trx.py still does handle only a single pair
of MS and BTS. No regressions have been observed. Both new and
refactored classes were documented.

Change-Id: Ice44e2b22566b3652ef6d43896055963b13ab185
Related: OS#3667
2018-12-18 05:47:11 +07:00
Vadim Yanitskiy 1dcc45beff trx_toolkit/ctrl_if.py: read data from socket in handle_rx()
It makes much more sense to read data from socket in handle_rx(),
instead of expecting a buffer with received data from caller.

Change-Id: I83479c60c54e36a2a7582714a6043090585957ae
2018-12-11 23:58:18 +07:00
Vadim Yanitskiy 59debdcd07 trx_toolkit: merge copyright.py into app_common.py
Since we have introduced ApplicationBase class, that are used
by all existing applications, let's merge the copyright
printing helper into it.

Change-Id: I8b70ec2dd08cb2ffed733d2c4e1215b094f8d3d5
2018-12-08 02:10:50 +07:00
Vadim Yanitskiy cdf349bc64 trx_toolkit: introduce logging configuration arguments
Before this change, it was impossible to configure logging
parameters from command line, such as log level and format.

This change introduces the following optional arguments:

  --log-level - logging level for stderr (by default, DEBUG);
  --log-format - logging message format for stderr;

  --log-file-name - enable logging to a given file;
  --log-file-level - logging level for file (by default, DEBUG);
  --log-file-format - logging message format for file;

which are defined in a new class called ApplicationBase, so
all existing applications should inherit them now.

Change-Id: Ic3b0440cd73946ad444bd7e48feb7a92d45f6488
2018-12-08 02:10:20 +07:00
Vadim Yanitskiy 5cb7e287ed trx_toolkit/fake_trx.py: migrate from getopt to argparse
Change-Id: I0218a328671c591b20b0666dc7c39ba865892acc
2018-12-07 08:20:37 +07:00
Vadim Yanitskiy 6bab6acee6 trx_toolkit: use generic logging module instead of print()
There are multiple advantages of using Python's logging module:

  - advanced message formatting (file name, line number, etc.),
  - multiple logging targets (e.g. stderr, file, socket),
  - logging levels (e.g. DEBUG, INFO, ERROR),
  - the pythonic way ;)

so, let's replace multiple print() calls by logging calls,
add use the following logging message format by default:

  [%(levelname)s] %(filename)s:%(lineno)d %(message)s

Examples:

  [INFO] ctrl_if_bts.py:57 Starting transceiver...
  [DEBUG] clck_gen.py:87 IND CLOCK 26826
  [DEBUG] ctrl_if_bts.py:71 Recv POWEROFF cmd
  [INFO] ctrl_if_bts.py:73 Stopping transceiver...
  [INFO] fake_trx.py:127 Shutting down...

Please note that there is no way to filter messages by logging
level yet. This is to be introduced soon, together with argparse.

Change-Id: I7fcafabafe8323b58990997a47afdd48b6d1f357
2018-12-07 05:36:20 +07:00
Vadim Yanitskiy 72c8296bfe trx_toolkit/fake_trx.py: drop randomization related cmd options
The randomization of both UL/DL RSSI and ToA values is optional,
and can be configured from the control interface (see both
FAKE_RSSI and FAKE_TOA commands).

The command line options for enabling / disabling the randomization
were redundant, so let's get rid of them and check if the
corresponding treshold value is set.

Change-Id: I6adc13b8989ade2fab895673525c0ca17bf9b3f2
2018-12-07 03:06:54 +07:00
Pau Espin 55afe0072b trx_toolkit: Add cmdline arg to set bind addr
Previous hardcoded default of 0.0.0.0 was inappropiate in some
scenarios, as it sets the SRC addr of the packets sent through the
socket based on the routing.

For instance, if iface IF1 has assigned two IP addresses A and B,
A being the first addr of the interface, and osmo-bts-trx is
configured with "osmotrx ip local A" and "osmotrx ip remote B",
the following happens:

  CMD POWER OFF src=A:5801 dst=B:5701
  RSP POWER OFF src=A:5701 dst=A:5701 <-- A is assigned as src addr.

But osmo-bts-trx is waiting for packets from B:5701, and the packet
is dropped with ICMP Unreachable. If addr binding is forced in
fake_trx to B, then everthing's fine.

Let's extend the UDPLink in order to allow manual, but optional
setting of bind address, and add a corresponding cmdline
argument to all executables.

Change-Id: I7be18fef40967fb7551f4115f22cbbd9cdb0840d
2018-04-04 17:14:26 +00:00
Vadim Yanitskiy 23914b9cf8 Rename 'fake_trx' to 'trx_toolkit'
This toolkit has branched out into several different tools for
TRX interface hacking, and creating a virtual Um-interface
(FakeTRX) is only one of its potential applications.

Change-Id: I56bcbc76b9c273d6b469a2bb68ddc46f3980e835
2018-03-13 02:10:02 +07:00