diff options
authorHarald Welte <laforge@gnumonks.org>2019-06-02 17:38:50 +0200
committerlaforge <laforge@gnumonks.org>2019-06-13 15:38:01 +0000
commit8ea9ba6af8317d4240d86d3f5dfb6c176b22a9b6 (patch)
parentb24ef2357032c1ed25c2f95f8ca2e7b4cd013e82 (diff)
[correctly] use the LAPDm T200 values received via OML
As per GSM TS 12.21, the LAPDm timers (T200) of the LAPDm instances in the BTS are configured via OML from the BSC. While OsmoBSC is sending them and OsmoBTS is parsing them, OsmoBTS stopped to make use of them from commit 3ca59512d2f4eb1f87699e8fada67f33674918b4 (January 2016) onwards. The cause for this has been documented and discovered in May 2017 in https://osmocom.org/issues/2294 and it is quite obvious: LAPDm timers are supposed to start when a given frame is actually transmitted on the radio interface. PH-RTS.ind and PH-DATA.req are suppsed to be used over a synchronous interface in some deeply embedded processor. With OsmoBTS however, we have an asynchronous L1/L2 interface between a DSP (osmo-bts-{sysmo,lc15,oc2g,octphy}) or OsmoTRX (osmo-bts-trx) and we receive PH-RTS.ind quite some time ahead. So if we start T200 at that point, then it will start running way before it has been sent or before the MS has had a chance to receive the message. The "correct" way to handle this is to actually measure the difference between frame numbers in PH-RTS.ind (uplink, advanced) and PH-DATA.ind (downlink) or PH-TIME.ind, and then add that amount to the actual timeout value. This ensures that the timers will time-out the user-specified amount of time after the actual transmit. Change-Id: If8babda9e3e5e219908911ddd9c0756b5ea0bca4 Closes: OS#2294 Closes: OS#3906
1 files changed, 13 insertions, 16 deletions
diff --git a/src/common/oml.c b/src/common/oml.c
index d264a6e1..ad58cb92 100644
--- a/src/common/oml.c
+++ b/src/common/oml.c
@@ -488,8 +488,15 @@ const unsigned int oml_default_t200_ms[7] = {
[T200_SACCH_TCH_SAPI3] = 2000,
-static void dl_set_t200(struct lapdm_datalink *dl, unsigned int t200_msec)
+static void dl_set_t200(struct gsm_bts *bts, struct lapdm_datalink *dl, unsigned int t200_msec)
+ int32_t fn_advance = bts_get_avg_fn_advance(bts);
+ int32_t fn_advance_us = fn_advance * 4615; /* 4.615 ms per frame */
+ /* we have to compensate for the "RTS advance" due to the asynchronous interface between
+ * the BTS (LAPDm) and the PHY/L1 (OsmoTRX or DSP in case of osmo-bts-{sysmo,lc15,oc2g,octphy} */
+ t200_msec += fn_advance_us / 1000;
dl->dl.t200_sec = t200_msec / 1000;
dl->dl.t200_usec = (t200_msec % 1000) * 1000;
@@ -528,10 +535,10 @@ int oml_set_lchan_t200(struct gsm_lchan *lchan)
LOGPLCHAN(lchan, DLLAPD, LOGL_DEBUG, "Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in ms)\n",
t200_dcch, t200_dcch_sapi3, t200_acch, t200_acch_sapi3);
- dl_set_t200(&lc->lapdm_dcch.datalink[DL_SAPI0], t200_dcch);
- dl_set_t200(&lc->lapdm_dcch.datalink[DL_SAPI3], t200_dcch_sapi3);
- dl_set_t200(&lc->lapdm_acch.datalink[DL_SAPI0], t200_acch);
- dl_set_t200(&lc->lapdm_acch.datalink[DL_SAPI3], t200_acch_sapi3);
+ dl_set_t200(bts, &lc->lapdm_dcch.datalink[DL_SAPI0], t200_dcch);
+ dl_set_t200(bts, &lc->lapdm_dcch.datalink[DL_SAPI3], t200_dcch_sapi3);
+ dl_set_t200(bts, &lc->lapdm_acch.datalink[DL_SAPI0], t200_acch);
+ dl_set_t200(bts, &lc->lapdm_acch.datalink[DL_SAPI3], t200_acch_sapi3);
return 0;
@@ -674,20 +681,10 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
payload = TLVP_VAL(&tp, NM_ATT_T200);
for (i = 0; i < ARRAY_SIZE(bts->t200_ms); i++) {
uint32_t t200_ms = payload[i] * abis_nm_t200_ms[i];
-#if 0
bts->t200_ms[i] = t200_ms;
DEBUGPFOH(DOML, foh, "T200[%u]: OML=%u, mult=%u => %u ms\n",
- i, payload[i], abis_nm_t200_mult[i],
+ i, payload[i], abis_nm_t200_ms[i],
- /* we'd rather use the 1s/2s (long) defaults by
- * libosmocore, as we appear to have some bug(s)
- * related to handling T200 expiration in
- * libosmogsm lapd(m) code? */
- LOGPFOH(DOML, LOGL_NOTICE, foh, "Ignoring T200[%u] (%u ms) "
- "as sent by BSC due to suspected LAPDm bug!\n",
- i, t200_ms);