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

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">l1sap: rework handling of DATA.ind on SACCH<br><br>Currently an Uplink SACCH block is being passed to LAPDm first, and<br>then gets forwareded to the BSC in handle_ms_meas_report(), together<br>with the Uplink measurements collected so far.<br><br>This approach has a serious flaw: handle_ms_meas_report() won't be<br>called if an Uplink block contains SAPI=3 data (SMS) or was not<br>decoded at all (len=0) fow whatever reason.  Therefore, no RSL<br>MEASurement RESult message will be sent to the BSC.<br><br>Rename handle_ms_meas_report() to lchan_meas_handle_sacch(), and call<br>it from l1sap_ph_data_ind().  This way perioduc RSL MEASurement RESult<br>messages will be sent regardless of what happens on Uplink SACCH.<br><br>Change-Id: Ifed91f87fd653debc87a09da3fd31ad64a13f330<br>Fixes: TC_meas_res_speech_{tchf,tchh}_sapi3<br>Related: SYS#5319<br>---<br>M include/osmo-bts/measurement.h<br>M src/common/l1sap.c<br>M src/common/measurement.c<br>M src/common/rsl.c<br>4 files changed, 84 insertions(+), 74 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmo-bts/measurement.h b/include/osmo-bts/measurement.h</span><br><span>index f63a05a..ad86d8d 100644</span><br><span>--- a/include/osmo-bts/measurement.h</span><br><span>+++ b/include/osmo-bts/measurement.h</span><br><span>@@ -20,8 +20,6 @@</span><br><span> </span><br><span> int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int handle_ms_meas_report(struct gsm_lchan *lchan,</span><br><span style="color: hsl(0, 100%, 40%);">-                          const struct gsm48_hdr *gh,</span><br><span style="color: hsl(0, 100%, 40%);">-                     unsigned int len);</span><br><span style="color: hsl(120, 100%, 40%);">+void lchan_meas_handle_sacch(struct gsm_lchan *lchan, struct msgb *msg);</span><br><span> </span><br><span> #endif</span><br><span>diff --git a/src/common/l1sap.c b/src/common/l1sap.c</span><br><span>index f983b62..8dee209 100644</span><br><span>--- a/src/common/l1sap.c</span><br><span>+++ b/src/common/l1sap.c</span><br><span>@@ -33,7 +33,6 @@</span><br><span> #include <osmocom/gsm/l1sap.h></span><br><span> #include <osmocom/gsm/gsm_utils.h></span><br><span> #include <osmocom/gsm/rsl.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/protocol/gsm_44_004.h></span><br><span> #include <osmocom/core/gsmtap.h></span><br><span> #include <osmocom/core/gsmtap_util.h></span><br><span> #include <osmocom/core/utils.h></span><br><span>@@ -1470,7 +1469,6 @@</span><br><span>  uint8_t tn;</span><br><span>  uint32_t fn;</span><br><span>         enum osmo_ph_pres_info_type pr_info = data_ind->pdch_presence_info;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct gsm_sacch_l1_hdr *l1_hdr;</span><br><span> </span><br><span>         chan_nr = data_ind->chan_nr;</span><br><span>      link_id = data_ind->link_id;</span><br><span>@@ -1529,48 +1527,33 @@</span><br><span>    if (bts_internal_flag_get(trx->bts, BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB))</span><br><span>                 process_l1sap_meas_data(lchan, l1sap, PRIM_PH_DATA);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        if (L1SAP_IS_LINK_SACCH(link_id))</span><br><span style="color: hsl(120, 100%, 40%);">+     if (L1SAP_IS_LINK_SACCH(link_id)) {</span><br><span>          repeated_ul_sacch_active_decision(lchan, data_ind->ber10k);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      /* bad frame */</span><br><span style="color: hsl(0, 100%, 40%);">- if (len == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         if (L1SAP_IS_LINK_SACCH(link_id)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     /* In case we loose a SACCH block, we must take care</span><br><span style="color: hsl(0, 100%, 40%);">-                     * that the related measurement report is sent via RSL.</span><br><span style="color: hsl(0, 100%, 40%);">-                  * This is a fallback method. The report will also</span><br><span style="color: hsl(0, 100%, 40%);">-                       * lack the measurement report from the MS side. See</span><br><span style="color: hsl(0, 100%, 40%);">-                     * also rsl.c:lapdm_rll_tx_cb() */</span><br><span style="color: hsl(0, 100%, 40%);">-                      LOGPGT(DL1P, LOGL_INFO, &g_time, "Lost SACCH block, faking meas reports and ms pwr\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                   handle_ms_meas_report(lchan, NULL, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Radio Link Timeout counter */</span><br><span style="color: hsl(120, 100%, 40%);">+              if (len == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       LOGPGT(DL1P, LOGL_INFO, &g_time, "%s Lost SACCH block\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                              gsm_lchan_name(lchan));</span><br><span>                       radio_link_timeout(lchan, true);</span><br><span style="color: hsl(120, 100%, 40%);">+              } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      radio_link_timeout(lchan, false);</span><br><span>            }</span><br><span style="color: hsl(0, 100%, 40%);">-               return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Trigger the measurement reporting/processing logic */</span><br><span style="color: hsl(120, 100%, 40%);">+              lchan_meas_handle_sacch(lchan, msg);</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* bad frame */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (len == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    /* report first valid received frame to handover process */</span><br><span>  if (lchan->ho.active == HANDOVER_WAIT_FRAME)</span><br><span>              handover_frame(lchan);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (L1SAP_IS_LINK_SACCH(link_id)) {</span><br><span style="color: hsl(0, 100%, 40%);">-             radio_link_timeout(lchan, false);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (L1SAP_IS_LINK_SACCH(link_id))</span><br><span>            le = &lchan->lapdm_ch.lapdm_acch;</span><br><span style="color: hsl(0, 100%, 40%);">-                /* save the SACCH L1 header in the lchan struct for RSL MEAS RES */</span><br><span style="color: hsl(0, 100%, 40%);">-             if (len != GSM_MACBLOCK_LEN) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  LOGPGT(DL1P, LOGL_NOTICE, &g_time, "SACCH with odd len=%u!?!\n", len);</span><br><span style="color: hsl(0, 100%, 40%);">-                    return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-               /* Some brilliant engineer decided that the ordering of</span><br><span style="color: hsl(0, 100%, 40%);">-          * fields on the Um interface is different from the</span><br><span style="color: hsl(0, 100%, 40%);">-              * order of fields in RSL. See 3GPP TS 44.004 (section 7.2)</span><br><span style="color: hsl(0, 100%, 40%);">-              * vs. 3GPP TS 48.058 (section 9.3.10). */</span><br><span style="color: hsl(0, 100%, 40%);">-              l1_hdr = (struct gsm_sacch_l1_hdr*)data;</span><br><span style="color: hsl(0, 100%, 40%);">-                lchan->meas.l1_info.ms_pwr = l1_hdr->ms_pwr;</span><br><span style="color: hsl(0, 100%, 40%);">-              lchan->meas.l1_info.fpc_epc = l1_hdr->fpc_epc;</span><br><span style="color: hsl(0, 100%, 40%);">-            lchan->meas.l1_info.srr_sro = l1_hdr->srr_sro;</span><br><span style="color: hsl(0, 100%, 40%);">-            lchan->meas.l1_info.ta = l1_hdr->ta;</span><br><span style="color: hsl(0, 100%, 40%);">-              lchan->meas.flags |= LC_UL_M_F_L1_VALID;</span><br><span style="color: hsl(0, 100%, 40%);">-     } else</span><br><span style="color: hsl(120, 100%, 40%);">+        else</span><br><span>                 le = &lchan->lapdm_ch.lapdm_dcch;</span><br><span> </span><br><span>         if (check_for_first_ciphrd(lchan, data, len))</span><br><span>diff --git a/src/common/measurement.c b/src/common/measurement.c</span><br><span>index a83be34..3aeb901 100644</span><br><span>--- a/src/common/measurement.c</span><br><span>+++ b/src/common/measurement.c</span><br><span>@@ -2,8 +2,11 @@</span><br><span> #include <stdint.h></span><br><span> #include <errno.h></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/gsm_utils.h></span><br><span> #include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/endian.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsm_utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/protocol/gsm_44_004.h></span><br><span> </span><br><span> #include <osmo-bts/gsm_data.h></span><br><span> #include <osmo-bts/logging.h></span><br><span>@@ -865,24 +868,74 @@</span><br><span>               LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "DL-FACCH repetition: active => inactive\n");</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Called every time a Measurement Result (TS 08.58 8.4.8) is received from</span><br><span style="color: hsl(0, 100%, 40%);">- * lower layers and has to be forwarded to BSC */</span><br><span style="color: hsl(0, 100%, 40%);">-int handle_ms_meas_report(struct gsm_lchan *lchan,</span><br><span style="color: hsl(0, 100%, 40%);">-                      const struct gsm48_hdr *gh,</span><br><span style="color: hsl(0, 100%, 40%);">-                     unsigned int len)</span><br><span style="color: hsl(120, 100%, 40%);">+static bool data_is_rr_meas_rep(const uint8_t *data)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        const struct gsm48_hdr *gh = (void *)(data + 5);</span><br><span style="color: hsl(120, 100%, 40%);">+      const uint8_t *lapdm_hdr = (void *)(data + 2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* LAPDm address field: SAPI=0, C/R=0, EA=1 */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (lapdm_hdr[0] != 0x01)</span><br><span style="color: hsl(120, 100%, 40%);">+             return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* LAPDm control field: U, func=UI */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lapdm_hdr[1] != 0x03)</span><br><span style="color: hsl(120, 100%, 40%);">+             return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Protocol discriminator: RR */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (gh->proto_discr != GSM48_PDISC_RR)</span><br><span style="color: hsl(120, 100%, 40%);">+             return false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (gh->msg_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case GSM48_MT_RR_EXT_MEAS_REP:</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM48_MT_RR_MEAS_REP:</span><br><span style="color: hsl(120, 100%, 40%);">+            return true;</span><br><span style="color: hsl(120, 100%, 40%);">+  default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return 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%);">+/* Called every time a SACCH block is received from lower layers */</span><br><span style="color: hsl(120, 100%, 40%);">+void lchan_meas_handle_sacch(struct gsm_lchan *lchan, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       const struct gsm48_meas_res *mr = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+       const struct gsm48_hdr *gh = NULL;</span><br><span>   int timing_offset, rc;</span><br><span>       struct lapdm_entity *le;</span><br><span style="color: hsl(0, 100%, 40%);">-        bool dtxu_used;</span><br><span style="color: hsl(120, 100%, 40%);">+       bool dtxu_used = true; /* safe default assumption */</span><br><span>         uint8_t ms_pwr;</span><br><span>      uint8_t ms_ta;</span><br><span>       int8_t ul_rssi;</span><br><span>      int16_t ul_ci_cb;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (msgb_l2len(msg) == GSM_MACBLOCK_LEN) {</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Some brilliant engineer decided that the ordering of</span><br><span style="color: hsl(120, 100%, 40%);">+                * fields on the Um interface is different from the</span><br><span style="color: hsl(120, 100%, 40%);">+            * order of fields in RSL. See 3GPP TS 44.004 (section 7.2)</span><br><span style="color: hsl(120, 100%, 40%);">+            * vs. 3GPP TS 48.058 (section 9.3.10). */</span><br><span style="color: hsl(120, 100%, 40%);">+            const struct gsm_sacch_l1_hdr *l1h = msgb_l2(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+            lchan->meas.l1_info.ms_pwr = l1h->ms_pwr;</span><br><span style="color: hsl(120, 100%, 40%);">+               lchan->meas.l1_info.fpc_epc = l1h->fpc_epc;</span><br><span style="color: hsl(120, 100%, 40%);">+             lchan->meas.l1_info.srr_sro = l1h->srr_sro;</span><br><span style="color: hsl(120, 100%, 40%);">+             lchan->meas.l1_info.ta = l1h->ta;</span><br><span style="color: hsl(120, 100%, 40%);">+               lchan->meas.flags |= LC_UL_M_F_L1_VALID;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* Check if this is a Measurement Report */</span><br><span style="color: hsl(120, 100%, 40%);">+           if (data_is_rr_meas_rep(msgb_l2(msg))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* Skip both L1 SACCH and LAPDm headers */</span><br><span style="color: hsl(120, 100%, 40%);">+                    msg->l3h = (void *)(msg->l2h + 2 + 3);</span><br><span style="color: hsl(120, 100%, 40%);">+                  gh = msgb_l3(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%);">+           ms_pwr = lchan->meas.l1_info.ms_pwr;</span><br><span style="color: hsl(120, 100%, 40%);">+               ms_ta = lchan->meas.l1_info.ta;</span><br><span style="color: hsl(120, 100%, 40%);">+    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              lchan->meas.flags &= ~LC_UL_M_F_L1_VALID;</span><br><span style="color: hsl(120, 100%, 40%);">+              ms_pwr = lchan->ms_power_ctrl.current;</span><br><span style="color: hsl(120, 100%, 40%);">+             ms_ta = lchan->ta_ctrl.current;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  le = &lchan->lapdm_ch.lapdm_acch;</span><br><span> </span><br><span>         timing_offset = ms_to_valid(lchan) ? ms_to2rsl(lchan, le) : -1;</span><br><span style="color: hsl(0, 100%, 40%);">- rc = rsl_tx_meas_res(lchan, (const uint8_t *)gh, len, timing_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg), timing_offset);</span><br><span>   if (rc == 0) /* Count successful transmissions */</span><br><span>            lchan->meas.res_nr++;</span><br><span> </span><br><span>@@ -896,25 +949,9 @@</span><br><span>   * feed the Control Loop with the measurements for the same</span><br><span>   * period (the previous one), which is stored in lchan->meas(.ul_res):</span><br><span>     */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (len == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         dtxu_used = true;</span><br><span style="color: hsl(0, 100%, 40%);">-               ms_ta = lchan->ta_ctrl.current;</span><br><span style="color: hsl(0, 100%, 40%);">-              ms_pwr = lchan->ms_power_ctrl.current;</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* if len!=0, it means we were able to parse L1Header in UL SACCH: */</span><br><span style="color: hsl(0, 100%, 40%);">-           OSMO_ASSERT(lchan->meas.flags & LC_UL_M_F_L1_VALID);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             ms_ta = lchan->meas.l1_info.ta;</span><br><span style="color: hsl(0, 100%, 40%);">-              ms_pwr = lchan->meas.l1_info.ms_pwr;</span><br><span style="color: hsl(0, 100%, 40%);">-         switch (gh->msg_type) {</span><br><span style="color: hsl(0, 100%, 40%);">-              case GSM48_MT_RR_MEAS_REP:</span><br><span style="color: hsl(0, 100%, 40%);">-                      dtxu_used = (len > sizeof(*gh) + 1) && !!(gh->data[0] & 0x40);</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case GSM48_MT_RR_EXT_MEAS_REP:</span><br><span style="color: hsl(0, 100%, 40%);">-          default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        dtxu_used = true; /* FIXME: not implemented */</span><br><span style="color: hsl(0, 100%, 40%);">-                  break;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (gh && gh->msg_type == GSM48_MT_RR_MEAS_REP) {</span><br><span style="color: hsl(120, 100%, 40%);">+          mr = (const struct gsm48_meas_res *)gh->data;</span><br><span style="color: hsl(120, 100%, 40%);">+              dtxu_used = mr->dtx_used;</span><br><span>         }</span><br><span> </span><br><span>        if (dtxu_used) {</span><br><span>@@ -934,8 +971,6 @@</span><br><span>       /* Reset state for next iteration */</span><br><span>         lchan->tch.dtx.dl_active = false;</span><br><span>         lchan->meas.flags &= ~LC_UL_M_F_OSMO_EXT_VALID;</span><br><span style="color: hsl(0, 100%, 40%);">-  lchan->meas.flags &= ~LC_UL_M_F_L1_VALID;</span><br><span>     lchan->ms_t_offs = -1;</span><br><span>    lchan->p_offs = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-  return rc;</span><br><span> }</span><br><span>diff --git a/src/common/rsl.c b/src/common/rsl.c</span><br><span>index 2d00005..5d069c2 100644</span><br><span>--- a/src/common/rsl.c</span><br><span>+++ b/src/common/rsl.c</span><br><span>@@ -3566,17 +3566,11 @@</span><br><span>       msg->trx = lchan->ts->trx;</span><br><span>  msg->lchan = lchan;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      /* check if this is a measurement report from SACCH which needs special</span><br><span style="color: hsl(0, 100%, 40%);">-  * processing before forwarding */</span><br><span style="color: hsl(120, 100%, 40%);">+    /* If this is a Measurement Report, then we simply ignore it,</span><br><span style="color: hsl(120, 100%, 40%);">+  * because it has already been processed in l1sap_ph_data_ind(). */</span><br><span>  if (rslms_is_meas_rep(msg)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Handing RLL msg %s from LAPDm to MEAS REP\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                        rsl_msg_name(rh->msg_type));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               rc = handle_ms_meas_report(lchan, (struct gsm48_hdr *)msgb_l3(msg), msgb_l3len(msg));</span><br><span>                msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+            return 0;</span><br><span>    } else if (rslms_is_gprs_susp_req(msg)) {</span><br><span>            return handle_gprs_susp_req(msg);</span><br><span>    } else {</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/26046">change 26046</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/+/26046"/><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: Ifed91f87fd653debc87a09da3fd31ad64a13f330 </div>
<div style="display:none"> Gerrit-Change-Number: 26046 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: fixeria <vyanitskiy@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>