<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-remsim/+/16587">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Replace bankd_client_fsm with rspro_client_fsm<br><br>There was a lot of similarity between the bankd_client_fsm (for the<br>client->bankd RSPRO connection) and the rspro_client_fsm (for the<br>client->server and the bankd->server RSPRO connections).<br><br>With the last few commits introducing the missing features to<br>rspro_client_fsm, we can completely obsolete bankd_client_fsm and<br>further simplify the codebase.<br><br>Change-Id: Icbe9881a0391fcd0c47e5d930dc764fc0cb1dfbf<br>---<br>M src/Makefile.am<br>D src/bankd_client_fsm.c<br>M src/client.h<br>M src/simtrace2-remsim_client.c<br>4 files changed, 34 insertions(+), 357 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/Makefile.am b/src/Makefile.am</span><br><span>index fa0f732..35da621 100644</span><br><span>--- a/src/Makefile.am</span><br><span>+++ b/src/Makefile.am</span><br><span>@@ -28,12 +28,12 @@</span><br><span> </span><br><span> bin_PROGRAMS = osmo-remsim-client-st2</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-remsim_client_SOURCES = remsim_client.c rspro_client_fsm.c bankd_client_fsm.c debug.c</span><br><span style="color: hsl(120, 100%, 40%);">+remsim_client_SOURCES = remsim_client.c rspro_client_fsm.c debug.c</span><br><span> remsim_client_LDADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) $(OSMOABIS_LIBS) \</span><br><span>                    libosmo-rspro.la</span><br><span> </span><br><span> osmo_remsim_client_st2_SOURCES = simtrace2-remsim_client.c \</span><br><span style="color: hsl(0, 100%, 40%);">-                                bankd_client_fsm.c rspro_client_fsm.c debug.c \</span><br><span style="color: hsl(120, 100%, 40%);">+                               rspro_client_fsm.c debug.c \</span><br><span>                                 simtrace2/apdu_dispatch.c \</span><br><span>                                  simtrace2/simtrace2-discovery.c \</span><br><span>                            simtrace2/libusb_util.c</span><br><span>diff --git a/src/bankd_client_fsm.c b/src/bankd_client_fsm.c</span><br><span>deleted file mode 100644</span><br><span>index 7ddc065..0000000</span><br><span>--- a/src/bankd_client_fsm.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,278 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2018-2019 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * SPDX-License-Identifier: GPL-2.0+</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(0, 100%, 40%);">- * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(0, 100%, 40%);">- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</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%);">-#include <stdint.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <string.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <errno.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <talloc.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/logging.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/utils.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/msgb.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/fsm.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/abis/ipa.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/protocol/ipaccess.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include "client.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "rspro_util.h"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define S(x)     (1 << (x))</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void bankd_updown_cb(struct ipa_client_conn *conn, int up)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct bankd_client *bc = conn->data;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        printf("RSPRO link to %s:%d %s\n", conn->addr, conn->port, up ? "UP" : "DOWN");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     osmo_fsm_inst_dispatch(bc->bankd_fi, up ? BDC_E_TCP_UP: BDC_E_TCP_DOWN, 0);</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%);">-/* internal function, bypassing FSM state */</span><br><span style="color: hsl(0, 100%, 40%);">-static int _bankd_conn_send_rspro(struct bankd_client *bc, RsproPDU_t *rspro)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       return ipa_client_conn_send_rspro(bc->bankd_conn, rspro);</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%);">-int bankd_conn_send_rspro(struct bankd_client *bc, RsproPDU_t *rspro)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     if (osmo_fsm_inst_dispatch(bc->bankd_fi, BDC_E_RSPRO_TX, rspro) < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-            ASN_STRUCT_FREE(asn_DEF_RsproPDU, rspro);</span><br><span style="color: hsl(0, 100%, 40%);">-               return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</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%);">-/***********************************************************************</span><br><span style="color: hsl(0, 100%, 40%);">- * client-side FSM for RSPRO connection to remsim-bankd</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This is part of remsim-client and manages the connection to remsim-bankd,</span><br><span style="color: hsl(0, 100%, 40%);">- * over which actual TPDU exchanges happen.</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%);">-enum bankd_conn_fsm_state {</span><br><span style="color: hsl(0, 100%, 40%);">-  /* waiting for initial connection to remsim-bankd */</span><br><span style="color: hsl(0, 100%, 40%);">-    BDC_ST_INIT,</span><br><span style="color: hsl(0, 100%, 40%);">-    /* bankd connection established, waiting for ClientConnectRes */</span><br><span style="color: hsl(0, 100%, 40%);">-        BDC_ST_ESTABLISHED,</span><br><span style="color: hsl(0, 100%, 40%);">-     /* bankd connection established, ClientConnect succeeded */</span><br><span style="color: hsl(0, 100%, 40%);">-     BDC_ST_CONNECTED,</span><br><span style="color: hsl(0, 100%, 40%);">-       /* connection lost, we're waiting for a re-establish */</span><br><span style="color: hsl(0, 100%, 40%);">-     BDC_ST_REESTABLISH,</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%);">-static const struct value_string remsim_client_bankd_fsm_event_names[] = {</span><br><span style="color: hsl(0, 100%, 40%);">- OSMO_VALUE_STRING(BDC_E_ESTABLISH),</span><br><span style="color: hsl(0, 100%, 40%);">-     OSMO_VALUE_STRING(BDC_E_TCP_UP),</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_VALUE_STRING(BDC_E_TCP_DOWN),</span><br><span style="color: hsl(0, 100%, 40%);">-      OSMO_VALUE_STRING(BDC_E_CLIENT_CONN_RES),</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_VALUE_STRING(BDC_E_RSPRO_TX),</span><br><span style="color: hsl(0, 100%, 40%);">-      { 0, NULL }</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%);">-#define T1_WAIT_CLIENT_CONN_RES            10</span><br><span style="color: hsl(0, 100%, 40%);">-#define T2_RECONNECT                  10</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%);">-static void bdc_st_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        switch (event) {</span><br><span style="color: hsl(0, 100%, 40%);">-        case BDC_E_ESTABLISH:</span><br><span style="color: hsl(0, 100%, 40%);">-           osmo_fsm_inst_state_chg(fi, BDC_ST_REESTABLISH, T2_RECONNECT, 2);</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                OSMO_ASSERT(0);</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%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void bdc_st_established_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct bankd_client *bc = (struct bankd_client *) fi->priv;</span><br><span style="color: hsl(0, 100%, 40%);">-  RsproPDU_t *pdu;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Send ClientConnReq */</span><br><span style="color: hsl(0, 100%, 40%);">-        pdu = rspro_gen_ConnectClientReq(&bc->srv_conn.own_comp_id, bc->srv_conn.clslot);</span><br><span style="color: hsl(0, 100%, 40%);">-     _bankd_conn_send_rspro(bc, pdu);</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%);">-static void bdc_st_established(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  switch (event) {</span><br><span style="color: hsl(0, 100%, 40%);">-        case BDC_E_TCP_DOWN:</span><br><span style="color: hsl(0, 100%, 40%);">-            osmo_fsm_inst_state_chg(fi, BDC_ST_REESTABLISH, T2_RECONNECT, 2);</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BDC_E_CLIENT_CONN_RES:</span><br><span style="color: hsl(0, 100%, 40%);">-             /* somehow notify the main code? */</span><br><span style="color: hsl(0, 100%, 40%);">-             osmo_fsm_inst_state_chg(fi, BDC_ST_CONNECTED, 0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-            break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                OSMO_ASSERT(0);</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%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void bdc_st_connected(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct bankd_client *bc = (struct bankd_client *) fi->priv;</span><br><span style="color: hsl(0, 100%, 40%);">-  RsproPDU_t *pdu = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- switch (event) {</span><br><span style="color: hsl(0, 100%, 40%);">-        case BDC_E_TCP_DOWN:</span><br><span style="color: hsl(0, 100%, 40%);">-            osmo_fsm_inst_state_chg(fi, BDC_ST_REESTABLISH, T2_RECONNECT, 2);</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BDC_E_RSPRO_TX:</span><br><span style="color: hsl(0, 100%, 40%);">-            pdu = data;</span><br><span style="color: hsl(0, 100%, 40%);">-             _bankd_conn_send_rspro(bc, pdu);</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                OSMO_ASSERT(0);</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%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void bdc_st_reestablish_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct bankd_client *bc = (struct bankd_client *) fi->priv;</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%);">- /* re-create bankd_conn */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (bc->bankd_conn) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGPFSML(fi, LOGL_INFO, "Destroying existing connection to bankd\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         ipa_client_conn_close(bc->bankd_conn);</span><br><span style="color: hsl(0, 100%, 40%);">-               ipa_client_conn_destroy(bc->bankd_conn);</span><br><span style="color: hsl(0, 100%, 40%);">-             bc->bankd_conn = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       LOGPFSML(fi, LOGL_INFO, "Creating TCP connection to bankd at %s:%u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                 bc->bankd_host, bc->bankd_port);</span><br><span style="color: hsl(0, 100%, 40%);">- bc->bankd_conn = ipa_client_conn_create(bc, NULL, 0, bc->bankd_host, bc->bankd_port,</span><br><span style="color: hsl(0, 100%, 40%);">-                                           bankd_updown_cb, bankd_read_cb, NULL, bc);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!bc->bankd_conn) {</span><br><span style="color: hsl(0, 100%, 40%);">-               fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">-            exit(1);</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%);">-       /* Attempt to connect TCP socket */</span><br><span style="color: hsl(0, 100%, 40%);">-     rc = ipa_client_conn_open(bc->bankd_conn);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                fprintf(stderr, "Unable to connect RSPRO to %s:%d - %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    bc->bankd_conn->addr, bc->bankd_conn->port, strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">-               /* FIXME: retry? Timer? Abort? */</span><br><span style="color: hsl(0, 100%, 40%);">-               OSMO_ASSERT(0);</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%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void bdc_st_reestablish(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- switch (event) {</span><br><span style="color: hsl(0, 100%, 40%);">-        case BDC_E_TCP_UP:</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_fsm_inst_state_chg(fi, BDC_ST_ESTABLISHED, T1_WAIT_CLIENT_CONN_RES, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-            break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BDC_E_TCP_DOWN:</span><br><span style="color: hsl(0, 100%, 40%);">-            /* wait for normal T2 timeout */</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                OSMO_ASSERT(0);</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%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void bdc_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        switch (event) {</span><br><span style="color: hsl(0, 100%, 40%);">-        case BDC_E_ESTABLISH:</span><br><span style="color: hsl(0, 100%, 40%);">-           osmo_fsm_inst_state_chg(fi, BDC_ST_REESTABLISH, T2_RECONNECT, 2);</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                OSMO_ASSERT(0);</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%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int remsim_client_bankd_fsm_timer_cb(struct osmo_fsm_inst *fi)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        switch (fi->T) {</span><br><span style="color: hsl(0, 100%, 40%);">-     case 2:</span><br><span style="color: hsl(0, 100%, 40%);">-         /* TCP reconnect failed: retry */</span><br><span style="color: hsl(0, 100%, 40%);">-               osmo_fsm_inst_state_chg(fi, BDC_ST_REESTABLISH, T2_RECONNECT, 2);</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case 1:</span><br><span style="color: hsl(0, 100%, 40%);">-         /* no ClientConnectRes received: disconnect + reconnect */</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_fsm_inst_state_chg(fi, BDC_ST_REESTABLISH, T2_RECONNECT, 2);</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                OSMO_ASSERT(0);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</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%);">-static const struct osmo_fsm_state bankd_conn_fsm_states[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-        [BDC_ST_INIT] = {</span><br><span style="color: hsl(0, 100%, 40%);">-               .name = "INIT",</span><br><span style="color: hsl(0, 100%, 40%);">-               .in_event_mask = 0, /* S(BDC_E_ESTABLISH) via allstate */</span><br><span style="color: hsl(0, 100%, 40%);">-               .out_state_mask = S(BDC_ST_REESTABLISH),</span><br><span style="color: hsl(0, 100%, 40%);">-                .action = bdc_st_init,</span><br><span style="color: hsl(0, 100%, 40%);">-  },</span><br><span style="color: hsl(0, 100%, 40%);">-      [BDC_ST_ESTABLISHED] = {</span><br><span style="color: hsl(0, 100%, 40%);">-                .name = "ESTABLISHED",</span><br><span style="color: hsl(0, 100%, 40%);">-                .in_event_mask = S(BDC_E_TCP_DOWN) | S(BDC_E_CLIENT_CONN_RES),</span><br><span style="color: hsl(0, 100%, 40%);">-          .out_state_mask = S(BDC_ST_CONNECTED) | S(BDC_ST_REESTABLISH),</span><br><span style="color: hsl(0, 100%, 40%);">-          .action = bdc_st_established,</span><br><span style="color: hsl(0, 100%, 40%);">-           .onenter = bdc_st_established_onenter,</span><br><span style="color: hsl(0, 100%, 40%);">-  },</span><br><span style="color: hsl(0, 100%, 40%);">-      [BDC_ST_CONNECTED] = {</span><br><span style="color: hsl(0, 100%, 40%);">-          .name = "CONNECTED",</span><br><span style="color: hsl(0, 100%, 40%);">-          .in_event_mask = S(BDC_E_TCP_DOWN) | S(BDC_E_RSPRO_TX),</span><br><span style="color: hsl(0, 100%, 40%);">-         .out_state_mask = S(BDC_ST_REESTABLISH),</span><br><span style="color: hsl(0, 100%, 40%);">-                .action = bdc_st_connected,</span><br><span style="color: hsl(0, 100%, 40%);">-     },</span><br><span style="color: hsl(0, 100%, 40%);">-      [BDC_ST_REESTABLISH] = {</span><br><span style="color: hsl(0, 100%, 40%);">-                .name = "REESTABLISH",</span><br><span style="color: hsl(0, 100%, 40%);">-                .in_event_mask = S(BDC_E_TCP_UP) | S(BDC_E_TCP_DOWN),</span><br><span style="color: hsl(0, 100%, 40%);">-           .out_state_mask = S(BDC_ST_ESTABLISHED) | S(BDC_ST_REESTABLISH),</span><br><span style="color: hsl(0, 100%, 40%);">-                .action = bdc_st_reestablish,</span><br><span style="color: hsl(0, 100%, 40%);">-           .onenter = bdc_st_reestablish_onenter,</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%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct osmo_fsm remsim_client_bankd_fsm = {</span><br><span style="color: hsl(0, 100%, 40%);">- .name = "BANKD_CONN",</span><br><span style="color: hsl(0, 100%, 40%);">- .states = bankd_conn_fsm_states,</span><br><span style="color: hsl(0, 100%, 40%);">-        .num_states = ARRAY_SIZE(bankd_conn_fsm_states),</span><br><span style="color: hsl(0, 100%, 40%);">-        .allstate_event_mask = S(BDC_E_ESTABLISH),</span><br><span style="color: hsl(0, 100%, 40%);">-      .allstate_action = bdc_allstate_action,</span><br><span style="color: hsl(0, 100%, 40%);">- .timer_cb = remsim_client_bankd_fsm_timer_cb,</span><br><span style="color: hsl(0, 100%, 40%);">-   .log_subsys = DMAIN,</span><br><span style="color: hsl(0, 100%, 40%);">-    .event_names = remsim_client_bankd_fsm_event_names,</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%);">-int bankd_conn_fsm_alloc(struct bankd_client *bc)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct osmo_fsm_inst *fi;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       fi = osmo_fsm_inst_alloc(&remsim_client_bankd_fsm, bc, bc, LOGL_DEBUG, "bankd");</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!fi)</span><br><span style="color: hsl(0, 100%, 40%);">-                return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      bc->bankd_fi = fi;</span><br><span style="color: hsl(0, 100%, 40%);">-   return 0;</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%);">-static __attribute__((constructor)) void on_dso_load(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   OSMO_ASSERT(osmo_fsm_register(&remsim_client_bankd_fsm) == 0);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/src/client.h b/src/client.h</span><br><span>index 80edaa3..96a454f 100644</span><br><span>--- a/src/client.h</span><br><span>+++ b/src/client.h</span><br><span>@@ -9,36 +9,16 @@</span><br><span> #include "slotmap.h"</span><br><span> #include "debug.h"</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* fsm.c */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum bankd_conn_fsm_event {</span><br><span style="color: hsl(0, 100%, 40%);">-        BDC_E_ESTABLISH,        /* instruct BDC to (re)etablish TCP connection to bankd */</span><br><span style="color: hsl(0, 100%, 40%);">-      BDC_E_TCP_UP,           /* notify BDC that TCP connection is up/connected */</span><br><span style="color: hsl(0, 100%, 40%);">-    BDC_E_TCP_DOWN,         /* notify BDC that TCP connection is down/disconnected */</span><br><span style="color: hsl(0, 100%, 40%);">-       BDC_E_CLIENT_CONN_RES,  /* notify BDC that ClientConnectRes has been received */</span><br><span style="color: hsl(0, 100%, 40%);">-        BDC_E_RSPRO_TX,         /* transmit a RSPRO PDU to the bankd */</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%);">-extern struct osmo_fsm remsim_client_bankd_fsm;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* main.c */</span><br><span> </span><br><span> struct bankd_client {</span><br><span>        /* connection to the remsim-server (control) */</span><br><span>      struct rspro_server_conn srv_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* connection to the remsim-bankd (data) */</span><br><span style="color: hsl(120, 100%, 40%);">+   struct rspro_server_conn bankd_conn;</span><br><span> </span><br><span>     /* remote component ID */</span><br><span>    struct app_comp_id peer_comp_id;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    /* connection to the remsim-bankd */</span><br><span style="color: hsl(0, 100%, 40%);">-    char *bankd_host;</span><br><span style="color: hsl(0, 100%, 40%);">-       uint16_t bankd_port;</span><br><span>         struct bank_slot bankd_slot;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct ipa_client_conn *bankd_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct osmo_fsm_inst *bankd_fi;</span><br><span> };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int bankd_conn_send_rspro(struct bankd_client *bc, RsproPDU_t *pdu);</span><br><span style="color: hsl(0, 100%, 40%);">-int bankd_read_cb(struct ipa_client_conn *conn, struct msgb *msg);</span><br><span style="color: hsl(0, 100%, 40%);">-int bankd_conn_fsm_alloc(struct bankd_client *bc);</span><br><span>diff --git a/src/simtrace2-remsim_client.c b/src/simtrace2-remsim_client.c</span><br><span>index 19f84a3..d54e963 100644</span><br><span>--- a/src/simtrace2-remsim_client.c</span><br><span>+++ b/src/simtrace2-remsim_client.c</span><br><span>@@ -430,7 +430,7 @@</span><br><span>                 BankSlot_t bslot;</span><br><span>            bank_slot2rspro(&bslot, &g_client->bankd_slot);</span><br><span>           RsproPDU_t *pdu = rspro_gen_TpduModem2Card(g_client->srv_conn.clslot, &bslot, apdu_command, sizeof(ac.hdr) + ac.lc.tot); // create RSPRO packet</span><br><span style="color: hsl(0, 100%, 40%);">-          bankd_conn_send_rspro(g_client, pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+         server_conn_send_rspro(&g_client->bankd_conn, pdu);</span><br><span>           // the response will come separately</span><br><span>         } else if (ac.lc.tot > ac.lc.cur) { // there is pending data from the modem</span><br><span>               cardem_request_pb_and_rx(ci, ac.hdr.ins, ac.lc.tot - ac.lc.cur); // send procedure byte to get remaining data</span><br><span>@@ -532,7 +532,7 @@</span><br><span> </span><br><span> /** remsim_client **/</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int bankd_handle_tpduCardToModem(struct bankd_client *bc, RsproPDU_t *pdu)</span><br><span style="color: hsl(120, 100%, 40%);">+static int bankd_handle_tpduCardToModem(struct bankd_client *bc, const RsproPDU_t *pdu)</span><br><span> {</span><br><span>  OSMO_ASSERT(pdu);</span><br><span>    OSMO_ASSERT(RsproPDUchoice_PR_tpduCardToModem == pdu->msg.present);</span><br><span>@@ -554,7 +554,7 @@</span><br><span>         return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int bankd_handle_setAtrReq(struct bankd_client *bc, RsproPDU_t *pdu)</span><br><span style="color: hsl(120, 100%, 40%);">+static int bankd_handle_setAtrReq(struct bankd_client *bc, const RsproPDU_t *pdu)</span><br><span> {</span><br><span>        RsproPDU_t *resp;</span><br><span>    int rc;</span><br><span>@@ -571,70 +571,35 @@</span><br><span>              resp = rspro_gen_SetAtrRes(ResultCode_cardTransmissionError);</span><br><span>        if (!resp)</span><br><span>           return -ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">- bankd_conn_send_rspro(g_client, resp);</span><br><span style="color: hsl(120, 100%, 40%);">+        server_conn_send_rspro(&g_client->bankd_conn, resp);</span><br><span> </span><br><span>      return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int bankd_handle_msg(struct bankd_client *bc, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+/* handle incoming message from bankd */</span><br><span style="color: hsl(120, 100%, 40%);">+static int bankd_handle_rx(struct rspro_server_conn *bankdc, const RsproPDU_t *pdu)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    RsproPDU_t *pdu = rspro_dec_msg(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!pdu) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGPFSML(bc->bankd_fi, LOGL_ERROR, "Error decoding PDU\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    switch (pdu->msg.present) {</span><br><span>       case RsproPDUchoice_PR_connectClientRes:</span><br><span>             /* Store 'identity' of bankd to in peer_comp_id */</span><br><span style="color: hsl(0, 100%, 40%);">-              rspro_comp_id_retrieve(&bc->peer_comp_id, &pdu->msg.choice.connectClientRes.identity);</span><br><span style="color: hsl(0, 100%, 40%);">-            osmo_fsm_inst_dispatch(bc->bankd_fi, BDC_E_CLIENT_CONN_RES, pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+          rspro_comp_id_retrieve(&bankdc->peer_comp_id, &pdu->msg.choice.connectClientRes.identity);</span><br><span style="color: hsl(120, 100%, 40%);">+              osmo_fsm_inst_dispatch(bankdc->fi, SRVC_E_CLIENT_CONN_RES, (void *) pdu);</span><br><span>                 break;</span><br><span>       case RsproPDUchoice_PR_tpduCardToModem: // APDU response from card received</span><br><span style="color: hsl(0, 100%, 40%);">-             bankd_handle_tpduCardToModem(bc, pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+                bankd_handle_tpduCardToModem(g_client, pdu);</span><br><span>                 break;</span><br><span>       case RsproPDUchoice_PR_setAtrReq:</span><br><span style="color: hsl(0, 100%, 40%);">-               bankd_handle_setAtrReq(bc, pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+              bankd_handle_setAtrReq(g_client, pdu);</span><br><span>               break;</span><br><span>       default:</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGPFSML(bc->bankd_fi, LOGL_ERROR, "Unknown/Unsuppoerted RSPRO PDU %s: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                       rspro_msgt_name(pdu), msgb_hexdump(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGPFSML(bankdc->fi, LOGL_ERROR, "Unknown/Unsuppoerted RSPRO PDU %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                   rspro_msgt_name(pdu));</span><br><span>              return -1;</span><br><span>   }</span><br><span> </span><br><span>        return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int bankd_read_cb(struct ipa_client_conn *conn, struct msgb *msg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct ipaccess_head_ext *he = (struct ipaccess_head_ext *) msgb_l2(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-       struct bankd_client *bc = conn->data;</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%);">- if (msgb_length(msg) < sizeof(*hh))</span><br><span style="color: hsl(0, 100%, 40%);">-          goto invalid;</span><br><span style="color: hsl(0, 100%, 40%);">-   msg->l2h = &hh->data[0];</span><br><span style="color: hsl(0, 100%, 40%);">-      if (hh->proto != IPAC_PROTO_OSMO)</span><br><span style="color: hsl(0, 100%, 40%);">-            goto invalid;</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!he || msgb_l2len(msg) < sizeof(*he))</span><br><span style="color: hsl(0, 100%, 40%);">-            goto invalid;</span><br><span style="color: hsl(0, 100%, 40%);">-   msg->l2h = &he->data[0];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (he->proto != IPAC_PROTO_EXT_RSPRO)</span><br><span style="color: hsl(0, 100%, 40%);">-               goto invalid;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   LOGPFSML(bc->bankd_fi, LOGL_DEBUG, "Received RSPRO %s\n", msgb_hexdump(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = bankd_handle_msg(bc, msg);</span><br><span style="color: hsl(0, 100%, 40%);">- msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">- return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-invalid:</span><br><span style="color: hsl(0, 100%, 40%);">-      msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* handle incoming messages from server */</span><br><span> static int srvc_handle_rx(struct rspro_server_conn *srvc, const RsproPDU_t *pdu)</span><br><span> {</span><br><span>@@ -651,18 +616,21 @@</span><br><span>           if (!g_client->srv_conn.clslot)</span><br><span>                   g_client->srv_conn.clslot = talloc_zero(g_client, ClientSlot_t);</span><br><span>          *g_client->srv_conn.clslot = pdu->msg.choice.configClientIdReq.clientSlot;</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!g_client->bankd_conn.clslot)</span><br><span style="color: hsl(120, 100%, 40%);">+                  g_client->bankd_conn.clslot = talloc_zero(g_client, ClientSlot_t);</span><br><span style="color: hsl(120, 100%, 40%);">+         *g_client->bankd_conn.clslot = *g_client->srv_conn.clslot;</span><br><span>             /* send response to server */</span><br><span>                resp = rspro_gen_ConfigClientIdRes(ResultCode_ok);</span><br><span>           server_conn_send_rspro(srvc, resp);</span><br><span>          break;</span><br><span>       case RsproPDUchoice_PR_configClientBankReq:</span><br><span>          /* store/set the bankd ip/port as instructed by the server */</span><br><span style="color: hsl(0, 100%, 40%);">-           osmo_talloc_replace_string(g_client, &g_client->bankd_host,</span><br><span style="color: hsl(120, 100%, 40%);">+            osmo_talloc_replace_string(g_client, &g_client->bankd_conn.server_host,</span><br><span>                                          rspro_IpAddr2str(&pdu->msg.choice.configClientBankReq.bankd.ip));</span><br><span>          rspro2bank_slot(&g_client->bankd_slot, &pdu->msg.choice.configClientBankReq.bankSlot);</span><br><span style="color: hsl(0, 100%, 40%);">-            g_client->bankd_port = pdu->msg.choice.configClientBankReq.bankd.port;</span><br><span style="color: hsl(120, 100%, 40%);">+          g_client->bankd_conn.server_port = pdu->msg.choice.configClientBankReq.bankd.port;</span><br><span>             /* instruct bankd FSM to connect */</span><br><span style="color: hsl(0, 100%, 40%);">-             osmo_fsm_inst_dispatch(g_client->bankd_fi, BDC_E_ESTABLISH, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+         osmo_fsm_inst_dispatch(g_client->bankd_conn.fi, SRVC_E_ESTABLISH, NULL);</span><br><span>          /* send response to server */</span><br><span>                resp = rspro_gen_ConfigClientBankRes(ResultCode_ok);</span><br><span>                 server_conn_send_rspro(srvc, resp);</span><br><span>@@ -733,7 +701,7 @@</span><br><span> </span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   struct rspro_server_conn *srvc;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct rspro_server_conn *srvc, *bankdc;</span><br><span>     struct st_transport *transp = ci->slot->transp;</span><br><span>        char *gsmtap_host = "127.0.0.1";</span><br><span>   int rc;</span><br><span>@@ -853,6 +821,8 @@</span><br><span>                g_client->srv_conn.clslot = talloc_zero(g_client, ClientSlot_t);</span><br><span>          g_client->srv_conn.clslot->clientId = client_id;</span><br><span>               g_client->srv_conn.clslot->slotNr = client_slot;</span><br><span style="color: hsl(120, 100%, 40%);">+                g_client->bankd_conn.clslot = talloc_zero(g_client, ClientSlot_t);</span><br><span style="color: hsl(120, 100%, 40%);">+         *g_client->bankd_conn.clslot = *g_client->srv_conn.clslot;</span><br><span>     }</span><br><span> </span><br><span>        srvc = &g_client->srv_conn;</span><br><span>@@ -870,13 +840,18 @@</span><br><span>   }</span><br><span>    osmo_fsm_inst_dispatch(srvc->fi, SRVC_E_ESTABLISH, NULL);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        asn_debug = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (bankd_conn_fsm_alloc(g_client) < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-            fprintf(stderr, "Unable to connect: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+        bankdc = &g_client->bankd_conn;</span><br><span style="color: hsl(120, 100%, 40%);">+        /* server_host / server_port are configured from remsim-server */</span><br><span style="color: hsl(120, 100%, 40%);">+     bankdc->handle_rx = bankd_handle_rx;</span><br><span style="color: hsl(120, 100%, 40%);">+       memcpy(&bankdc->own_comp_id, &srvc->own_comp_id, sizeof(bankdc->own_comp_id));</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = server_conn_fsm_alloc(g_client, bankdc);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              fprintf(stderr, "Unable to create bankd conn FSM: %s\n", strerror(errno));</span><br><span>                 exit(1);</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ asn_debug = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     // connect to SIMtrace2 cardem</span><br><span>       do {</span><br><span>                 struct usb_interface_match _ifm, *ifm = &_ifm;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-remsim/+/16587">change 16587</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-remsim/+/16587"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-remsim </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Icbe9881a0391fcd0c47e5d930dc764fc0cb1dfbf </div>
<div style="display:none"> Gerrit-Change-Number: 16587 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>