This patch addes support for GlobalPlatform command. Android is using
STORE DATA commands on a logical channel.
simtrace2-cardem-pcsc is failing otherwise e.g. on an Pixel 4 with Android 12.
Once the IuUP FSM moved away from Init state, it stopped handling
Initialization messages received from peers and simply ignored them
starting from that point. As a result, if the first IuUP Init ACK it
sent to the peer was lost, the peer would keep retrying with more IuUP
Init and getting no answer.
In any case, it seems possible and desirable that a peer may send an
IuUP Init at a later point, as pointed out vaguely in 3GPP TS 25.415.
Upon reception of a frame indicating that an Initialisation procedure is
active in the peer Iu UP entity, the Iu UP protocol layer forwards the whole
protocol information contained in the INITIALISATION control frame to the
upper layers. It also stores the RAB sub-Flow Combination set (and thus
replaces a possible previous set) in order to control during the transfer of
user data, that the Iu UP payload is correctly formatted (e.g. RFCI matches
the expected Iu UP frame payload total length). The peer Iu UP entity
receiving the INITIALISATION control frame shall choose a version that it
supports among the proposed versions indicated by the sender for which it
has enough initialisation information.
sec B.2.2 "Initialisation State":
After sending a positive acknowledgement of the last INITIALISATION control
frame, the Iu UP instance enters SMpSDU data transfer ready state. Note that
CN does not know if the initialisation ACK was correctly received by the RNC
(and Initialisation procedure successfully completed) until it receives RAB
assignment response, or use data from the RNC. The CN must therefore be able
to continue receiving INITIALISATION control frames by re-entering the
Initialisation state (from Support Mode Data Transfer Ready State), if the CN
has started to send user data before receiving the indication that
Initialisation was successfully completed
sec B.2.3 "Support Mode Data Transfer Ready State":
In case of handover or relocation, Initialisation procedures may have to be
performed and Iu UP instance may have to enter the initialisation state.
This test shows a bug in IuUP stack which makes it only handle the first
Initialization IuUP message. After it moves to SMpSDU, it stops handling
A fix is provided in a follow up patch.
The event is expected since the user of the IuUP stack can send a
CONFIGURE.req to transition to state null. The handling was already
there in the function, but the bit was missing in the FSM definition.
The new functions accept an additional mode_id poiner, which is
currently set for the following frames: AFS_ONSET, AHS_ONSET,
AHS_SID_FIRST_P2 with N * 16 - M bit pattern.
Also, the new API accepts soft-bits instead of hard-bits.
Converting bits from soft to hard is now performed internally.
The initially merged IuUP API and implementation assumed that RFCI with
ID was always in the position of its ID inside the list of RFCIs. This
was the case for messages sent by ip.access nano3g as well as our own
osmocom implementation. However it was noticed that other nodes from
other vendors actually use other order, as allowed by the IuUP message
Hence, we need to break the assumption and provide explicit ID
information in the list.
NOTICE: This commit breaks API and ABI compatibility with older versions
of libosmogsm, but not with any previous release of libosmocore since
the API is only available in master so far (it was added in
Similary, it's only user (osmo-mgw) only uses the API in master, so
there's no API breakage with older releases.
Parsing of CMI/CMC/CMR from AMR's special DTX frames is currently
not implemented. It's better to keep the old stored value rather
than resetting it to 0 every time we receive such a frame.
Add TODO comments for each DTX frame type.
As was demonstrated in , there is a TCH/AHS specific problem in
libosmocoding causing unexpected BER ~50% in decoded AHS_SID_UPDATE
frames. The reason is that A[H]S_SID_UPDATE employs quite tricky
interleaving algorithm, which is different from the algorithm used
by normal TCH/AHS speech frames or A[F]S_SID_UPDATE frames.
An AHS_SID_UPDATE frame consists of two halves (228 bits each):
| in-band | SID marker | in-band | coded data |
| 16 bits | 212 bits | 16 bits | 212 bits |
The first half contains coded in-band signalling data (16 bits) and
the identification marker (212 bits), which allows to detect that
it's an AHS_SID_UPDATE. This half is carried by even bits of the
first two bursts and odd bits of the last two bursts.
The other half also contains the in-band data (16 bits), while the
remaining 212 bits contain encoded SID_UPDATE (212 bits). This
half is carried by even bits of the last two bursts and odd bits
of the first two bursts.
Current implementation does not use odd bits of the first two
bursts at all, so buffer cB in gsm0503_tch_ahs_decode_dtx()
contains only 114 out of 228 bits.
This patch changes the logic, so that gsm0503_tch_ahs_decode_dtx()
would not split AHS_SID_UPDATE onto two frames anymore like its
TCH/AFS equivalent does, but attempt to deinterleave the second
half and attempt to decode the payload immediately.
Related:  I434157e2091a306c039123cea08d84bd8533c937
At the moment msgb_apdu_de(resp) is used to check if the msgb that is
handed over to get_sw is properly populated with data.
However, since msgb_apdu_de() is just adding an offset, which cannot be
0 to ->l2h the returned value also can never be NULL. This means that we
cannot use msgb_apdu_de() to detect if resp contains a nullpointer.
Lets check if ->l2h is not NULL instead. This will make sure that ->l2h
This patch extends the existing unit test coverage for AMR's special
DTX frames. The new tests confirm that the problem with unexpected
BER in decoded AFS_SID_UPDATE frames has been actually fixed .
Additionally this patch demonstrates another TCH/AHS specific problem,
which negatively affects RxQual-SUB measurements in osmo-bts-trx: the
actual content of AHS_SID_UPDATE_CN is decoded with ~50% BER, because
the burst buffer contains only half of the burst bits.
Related:  I813081a4c0865958eee2496fe251ae17235ac842
Both gsm0503_tch_a[fh]s_decode_dtx() functions accept an optional
'dtx' pointer, which is used to indicate type of a received AMR
block to the caller in DTX mode of operation. If not NULL, it's
expected to be updated by gsm0503_detect_a[fh]s_dtx_frame() every
time one of the mentioned functions is called.
However, in case of FACCH both functions return early, so the value
of dtx remains unchanged and thus FACCH frames may be misinterpreted
as AMR's special DTX frames. This is rather critical during the DTX
silence periods, when all special DTX frames (e.g. SID_UPDATE) are
being treated as SUB frames. Each unsuccessful FACCH decoding
attempt will 'poison' SUB measurements, causing unexpected RxQual-
SUB values in the Uplink measurement reports.
Fix this by resetting *dtx to AMR_OTHER in the FACCH specific path.
There are two similar values in enum gsm0503_amr_dtx_frames:
* AFS_SID_UPDATE - precursor of SID UPDATE,
* AFS_SID_UPDATE_CN - the actual SID UPDATE.
The former is internally used by libosmocoding to mark the current
frame as a precursor of the actual SID UPDATE frame - the later.
| _ | _ | _ | _ | a | b | c | d | AFS_SID_UPDATE
| a | b | c | d | _ | _ | _ | _ | AFS_SID_UPDATE_CN
This is required because function gsm0503_tch_afs_decode_dtx() is
invoked by TDMA scheduler on every 4th received burst, while the
burst buffer is 8 bursts wide.
Currently, whenever gsm0503_detect_afs_dtx_frame() detects an
AFS_SID_UPDATE frame, we still attempt to decode it as a speech
or data below in gsm0503_tch_afs_decode_dtx(). This is indeed
a bug, which results in unexpected BER values:
* expected BER 0/212,
* actual BER 252/448.
We should return immediately once we have detected an AFS_SID_UPDATE.
This patch fixes unexpected BER-SUB values during DTXu silence periods.
The pointer is initialized in all its uses, however newer gcc warns
inlined from ‘main’ at /libosmocore/utils/osmo-arfcn.c:144:16:
/usr/include/bits/stdlib-float.h:27:10: error: ‘param’ may be used uninitialized [-Werror=maybe-uninitialized]
/libosmocore/src/coding/gsm0503_coding.c: In function 'osmo_conv_decode_ber_punctured':
/libosmocore/src/coding/gsm0503_coding.c:563:31: error: 'coded_len' may be used uninitialized [-Werror=maybe-uninitialized]
563 | *n_bits_total = coded_len;
/libosmocore/src/coding/gsm0503_coding.c:541:21: note: 'coded_len' was declared here
541 | int res, i, coded_len;
This error is really a false positive. However, it is true that the code
used to be a bit more complex than required, since the 2 later conditions
could be inside the first one.
Let's simply do early termination to simplify the function, and get rid
of the gcc warning.
The point of having a public API to register further stats reporters
is to enable applications or other libraries to do so. As we in
libosmocore don't know anything about the parameters of such a stats
reporter, don't try to do a partial save of them when saving the config
In many cases, a lot of the counters are zero, and we're likely
not interested in those, but only the non-zero counters. Add a version
of the 'show stats' command which dumps only those items with a non-zero
It was recently found that several IEs which were added in the header
file were not actually added to the tlv_definition, and hence the tlv
parser failed to decode them. Let's make sure we don't foget to add new
IEs in the future.
There are cases where we want to be notified of a successful BVC reset,
e.g. for a signalling because we can then start resetting the PtP-BVCs.
With this hook it's now possible to do that.
pthread_getname_np() is a non-portable extension of pthreads. While
it exists in glibc, for example musl didn't have it until rather
recently (April 2021) and there still hasn't yet been a musl release
with this change, resulting even current OpenWRT not yet supporting
So let's check if pthread_getname_np is supported, and only use it
in that case.
The libsctp use in libosmocore is internal, not exposed to applications.
Hence, it must not be in "Requires" but in "Requires.private".
Ever since Change-Id If76a4bd2cc7b3c7adf5d84790a944d78be70e10a in 2020
(part of libosmocore >= 1.4.0) we have introduced cpu_sched_vty.c, which
directly uses libpthread. As a result, libosmovty should be using
pthread compiler flags and link against libpthread.
This missing dependency is causing osmocom applications to
fail to link on OpenWRT (at leats for ath79-generic).
Now that the libosmo*.pc files 'Require' the libsctp pkg-config
file to be installed, we need an explicit package dependency
from libosmocore-devel to lksctp-tools-devel, the package providing
the related libsctp.pc file.
As our pkg-config files now 'Require' libsctp, we are seeing build
failures as libsctp-dev is not installed when building
libosmocore-dependant packages. Let's add the missing dependency.
According to the pkg-config manual, "Libs" should not contain flags
for _required_ packages. Instead, they should be expressed via
"Requires". Let's do that