osmo-bts-trx: check if scheduling of [dummy] FACCH/H is allowed

Currently (without this patch) if tch_dl_dequeue() yields nothing we're
scheduling dummy FACCH/H *regardless* if it's permitted to start at the
given TDMA FN or not.  This may result in misaligned FACCH transmission,
so the MS will not able to decode anything and will report BER>0.

With this patch applied we schedule FACCH/H if it's allowed to start
at the current TDMA FN;  otherwise send half-filled bursts with even
numbered bits contaning 232 encoded bits of the previous L2 frame
and 232 odd numbered bits all set to 0.

This patch does not guard against sporadic gaps in the Downlink TCH
queue.  However when tch_dl_dequeue() constantly yields nothing, e.g.
when we end up with a codec mismatch, then this additional check saves
us from starting misaligned FACCH/H transmission.  If we start at a wrong
TDMA offset, then all subsequent FACCH frames will be scheduled at wrong
offsets and thus none of them will be decoded by the MS.

Change-Id: I6f8af140a6ccf3d5fd7b98f6cb5c18e2c5e2f61b
Related: SYS#5919, OS#4823
This commit is contained in:
Vadim Yanitskiy 2022-04-19 19:37:54 +03:00 committed by laforge
parent 0fb9517fed
commit 11fb108221
2 changed files with 13 additions and 1 deletions

View File

@ -998,7 +998,7 @@ static int rts_tchf_fn(const struct l1sched_ts *l1ts, const struct trx_dl_burst_
/* FACCH/H channel mapping for Downlink (see 3GPP TS 45.002, table 1).
* This mapping is valid for both FACCH/H(0) and FACCH/H(1). */
static const uint8_t sched_tchh_dl_facch_map[26] = {
const uint8_t sched_tchh_dl_facch_map[26] = {
[4] = 1, /* FACCH/H(0): B0(4,6,8,10,13,15) */
[5] = 1, /* FACCH/H(1): B0(5,7,9,11,14,16) */
[13] = 1, /* FACCH/H(0): B1(13,15,17,19,21,23) */

View File

@ -75,6 +75,9 @@ static const uint8_t sched_tchh_ul_facch_map[26] = {
[3] = 1, /* FACCH/H(1): B2(18,20,22,24,1,3) */
};
/* TDMA frame number of burst 'a' is used as the table index. */
extern const uint8_t sched_tchh_dl_facch_map[26];
/*! \brief a single TCH/H burst was received by the PHY, process it */
int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)
{
@ -407,6 +410,15 @@ int tx_tchh_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br)
};
LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "No TCH or FACCH prim for transmit.\n");
/* FACCH/H can only be scheduled at specific TDMA offset */
if (!sched_tchh_dl_facch_map[br->fn % 26]) {
/* FACCH/H is not allowed, send half-filled bursts with even numbered
* bits contaning 232 encoded bits of the previous L2 frame, and 232
* odd numbered bits all set to 0. */
goto send_burst;
}
gsm0503_tch_hr_encode(*bursts_p, dummy, sizeof(dummy));
chan_state->dl_ongoing_facch = 1;
chan_state->dl_facch_bursts = 6;