aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-sysmo
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-05-28 16:00:36 +0200
committerHarald Welte <laforge@gnumonks.org>2017-05-29 21:58:51 +0200
commita8bf666a099ecc7bb8436f31b7f30e246ef50015 (patch)
treedad283fd0790c52f1442f1e34c6dacecade25543 /src/osmo-bts-sysmo
parentcb5a969a4548ec70ff16a74aa834cb5ebf50dc0a (diff)
sysmobts: Re-order the bit-endianness of every HR codec parameter
The so-called "RTP mode" of the DSP contains a bug on all firmware versions < 5.3.3 which causes the bit-order within each of the non-aligned codec parameters to be wrong. Introduce a function originally written by Sylvain Munaut during 32C3 in http://git.osmocom.org/openbsc/commit/?h=sylvain/32c3_codec&id=5b4a16bbe93a7b1ace65cc23d6cce56ecf4f1275 to bring the bits into [the correct] order. This has never been seen in a "pure sysmoBTS" setup, as all BTSs would use the same (wrong) bit-ordering and thus interoperate. This patch now checks for an affected DSP firmware version and then jumbles (old DSP firmware version) or does nothing (new DSP firmware version). Change-Id: Ia0eee4f514fb8fd81c052bb44a4facba898d6afb Closes: SYS#2452
Diffstat (limited to 'src/osmo-bts-sysmo')
-rw-r--r--src/osmo-bts-sysmo/l1_if.c3
-rw-r--r--src/osmo-bts-sysmo/l1_if.h1
-rw-r--r--src/osmo-bts-sysmo/tch.c59
3 files changed, 57 insertions, 6 deletions
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 8820f083..60638e18 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -1460,6 +1460,9 @@ static int info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
LOGP(DL1C, LOGL_FATAL, "BTS band %s not supported by hw\n",
gsm_band_name(trx->bts->band));
+ if (l1if_dsp_ver(fl1h) < L1_VER_SHIFT(5,3,3))
+ fl1h->rtp_hr_jumble_needed = true;
+
/* Request the activation */
l1if_activate_rf(fl1h, 1);
diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h
index 961e5853..033e7f58 100644
--- a/src/osmo-bts-sysmo/l1_if.h
+++ b/src/osmo-bts-sysmo/l1_if.h
@@ -74,6 +74,7 @@ struct femtol1_hdl {
} hw_info;
int fixup_needed;
+ bool rtp_hr_jumble_needed;
struct calib_send_state st;
diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c
index 55c4049c..475652ee 100644
--- a/src/osmo-bts-sysmo/tch.c
+++ b/src/osmo-bts-sysmo/tch.c
@@ -157,6 +157,43 @@ static int rtppayload_to_l1_efr(uint8_t *l1_payload, const uint8_t *rtp_payload,
#warning No EFR support in L1
#endif /* L1_HAS_EFR */
+#ifdef USE_L1_RTP_MODE
+/* change the bit-order of each unaligned field inside the HR codec
+ * payload from little-endian bit-ordering to bit-endian and vice-versa.
+ * This is required on all sysmoBTS DSP versions < 5.3.3 in order to
+ * be compliant with ETSI TS 101 318 Chapter 5.2 */
+static void hr_jumble(uint8_t *dst, const uint8_t *src)
+{
+ /* Table 2 / Section 5.2.1 of ETSI TS 101 381 */
+ const int p_unvoiced[] =
+ { 5, 11, 9, 8, 1, 2, 7, 7, 5, 7, 7, 5, 7, 7, 5, 7, 7, 5 };
+ /* Table 3 / Section 5.2.1 of ETSI TS 101 381 */
+ const int p_voiced[] =
+ { 5, 11, 9, 8, 1, 2, 8, 9, 5, 4, 9, 5, 4, 9, 5, 4, 9, 5 };
+
+ int base, i, j, l, si, di;
+ const int *p;
+
+ memset(dst, 0x00, GSM_HR_BYTES);
+
+ p = (src[4] & 0x30) ? p_voiced : p_unvoiced;
+
+ base = 0;
+ for (i = 0; i < 18; i++) {
+ l = p[i];
+ for (j = 0; j < l; j++) {
+ si = base + j;
+ di = base + l - j - 1;
+
+ if (src[si >> 3] & (1 << (7 - (si & 7))))
+ dst[di >> 3] |= (1 << (7 - (di & 7)));
+ }
+
+ base += l;
+ }
+}
+#endif /* USE_L1_RTP_MODE */
+
static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len,
struct gsm_lchan *lchan)
{
@@ -174,9 +211,14 @@ static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len
}
cur = msgb_put(msg, GSM_HR_BYTES);
+#ifdef USE_L1_RTP_MODE
+ struct femtol1_hdl *fl1h = trx_femtol1_hdl(lchan->ts->trx);
+ if (fl1h->rtp_hr_jumble_needed)
+ hr_jumble(cur, l1_payload);
+ else
+ memcpy(cur, l1_payload, GSM_HR_BYTES);
+#else /* USE_L1_RTP_MODE */
memcpy(cur, l1_payload, GSM_HR_BYTES);
-
-#ifndef USE_L1_RTP_MODE
/* reverse the bit-order of each payload byte */
osmo_revbytebits_buf(cur, GSM_HR_BYTES);
#endif /* USE_L1_RTP_MODE */
@@ -193,7 +235,7 @@ static struct msgb *l1_to_rtppayload_hr(uint8_t *l1_payload, uint8_t payload_len
* \returns number of \a l1_payload bytes filled
*/
static int rtppayload_to_l1_hr(uint8_t *l1_payload, const uint8_t *rtp_payload,
- unsigned int payload_len)
+ unsigned int payload_len, struct gsm_lchan *lchan)
{
if (payload_len != GSM_HR_BYTES) {
@@ -202,9 +244,14 @@ static int rtppayload_to_l1_hr(uint8_t *l1_payload, const uint8_t *rtp_payload,
return 0;
}
+#ifdef USE_L1_RTP_MODE
+ struct femtol1_hdl *fl1h = trx_femtol1_hdl(lchan->ts->trx);
+ if (fl1h->rtp_hr_jumble_needed)
+ hr_jumble(l1_payload, rtp_payload);
+ else
+ memcpy(l1_payload, rtp_payload, GSM_HR_BYTES);
+#else /* USE_L1_RTP_MODE */
memcpy(l1_payload, rtp_payload, GSM_HR_BYTES);
-
-#ifndef USE_L1_RTP_MODE
/* reverse the bit-order of each payload byte */
osmo_revbytebits_buf(l1_payload, GSM_HR_BYTES);
#endif /* USE_L1_RTP_MODE */
@@ -345,7 +392,7 @@ int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
} else{
*payload_type = GsmL1_TchPlType_Hr;
rc = rtppayload_to_l1_hr(l1_payload,
- rtp_pl, rtp_pl_len);
+ rtp_pl, rtp_pl_len, lchan);
if (rc && lchan->ts->trx->bts->dtxd)
is_sid = osmo_hr_check_sid(rtp_pl, rtp_pl_len);
}