<p>Vadim Yanitskiy has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/11138">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">trxcon/scheduler: fix Measurement Reporting on SACCH<br><br>According to 3GPP TS 04.08, section 3.4.1, SACCH logical channel<br>accompanies either a traffic or a signaling channel. It has the<br>particularity that continuous transmission must occur in both<br>directions, so on the Uplink direction measurement result messages<br>are sent at each possible occasion when nothing else has to be sent.<br>The LAPDm fill frames (0x01, 0x03, 0x01, 0x2b, ...) are not<br>applicable on SACCH channels!<br><br>Unfortunately, 3GPP TS 04.08 doesn't clearly state which "else<br>messages" besides Measurement Reports can be send by the MS on<br>SACCH channels. However, in sub-clause 3.4.1 it's stated that<br>the interval between two successive measurement result messages<br>shall not exceed one L2 frame.<br><br>This change introduces a separate handler for SACCH primitives,<br>which dequeues a SACCH primitive from transmit queue, if present.<br>Otherwise it dequeues a cached Measurement Report (the last<br>received one). Finally, if the cache is empty, a "dummy"<br>measurement report is used. When it's possible,<br>a non-MR primitive is prioritized.<br><br>Change-Id: If1b8dc74ced746d6270676fdde75fcda32f91a3d<br>Related: OS#2988<br>---<br>M src/host/trxcon/sched_prim.c<br>M src/host/trxcon/sched_trx.c<br>M src/host/trxcon/sched_trx.h<br>3 files changed, 197 insertions(+), 14 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/38/11138/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/host/trxcon/sched_prim.c b/src/host/trxcon/sched_prim.c</span><br><span>index e03f93f..0f3258f 100644</span><br><span>--- a/src/host/trxcon/sched_prim.c</span><br><span>+++ b/src/host/trxcon/sched_prim.c</span><br><span>@@ -126,6 +126,180 @@</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Composes a new primitive using either cached (if populated),</span><br><span style="color: hsl(120, 100%, 40%);">+ * or "dummy" Measurement Report message.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param  lchan lchan to assign a primitive</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return       SACCH primitive to be transmitted</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct trx_ts_prim *prim_compose_mr(struct trx_lchan_state *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct trx_ts_prim *prim;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t *mr_src_ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+  bool cached;</span><br><span style="color: hsl(120, 100%, 40%);">+  int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* "Dummy" Measurement Report */</span><br><span style="color: hsl(120, 100%, 40%);">+    static const uint8_t meas_rep_dummy[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* L1 SACCH pseudo-header */</span><br><span style="color: hsl(120, 100%, 40%);">+          0x0f, 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* LAPDm header */</span><br><span style="color: hsl(120, 100%, 40%);">+            0x01, 0x03, 0x49,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Measurement report */</span><br><span style="color: hsl(120, 100%, 40%);">+              0x06, 0x15, 0x36, 0x36, 0x01, 0xC0,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* TODO: Padding? Randomize if so */</span><br><span style="color: hsl(120, 100%, 40%);">+          0x00, 0x00, 0x00, 0x00, 0x00, 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+           0x00, 0x00, 0x00, 0x00, 0x00, 0x00,</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%);">+  /* Allocate a new primitive */</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = sched_prim_init(lchan, &prim, GSM_MACBLOCK_LEN,</span><br><span style="color: hsl(120, 100%, 40%);">+              trx_lchan_desc[lchan->type].chan_nr, TRX_CH_LID_SACCH);</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(rc == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Check if the MR cache is populated (verify LAPDm header) */</span><br><span style="color: hsl(120, 100%, 40%);">+        cached = (lchan->sacch.mr_cache[2] != 0x00</span><br><span style="color: hsl(120, 100%, 40%);">+         && lchan->sacch.mr_cache[3] != 0x00</span><br><span style="color: hsl(120, 100%, 40%);">+                && lchan->sacch.mr_cache[4] != 0x00);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (cached) { /* Use the cached one */</span><br><span style="color: hsl(120, 100%, 40%);">+                mr_src_ptr = lchan->sacch.mr_cache;</span><br><span style="color: hsl(120, 100%, 40%);">+                lchan->sacch.mr_cache_usage++;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else { /* Use "dummy" one */</span><br><span style="color: hsl(120, 100%, 40%);">+              mr_src_ptr = (uint8_t *) meas_rep_dummy;</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%);">+   /* Compose a new Measurement Report primitive */</span><br><span style="color: hsl(120, 100%, 40%);">+      memcpy(prim->payload, mr_src_ptr, GSM_MACBLOCK_LEN);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if 0 /* Conflicts with the distance spoofing feature */</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Update L1 SACCH pseudo-header */</span><br><span style="color: hsl(120, 100%, 40%);">+   prim->payload[0] = trx->tx_power;</span><br><span style="color: hsl(120, 100%, 40%);">+       prim->payload[1] = trx->ta;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Inform about the cache usage count */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (cached && lchan->sacch.mr_cache_usage > 5) {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGP(DSCHD, LOGL_NOTICE, "SACCH MR cache usage count=%u > 5 "</span><br><span style="color: hsl(120, 100%, 40%);">+                    "on lchan=%s => ancient measurements, please fix!\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    lchan->sacch.mr_cache_usage,</span><br><span style="color: hsl(120, 100%, 40%);">+                       trx_lchan_desc[lchan->type].name);</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%);">+   LOGP(DSCHD, LOGL_NOTICE, "Transmitting a %s Measurement Report "</span><br><span style="color: hsl(120, 100%, 40%);">+            "on lchan=%s\n", (cached ? "cached" : "dummy"),</span><br><span style="color: hsl(120, 100%, 40%);">+         trx_lchan_desc[lchan->type].name);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return prim;</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%);">+ * Dequeues a SACCH primitive from transmit queue, if present.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Otherwise dequeues a cached Measurement Report (the last</span><br><span style="color: hsl(120, 100%, 40%);">+ * received one). Finally, if the cache is empty, a "dummy"</span><br><span style="color: hsl(120, 100%, 40%);">+ * measurement report is used.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * According to 3GPP TS 04.08, section 3.4.1, SACCH channel</span><br><span style="color: hsl(120, 100%, 40%);">+ * accompanies either a traffic or a signaling channel. It</span><br><span style="color: hsl(120, 100%, 40%);">+ * has the particularity that continuous transmission must</span><br><span style="color: hsl(120, 100%, 40%);">+ * occur in both directions, so on the Uplink direction</span><br><span style="color: hsl(120, 100%, 40%);">+ * measurement result messages are sent at each possible</span><br><span style="color: hsl(120, 100%, 40%);">+ * occasion when nothing else has to be sent. The LAPDm</span><br><span style="color: hsl(120, 100%, 40%);">+ * fill frames (0x01, 0x03, 0x01, 0x2b, ...) are not</span><br><span style="color: hsl(120, 100%, 40%);">+ * applicable on SACCH channels!</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Unfortunately, 3GPP TS 04.08 doesn't clearly state</span><br><span style="color: hsl(120, 100%, 40%);">+ * which "else messages" besides Measurement Reports</span><br><span style="color: hsl(120, 100%, 40%);">+ * can be send by the MS on SACCH channels. However,</span><br><span style="color: hsl(120, 100%, 40%);">+ * in sub-clause 3.4.1 it's stated that the interval</span><br><span style="color: hsl(120, 100%, 40%);">+ * between two successive measurement result messages</span><br><span style="color: hsl(120, 100%, 40%);">+ * shall not exceed one L2 frame.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param  queue transmit queue to take a prim from</span><br><span style="color: hsl(120, 100%, 40%);">+ * @param  lchan lchan to assign a primitive</span><br><span style="color: hsl(120, 100%, 40%);">+ * @return       SACCH primitive to be transmitted</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct trx_ts_prim *prim_dequeue_sacch(struct llist_head *queue,</span><br><span style="color: hsl(120, 100%, 40%);">+     struct trx_lchan_state *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct trx_ts_prim *prim_nmr = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct trx_ts_prim *prim_mr = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct trx_ts_prim *prim;</span><br><span style="color: hsl(120, 100%, 40%);">+     bool mr_now;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Shall we transmit MR now? */</span><br><span style="color: hsl(120, 100%, 40%);">+       mr_now = !lchan->sacch.mr_tx_last;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PRIM_IS_MR(prim) \</span><br><span style="color: hsl(120, 100%, 40%);">+   (prim->payload[5] == GSM48_PDISC_RR \</span><br><span style="color: hsl(120, 100%, 40%);">+              && prim->payload[6] == GSM48_MT_RR_MEAS_REP)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Iterate over all primitives in the queue */</span><br><span style="color: hsl(120, 100%, 40%);">+        llist_for_each_entry(prim, queue, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* We are looking for particular channel */</span><br><span style="color: hsl(120, 100%, 40%);">+           if (prim->chan != lchan->type)</span><br><span style="color: hsl(120, 100%, 40%);">+                  continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Just to be sure... */</span><br><span style="color: hsl(120, 100%, 40%);">+              if (prim->payload_len != GSM_MACBLOCK_LEN)</span><br><span style="color: hsl(120, 100%, 40%);">+                 continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Look for a Measurement Report */</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!prim_mr && PRIM_IS_MR(prim))</span><br><span style="color: hsl(120, 100%, 40%);">+                     prim_mr = prim;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Look for anything else */</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!prim_nmr && !PRIM_IS_MR(prim))</span><br><span style="color: hsl(120, 100%, 40%);">+                   prim_nmr = prim;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Should we look further? */</span><br><span style="color: hsl(120, 100%, 40%);">+         if (mr_now && prim_mr)</span><br><span style="color: hsl(120, 100%, 40%);">+                        break; /* MR was found */</span><br><span style="color: hsl(120, 100%, 40%);">+             else if (!mr_now && prim_nmr)</span><br><span style="color: hsl(120, 100%, 40%);">+                 break; /* something else was found */</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%);">+   LOGP(DSCHD, LOGL_DEBUG, "SACCH MR selection on lchan=%s: "</span><br><span style="color: hsl(120, 100%, 40%);">+          "mr_tx_last=%d prim_mr=%p prim_nmr=%p\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           trx_lchan_desc[lchan->type].name,</span><br><span style="color: hsl(120, 100%, 40%);">+          lchan->sacch.mr_tx_last,</span><br><span style="color: hsl(120, 100%, 40%);">+           prim_mr, prim_nmr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Prioritize non-MR prim if possible */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (mr_now && prim_mr)</span><br><span style="color: hsl(120, 100%, 40%);">+                prim = prim_mr;</span><br><span style="color: hsl(120, 100%, 40%);">+       else if (!mr_now && prim_nmr)</span><br><span style="color: hsl(120, 100%, 40%);">+         prim = prim_nmr;</span><br><span style="color: hsl(120, 100%, 40%);">+      else if (!mr_now && prim_mr)</span><br><span style="color: hsl(120, 100%, 40%);">+          prim = prim_mr;</span><br><span style="color: hsl(120, 100%, 40%);">+       else /* Nothing was found */</span><br><span style="color: hsl(120, 100%, 40%);">+          prim = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Have we found what we were looking for? */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (prim) /* Dequeue if so */</span><br><span style="color: hsl(120, 100%, 40%);">+         llist_del(&prim->list);</span><br><span style="color: hsl(120, 100%, 40%);">+        else /* Otherwise compose a new MR */</span><br><span style="color: hsl(120, 100%, 40%);">+         prim = prim_compose_mr(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Update the cached report */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (prim == prim_mr) {</span><br><span style="color: hsl(120, 100%, 40%);">+                memcpy(lchan->sacch.mr_cache,</span><br><span style="color: hsl(120, 100%, 40%);">+                      prim->payload, GSM_MACBLOCK_LEN);</span><br><span style="color: hsl(120, 100%, 40%);">+          lchan->sacch.mr_cache_usage = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         LOGP(DSCHD, LOGL_DEBUG, "SACCH MR cache has been updated "</span><br><span style="color: hsl(120, 100%, 40%);">+                  "for lchan=%s\n", trx_lchan_desc[lchan->type].name);</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%);">+   /* Update the MR transmission state */</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan->sacch.mr_tx_last = PRIM_IS_MR(prim);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return prim;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Dequeues a primitive of a given channel type */</span><br><span> static struct trx_ts_prim *prim_dequeue_one(struct llist_head *queue,</span><br><span>     enum trx_lchan_type lchan_type)</span><br><span>@@ -289,6 +463,10 @@</span><br><span> struct trx_ts_prim *sched_prim_dequeue(struct llist_head *queue,</span><br><span>   uint32_t fn, struct trx_lchan_state *lchan)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+      /* SACCH is unorthodox, see 3GPP TS 04.08, section 3.4.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (CHAN_IS_SACCH(lchan->type))</span><br><span style="color: hsl(120, 100%, 40%);">+            return prim_dequeue_sacch(queue, lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   /* There is nothing to dequeue */</span><br><span>    if (llist_empty(queue))</span><br><span>              return NULL;</span><br><span>@@ -350,6 +528,8 @@</span><br><span> </span><br><span>       /* Make sure that there is no existing primitive */</span><br><span>  OSMO_ASSERT(lchan->prim == NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Not applicable for SACCH! */</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(!CHAN_IS_SACCH(lchan->type));</span><br><span> </span><br><span>     /**</span><br><span>   * Determine what actually should be generated:</span><br><span>@@ -364,18 +544,8 @@</span><br><span>               /* FIXME: should we do anything for CSD? */</span><br><span>          return 0;</span><br><span>    } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                uint8_t *cur = prim_buffer;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             if (CHAN_IS_SACCH(chan)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      /* Add 2-byte SACCH header */</span><br><span style="color: hsl(0, 100%, 40%);">-                   /* FIXME: How to get TA and MS Tx Power from l1l->trx->tx_power + l1l->trx->ta? */</span><br><span style="color: hsl(0, 100%, 40%);">-                  cur[0] = cur[1] = 0x00;</span><br><span style="color: hsl(0, 100%, 40%);">-                 cur += 2;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               /* Copy a fill frame payload */</span><br><span style="color: hsl(0, 100%, 40%);">-         memcpy(cur, lapdm_fill_frame, sizeof(lapdm_fill_frame));</span><br><span style="color: hsl(0, 100%, 40%);">-                cur += sizeof(lapdm_fill_frame);</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Copy LAPDm fill frame's header */</span><br><span style="color: hsl(120, 100%, 40%);">+              memcpy(prim_buffer, lapdm_fill_frame, sizeof(lapdm_fill_frame));</span><br><span> </span><br><span>                 /**</span><br><span>           * TS 144.006, section 5.2 "Frame delimitation and fill bits"</span><br><span>@@ -383,7 +553,7 @@</span><br><span>                 * be set to the binary value "00101011", each fill bit should</span><br><span>              * be set to a random value when sent by the network.</span><br><span>                 */</span><br><span style="color: hsl(0, 100%, 40%);">-             for (i = cur - prim_buffer; i < GSM_MACBLOCK_LEN; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+             for (i = sizeof(lapdm_fill_frame); i < GSM_MACBLOCK_LEN; i++)</span><br><span>                     prim_buffer[i] = (uint8_t) rand();</span><br><span> </span><br><span>               /* Define a prim length */</span><br><span>diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c</span><br><span>index fc29998..0b83af3 100644</span><br><span>--- a/src/host/trxcon/sched_trx.c</span><br><span>+++ b/src/host/trxcon/sched_trx.c</span><br><span>@@ -460,7 +460,7 @@</span><br><span>    /* Forget the current prim */</span><br><span>        sched_prim_drop(lchan);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     /* TCH specific variables */</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Channel specific stuff */</span><br><span>         if (CHAN_IS_TCH(lchan->type)) {</span><br><span>           lchan->dl_ongoing_facch = 0;</span><br><span>              lchan->ul_facch_blocks = 0;</span><br><span>@@ -469,6 +469,9 @@</span><br><span> </span><br><span>             /* Reset AMR state */</span><br><span>                memset(&lchan->amr, 0x00, sizeof(lchan->amr));</span><br><span style="color: hsl(120, 100%, 40%);">+      } else if (CHAN_IS_SACCH(lchan->type)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Reset SACCH state */</span><br><span style="color: hsl(120, 100%, 40%);">+               memset(&lchan->sacch, 0x00, sizeof(lchan->sacch));</span><br><span>         }</span><br><span> </span><br><span>        /* Reset ciphering state */</span><br><span>diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h</span><br><span>index 818c95a..0feaeec 100644</span><br><span>--- a/src/host/trxcon/sched_trx.h</span><br><span>+++ b/src/host/trxcon/sched_trx.h</span><br><span>@@ -186,6 +186,16 @@</span><br><span>          int32_t toa256_sum;</span><br><span>  } meas;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   /*! \brief SACCH state */</span><br><span style="color: hsl(120, 100%, 40%);">+     struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              /*! \brief Cached measurement report (last received) */</span><br><span style="color: hsl(120, 100%, 40%);">+               uint8_t mr_cache[GSM_MACBLOCK_LEN];</span><br><span style="color: hsl(120, 100%, 40%);">+           /*! \brief Cache usage counter */</span><br><span style="color: hsl(120, 100%, 40%);">+             uint8_t mr_cache_usage;</span><br><span style="color: hsl(120, 100%, 40%);">+               /*! \brief What MR transmitted last time? */</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t mr_tx_last; /*!< 0x01 - yes, 0x00 - no */</span><br><span style="color: hsl(120, 100%, 40%);">+  } sacch;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   /* AMR specific */</span><br><span>   struct {</span><br><span>             /*! \brief 4 possible codecs for AMR */</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/11138">change 11138</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/11138"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmocom-bb </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: If1b8dc74ced746d6270676fdde75fcda32f91a3d </div>
<div style="display:none"> Gerrit-Change-Number: 11138 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Vadim Yanitskiy <axilirator@gmail.com> </div>