fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/35695?usp=email )
Change subject: mobile: properly handle different TRAFFIC.{ind,req} formats for CSD ......................................................................
mobile: properly handle different TRAFFIC.{ind,req} formats for CSD
So far we supported the Texas Instruments format (TCH_DATA_IOF_TI), which is used by Calypso based phones (e.g. Motorola C1xx), but not the format that trxcon speaks/understands (TCH_DATA_IOF_OSMO).
Change-Id: Ib17e800e91ad536db53aa55661076089f0ce34b0 Related: OS#4396 --- M src/host/layer23/src/mobile/tch_data.c 1 file changed, 44 insertions(+), 16 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/95/35695/1
diff --git a/src/host/layer23/src/mobile/tch_data.c b/src/host/layer23/src/mobile/tch_data.c index 451f267..06df85f 100644 --- a/src/host/layer23/src/mobile/tch_data.c +++ b/src/host/layer23/src/mobile/tch_data.c @@ -290,9 +290,7 @@ const struct gsm48_rr_cd *cd = &ms->rrlayer.cd_now; const struct csd_v110_frame_desc *desc; ubit_t data[4 * 60]; - - if (msgb_l3len(msg) < 30) - return -EINVAL; + size_t data_len;
if ((cd->chan_nr & RSL_CHAN_NR_MASK) == RSL_CHAN_Bm_ACCHs) desc = &csd_v110_lchan_desc[cd->mode].fr; @@ -301,18 +299,26 @@ if (OSMO_UNLIKELY(desc->num_blocks == 0)) return -ENOTSUP;
+ data_len = desc->num_blocks * desc->num_bits; + OSMO_ASSERT(sizeof(data) >= data_len); + switch (ms->settings.tch_data.io_format) { case TCH_DATA_IOF_OSMO: + /* trxcon emits raw bits from the convolutional decoder */ + if (OSMO_UNLIKELY(msgb_l3len(msg) != data_len)) + return -EINVAL; + memcpy(&data[0], msgb_l3(msg), msgb_l3len(msg)); break; case TCH_DATA_IOF_TI: - /* the layer1 firmware emits frames with swapped words (LE ordering) */ + /* the layer1 firmware emits packed bits (LE ordering) */ + if (OSMO_UNLIKELY(msgb_l3len(msg) < data_len / 8)) + return -EINVAL; + /* ... with swapped words (LE ordering) */ swap_words(msgb_l3(msg), msgb_l3len(msg)); + osmo_pbit2ubit_ext(data, 0, msgb_l3(msg), 0, data_len, 1); break; }
- /* unpack packed bits (MSB goes first) */ - osmo_pbit2ubit_ext(data, 0, msgb_l3(msg), 0, sizeof(data), 1); - for (unsigned int i = 0; i < desc->num_blocks; i++) { struct osmo_v110_decoded_frame df;
@@ -340,6 +346,7 @@ const struct csd_v110_frame_desc *desc; ubit_t data[60 * 4]; struct msgb *nmsg; + size_t data_len;
if ((cd->chan_nr & RSL_CHAN_NR_MASK) == RSL_CHAN_Bm_ACCHs) desc = &csd_v110_lchan_desc[cd->mode].fr; @@ -348,6 +355,9 @@ if (OSMO_UNLIKELY(desc->num_blocks == 0)) return -ENOTSUP;
+ data_len = desc->num_blocks * desc->num_bits; + OSMO_ASSERT(sizeof(data) >= data_len); + for (unsigned int i = 0; i < desc->num_blocks; i++) { struct osmo_v110_decoded_frame df;
@@ -368,19 +378,23 @@ osmo_csd_3k6_encode_frame(&data[i * 36], 36, &df); }
- nmsg = msgb_alloc_headroom(33 + 64, 64, __func__); - OSMO_ASSERT(nmsg != NULL); - - nmsg->l2h = msgb_put(nmsg, 33); /* XXX: proper size */ - - /* pack unpacked bits (MSB goes first) */ - osmo_ubit2pbit_ext(msgb_l2(nmsg), 0, &data[0], 0, sizeof(data), 1); - switch (ms->settings.tch_data.io_format) { case TCH_DATA_IOF_OSMO: + /* trxcon operates on unpacked bits */ + nmsg = msgb_alloc_headroom(data_len + 64, 64, __func__); + if (nmsg == NULL) + return -ENOMEM; + memcpy(msgb_put(nmsg, data_len), &data[0], data_len); break; case TCH_DATA_IOF_TI: - /* the layer1 firmware expects frames with swapped words (LE ordering) */ + /* XXX: the layer1 firmware expects TRAFFIC.req with len=33 bytes */ + nmsg = msgb_alloc_headroom(33 + 64, 64, __func__); + if (nmsg == NULL) + return -ENOMEM; + nmsg->l2h = msgb_put(nmsg, 33); + /* the layer1 firmware expects packed bits (LE ordering) */ + osmo_ubit2pbit_ext(msgb_l2(nmsg), 0, &data[0], 0, sizeof(data), 1); + /* ... with swapped words (LE ordering) */ swap_words(msgb_l2(nmsg), msgb_l2len(nmsg)); break; }