fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/38316?usp=email )
Change subject: l1sap: ensure DL RLP frame alignment for TCH/F4.8 NT ......................................................................
l1sap: ensure DL RLP frame alignment for TCH/F4.8 NT
Related: OS#6578 Change-Id: Ic8ec1a5d84950d27b22fd7491d5e4a82ace9fd62 --- M include/osmo-bts/csd_v110.h M src/common/csd_v110.c M src/common/l1sap.c M tests/csd/csd_test.c 4 files changed, 31 insertions(+), 7 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/16/38316/1
diff --git a/include/osmo-bts/csd_v110.h b/include/osmo-bts/csd_v110.h index f1c1027..54a6745 100644 --- a/include/osmo-bts/csd_v110.h +++ b/include/osmo-bts/csd_v110.h @@ -22,4 +22,4 @@ int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp, const uint8_t *data, size_t data_len, uint32_t fn); int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data, - const uint8_t *rtp, size_t rtp_len); + const uint8_t *rtp, size_t rtp_len, uint32_t fn); diff --git a/src/common/csd_v110.c b/src/common/csd_v110.c index d25eb7b..f214735 100644 --- a/src/common/csd_v110.c +++ b/src/common/csd_v110.c @@ -158,7 +158,7 @@ }
int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data, - const uint8_t *rtp, size_t rtp_len) + const uint8_t *rtp, size_t rtp_len, uint32_t fn) { const struct csd_v110_frame_desc *desc; ubit_t ra_bits[80 * 4]; @@ -187,6 +187,23 @@ ra_bits[i] = (rtp[i] >> 7); }
+ /* TCH/F4.8 NT: check RLP frame alignment */ + if (lchan->tch_mode == GSM48_CMODE_DATA_6k0 && + lchan->csd_mode == LCHAN_CSD_M_NT) { + const ubit_t e2 = csd_v110_tchf48_nt_e2_map[fn % 26]; + const ubit_t *e_bits; + + /* check bits E2/E3 in the 1st V.110 frame */ + e_bits = &ra_bits[0 * 80 + 5 * 8 + 1]; + if (e_bits[1] != e2 || e_bits[2] != 0) + return -EAGAIN; + /* check bits E2/E3 in the 2nd V.110 frame */ + e_bits = &ra_bits[1 * 80 + 5 * 8 + 1]; + if (e_bits[1] != e2 || e_bits[2] != 1) + return -EAGAIN; + /* -EAGAIN means postpone transmission */ + } + /* RA1'/RA1: convert from an intermediate rate to radio rate */ for (unsigned int i = 0; i < desc->num_blocks; i++) { struct osmo_v110_decoded_frame df; diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 85e986d..3f7aa6a 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -1635,11 +1635,11 @@
memcpy(&rtp[0], msgb_l2(resp_msg), OSMO_MIN(msgb_l2len(resp_msg), sizeof(rtp))); - msgb_get(resp_msg, msgb_l2len(resp_msg));
int rc = csd_v110_rtp_decode(lchan, msgb_l2(resp_msg), - &rtp[0], sizeof(rtp)); + &rtp[0], sizeof(rtp), fn); if (rc > 0) { + msgb_get(resp_msg, msgb_l2len(resp_msg)); msgb_put(resp_msg, rc); /* 'fake' tch_ind containing all-zero so gsmtap code can be shared * between UL and DL */ @@ -1648,8 +1648,15 @@ msgb_l2(resp_msg), msgb_l2len(resp_msg)); } else { - rate_ctr_inc2(trx->bts->ctrs, BTS_CTR_RTP_RX_DROP_V110_DEC); - msgb_free(resp_msg); + if (rc == -EAGAIN) { + /* enqueue back, postpone transmission + * XXX: we don't have msgb_enqueue_tail[_count]() */ + llist_add(&resp_msg->list, &lchan->dl_tch_queue); + lchan->dl_tch_queue_len++; + } else { + rate_ctr_inc2(trx->bts->ctrs, BTS_CTR_RTP_RX_DROP_V110_DEC); + msgb_free(resp_msg); + } resp_msg = NULL; resp_l1sap = &empty_l1sap; } diff --git a/tests/csd/csd_test.c b/tests/csd/csd_test.c index bef0ec8..0ca7209 100644 --- a/tests/csd/csd_test.c +++ b/tests/csd/csd_test.c @@ -136,7 +136,7 @@ fprintf(stderr, " %s\n", osmo_hexdump(&rtp[i * 16], 16));
/* decode the encoded RTP frame */ - rc = csd_v110_rtp_decode(&lchan, &data_dec[0], &rtp[0], sizeof(rtp)); + rc = csd_v110_rtp_decode(&lchan, &data_dec[0], &rtp[0], sizeof(rtp), 0); fprintf(stderr, "[i] csd_v110_rtp_decode() returns %d\n", rc); if (rc != bit_num) return;