<p>neels has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/26614">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">fix gscon clear 3/n: separate state for SCCP RLSD<br><br>Properly implement the separate conn release stages in separate FSM<br>states:<br><br>x) sent Clear Request, wait for a Clear Command from the MSC.<br>   Timeout after a configurable 60s.<br><br>y) after a Clear Command and sending a Clear Complete, wait for the SCCP<br>   RLSD. Timeout after a configurable 60s.<br><br>z) terminate after the RLSD is received / after timeout.<br><br>handover_test.c needs a little tweak to make the MGCP release work with<br>its fake MGCP client, because cleanup now ensures to invoke<br>gscon_forget_mgw_endpoint() in all cases.<br><br>Related: I680ec4ed866aa5f0b1ff29e7e98322615cfb288d (osmo-ttcn3-hacks)<br>Related: OS#5337<br>Change-Id: Ie975117d37f38ba853589dc7f8d3e94f8f9586b2<br>---<br>M src/osmo-bsc/bsc_subscr_conn_fsm.c<br>M tests/handover/handover_test.c<br>2 files changed, 75 insertions(+), 54 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/14/26614/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c</span><br><span>index e33fe43..121b154 100644</span><br><span>--- a/src/osmo-bsc/bsc_subscr_conn_fsm.c</span><br><span>+++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c</span><br><span>@@ -67,7 +67,8 @@</span><br><span>  ST_ASSIGNMENT,</span><br><span>       ST_HANDOVER,</span><br><span>         /* BSSMAP CLEAR has been received */</span><br><span style="color: hsl(0, 100%, 40%);">-    ST_CLEARING,</span><br><span style="color: hsl(120, 100%, 40%);">+  ST_WAIT_CLEAR_CMD,</span><br><span style="color: hsl(120, 100%, 40%);">+    ST_WAIT_SCCP_RLSD,</span><br><span> };</span><br><span> </span><br><span> static const struct value_string gscon_fsm_event_names[] = {</span><br><span>@@ -95,7 +96,8 @@</span><br><span> </span><br><span> struct osmo_tdef_state_timeout conn_fsm_timeouts[32] = {</span><br><span>     [ST_WAIT_CC] = { .T = -3210 },</span><br><span style="color: hsl(0, 100%, 40%);">-  [ST_CLEARING] = { .T = -4 },</span><br><span style="color: hsl(120, 100%, 40%);">+  [ST_WAIT_CLEAR_CMD] = { .T = -4 },</span><br><span style="color: hsl(120, 100%, 40%);">+    [ST_WAIT_SCCP_RLSD] = { .T = -4 },</span><br><span> };</span><br><span> </span><br><span> /* Transition to a state, using the T timer defined in conn_fsm_timeouts.</span><br><span>@@ -143,44 +145,71 @@</span><br><span> {</span><br><span>       /* already clearing? */</span><br><span>      switch (conn->fi->state) {</span><br><span style="color: hsl(0, 100%, 40%);">-        case ST_CLEARING:</span><br><span style="color: hsl(120, 100%, 40%);">+     case ST_WAIT_CLEAR_CMD:</span><br><span style="color: hsl(120, 100%, 40%);">+       case ST_WAIT_SCCP_RLSD:</span><br><span>              return;</span><br><span>      default:</span><br><span>             break;</span><br><span>       }</span><br><span> </span><br><span>        conn->clear_cause = cause;</span><br><span style="color: hsl(0, 100%, 40%);">-   conn_fsm_state_chg(ST_CLEARING);</span><br><span style="color: hsl(120, 100%, 40%);">+      conn_fsm_state_chg(ST_WAIT_CLEAR_CMD);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void gscon_fsm_clearing_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span style="color: hsl(120, 100%, 40%);">+static void gscon_fsm_wait_clear_cmd_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span> {</span><br><span>       struct msgb *resp;</span><br><span>   int rc;</span><br><span>      struct gsm_subscriber_connection *conn = fi->priv;</span><br><span>        enum gsm0808_cause cause = conn->clear_cause;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    if (conn->rx_clear_command) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGPFSML(conn->fi, LOGL_DEBUG, "Not sending BSSMAP CLEAR REQUEST, already got CLEAR COMMAND from MSC\n");</span><br><span style="color: hsl(0, 100%, 40%);">-          return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    if (!conn->sccp.msc) {</span><br><span>            LOGPFSML(fi, LOGL_ERROR, "Unable to deliver BSSMAP Clear Request message, no MSC for this conn\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           return;</span><br><span style="color: hsl(120, 100%, 40%);">+               goto nothing_sent;</span><br><span>   }</span><br><span> </span><br><span>        LOGPFSML(fi, LOGL_DEBUG, "Tx BSSMAP CLEAR REQUEST(%s) to MSC\n", gsm0808_cause_name(cause));</span><br><span>       resp = gsm0808_create_clear_rqst(cause);</span><br><span>     if (!resp) {</span><br><span>                 LOGPFSML(fi, LOGL_ERROR, "Unable to compose BSSMAP Clear Request message\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(120, 100%, 40%);">+               goto nothing_sent;</span><br><span>   }</span><br><span> </span><br><span>        rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_CLEAR_RQST));</span><br><span>      rc = osmo_bsc_sigtran_send(conn, resp);</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+        if (rc < 0) {</span><br><span>             LOGPFSML(conn->fi, LOGL_ERROR, "Unable to deliver BSSMAP Clear Request message\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto nothing_sent;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</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%);">+nothing_sent:</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Normally, we request a CLEAR from the MSC and terminate as soon as the CLEAR COMMAND has been issued by the</span><br><span style="color: hsl(120, 100%, 40%);">+         * MSC. But if we are trying to clear without being able to send anything to the MSC, we might as well shut down</span><br><span style="color: hsl(120, 100%, 40%);">+       * the conn right away now. */</span><br><span style="color: hsl(120, 100%, 40%);">+        conn_fsm_state_chg(ST_WAIT_SCCP_RLSD);</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%);">+void gscon_fsm_wait_sccp_rlsd_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct gsm_subscriber_connection *conn = fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* According to 3GPP 48.008 3.1.9.1. "The BSS need not wait for the radio channel</span><br><span style="color: hsl(120, 100%, 40%);">+         * release to be completed or for the guard timer to expire before returning the</span><br><span style="color: hsl(120, 100%, 40%);">+       * CLEAR COMPLETE message" */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!gscon_sigtran_send(conn, gsm0808_create_clear_complete()))</span><br><span style="color: hsl(120, 100%, 40%);">+               rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_CLEAR_COMPLETE));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Give the handover_fsm a chance to book this as handover success before tearing down everything,</span><br><span style="color: hsl(120, 100%, 40%);">+     * making it look like a sudden death failure. */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (conn->ho.fi)</span><br><span style="color: hsl(120, 100%, 40%);">+           osmo_fsm_inst_dispatch(conn->ho.fi, HO_EV_CONN_RELEASING, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (conn->lcs.loc_req)</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_fsm_inst_dispatch(conn->lcs.loc_req->fi, LCS_LOC_REQ_EV_CONN_CLEAR, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       gscon_release_lchans(conn, true, bsc_gsm48_rr_cause_from_gsm0808_cause(conn->clear_cause));</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_mgcpc_ep_clear(conn->user_plane.mgw_endpoint);</span><br><span> }</span><br><span> </span><br><span> /* forward MO DTAP from RSL side to BSSAP side */</span><br><span>@@ -682,13 +711,13 @@</span><br><span>                 .name = "INIT",</span><br><span>            .in_event_mask = S(GSCON_EV_MO_COMPL_L3) | S(GSCON_EV_A_CONN_IND)</span><br><span>                    | S(GSCON_EV_HANDOVER_END),</span><br><span style="color: hsl(0, 100%, 40%);">-             .out_state_mask = S(ST_WAIT_CC) | S(ST_ACTIVE) | S(ST_CLEARING),</span><br><span style="color: hsl(120, 100%, 40%);">+              .out_state_mask = S(ST_WAIT_CC) | S(ST_ACTIVE) | S(ST_WAIT_CLEAR_CMD) | S(ST_WAIT_SCCP_RLSD),</span><br><span>                .action = gscon_fsm_init,</span><br><span>     },</span><br><span>  [ST_WAIT_CC] = {</span><br><span>             .name = "WAIT_CC",</span><br><span>                 .in_event_mask = S(GSCON_EV_A_CONN_CFM),</span><br><span style="color: hsl(0, 100%, 40%);">-                .out_state_mask = S(ST_ACTIVE) | S(ST_CLEARING),</span><br><span style="color: hsl(120, 100%, 40%);">+              .out_state_mask = S(ST_ACTIVE) | S(ST_WAIT_CLEAR_CMD) | S(ST_WAIT_SCCP_RLSD),</span><br><span>                .action = gscon_fsm_wait_cc,</span><br><span>         },</span><br><span>   [ST_ACTIVE] = {</span><br><span>@@ -698,27 +727,32 @@</span><br><span>                               | S(GSCON_EV_LCS_LOC_REQ_END)</span><br><span>                                | S(GSCON_EV_MO_COMPL_L3)</span><br><span>                            ,</span><br><span style="color: hsl(0, 100%, 40%);">-              .out_state_mask = S(ST_CLEARING) | S(ST_ASSIGNMENT) |</span><br><span style="color: hsl(120, 100%, 40%);">+         .out_state_mask = S(ST_WAIT_CLEAR_CMD) | S(ST_WAIT_SCCP_RLSD) | S(ST_ASSIGNMENT) |</span><br><span>                             S(ST_HANDOVER),</span><br><span>            .action = gscon_fsm_active,</span><br><span>  },</span><br><span>   [ST_ASSIGNMENT] = {</span><br><span>          .name = "ASSIGNMENT",</span><br><span>              .in_event_mask = EV_TRANSPARENT_SCCP | S(GSCON_EV_ASSIGNMENT_END),</span><br><span style="color: hsl(0, 100%, 40%);">-              .out_state_mask = S(ST_ACTIVE) | S(ST_CLEARING),</span><br><span style="color: hsl(120, 100%, 40%);">+              .out_state_mask = S(ST_ACTIVE) | S(ST_WAIT_CLEAR_CMD) | S(ST_WAIT_SCCP_RLSD),</span><br><span>                .action = gscon_fsm_assignment,</span><br><span>      },</span><br><span>   [ST_HANDOVER] = {</span><br><span>            .name = "HANDOVER",</span><br><span>                .in_event_mask = EV_TRANSPARENT_SCCP | S(GSCON_EV_HANDOVER_END),</span><br><span style="color: hsl(0, 100%, 40%);">-                .out_state_mask = S(ST_ACTIVE) | S(ST_CLEARING),</span><br><span style="color: hsl(120, 100%, 40%);">+              .out_state_mask = S(ST_ACTIVE) | S(ST_WAIT_CLEAR_CMD) | S(ST_WAIT_SCCP_RLSD),</span><br><span>                .action = gscon_fsm_handover,</span><br><span>        },</span><br><span style="color: hsl(0, 100%, 40%);">-      [ST_CLEARING] = {</span><br><span style="color: hsl(0, 100%, 40%);">-               .name = "CLEARING",</span><br><span style="color: hsl(0, 100%, 40%);">-           .onenter = gscon_fsm_clearing_onenter,</span><br><span style="color: hsl(0, 100%, 40%);">-          /* dead end state */</span><br><span style="color: hsl(0, 100%, 40%);">-     },</span><br><span style="color: hsl(120, 100%, 40%);">+   [ST_WAIT_CLEAR_CMD] = {</span><br><span style="color: hsl(120, 100%, 40%);">+               .name = "WAIT_CLEAR_CMD",</span><br><span style="color: hsl(120, 100%, 40%);">+           .onenter = gscon_fsm_wait_clear_cmd_onenter,</span><br><span style="color: hsl(120, 100%, 40%);">+          .out_state_mask = S(ST_WAIT_SCCP_RLSD),</span><br><span style="color: hsl(120, 100%, 40%);">+       },</span><br><span style="color: hsl(120, 100%, 40%);">+    [ST_WAIT_SCCP_RLSD] = {</span><br><span style="color: hsl(120, 100%, 40%);">+               .name = "WAIT_SCCP_RLSD",</span><br><span style="color: hsl(120, 100%, 40%);">+           .onenter = gscon_fsm_wait_sccp_rlsd_onenter,</span><br><span style="color: hsl(120, 100%, 40%);">+          .in_event_mask = S(GSCON_EV_HANDOVER_END),</span><br><span style="color: hsl(120, 100%, 40%);">+    },</span><br><span> };</span><br><span> </span><br><span> void gscon_change_primary_lchan(struct gsm_subscriber_connection *conn, struct gsm_lchan *new_lchan)</span><br><span>@@ -848,44 +882,19 @@</span><br><span> static void gscon_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span> {</span><br><span>    struct gsm_subscriber_connection *conn = fi->priv;</span><br><span style="color: hsl(0, 100%, 40%);">-   const enum gsm0808_cause *cause_0808;</span><br><span>        const struct tlv_parsed *tp;</span><br><span>         struct osmo_mobile_identity mi_imsi;</span><br><span> </span><br><span>     /* Regular allstate event processing */</span><br><span>      switch (event) {</span><br><span>     case GSCON_EV_A_CLEAR_CMD:</span><br><span style="color: hsl(0, 100%, 40%);">-              conn->rx_clear_command = true;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               /* Give the handover_fsm a chance to book this as handover success before tearing down everything,</span><br><span style="color: hsl(0, 100%, 40%);">-               * making it look like a sudden death failure. */</span><br><span style="color: hsl(0, 100%, 40%);">-               if (conn->ho.fi)</span><br><span style="color: hsl(0, 100%, 40%);">-                     osmo_fsm_inst_dispatch(conn->ho.fi, HO_EV_CONN_RELEASING, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             if (conn->lcs.loc_req)</span><br><span style="color: hsl(0, 100%, 40%);">-                       osmo_fsm_inst_dispatch(conn->lcs.loc_req->fi, LCS_LOC_REQ_EV_CONN_CLEAR, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>                OSMO_ASSERT(data);</span><br><span style="color: hsl(0, 100%, 40%);">-              cause_0808 = data;</span><br><span style="color: hsl(0, 100%, 40%);">-              /* MSC tells us to cleanly shut down */</span><br><span style="color: hsl(0, 100%, 40%);">-         if (conn->fi->state != ST_CLEARING)</span><br><span style="color: hsl(0, 100%, 40%);">-                       osmo_fsm_inst_state_chg(fi, ST_CLEARING, 60, -4);</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGPFSML(fi, LOGL_DEBUG, "Releasing all lchans (if any) after BSSMAP Clear Command\n");</span><br><span style="color: hsl(0, 100%, 40%);">-               gscon_release_lchans(conn, true, bsc_gsm48_rr_cause_from_gsm0808_cause(*cause_0808));</span><br><span style="color: hsl(0, 100%, 40%);">-           /* FIXME: Release all terestrial resources in ST_CLEARING */</span><br><span style="color: hsl(0, 100%, 40%);">-            /* According to 3GPP 48.008 3.1.9.1. "The BSS need not wait for the radio channel</span><br><span style="color: hsl(0, 100%, 40%);">-           * release to be completed or for the guard timer to expire before returning the</span><br><span style="color: hsl(0, 100%, 40%);">-                 * CLEAR COMPLETE message" */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              /* Close MGCP connections */</span><br><span style="color: hsl(0, 100%, 40%);">-            osmo_mgcpc_ep_clear(conn->user_plane.mgw_endpoint);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_CLEAR_COMPLETE));</span><br><span style="color: hsl(0, 100%, 40%);">-             gscon_sigtran_send(conn, gsm0808_create_clear_complete());</span><br><span style="color: hsl(120, 100%, 40%);">+            conn->clear_cause = *(const enum gsm0808_cause*)data;</span><br><span style="color: hsl(120, 100%, 40%);">+              conn_fsm_state_chg(ST_WAIT_SCCP_RLSD);</span><br><span>               break;</span><br><span>       case GSCON_EV_A_DISC_IND:</span><br><span style="color: hsl(0, 100%, 40%);">-               /* MSC or SIGTRAN network has hard-released SCCP connection,</span><br><span style="color: hsl(0, 100%, 40%);">-             * terminate the FSM now. */</span><br><span style="color: hsl(120, 100%, 40%);">+          /* MSC or SIGTRAN network has hard-released SCCP connection, terminate the FSM now.</span><br><span style="color: hsl(120, 100%, 40%);">+            * Cleanup is done in gscon_pre_term() and gscon_cleanup(). */</span><br><span>               osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, data);</span><br><span>                 break;</span><br><span>       case GSCON_EV_FORGET_MGW_ENDPOINT:</span><br><span>@@ -975,6 +984,13 @@</span><br><span> </span><br><span>        osmo_mgcpc_ep_clear(conn->user_plane.mgw_endpoint);</span><br><span>       conn->user_plane.mgw_endpoint = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+      conn->user_plane.mgw_endpoint = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (conn->ho.fi)</span><br><span style="color: hsl(120, 100%, 40%);">+           osmo_fsm_inst_dispatch(conn->ho.fi, HO_EV_CONN_RELEASING, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (conn->lcs.loc_req)</span><br><span style="color: hsl(120, 100%, 40%);">+             osmo_fsm_inst_dispatch(conn->lcs.loc_req->fi, LCS_LOC_REQ_EV_CONN_CLEAR, NULL);</span><br><span> </span><br><span>    if (conn->lcls.fi) {</span><br><span>              /* request termination of LCLS FSM */</span><br><span>@@ -1013,8 +1029,9 @@</span><br><span>        case -4:</span><br><span>             /* The MSC has sent a BSSMAP Clear Command, we acknowledged that, but the conn was never</span><br><span>              * disconnected. */</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGPFSML(fi, LOGL_ERROR, "Long after a BSSMAP Clear Command, the conn is still not"</span><br><span style="color: hsl(0, 100%, 40%);">-                    " released. For sanity, discarding this conn now.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGPFSML(fi, LOGL_ERROR, "Long after expecting %s, the conn is still not"</span><br><span style="color: hsl(120, 100%, 40%);">+                    " released. For sanity, discarding this conn now.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                       fi->state == ST_WAIT_CLEAR_CMD ? "BSSMAP Clear Command" : "SCCP RLSD");</span><br><span>              a_reset_conn_fail(conn->sccp.msc);</span><br><span>                osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL);</span><br><span>           break;</span><br><span>diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c</span><br><span>index 17bc048..dd2f16a 100644</span><br><span>--- a/tests/handover/handover_test.c</span><br><span>+++ b/tests/handover/handover_test.c</span><br><span>@@ -1710,3 +1710,7 @@</span><br><span>  };</span><br><span>   return &ret;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+struct mgcp_client *osmo_mgcpc_ep_client(const struct osmo_mgcpc_ep *ep)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bsc/+/26614">change 26614</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-bsc/+/26614"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Ie975117d37f38ba853589dc7f8d3e94f8f9586b2 </div>
<div style="display:none"> Gerrit-Change-Number: 26614 </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-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>