<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>