fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bts/+/34991?usp=email )
Change subject: osmo-bts-trx: tx_tch[fh]_fn(): rework generation of dummy FACCH ......................................................................
osmo-bts-trx: tx_tch[fh]_fn(): rework generation of dummy FACCH
Even though it might have a somewhat higher performance impact, opting for the common code path for FACCH by allocating a msgb on heap is more favorable for both readability and maintainability.
This choice is preferred over directly calling gsm0503_tch_fr_encode() and then using a 'goto' statement. A similar strategy will be adopted in an follow up patch for CSD.
Change-Id: I67cb5c6f4d15149996e17c78a59d66db396da8ff Related: OS#1572 --- M src/osmo-bts-trx/sched_lchan_tchf.c M src/osmo-bts-trx/sched_lchan_tchh.c 2 files changed, 61 insertions(+), 28 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve fixeria: Looks good to me, approved falconia: Looks good to me, but someone else must approve
diff --git a/src/osmo-bts-trx/sched_lchan_tchf.c b/src/osmo-bts-trx/sched_lchan_tchf.c index 34af8a1..c0dfd47 100644 --- a/src/osmo-bts-trx/sched_lchan_tchf.c +++ b/src/osmo-bts-trx/sched_lchan_tchf.c @@ -490,6 +490,19 @@ } }
+struct msgb *tch_dummy_msgb(size_t size, uint8_t pad) +{ + struct msgb *msg; + + msg = msgb_alloc(size, __func__); + OSMO_ASSERT(msg != NULL); + + msg->l2h = msgb_put(msg, size); + memset(msg->l2h, pad, size); + + return msg; +} + /* obtain a to-be-transmitted TCH/F (Full Traffic Channel) burst */ int tx_tchf_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) { @@ -519,11 +532,6 @@ /* dequeue a TCH and/or a FACCH message to be transmitted */ tch_dl_dequeue(l1ts, br, &msg_tch, &msg_facch); if (msg_tch == NULL && msg_facch == NULL) { - static const uint8_t dummy[GSM_MACBLOCK_LEN] = { - 0x03, 0x03, 0x01, /* TODO: use randomized padding */ - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - }; int rc;
LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "No TCH or FACCH prim for transmit.\n"); @@ -541,13 +549,18 @@ case GSM48_CMODE_SPEECH_EFR: rc = gsm0503_tch_fr_encode(BUFPOS(bursts_p, 0), NULL, 0, 1); if (rc == 0) - break; + goto send_burst; /* fall-through */ + case GSM48_CMODE_SIGN: default: - gsm0503_tch_fr_encode(BUFPOS(bursts_p, 0), dummy, sizeof(dummy), 1); - chan_state->dl_facch_bursts = 8; + /* TODO: use randomized padding */ + msg_facch = tch_dummy_msgb(GSM_MACBLOCK_LEN, GSM_MACBLOCK_PADDING); + /* dummy LAPDm func=UI frame */ + msg_facch->l2h[0] = 0x03; + msg_facch->l2h[1] = 0x03; + msg_facch->l2h[2] = 0x01; + break; } - goto send_burst; }
/* Unlike SACCH, FACCH has no dedicated slots on the multiframe layout. diff --git a/src/osmo-bts-trx/sched_lchan_tchh.c b/src/osmo-bts-trx/sched_lchan_tchh.c index 77309cf..96ee5e8 100644 --- a/src/osmo-bts-trx/sched_lchan_tchh.c +++ b/src/osmo-bts-trx/sched_lchan_tchh.c @@ -399,6 +399,8 @@ extern void tch_dl_dequeue(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br, struct msgb **msg_tch, struct msgb **msg_facch);
+struct msgb *tch_dummy_msgb(size_t size, uint8_t pad); + /* obtain a to-be-transmitted TCH/H (Half Traffic Channel) burst */ int tx_tchh_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) { @@ -445,11 +447,6 @@
/* no message at all, send a dummy L2 frame on FACCH */ if (msg_tch == NULL && msg_facch == NULL) { - static const uint8_t dummy[GSM_MACBLOCK_LEN] = { - 0x03, 0x03, 0x01, /* TODO: use randomized padding */ - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - }; int rc;
LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "No TCH or FACCH prim for transmit.\n"); @@ -462,25 +459,30 @@ * and decide what is the correct BTS Tx behavior for frame * gaps in TCH/AHS. See OS#6049. */ - if (tch_mode == GSM48_CMODE_SPEECH_V1) { + switch (tch_mode) { + case GSM48_CMODE_SPEECH_V1: rc = gsm0503_tch_hr_encode(BUFPOS(bursts_p, 0), NULL, 0); if (rc == 0) goto send_burst; - } + /* fall-through */ + case GSM48_CMODE_SIGN: + default: + /* 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; + }
- /* 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; + /* TODO: use randomized padding */ + msg_facch = tch_dummy_msgb(GSM_MACBLOCK_LEN, GSM_MACBLOCK_PADDING); + /* dummy LAPDm func=UI frame */ + msg_facch->l2h[0] = 0x03; + msg_facch->l2h[1] = 0x03; + msg_facch->l2h[2] = 0x01; + break; } - - gsm0503_tch_hr_encode(BUFPOS(bursts_p, 0), dummy, sizeof(dummy)); - if (chan_state->rsl_cmode != RSL_CMOD_SPD_DATA) - chan_state->dl_ongoing_facch = 1; - chan_state->dl_facch_bursts = 6; - goto send_burst; }
/* Unlike SACCH, FACCH has no dedicated slots on the multiframe layout.