<p>neels has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/21078">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">fix SAPIs for handover to match 48.058 4.1.{3,4}<br><br>Change-Id: Ibea973ccadf5d424213f141f97a61395856b76de<br>---<br>M include/osmo-bts/gsm_data.h<br>M src/common/handover.c<br>M src/common/l1sap.c<br>M src/common/rsl.c<br>M src/common/scheduler.c<br>M src/osmo-bts-sysmo/oml.c<br>M src/osmo-bts-trx/l1_if.c<br>7 files changed, 77 insertions(+), 22 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/78/21078/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h</span><br><span>index 1c1c5d4..f16cb21 100644</span><br><span>--- a/include/osmo-bts/gsm_data.h</span><br><span>+++ b/include/osmo-bts/gsm_data.h</span><br><span>@@ -194,6 +194,28 @@</span><br><span> </span><br><span> char *name;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* For handover, activation is described in 3GPP TS 48.058 4.1.3 and 4.1.4:</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * | | Access || transmit | activate</span><br><span style="color: hsl(120, 100%, 40%);">+ * | MS Power | Delay || on main channel | dl SACCH</span><br><span style="color: hsl(120, 100%, 40%);">+ * ----------------------------------------------------------------------</span><br><span style="color: hsl(120, 100%, 40%);">+ * async ho no * --> yes no</span><br><span style="color: hsl(120, 100%, 40%);">+ * async ho yes * --> yes may be started</span><br><span style="color: hsl(120, 100%, 40%);">+ * sync ho no no --> yes no</span><br><span style="color: hsl(120, 100%, 40%);">+ * sync ho yes no --> yes may be started</span><br><span style="color: hsl(120, 100%, 40%);">+ * sync ho yes yes --> yes shall be started</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Always start the main channel immediately.</span><br><span style="color: hsl(120, 100%, 40%);">+ * dl_sacch.want_active indicates whether dl SACCH should be activated on CHAN ACT.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct {</span><br><span style="color: hsl(120, 100%, 40%);">+ bool want_active;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Indicates whether BTS model specific code has activated the dl SACCH SAPI yet.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Note: after deactivating SACCH on channel release or likewise, this remains true, so it is not an</span><br><span style="color: hsl(120, 100%, 40%);">+ * indicator whether SACCH is still active at any point in time, only for initial activation. */</span><br><span style="color: hsl(120, 100%, 40%);">+ bool activated;</span><br><span style="color: hsl(120, 100%, 40%);">+ } dl_sacch;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Number of different GsmL1_Sapi_t used in osmo_bts_sysmo is 23.</span><br><span> * Currently we don't share these headers so this is a magic number. */</span><br><span> struct llist_head sapi_cmds;</span><br><span>diff --git a/src/common/handover.c b/src/common/handover.c</span><br><span>index b615932..b8298c3 100644</span><br><span>--- a/src/common/handover.c</span><br><span>+++ b/src/common/handover.c</span><br><span>@@ -112,6 +112,7 @@</span><br><span> </span><br><span> /* Set timing advance */</span><br><span> lchan->rqd_ta = acc_delay;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->dl_sacch.want_active = true;</span><br><span> </span><br><span> /* Stop handover detection, wait for valid frame */</span><br><span> lchan->ho.active = HANDOVER_WAIT_FRAME;</span><br><span>diff --git a/src/common/l1sap.c b/src/common/l1sap.c</span><br><span>index c9ec9bf..1181e2e 100644</span><br><span>--- a/src/common/l1sap.c</span><br><span>+++ b/src/common/l1sap.c</span><br><span>@@ -1525,6 +1525,7 @@</span><br><span> {</span><br><span> struct gsm_bts *bts = trx->bts;</span><br><span> struct lapdm_channel *lc;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_lchan *lchan;</span><br><span> </span><br><span> DEBUGPFN(DL1P, rach_ind->fn, "Rx PH-RA.ind\n");</span><br><span> </span><br><span>@@ -1557,10 +1558,10 @@</span><br><span> bts->load.rach.access++;</span><br><span> </span><br><span> lc = &trx->ts[0].lchan[CCCH_LCHAN].lapdm_ch;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan = get_lchan_by_chan_nr(trx, rach_ind->chan_nr);</span><br><span> </span><br><span> /* According to 3GPP TS 48.058 ยง 9.3.17 Access Delay is expressed same way as TA (number of symbols) */</span><br><span style="color: hsl(0, 100%, 40%);">- set_ms_to_data(get_lchan_by_chan_nr(trx, rach_ind->chan_nr),</span><br><span style="color: hsl(0, 100%, 40%);">- rach_ind->acc_delay, false);</span><br><span style="color: hsl(120, 100%, 40%);">+ set_ms_to_data(lchan, rach_ind->acc_delay, false);</span><br><span> </span><br><span> /* check for packet access */</span><br><span> if ((trx == bts->c0 && L1SAP_IS_PACKET_RACH(rach_ind->ra)) ||</span><br><span>diff --git a/src/common/rsl.c b/src/common/rsl.c</span><br><span>index 660fd0c..35e5d9a 100644</span><br><span>--- a/src/common/rsl.c</span><br><span>+++ b/src/common/rsl.c</span><br><span>@@ -1095,6 +1095,7 @@</span><br><span> struct tlv_parsed tp;</span><br><span> uint8_t type;</span><br><span> int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool ms_power_present = false;</span><br><span> </span><br><span> if (lchan->state != LCHAN_S_NONE) {</span><br><span> LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "error: lchan is not available, but in state: %s.\n",</span><br><span>@@ -1188,6 +1189,7 @@</span><br><span> if (TLVP_PRES_LEN(&tp, RSL_IE_MS_POWER, 1)) {</span><br><span> lchan->ms_power_ctrl.max = *TLVP_VAL(&tp, RSL_IE_MS_POWER) & 0x1F;</span><br><span> lchan->ms_power_ctrl.current = lchan->ms_power_ctrl.max;</span><br><span style="color: hsl(120, 100%, 40%);">+ ms_power_present = true;</span><br><span> }</span><br><span> /* 9.3.24 Timing Advance */</span><br><span> if (TLVP_PRES_LEN(&tp, RSL_IE_TIMING_ADVANCE, 1))</span><br><span>@@ -1312,6 +1314,18 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Indicate which SAPIs should be enabled before the first RACH is received, for handover. See 3GPP TS 48.058</span><br><span style="color: hsl(120, 100%, 40%);">+ * 4.1.3 and 4.1.4. */</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (type) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case RSL_ACT_INTER_ASYNC:</span><br><span style="color: hsl(120, 100%, 40%);">+ case RSL_ACT_INTER_SYNC:</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->dl_sacch.want_active = ms_power_present;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->dl_sacch.want_active = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Remember to send an RSL ACK once the lchan is active */</span><br><span> lchan->rel_act_kind = LCHAN_REL_ACT_RSL;</span><br><span> </span><br><span>diff --git a/src/common/scheduler.c b/src/common/scheduler.c</span><br><span>index b61330d..d959eb0 100644</span><br><span>--- a/src/common/scheduler.c</span><br><span>+++ b/src/common/scheduler.c</span><br><span>@@ -858,6 +858,12 @@</span><br><span> return -ENODEV;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* For handover detection, there are cases where the SACCH should remain inactive until the first RACH</span><br><span style="color: hsl(120, 100%, 40%);">+ * indicating the TA is received. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (L1SAP_IS_LINK_SACCH(link_id)</span><br><span style="color: hsl(120, 100%, 40%);">+ && !l1t->ts[tn].chan_state[chan].lchan->dl_sacch.activated)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> LOGL1S(DL1P, LOGL_DEBUG, l1t, tn, chan, fn,</span><br><span> "PH-RTS.ind: chan_nr=0x%02x link_id=0x%02x\n", chan_nr, link_id);</span><br><span> </span><br><span>diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c</span><br><span>index e8bfb2d..c70f4ba 100644</span><br><span>--- a/src/osmo-bts-sysmo/oml.c</span><br><span>+++ b/src/osmo-bts-sysmo/oml.c</span><br><span>@@ -1176,10 +1176,10 @@</span><br><span> "%s Trying to activate lchan, but commands in queue\n",</span><br><span> gsm_lchan_name(lchan));</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* override the regular SAPIs if this is the first hand-over</span><br><span style="color: hsl(0, 100%, 40%);">- * related activation of the LCHAN */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* For handover, always start the main channel immediately. lchan->dl_sacch.want_active indicates whether dl</span><br><span style="color: hsl(120, 100%, 40%);">+ * SACCH should be activated. Also, for HO, start the RACH SAPI. */</span><br><span> if (lchan->ho.active == HANDOVER_ENABLED)</span><br><span style="color: hsl(0, 100%, 40%);">- s4l = &sapis_for_ho;</span><br><span style="color: hsl(120, 100%, 40%);">+ enqueue_sapi_act_cmd(lchan, GsmL1_Sapi_Rach, GsmL1_Dir_RxUplink);</span><br><span> </span><br><span> for (i = 0; i < s4l->num_sapis; i++) {</span><br><span> int sapi = s4l->sapis[i].sapi;</span><br><span>@@ -1192,6 +1192,15 @@</span><br><span> fl1h->alive_prim_cnt = 0;</span><br><span> osmo_timer_schedule(&fl1h->alive_timer, 5, 0);</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* For handover, possibly postpone activating the dl SACCH until the HO RACH is received. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sapi == GsmL1_Sapi_Sacch && dir == GsmL1_Dir_TxDownlink) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!lchan->dl_sacch.want_active)</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->dl_sacch.activated = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> enqueue_sapi_act_cmd(lchan, sapi, dir);</span><br><span> }</span><br><span> </span><br><span>@@ -1651,17 +1660,9 @@</span><br><span> return enqueue_sapi_deact_cmd(lchan, sapi, dir);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int release_sapis_for_ho(struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+static int release_rach_sapi(struct gsm_lchan *lchan)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- int res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- int i;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- const struct lchan_sapis *s4l = &sapis_for_ho;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (i = s4l->num_sapis-1; i >= 0; i--)</span><br><span style="color: hsl(0, 100%, 40%);">- res |= check_sapi_release(lchan,</span><br><span style="color: hsl(0, 100%, 40%);">- s4l->sapis[i].sapi, s4l->sapis[i].dir);</span><br><span style="color: hsl(0, 100%, 40%);">- return res;</span><br><span style="color: hsl(120, 100%, 40%);">+ return check_sapi_release(lchan, GsmL1_Sapi_Rach, GsmL1_Dir_RxUplink);</span><br><span> }</span><br><span> </span><br><span> static int lchan_deactivate_sapis(struct gsm_lchan *lchan)</span><br><span>@@ -1678,12 +1679,18 @@</span><br><span> if (s4l->sapis[i].sapi == GsmL1_Sapi_Sch)</span><br><span> osmo_timer_del(&fl1h->alive_timer);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* If no dl SACCH has been activated, skip its release */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (s4l->sapis[i].sapi == GsmL1_Sapi_Sacch</span><br><span style="color: hsl(120, 100%, 40%);">+ && s4l->sapis[i].dir == GsmL1_Dir_TxDownlink</span><br><span style="color: hsl(120, 100%, 40%);">+ && !lchan->dl_sacch.activated)</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Release if it was allocated */</span><br><span> res |= check_sapi_release(lchan, s4l->sapis[i].sapi, s4l->sapis[i].dir);</span><br><span> }</span><br><span> </span><br><span> /* always attempt to disable the RACH burst */</span><br><span style="color: hsl(0, 100%, 40%);">- res |= release_sapis_for_ho(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+ res |= release_rach_sapi(lchan);</span><br><span> </span><br><span> /* nothing was queued */</span><br><span> if (res == 0) {</span><br><span>@@ -1886,13 +1893,13 @@</span><br><span> gsm_lchan_name(lchan));</span><br><span> </span><br><span> /* Give up listening to RACH bursts */</span><br><span style="color: hsl(0, 100%, 40%);">- release_sapis_for_ho(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+ release_rach_sapi(lchan);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* Activate the normal SAPIs */</span><br><span style="color: hsl(0, 100%, 40%);">- for (i = 0; i < s4l->num_sapis; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">- int sapi = s4l->sapis[i].sapi;</span><br><span style="color: hsl(0, 100%, 40%);">- int dir = s4l->sapis[i].dir;</span><br><span style="color: hsl(0, 100%, 40%);">- enqueue_sapi_act_cmd(lchan, sapi, dir);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Activate the dl SACCH if not yet active */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->dl_sacch.want_active</span><br><span style="color: hsl(120, 100%, 40%);">+ && !lchan->dl_sacch.activated) {</span><br><span style="color: hsl(120, 100%, 40%);">+ enqueue_sapi_act_cmd(lchan, GsmL1_Sapi_Sacch, GsmL1_Dir_TxDownlink);</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->dl_sacch.activated = true;</span><br><span> }</span><br><span> </span><br><span> return 0;</span><br><span>diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c</span><br><span>index fc8ef76..21445da 100644</span><br><span>--- a/src/osmo-bts-trx/l1_if.c</span><br><span>+++ b/src/osmo-bts-trx/l1_if.c</span><br><span>@@ -439,6 +439,10 @@</span><br><span> case PRIM_INFO_MODIFY:</span><br><span> chan_nr = l1sap->u.info.u.act_req.chan_nr;</span><br><span> lchan = get_lchan_by_chan_nr(trx, chan_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* For osmo-bts-trx, the dl_sacch.activated directly has the effect of transmitting the SACCH,</span><br><span style="color: hsl(120, 100%, 40%);">+ * no need to interact with another entity to activate the SAPI. Just set it to whatever the</span><br><span style="color: hsl(120, 100%, 40%);">+ * caller wants. */</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->dl_sacch.activated = lchan->dl_sacch.want_active;</span><br><span> if (l1sap->u.info.type == PRIM_INFO_ACTIVATE) {</span><br><span> if ((chan_nr & 0xE0) == 0x80) {</span><br><span> LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot activate"</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/21078">change 21078</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-bts/+/21078"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-bts </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ibea973ccadf5d424213f141f97a61395856b76de </div>
<div style="display:none"> Gerrit-Change-Number: 21078 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>