This patch brings decoding of the CS1 in consistency with the other
three coding schemes, for which we support decoding USF independently.
Change-Id: I61a3628741c0ac68374fc7f077cf3a07e51277c3
The USF (Uplink State Flag) field is present in the MAC header of all
Downlink PDCH blocks. It is used by the network to indicate which MS
can transmit on subsequent Uplink PDCH block(s). This field is of a
high importance for the MS, thus the decoder API allows the caller
to obtain USF value separately from the actual data bits.
In the case of gsm0503_pdtch_decode(), if the 'usf_p' pointer is not
NULL, the USF value would be assigned for CS2/CS3/CS4 (but not CS1)
even if the CRC check fails (negative return value). A subsequent
patch is to bring the CS1 in consistency with CS2/CS3/CS4.
In the case of gsm0503_pdtch_egprs_decode(), decoding of the USF
field separately from data bits is not implemented, and moreover
the function itself cannot be used for decoding Downlink blocks.
Change-Id: I43e8bfb4003f34766ace7c5c6080ca583ce5efbb
Similar to Change ID Iade3310e16b906efb6892d28f474a0d15204e861, add
BFI support to TCH AFS and TCH AHS encoder.
Every BTS needs to have some graceful handling for the scenario
where it is time to send out a speech frame on TCH DL, but there is
no frame to be sent. One possible solution is to transmit dummy
FACCH, but this option is unattractive for TCH/AHS where FACCH
displaces two speech frames rather than one. A more elegant solution
is to emit a speech frame with inverted CRC6, causing the MS receiver
to declare a BFI condition to trigger substitution and muting procedure.
Setting all u(k) bits to 0 is one way to produce such an inverted-CRC
speech frame (normal TCH FR/HR CRC6 for an all-zeros frame would be
111111). This patch adds the abiliy to gsm0503_tch_{afs,ahs}_encode()
functions, indicated by payload length of 0.
See §6.2 of 3GPP TS 26.191 for substitution and muting procedure.
Related: OS#6049
Change-Id: I82ce2adf995a4b42d1f378c5819f88d773b9104a
See 3GPP TS 45.003 section 3.6. This channel mode is a bit special,
because unlike the other CSD specific channel modes it's interleaved
over 8 (not 22!) consecutive bursts, just like TCH/FS.
Change-Id: I4685376c8deb04db670684c9ebf685ad6fc989fa
Related: OS#1572
Convolutional codes terminated with CONV_TERM_FLUSH (the default)
always append k-1 zeroes at the end to "flush" the encoder state.
This is the case for both TCH/F9.6 and TCH/F14.4.
Change-Id: I4a77ecb9af72b2fd4ea92c42d6748879e73d2cf2
Related: OS#1572
The spec isn't super clear, but basically the conv coding is done
in two blocks of 72 bits.
The way it's currently implemented isn't "wrong" in the sense it will
produce correct output given no bit errors, but it's better to do the
decoding in two blocks because this then it makes use of the fact we
know the state of the encoder after the 72 bits, which improves the
corrective ability of the code.
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Change-Id: Id2551ffe2a0ebfd0a6df0e1d288a6f0af7e1eda7
According to 3GPP TS 45.003, section 3.9.2, the convolutional coding
is *not* employed in the case of SID_FIRST. This is why we're using
sid_first_dummy[] in this function.
The conv[] array is not initialized in the case of AFS_SID_FIRST and
passing it to tch_amr_reassemble() is highly likely a copy-paste bug.
Pass the sid_first_dummy[] instead.
Change-Id: Ic8bfc34ce9d14821fe4e82932325f0c517d443a1
Fixes: CID#272949 "Uninitialized scalar variable"
Every BTS needs to have some graceful handling for the scenario
where it is time to send out a speech frame on TCH DL, but there is
no frame to be sent. One possible solution is to transmit dummy
FACCH, but this option is unattractive for TCH/HS where FACCH
displaces two speech frames rather than one. A more elegant
solution is to emit a speech frame with inverted CRC3, causing
the MS receiver to declare a BFI condition to its Rx DTX handler.
Setting all u(k) bits to 0 is one way to produce such an inverted-CRC
speech frame (normal TCH FR/HR CRC3 for an all-zeros frame would be
111), and this method is in fact what sysmoBTS PHY is observed to do.
Add the same ability to gsm0503_tch_{fr,hr}_encode() functions,
indicated by payload length of 0.
Change-Id: Iade3310e16b906efb6892d28f474a0d15204e861
These two functions are structured as switch statements handling
different types of input, but they also have a lot of empty spacing
lines in strange places, making them difficult to read and even more
difficult to add new functionality while maintaining the same style.
Remove those extra spaces.
Change-Id: I595a80898283d0932fb33f582347ec39a9481d1a
As was demonstrated in the unit test [1], FACCH bitstealing does not
work as expected in conjunction CSD specific encoding functions.
The problem is in _tch_csd_burst_map(): we don't check the stealing
flags hu(B) and hl(B) and overwrite both odd and even numbered bits
unconditionally. Even worse, we reset these stealing flags to 0.
* Do not overwrite the hu(B) and hl(B) flags.
* Copy *even* numbered bits only if hu(B) is not set.
* Copy *odd* numbered bits only if hl(B) is not set.
Change-Id: Ib5395c70e3e725469c18ff7d4c47c62ddfdbd55d
Related: [1] Idc6decec3b84981d2aab4e27caab9ad65180f945
Related: OS#1572
Currently FACCH/[FH] encoding and decoding is implemented as part of
the gsm0503_tch_[fh]r_{en,de}code and gsm0503_tch_a[fh]s_{en,de}code
API. This works fine for speech because one FACCH frame completely
replaces one or two speech frames, but this is not the case for CSD.
According to 3GPP TS 45.002, sections 4.2.5 and 4.3.5, for TCH data
channels FACCH does not replace data frames but disturbs some amount
of bits from them. Therefore we need to be able to perform FACCH
encoding and decoding independently from CSD specific coding API.
Change-Id: I0c7a9c180dcafe64e6aebe53518d3d11e1f29886
Related: OS#1572
Implement all CSD specific channel modes, except TCH/F2.4. All of
these modes are more or less similar to each other. The TCH/F2.4
is more similar to TCH/FS and slightly more complicated.
FACCH/F and FACCH/H will be implemented in a follow-up change.
Change-Id: Ib482817b5f6a4e3c7299f6e0b3841143b60fc93d
Related: OS#1572
The original design of gsm0503_tch_hr_{en,de}code() functions contains
a mistake in that a pseudo-RFC5993 format was chosen for HR codec frame
input and output, instead of "pure" (agnostic to outer RTP encoding)
form of 14 bytes. We would like to change this design so that we can
feed pure 14-byte HR codec frames to the channel coding function and
get such frames back from the channel decoding function - however,
we cannot break libosmocoding API for existing users. In the decoding
direction, create a new function that emits TS 101 318 format, and
turn the legacy gsm0503_tch_hr_decode() API into a wrapper function
for backward compatibility.
Related: OS#5688
Change-Id: If28ddb20789e8993b7558ca08020478615b4c708
The original design of gsm0503_tch_hr_{en,de}code() functions contains
a mistake in that a pseudo-RFC5993 format was chosen for HR codec frame
input and output, instead of "pure" (agnostic to outer RTP encoding)
form of 14 bytes. We would like to change this design so that we can
feed pure 14-byte HR codec frames to the channel coding function and
get such frames back from the channel decoding function - however,
we cannot break libosmocoding API for existing users. In the encoding
direction, make the new format our preferred one, but support the
extra-octet format for backward compatibility.
Related: OS#5688
Change-Id: I13eaad366f9f68615b9e9e4a5f87396a0e9dea0f
This function needs to look at hl and hu stealing bits in order to
decide if it should decode FACCH/H instead of TCH/HS traffic.
However, out of the 8 (in total) hl and hu bits that get set when
FACCH/H stealing takes place, the function only looked at 7 of them
- one was missed. Fix this bug.
Change-Id: I08c4358b26d69910190f89a53b654bc58c2efea9
In GSM 05.03 channel coding for EFR, there are 4 bits out of the
244-bit EFR codec frame that are triplicated before FR-like encoding,
and the decoder needs to apply a 2-out-of-3 majority voting function
to each of these triplicated bits after the FR-like decoding step.
For one of those 4 bits, this majority voting function was wrong
in the decoder implemented in gsm0503_tch_fr_decode() - fix it.
Change-Id: I47def75cdb066ed6372df4567404cc828589ed53
Currently there's a big mess where include dir osmocom/gprs/ is used by
both libosmogsm and libosmogb.
Most of the header files under osmocom/gprs/ are actually all the
headers of libosmogb (there's no osmocom/gb/ dir). But a couple files
are actually RLC/MAC (TS 44.060) related are are also stored in there.
Those files have no relation/use in Gb, and are actually interused with
GSM (eg System Information 13 Rest Octets).
Hence, it makes sense to have the RLC/MAC related parts inside
osmocom/gsm/ as they should be in libosmogsm (and they actually are,
see gprs_rlc.h function implemented in src/gsm/gsm48_rest_octets.c).
The fact that some libosmogsm headers were placed in osmocom/gprs
instead of osmocom/gsm already created some issues, like
libosmocore.spec.in putting "%_includedir/%name/osmocom/gprs/" under
libosmogb, which is wrong.
As a first step to fix the mess, we move the 2 RLC/MAC headers currently
under osmocom/gprs/{gprs_rlc,protocol/gsm_04_60}.h under a single header
gsm/protocol/gsm_44_060.h
The two old headers are left existing for backward compatibility and now
simply include the new libosmogsm header, plus a warning asking users to
switch to the new header so we can eventually get rid of them.
This means libosmogb depends on libosmogsm, which is fine and was
already the case beforehand (libosmogb using functions like
gsm48_encode_ra() and linking against it in src/gb/Makefile.am).
Change-Id: I70cc21bf25a7081070738abacb409ed19094c3b2
These functions can be re-used for parsing in-band data from DTX
specific frames like SID_FIRST, SID_UPDATE, SID_ONSET, etc.
Change-Id: I0106de7a7f87517006e323299b2dc08457d1c6cf
Related: OS#5570
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.
Change-Id: Ibcac395f800bb64150c97fcdaca3523ecfc5fcee
Related: OS#5570
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.
Change-Id: Ic4edbb8ab873fe0bdd69a8710803628bc4f447d0
Related: OS#5570
As was demonstrated in [1], 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.
Change-Id: I8686d895e96fa0e606c1898b6574cc80a8f46983
Related: [1] I434157e2091a306c039123cea08d84bd8533c937
Related: SYS#5853
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.
Change-Id: I2e6f4b748c6445725211e264ab5f3f5a2712087a
Related: SYS#5853
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.
Change-Id: I813081a4c0865958eee2496fe251ae17235ac842
Related: SYS#5853
"""
/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.
Change-Id: I31ebf0c4be61daf6395d9a9fac05c7fdceb8bcb9
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: I5050285e75cf120407a1d883e99b3c4bcae8ffd7
The encoder function gsm0503_tch_ahs_encode uses gsm0503_afs_ic_ubit
when encoding the CMR or FT (depends on the frame number). This is not
correct. It should use gsm0503_ahs_ic_ubit instead.
Change-Id: Id250b2102ac79ff222bd3ad9d1abc4b60abdd12b
Related: SYS#5549
gsm0503_coding contains AMR decoder functions for HR and FR. Those can
only decode AMR payload frames but not amr DTX frames. Lets add
functionality to detect DTX frames. Also lets add decoding for SID_UPDATE
frames as well as error checking for the SID frame recognition patterns.
Related: OS#2978
Change-Id: I2bbdb39ea20461ca08b2e6f1a33532cb55cd5195
osmo-gsm-tester raised an ASan warning in osmo-bts-trx during execution
of a test with EGPRS enabled and a modem connecting to it (see OS#4483
for full trace):
==12388==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7fa20b9ab8d0 at pc 0x7fa20b982894 bp 0x7ffdfea8b9c0 sp 0x7ffdfea8b9b8
READ of size 1 at 0x7fa20b9ab8d0 thread T0
#0 0x7fa20b982893 in gsm0503_mcs1_dl_interleave /home/osmocom-build/jenkins/workspace/osmo-gsm-tester_build-osmo-bts/libosmocore/src/coding/gsm0503_interleaving.c:165
Function gsm0503_mcs1_dl_interleave() was being passed the 6-bit USF
encoding while clrearly expecting a 12 element array. TS 05.03 5.1.5.1.2
"USF precoding" also clearly states that 12bit encoding is to be used
for MCS1-4.
Fixes: OS#4483
Change-Id: I94db14de770070b17894a9071aa14391d26e776c
According to 3GPP TS 44.004, figure 7.4a.b, the format of 11-bit
RACH uplink / Uplink access burst block is as defined follows:
<---------------------------------------------------
8 7 6 5 4 3 2 1
+--------------------------------------------------+
| 11 bit RACH uplink / Uplink access burst block | OCT1
+--------------------------------------------------+
| | OCT2
+-------------------+
As was (correctly) assumed in [1], the bit ordering in 11-bit RACH
coding functions is wrong. The problem is that neither of generic
functions from bit16gen.h can be used to load / store the RA11
value (regardless of the endianness), because they assume that
the payload is 16 bit long.
With this patch applied, RA11 values from [1] look correct:
< EGPRS Packet channel request message content > ::=
< Signalling : 110011 < RandomBits : 00111 > > |
< Signalling : 110011 < RandomBits : 00110 > > |
< Signalling : 110011 < RandomBits : 01111 > > |
< Signalling : 110011 < RandomBits : 01100 > > |
< Signalling : 110011 < RandomBits : 00111 > > |
< Signalling : 110011 < RandomBits : 10110 > > ;
[1] Id80e471d252b9416217b56f4c8c0a8f5f1289fee
Change-Id: I43d30611dd69f77f2b3b46f4b56056a8891d3c24
Related: OS#1548
Previsouly there were a lot of valid code paths which returned from the function
before setting bit counters which led to bogus BER output in osmo-bts-trx logs
when those code paths were hit.
Change-Id: I4722cae3794ccbb12001113c991d9cf345a52a96
Previously we didn't take into account puncturing and BER was always around
30% for GPRS/EDGE bursts because of they use puncturing coding unlike
"classical" GSM bursts.
Change-Id: I9da22e7051522d06d923fcec3b63cbed8db93910
For all other decode operations we report the BER, but not for the
RACH. This results in osmo-bts-trx not being able to report BER
to the higher layers, which is possible on other BTS backends.
Let's close this gap by introducing gsm0503_rach_ext_decode_ber()
and gsm0503_rach_decode_ber() with the usual n_errors / n_bits_total
arguments.
Change-Id: I2b1926a37bde860dcfeb0d613eb55a71271928c5
Since commit e094157e12, TCH frame
length definitions were added to libosmocodec.
No need to define them again.
Change-Id: Id8c6132534e36ea1e368432bb259fd4f3a531f90