<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/21014">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  pespin: Looks good to me, but someone else must approve
  fixeria: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">l1sap: add repeated downlink FACCH<br><br>3GPP TS 44.006, section 10 describes a method how the downlink<br>FACCH transmission can be repeated to increase transmission<br>reliability.<br><br>Change-Id: I72f0cf7eaaef9f80fc35e752c90ae0e2d24d0c75<br>Depends: libosmocore I6dda239e9cd7033297bed1deb5eb1d9f87b8433f<br>Related: OS#4796 SYS#5114<br>---<br>M include/osmo-bts/gsm_data.h<br>M include/osmo-bts/l1sap.h<br>M src/common/bts.c<br>M src/common/l1sap.c<br>M src/common/rsl.c<br>M src/osmo-bts-trx/main.c<br>6 files changed, 170 insertions(+), 7 deletions(-)<br><br></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 7670508..47a6db8 100644</span><br><span>--- a/include/osmo-bts/gsm_data.h</span><br><span>+++ b/include/osmo-bts/gsm_data.h</span><br><span>@@ -156,6 +156,11 @@</span><br><span>     LCHAN_REL_ACT_REACT, /* remove once auto-activation hack is removed from opstart_compl() */</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm_rep_facch {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t fn;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> struct gsm_lchan {</span><br><span>     /* The TS that we're part of */</span><br><span>  struct gsm_bts_trx_ts *ts;</span><br><span>@@ -272,6 +277,10 @@</span><br><span>            } dtx;</span><br><span>               uint8_t last_cmr;</span><br><span>            uint32_t last_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* SLOT #0 and #1 to store FACCH for repetition */</span><br><span style="color: hsl(120, 100%, 40%);">+            struct gsm_rep_facch rep_facch[2];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         } tch;</span><br><span> </span><br><span>   /* 3GPP TS 48.058 ยง 9.3.37: [0; 255] ok, -1 means invalid*/</span><br><span>@@ -314,6 +323,9 @@</span><br><span> </span><br><span>       /* ECU (Error Concealment Unit) state */</span><br><span>     struct osmo_ecu_state *ecu_state;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   struct abis_rsl_osmo_rep_acch_cap repeated_acch_capability;</span><br><span style="color: hsl(120, 100%, 40%);">+   bool repeated_dl_facch_active;</span><br><span> };</span><br><span> </span><br><span> static inline uint8_t lchan_get_ta(const struct gsm_lchan *lchan)</span><br><span>diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h</span><br><span>index 1fcf78c..85fe548 100644</span><br><span>--- a/include/osmo-bts/l1sap.h</span><br><span>+++ b/include/osmo-bts/l1sap.h</span><br><span>@@ -144,4 +144,7 @@</span><br><span> </span><br><span> int is_ccch_for_agch(struct gsm_bts_trx *trx, uint32_t fn);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void repeated_dl_facch_active_decision(struct gsm_lchan *lchan,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     const uint8_t *l3, size_t l3_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif /* L1SAP_H */</span><br><span>diff --git a/src/common/bts.c b/src/common/bts.c</span><br><span>index 6c25cbd..a1f9101 100644</span><br><span>--- a/src/common/bts.c</span><br><span>+++ b/src/common/bts.c</span><br><span>@@ -457,6 +457,11 @@</span><br><span>      t200_ms_acch[DL_SAPI0] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;</span><br><span>  t200_ms_acch[DL_SAPI3] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       if (lchan->repeated_acch_capability.dl_facch_all && (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            t200_ms_acch[DL_SAPI0] *= 2;</span><br><span style="color: hsl(120, 100%, 40%);">+          t200_ms_acch[DL_SAPI3] *= 2;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  switch (lchan->type) {</span><br><span>    case GSM_LCHAN_SDCCH:</span><br><span>                t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_SDCCH] + fn_advance_ms;</span><br><span>diff --git a/src/common/l1sap.c b/src/common/l1sap.c</span><br><span>index cfe7ebb..4398f2a 100644</span><br><span>--- a/src/common/l1sap.c</span><br><span>+++ b/src/common/l1sap.c</span><br><span>@@ -908,6 +908,112 @@</span><br><span>   }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Common dequeueing function */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline struct msgb *lapdm_phsap_dequeue_msg(struct lapdm_entity *le)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_phsap_prim pp;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (lapdm_phsap_dequeue_prim(le, &pp) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  return pp.oph.msg;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Special dequeueing function with FACCH repetition (3GPP TS 44.006, section 10) */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline struct msgb *lapdm_phsap_dequeue_msg_facch(struct gsm_lchan *lchan, struct lapdm_entity *le, uint32_t fn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_phsap_prim pp;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Note: The repeated version of the FACCH block must be scheduled 8 or 9 bursts after the original</span><br><span style="color: hsl(120, 100%, 40%);">+    * transmission. see 3GPP TS 44.006, section 10.2 for a more detailed explaination. */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (lchan->tch.rep_facch[0].msg && GSM_TDMA_FN_SUB(fn, lchan->tch.rep_facch[0].fn) >= 8) {</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Re-use stored FACCH message buffer from SLOT #0 for repetition. */</span><br><span style="color: hsl(120, 100%, 40%);">+         msg = lchan->tch.rep_facch[0].msg;</span><br><span style="color: hsl(120, 100%, 40%);">+         lchan->tch.rep_facch[0].msg = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+        } else if (lchan->tch.rep_facch[1].msg && GSM_TDMA_FN_SUB(fn, lchan->tch.rep_facch[1].fn) >= 8) {</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Re-use stored FACCH message buffer from SLOT #1 for repetition. */</span><br><span style="color: hsl(120, 100%, 40%);">+         msg = lchan->tch.rep_facch[1].msg;</span><br><span style="color: hsl(120, 100%, 40%);">+         lchan->tch.rep_facch[1].msg = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+        } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Fetch new FACCH from queue ... */</span><br><span style="color: hsl(120, 100%, 40%);">+          if (lapdm_phsap_dequeue_prim(le, &pp) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                     return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+          msg = pp.oph.msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Check if the LAPDm frame is a command frame,</span><br><span style="color: hsl(120, 100%, 40%);">+                * see also: 3GPP TS 04.06 section 3.2 and 3.3.2.</span><br><span style="color: hsl(120, 100%, 40%);">+              * If the MS explicitly indicated that repeated ACCH is</span><br><span style="color: hsl(120, 100%, 40%);">+                * supported, than all FACCH frames may be repeated</span><br><span style="color: hsl(120, 100%, 40%);">+            * see also: 3GPP TS 44.006, section 10.3). */</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!(lchan->repeated_acch_capability.dl_facch_all || msg->data[0] & 0x02))</span><br><span style="color: hsl(120, 100%, 40%);">+                 return msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* ... and store the message buffer for repetition. */</span><br><span style="color: hsl(120, 100%, 40%);">+                if (lchan->tch.rep_facch[0].msg == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 lchan->tch.rep_facch[0].msg = msgb_copy(msg, "rep_facch_0");</span><br><span style="color: hsl(120, 100%, 40%);">+                     lchan->tch.rep_facch[0].fn = fn;</span><br><span style="color: hsl(120, 100%, 40%);">+           } else if (lchan->tch.rep_facch[1].msg == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  lchan->tch.rep_facch[1].msg = msgb_copy(msg, "rep_facch_1");</span><br><span style="color: hsl(120, 100%, 40%);">+                     lchan->tch.rep_facch[1].fn = fn;</span><br><span style="color: hsl(120, 100%, 40%);">+           } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* By definition 3GPP TS 05.02 does not allow more than two (for TCH/H only one) FACCH blocks</span><br><span style="color: hsl(120, 100%, 40%);">+                  * to be transmitted simultaniously. */</span><br><span style="color: hsl(120, 100%, 40%);">+                       OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return msg;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Decide if repeated FACCH should be applied or not. If RXQUAL level, that the</span><br><span style="color: hsl(120, 100%, 40%);">+ * MS reports is high enough, FACCH repetition is not needed. */</span><br><span style="color: hsl(120, 100%, 40%);">+void repeated_dl_facch_active_decision(struct gsm_lchan *lchan, const uint8_t *l3,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      size_t l3_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      const struct gsm48_meas_res *meas_res;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t upper;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t lower;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!lchan->repeated_acch_capability.dl_facch_cmd</span><br><span style="color: hsl(120, 100%, 40%);">+      && !lchan->repeated_acch_capability.dl_facch_all)</span><br><span style="color: hsl(120, 100%, 40%);">+              return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Threshold disabled (always on) */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (lchan->repeated_acch_capability.rxqual == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+         lchan->repeated_dl_facch_active = true;</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* When the MS sets the SRR bit in the UL-SACCH L1 header</span><br><span style="color: hsl(120, 100%, 40%);">+      * (repeated SACCH requested) then it makes sense to enable</span><br><span style="color: hsl(120, 100%, 40%);">+    * FACCH repetition too. */</span><br><span style="color: hsl(120, 100%, 40%);">+   if ((lchan->meas.l1_info[0] >> 1) & 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+         lchan->repeated_dl_facch_active = true;</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Parse MS measurement results */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (l3_len <= sizeof(struct gsm48_meas_res *) + 2)</span><br><span style="color: hsl(120, 100%, 40%);">+         return;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (l3[0] != GSM48_PDISC_RR)</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (l3[1] != GSM48_MT_RR_MEAS_REP)</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+       l3 += 2;</span><br><span style="color: hsl(120, 100%, 40%);">+      meas_res = (struct gsm48_meas_res *)l3;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* If the RXQUAL level at the MS drops under a certain threshold</span><br><span style="color: hsl(120, 100%, 40%);">+       * we enable FACCH repetition. */</span><br><span style="color: hsl(120, 100%, 40%);">+     upper = lchan->repeated_acch_capability.rxqual;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (upper > 2)</span><br><span style="color: hsl(120, 100%, 40%);">+             lower = lchan->repeated_acch_capability.rxqual - 2;</span><br><span style="color: hsl(120, 100%, 40%);">+        else</span><br><span style="color: hsl(120, 100%, 40%);">+          lower = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (meas_res->rxqual_sub >= upper)</span><br><span style="color: hsl(120, 100%, 40%);">+              lchan->repeated_dl_facch_active = true;</span><br><span style="color: hsl(120, 100%, 40%);">+    else if (meas_res->rxqual_sub <= lower)</span><br><span style="color: hsl(120, 100%, 40%);">+         lchan->repeated_dl_facch_active = false;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* PH-RTS-IND prim received from bts model */</span><br><span> static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx,</span><br><span>    struct osmo_phsap_prim *l1sap, struct ph_data_param *rts_ind)</span><br><span>@@ -921,7 +1027,7 @@</span><br><span>         uint8_t *p = NULL;</span><br><span>   uint8_t *si;</span><br><span>         struct lapdm_entity *le;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct osmo_phsap_prim pp;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct msgb *pp_msg;</span><br><span>         bool dtxd_facch = false;</span><br><span>     int rc;</span><br><span>      int is_ag_res;</span><br><span>@@ -989,13 +1095,17 @@</span><br><span>                      p[0] = lchan->ms_power_ctrl.current;</span><br><span>                      p[1] = lchan->rqd_ta;</span><br><span>                     le = &lchan->lapdm_ch.lapdm_acch;</span><br><span style="color: hsl(120, 100%, 40%);">+                      pp_msg = lapdm_phsap_dequeue_msg(le);</span><br><span>                } else {</span><br><span>                     if (lchan->ts->trx->bts->dtxd)</span><br><span>                           dtxd_facch = true;</span><br><span>                   le = &lchan->lapdm_ch.lapdm_dcch;</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (lchan->repeated_dl_facch_active && lchan->rsl_cmode != RSL_CMOD_SPD_SIGN)</span><br><span style="color: hsl(120, 100%, 40%);">+                           pp_msg = lapdm_phsap_dequeue_msg_facch(lchan, le, fn);</span><br><span style="color: hsl(120, 100%, 40%);">+                        else</span><br><span style="color: hsl(120, 100%, 40%);">+                          pp_msg = lapdm_phsap_dequeue_msg(le);</span><br><span>                }</span><br><span style="color: hsl(0, 100%, 40%);">-               rc = lapdm_phsap_dequeue_prim(le, &pp);</span><br><span style="color: hsl(0, 100%, 40%);">-             if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!pp_msg) {</span><br><span>                       if (L1SAP_IS_LINK_SACCH(link_id)) {</span><br><span>                          /* No SACCH data from LAPDM pending, send SACCH filling */</span><br><span>                           uint8_t *si = lchan_sacch_get(lchan);</span><br><span>@@ -1020,16 +1130,16 @@</span><br><span>              } else {</span><br><span>                     /* The +2 is empty space where the DSP inserts the L1 hdr */</span><br><span>                         if (L1SAP_IS_LINK_SACCH(link_id))</span><br><span style="color: hsl(0, 100%, 40%);">-                               memcpy(p + 2, pp.oph.msg->data + 2, GSM_MACBLOCK_LEN - 2);</span><br><span style="color: hsl(120, 100%, 40%);">+                         memcpy(p + 2, pp_msg->data + 2, GSM_MACBLOCK_LEN - 2);</span><br><span>                    else {</span><br><span>                               p = msgb_put(msg, GSM_MACBLOCK_LEN);</span><br><span style="color: hsl(0, 100%, 40%);">-                            memcpy(p, pp.oph.msg->data, GSM_MACBLOCK_LEN);</span><br><span style="color: hsl(120, 100%, 40%);">+                             memcpy(p, pp_msg->data, GSM_MACBLOCK_LEN);</span><br><span>                                /* check if it is a RR CIPH MODE CMD. if yes, enable RX ciphering */</span><br><span style="color: hsl(0, 100%, 40%);">-                            check_for_ciph_cmd(pp.oph.msg, lchan, chan_nr);</span><br><span style="color: hsl(120, 100%, 40%);">+                               check_for_ciph_cmd(pp_msg, lchan, chan_nr);</span><br><span>                          if (dtxd_facch)</span><br><span>                                      dtx_dispatch(lchan, E_FACCH);</span><br><span>                        }</span><br><span style="color: hsl(0, 100%, 40%);">-                       msgb_free(pp.oph.msg);</span><br><span style="color: hsl(120, 100%, 40%);">+                        msgb_free(pp_msg);</span><br><span>           }</span><br><span>    } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) {</span><br><span>                p = msgb_put(msg, GSM_MACBLOCK_LEN);</span><br><span>diff --git a/src/common/rsl.c b/src/common/rsl.c</span><br><span>index a0c1fb2..14a0dcc 100644</span><br><span>--- a/src/common/rsl.c</span><br><span>+++ b/src/common/rsl.c</span><br><span>@@ -823,6 +823,13 @@</span><br><span>      */</span><br><span>  lapdm_channel_exit(&lchan->lapdm_ch);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      /* Also ensure that there are no leftovers from repeated FACCH</span><br><span style="color: hsl(120, 100%, 40%);">+         * that might cause memory leakage. */</span><br><span style="color: hsl(120, 100%, 40%);">+        msgb_free(lchan->tch.rep_facch[0].msg);</span><br><span style="color: hsl(120, 100%, 40%);">+    msgb_free(lchan->tch.rep_facch[1].msg);</span><br><span style="color: hsl(120, 100%, 40%);">+    lchan->tch.rep_facch[0].msg = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan->tch.rep_facch[1].msg = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     return tx_rf_rel_ack(lchan, chan_nr);</span><br><span> }</span><br><span> </span><br><span>@@ -1085,6 +1092,26 @@</span><br><span>      }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Parse RSL_IE_OSMO_REP_ACCH_CAP */</span><br><span style="color: hsl(120, 100%, 40%);">+static void parse_repeated_acch_capability(struct gsm_lchan *lchan, struct tlv_parsed *tp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       /* 3GPP TS 24.008, section 10.5.1.7 defines a Repeated ACCH Capability</span><br><span style="color: hsl(120, 100%, 40%);">+         * bit that indicates if REPEATED FACCH/SACCH is supported or not.</span><br><span style="color: hsl(120, 100%, 40%);">+     * Unfortunately there is not 3gpp spec that describes how this bit</span><br><span style="color: hsl(120, 100%, 40%);">+    * should be communicated in the RSL CHANNEL ACTIVATION. For osmo-bts</span><br><span style="color: hsl(120, 100%, 40%);">+  * we will use a propritary IE. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  memset(&lchan->repeated_acch_capability, 0, sizeof(lchan->repeated_acch_capability));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!TLVP_PRESENT(tp, RSL_IE_OSMO_REP_ACCH_CAP))</span><br><span style="color: hsl(120, 100%, 40%);">+              return;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (TLVP_LEN(tp, RSL_IE_OSMO_REP_ACCH_CAP) != sizeof(lchan->repeated_acch_capability))</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     memcpy(&lchan->repeated_acch_capability, TLVP_VAL(tp, RSL_IE_OSMO_REP_ACCH_CAP),</span><br><span style="color: hsl(120, 100%, 40%);">+              sizeof(lchan->repeated_acch_capability));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* 8.4.1 CHANnel ACTIVation is received */</span><br><span> static int rsl_rx_chan_activ(struct msgb *msg)</span><br><span> {</span><br><span>@@ -1327,6 +1354,8 @@</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 style="color: hsl(120, 100%, 40%);">+       parse_repeated_acch_capability(lchan, &tp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    /* actually activate the channel in the BTS */</span><br><span>       rc = l1sap_chan_act(lchan->ts->trx, dch->chan_nr, &tp);</span><br><span>         if (rc < 0)</span><br><span>@@ -1653,6 +1682,8 @@</span><br><span>       /* 9.3.53 MultiRate Control */</span><br><span>       /* 9.3.54 Supported Codec Types */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        parse_repeated_acch_capability(lchan, &tp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    l1sap_chan_modify(lchan->ts->trx, dch->chan_nr);</span><br><span> </span><br><span>        /* FIXME: delay this until L1 says OK? */</span><br><span>@@ -3007,6 +3038,7 @@</span><br><span>                    return 0;</span><br><span>            }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         repeated_dl_facch_active_decision(lchan, msgb_l3(msg), msgb_l3len(msg));</span><br><span>             rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg), le);</span><br><span>              msgb_free(msg);</span><br><span>              return rc;</span><br><span>diff --git a/src/osmo-bts-trx/main.c b/src/osmo-bts-trx/main.c</span><br><span>index 021c3c7..7e6dea9 100644</span><br><span>--- a/src/osmo-bts-trx/main.c</span><br><span>+++ b/src/osmo-bts-trx/main.c</span><br><span>@@ -144,6 +144,7 @@</span><br><span>    osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_AMR);</span><br><span>       osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH);</span><br><span>       osmo_bts_set_feature(bts->features, BTS_FEAT_HOPPING);</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_bts_set_feature(bts->features, BTS_FEAT_ACCH_REP);</span><br><span> </span><br><span>       bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB);</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/21014">change 21014</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/+/21014"/><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: I72f0cf7eaaef9f80fc35e752c90ae0e2d24d0c75 </div>
<div style="display:none"> Gerrit-Change-Number: 21014 </div>
<div style="display:none"> Gerrit-PatchSet: 11 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>