Since commit 221ee92551,
bts_model_trx_deact_rf() was being called when RF locking the TRX, which
was implemented by resetting the scheduler. This proved to be a messy
and wrong way to emulate disabling RF, since it modifies tate on lots of
structures from which it is later difficult to recover from, causing
bugs and issues like:
82a35a1dbfbe15a12c87eef420d1cahttps://osmocom.org/issues/4694https://osmocom.org/issues/4695https://osmocom.org/issues/4696https://osmocom.org/issues/4697
So for all these reasons, it is believed a good solution to avoid
resetting the scheduler and simply ask lower layers (osmo-trx) to take
care of disabling RF TX/RX on a given TRX. For TRX implementations not
supporting the newly added RFMUTE command, ramping down to -10dBm still
provides for a way to emulate RF locking. In any case, none of this was
supported until recently so it's not like we are breaking some feature
here.
Related: SYS#4920
Change-Id: I1423ddb390ef327ec7d4a27de2ac5dca663773a5
The idea behind the baseband frequency hopping is quite simple: we
have several RF carriers (transceivers) transmitting and receiving
on fixed frequencies (just like in a regular multi-trx setup), and
an additional burst routing layer between the schedulear and the
transceiver interface (TRXD over UDP).
Speaking in terms of the proposed implementation:
- on Downlink, dlfh_route_br() calculates the ARFCN corresponding
to the current TDMA frame number according to the hopping sequence
parametets, and picks the transceiver with matching ARFCN;
- on Uplink, ulfh_route_bi() iterates over the transceiver list of
of the BTS, calculating hopping ARFCNs for equivalent timeslots,
and picks the one with ARFCN matching the received burst.
In order to avoid frequent transceiver lookups on the Downlink path,
dlfh_route_br() maintains a "cache" in the timeslot state structure.
Unfortunately, this "cache" seems to be useless on the Uplink path,
so ulfh_route_bi() always needs to lookup the matching transceiver
for each burst received over the TRXD interface.
It may also happen that the scheduler will be unable to route an
Uplink or Downlink burst, e.g. due to inconsistent / incorrect
hopping sequence parameters received from the BSC, or in case
if a transceiver gets RF-locked by the BTS operator.
Such events are logged as "FATAL" and aditionally signalled by the
following osmo-bts-trx specific rate counters:
- trx_sched:dl_fh_no_carrier (Downlink), and
- trx_sched:ul_fh_no_carrier (Uplink).
Change-Id: I68f4ae09fd0789ad0d8f1c1e17e17dfc4de8e462
Related: SYS#4868, OS#4546
The state of each config required is now tracked through the "acked"
variables, this way the FSM can know when all configs are confirmed by
the TRX and can proceed to submit POWERON command.
With this version each TRX is still totally independent (there's an FSM
per TRX), which means POWERON can be sent on TRX0 before TRX!=0 are
fully configured. As a result, powe ramping may start before we know the
NOMTXPOWER of a TRX. This kind of issue will be fixed in next commit.
Related: SYS#4920
Change-Id: I1b736a4be5ce52a854f5767d8609153e1f4c08d9
With prior code state managing the TRXC side of osmo-bts-trx, there are
plenty o cases (race conditions) where things can go wrong/unexpected,
because there's really no infrastructure to wait and synchronize between
different TRXs (eg wait until all are configured to POWERON), or to
simply keep well known per-trx state regarding lower layers.
In order to fix in the future all of those issues and to sanitize
current code, a new per-trx FSM is introduced, which takes care of
submitting TRXC commands and waiting for response when needed to manage
the state of the TRX.
Related: OS#4364
Change-Id: I2a00c23df15840e33fbb232c9e1dd6db128f63f6
Using the VTY command will force that value and prevent osmo-bts-trx to
use/send NOMTXPOWER cmd over TRXC.
Change-Id: I496753bc74767a7e18b831768d9d422a738192b7
This change is similar to what we did for Uplink bursts:
- group all Downlink burst parameters into a single structure,
- allocate it once and pass a pointer to lchan handlers,
- pass a pointer to trx_if_send_burst().
Given that the structure is allocated and (zero-)initialized in
trx_sched_fn(), we can get rid of some memset() calls in lchan
handlers and thus improve the overall performance a bit.
Change-Id: If3014e69746559963569b77561dbf7b163c68ffa
The nominal transmit power is still only configurable manually from
osmo-bts-trx VTY interface. Support to retrieve the nominal power
from osmo-trx will come later.
Change-Id: Ia7c353e4c199e0fc3bcab55c45a4abda2c66d2c1
A NOPE.ind indicates absence of an Uplink burst, thus it does not
carry a burst. Let's init the burst length to avoid uninitialized
memory access in the scheduler code.
Change-Id: I77f686bf7df385215892e71733a28ff0d90d7222
Fixes: CID#205857
Each logical channel can now optionally have an additional handler,
that will be called when a NOPE / IDLE indication is received from
the transceiver. The aim of that handler is to keep the logical
channel state updated in case if one or more Uplink bursts are lost.
Change-Id: I71c552f44c25e56e9779d8b8ef5d4de9f8475637
Related: OS#3428
This variable meaning has been changing its exact meaning over time
until finally not being really clear which kind of state it holds.
Initially it seemed to be used to identfy whether CLOCK IND were being
received. However, over time both osmo-bts and osmo-trx have evolved and
were fixed so that clock indications are only sent by osmo-trx after
POWERON command is sent. As a result, this state can be checked simply by
looking at the "powered" phy_link variable, which is only set to true
once the TRX has confirmed the POWERON command, and hence it is sending
CLOCK IND.
On the other hand, at some point in time "available" started to be set to 1
in bts_model_phy_link_open(), which means available is nowadays almost
always 1 from startup until the end (only dropped during bts_shutdown(),
when we are already exiting the process anyway).
As a result, !available condition in scheduler_trx.c:trx_fn_timer_cb can
almost never happen, because available is set to true already. Only
possibility would be if an old process of osmo-trx (not set up by this
BTS process) is still sending CLOCK INDs, but in that case we for sure
don't want to configure the BTS based on that, but ignore them until
this BTS process has again configured the TRX. So that whole check can
be dropped. We are better checking for "powered" state, which is far
more accurate, and we better do that in trx_if.c before calling
trx_fn_timer_cb().
Other uses of "transceiver_available" being used can be changed to use
plink->state!= PHY_LINK_SHUTDOWN, since available was already being set
to 1 at the same time the plink->state was being set to
PHY_LINK_CONNECTING.
As a result of this state handling re-arrangement, OS#4215 is fixed
since trx_if_powered() is used instead of previous state condition to
check whether data frames should be sent.
Related: OS#4215
Change-Id: I35f4697bd33dbe8a4c76c9500b82c16589c701d4
Use of variables in each code is confusing and mixing configuration with
POWERON/POWEROFF state (which is at least per phy inst and not per TRX,
since those commands are only expected on the 1st phy inst).
* field "poweron" becomes "enabled", and is used as an indicator for
actions to take during TRX provisioning (hether to power it on and
configure it or to power it off).
* poweron/poweroff state becomes "powered", and it is shared by all trx
in same phy_link, and is updated only after confirmation by TRX.
* poweron_set becomes poweronoff_set (because it's used by both POWERON
and POWEROFF), and becomes shared by all trx in same phy_link, since
those CMDs are usually sent by first phy instance of the link (the first
trx).
Related: OS#4215
Change-Id: Icd0b482f1454236432e1952220bbec9d178b8607
Both TRX2L1 (Uplink) and L12TRX (Downlink) messages should use
the same TRXD header format (and version) as was negotiated.
Change-Id: Idbc598ef7c1871ee8da830f3fbe0a5cc386f873d
Related: OS#4006
This change introduces a new command for TRXD header format
negotiation - SETFORMAT. If the transceiver does not support
the format negotiation, it would reject this command with
'RSP ERR 1'. 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 SETFORMAT command 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,
OsmoBTS 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 would 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.
Change-Id: I8afe950bd1ec2afaf3347ff848ee46e69c4f5011
Related: OS#4006
Since we may have different versions of the TRXD header, some new
fields of an Uplink burst indication have conditional presence.
Therefore we need a smart function to print them conditionally.
Change-Id: I68729dc98a1840d2aa9e091153d176a103d5a228
Related: OS#4006
This kind of debugging can be done using trx_sniff.py tool from
the TRX Toolkit [1]. Probably, this code was needed during the
initial development and testing.
[1] https://git.osmocom.org/osmocom-bb/tree/src/target/trx_toolkit
Change-Id: I50e0e5feeba4c3028f55209dd8e41e09ed5f70b1
The new version adds the following fields to the TRX2L1 message,
keeping the L12TRX message unchanged:
+------+-----+-----+-----+--------------------+
| RSSI | ToA | MTS | C/I | soft-bits (254..0) |
+------+-----+-----+-----+--------------------+
- MTS (1 octet) - Modulation and Training Sequence info, and
- C/I (2 octets) - Carrier-to-Interference ratio (big endian).
== Coding of MTS: Modulation and Training Sequence info
3GPP TS 45.002 version 15.1.0 defines several modulation types,
and a few sets of training sequences for each type. The most
common are GMSK and 8-PSK (which is used in EDGE).
+-----------------+---------------------------------------+
| 7 6 5 4 3 2 1 0 | bit numbers (value range) |
+-----------------+---------------------------------------+
| . . . . . X X X | Training Sequence Code (0..7) |
+-----------------+---------------------------------------+
| . X X X X . . . | Modulation, TS set number (see below) |
+-----------------+---------------------------------------+
| X . . . . . . . | IDLE / nope frame indication (0 or 1) |
+-----------------+---------------------------------------+
The bit number 7 (MSB) is set to high when either nothing has been
detected, or during IDLE frames, so we can deliver noise levels,
and avoid clock gaps on the L1 side. Other bits are ignored,
and should be set to low (0) in this case.
== Coding of modulation and TS set number
GMSK has 4 sets of training sequences (see tables 5.2.3a-d),
while 8-PSK (see tables 5.2.3f-g) and the others have 2 sets.
Access and Synchronization bursts also have several synch.
sequences.
+-----------------+---------------------------------------+
| 7 6 5 4 3 2 1 0 | bit numbers (value range) |
+-----------------+---------------------------------------+
| . 0 0 X X . . . | GMSK, 4 TS sets (0..3) |
+-----------------+---------------------------------------+
| . 0 1 0 X . . . | 8-PSK, 2 TS sets (0..1) |
+-----------------+---------------------------------------+
| . 0 1 1 X . . . | AQPSK, 2 TS sets (0..1) |
+-----------------+---------------------------------------+
| . 1 0 0 X . . . | 16QAM, 2 TS sets (0..1) |
+-----------------+---------------------------------------+
| . 1 0 1 X . . . | 32QAM, 2 TS sets (0..1) |
+-----------------+---------------------------------------+
| . 1 1 1 X . . . | RESERVED (0) |
+-----------------+---------------------------------------+
== C/I: Carrier-to-Interference ratio
The C/I value is computed from the training sequence of each burst,
where we can compare the "ideal" training sequence with the actual
training sequence, and then express that difference in centiBels.
== Limitations
- The only supported modulation types are GMSK and 8-PSK.
Messages with other modulation types will be rejected.
- IDLE / NOPE indications are not (yet) handled.
- The logical channel handlers do not (yet) handle optional
fields, such as TSC and C/I. This will be implemented
in the follow-up changes.
Change-Id: If61c71d20d590bf07bfd019afb33000a0b6135bd
Related: OS#4006
It may be necessary to extend the message specific header with
more information. Since this is not a TLV-based protocol, we
need to include the header format version.
+-----------------+---------------------------+
| 7 6 5 4 3 2 1 0 | bit numbers (value range) |
+-----------------+---------------------------+
| X X X X . . . . | header version (0..15) |
+-----------------+---------------------------+
| . . . . . X X X | TDMA TN (0..7) |
+-----------------+---------------------------+
| . . . . X . . . | RESERVED (0) |
+-----------------+---------------------------+
Instead of prepending an additional byte, it was decided to use
4 MSB bits of the first octet, which used to be zero-initialized
due to the value range of TDMA TN (0..7). Therefore the current
header format has implicit version 0.
Otherwise Wireshark (or trx_sniff.py) would have to guess the
header version, or alternatively follow the control channel
looking for the version setting command.
This change introduces a new structure 'trx_ul_burst_ind', which
represents an Uplink burst and the corresponding meta info. The
purpose of this structure is to avoid overloading the existing
functions, such as trx_sched_ul_burst(), with more and more
arguments every time we bump the version.
On receipt of a TRXD message, trx_data_read_cb() now parses
the header version, and calls the corresponding dissector
functions, e.g. trx_data_handle_(hdr|burst)_v0().
Change-Id: I171c18229ca3e5cab70de0064a31e47c78602c0c
Related: OS#4006
This constant actually defines the maximum TRXD message length,
which includes the header and burst bits, not just burst.
Change-Id: I383125e1c4df039fc6b554833bc8736deacbe731
This way we unify format. We take the chance to add related information
to some log messages which were not printing that information (and was
confusing when using more than one phy instance).
Change-Id: I5b17a01638ade9a6c41da73e550d5947fa92f568
Later on it's expected to add more rsp parsing, so let's return here and
not depend on generic return further down.
Change-Id: I8ddee46374ab329c47dc68e720e236f13d393f66
If POWERON fails, announce to BSC that the TRX is not available, and
announce it as available as soon as POWERON success is received.
Related: OS#3692
Change-Id: Iaa8f497381038fd7f9f779a8211ebc6453837c65
The setup is only needed once, so no need to set it every time we want
to schedule it.
Furthermore, it will ease new code introduced in follow-up patches,
which will schedule this timer under some circumstances without need to
send a message at the same time (because re-try of a cmd after a delay
is wanted).
This commit adds an alloc function and an init function to keep
different parts of the code decoupled and avoid exposing more
implementation details between them (like exposing the trx_if timer).
Change-Id: I3b6461d0130d25284e673c5efce0b3832c48bbb5
There's no need to express TOA as a float:
* We receive it as signed 16bit integer in units 1/256 symbol periods
* We pass it to L1SAP as signed integer in 1/4 symbol periods
So turn it into an int16_t with 1/256 symbol period accuracy throughout
the code to avoid both float arithmetic as well as loosing any precision.
Change-Id: Idce4178e0b1f7e940ebc22b3e2f340fcd544d4ec
It was detected that under some conditions, osmo-trx (with limesdr)
may take a long time to answer to CMDs, which means trx_ctrl_timer will
trigger re-transmitting the last sent but yet unacked CMD. Due to the
high latency in osmo-trx, the original AND the rentrasnmited CMD are
handled after a while and RSP messages are sent for both. When
osmo-bts-trx receives the first RSP, it was marking the CMD as acked and
carried on with next one. Then, when the RSP from the retransmited CMD
arrives, it already lost state and doesn't know where does that come
from. As a result, osmo-bts-trx shutdowns.
The issue can be seen in the following truncated log from osmo-bts-trx
with TRX category enabled:
20180117135228175 Enqueuing TRX control command 'CMD RXTUNE 1782000'
20180117135228175 Enqueuing TRX control command 'CMD TXTUNE 1877000'
20180117135228175 Enqueuing TRX control command 'CMD SETTSC 7'
20180117135228175 Enqueuing TRX control command 'CMD POWERON'
20180117135228175 Enqueuing TRX control command 'CMD SETRXGAIN 1'
20180117135228175 Enqueuing TRX control command 'CMD SETPOWER 20'
20180117135228175 Enqueuing TRX control command 'CMD SETSLOT 0 5'
...
20180117135249829 Response message: 'RSP POWEROFF 0'
20180117135249855 Response message: 'RSP RXTUNE 0 1782000'
20180117135249876 Response message: 'RSP TXTUNE 0 1877000'
20180117135249876 Response message: 'RSP SETTSC 0 7'
20180117135250648 Response message: 'RSP POWERON 0'
20180117135251150 Response message: 'RSP SETRXGAIN 0 0'
20180117135253151 No response from transceiver for phy0.0 (CMD SETPOWER 20)
20180117135253777 Response message: 'RSP SETPOWER 0 20'
20180117135254535 Clock indication: fn=2018878
20180117135255777 No response from transceiver for phy0.0 (CMD SETSLOT 0 5)
...
20180117135256858 Response message: 'RSP SETPOWER 0 20'
20180117135256858 Discarding duplicated RSP from old CMD 'RSP SETPOWER 0 20'
20180117135256858 Response message: 'RSP SETSLOT 0 0 5'
20180117135256858 Response message: 'RSP SETSLOT 0 0 5'
20180117135256858 Discarding duplicated RSP from old CMD 'RSP SETSLOT 0 0 5'
Change-Id: I3633cba212edde878f83ed36aef922aaca6f503a
First the cached CMD sent (struct trx_ctrl_msg) is reworked to have the
cmdname and the params in different buffers for easier comparison with
RSP later.
For the receive path (trx_ctrl_read_cb), new function helpers are added
to parse the buffer into cmdname+params+code (parse_rsp) and to compare
if a given RSP matches the current CMD we sent (cmd_matches_rsp).
The reasoning behind this patch is that a way to check for parameters
when receiving a RSP will be needed in future work, as before this patch
checking of parameters is ignored. This commit is a preparation for commit
to check for duplicated responses.
Change-Id: I2474cbc3e4457cf04f78e1c168768295e1132034
The move includes a small logic change: If there's a mismatch between
the rsp and the cmd, now we bts_shutdown instead of blindly skipping
expected RSP and continuing with sending the next CMD in the queue. The
change is specially not a problem since next patches are improving the
logic furthermore to account for duplicates, different parameters, etc.
Change-Id: I7018ded23fe51f364f248ade111aaa80ef46187e
While debugging other protocol/timing issues between osmobts-trx and osmo-trx,
I found that sometimes two consecutives "POWER OFF" commands are
enqueued and sent to osmo-trx.
There's no point in doing so, as the write queue already maintains state
and retries the command until a RSP is received, then goes for the next
one.
With this change we hence improve timing response as we don't need to
wait for the second command to be processed, and on top we get cleaner
logs and simplified states which are easier to debug.
Change-Id: Ib6a5e7bfac8bc5e1b372da6a1f801c07a3d5ebb7
In trx_clk_read_cb(), when calling phy_instance_by_num(), that
function might in error cases return a NULL phy-instance. Let's
put an OSMO_ASSERT() there as safeguard to avoid NULL dereference
when dereferencing pinst->trx->bts.
Fixes: Coverity CID#178657
Change-Id: If6b6b45380368e9ee9e03ca1eb7ac56c21e72b03
We unconditionally pass "p+1" into sscanf() despite not knowing
if 'p' is NULL or not.
Change-Id: I40a49c3feb3b55ef577eebd7d567afdbcfe0d624
Fixes: Coverity CID#178661
There's a lot of pointer arithmetic in trx_ctrl_read_cb which is
not so nice. While I believe the current code is safe, Coverity
raises "CID 178665: Insecure data handling (INTEGER_OVERFLOW)"
regardin the use of rsp_len in the strcmp().
Let's put some OSMO_ASSERT() in front and hope that makes Coverity
happy.
Change-Id: I5a9b3307f83cdde7c8e9f66932446604f5623b05