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

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">abis.c: Transition to CONNECTED state only when OML link is up<br><br>This clarifies the different states and transitions between them:<br>OML LINK UP: CONNECTING->CONNECTED<br>ANY LINK DOWN: CONNECTING->CONNECTING, CONNECTED->FAILED<br>In follow up commits, support to reconnect instead of exit after the BTS<br>has already connected will be added, so only the last transition needs<br>to be changed.<br><br>Related: SYS#4971<br>Change-Id: I43e83b1b04fbaa1f87818c096e6ad3920801b1f6<br>---<br>M include/osmo-bts/abis.h<br>M src/common/abis.c<br>2 files changed, 73 insertions(+), 46 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmo-bts/abis.h b/include/osmo-bts/abis.h</span><br><span>index b05461b..1939faf 100644</span><br><span>--- a/include/osmo-bts/abis.h</span><br><span>+++ b/include/osmo-bts/abis.h</span><br><span>@@ -7,6 +7,7 @@</span><br><span> #include <osmo-bts/gsm_data.h></span><br><span> </span><br><span> enum abis_link_fsm_event {</span><br><span style="color: hsl(120, 100%, 40%);">+        ABIS_LINK_EV_SIGN_LINK_OML_UP,</span><br><span>       ABIS_LINK_EV_SIGN_LINK_DOWN,</span><br><span>         ABIS_LINK_EV_VTY_RM_ADDR,</span><br><span> };</span><br><span>diff --git a/src/common/abis.c b/src/common/abis.c</span><br><span>index ff9e5fa..551670c 100644</span><br><span>--- a/src/common/abis.c</span><br><span>+++ b/src/common/abis.c</span><br><span>@@ -63,12 +63,13 @@</span><br><span> #define S(x) (1 << (x))</span><br><span> </span><br><span> enum abis_link_fsm_state {</span><br><span style="color: hsl(0, 100%, 40%);">-       ABIS_LINK_ST_CONNECTING,</span><br><span style="color: hsl(0, 100%, 40%);">-        ABIS_LINK_ST_CONNECTED,</span><br><span style="color: hsl(0, 100%, 40%);">- ABIS_LINK_ST_FAILED,</span><br><span style="color: hsl(120, 100%, 40%);">+  ABIS_LINK_ST_CONNECTING, /* OML link has not yet been established */</span><br><span style="color: hsl(120, 100%, 40%);">+  ABIS_LINK_ST_CONNECTED, /* OML link is established, RSL links may be established or not */</span><br><span style="color: hsl(120, 100%, 40%);">+    ABIS_LINK_ST_FAILED, /* There used to be an active OML connection but it became broken */</span><br><span> };</span><br><span> </span><br><span> static const struct value_string abis_link_fsm_event_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+       { ABIS_LINK_EV_SIGN_LINK_OML_UP, "SIGN_LINK_OML_UP", },</span><br><span>    { ABIS_LINK_EV_SIGN_LINK_DOWN,   "SIGN_LINK_DOWN" },</span><br><span>       { ABIS_LINK_EV_VTY_RM_ADDR,      "VTY_RM_ADDR" },</span><br><span>  {}</span><br><span>@@ -81,6 +82,39 @@</span><br><span>      int line_ctr;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void reset_oml_link(struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   if (bts->oml_link) {</span><br><span style="color: hsl(120, 100%, 40%);">+               struct timespec now;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                e1inp_sign_link_destroy(bts->oml_link);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          /* Log a special notice if the OML connection was dropped relatively quickly. */</span><br><span style="color: hsl(120, 100%, 40%);">+              if (bts->oml_conn_established_timestamp.tv_sec != 0 && clock_gettime(CLOCK_MONOTONIC, &now) == 0 &&</span><br><span style="color: hsl(120, 100%, 40%);">+                bts->oml_conn_established_timestamp.tv_sec + OSMO_BTS_OML_CONN_EARLY_DISCONNECT >= now.tv_sec) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    LOGP(DABIS, LOGL_FATAL, "OML link was closed early within %" PRIu64 " seconds. "</span><br><span style="color: hsl(120, 100%, 40%);">+                       "If this situation persists, please check your BTS and BSC configuration files for errors. "</span><br><span style="color: hsl(120, 100%, 40%);">+                        "A common error is a mismatch between unit_id configuration parameters of BTS and BSC.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                          (uint64_t) (now.tv_sec - bts->oml_conn_established_timestamp.tv_sec));</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             bts->oml_link = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+     memset(&bts->oml_conn_established_timestamp, 0, sizeof(bts->oml_conn_established_timestamp));</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%);">+static void drain_oml_queue(struct gsm_bts *bts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     struct msgb *msg, *msg2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    llist_for_each_entry_safe(msg, msg2, &bts->oml_queue, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+          /* osmo-bts uses msg->trx internally, but libosmo-abis uses</span><br><span style="color: hsl(120, 100%, 40%);">+                 * the signalling link at msg->dst */</span><br><span style="color: hsl(120, 100%, 40%);">+              llist_del(&msg->list);</span><br><span style="color: hsl(120, 100%, 40%);">+         msg->dst = bts->oml_link;</span><br><span style="color: hsl(120, 100%, 40%);">+               abis_sendmsg(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%);">+</span><br><span> static void abis_link_connecting_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span> {</span><br><span>       struct e1inp_line *line;</span><br><span>@@ -135,8 +169,32 @@</span><br><span>              return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* The TCP connection to the BSC is now in progress. */</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_CONNECTED, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+    /* The TCP connection to the BSC is now in progress.</span><br><span style="color: hsl(120, 100%, 40%);">+   * Wait for OML Link UP to transition to CONNECTED. */</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%);">+static void abis_link_connecting(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct abis_link_fsm_priv *priv = fi->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gsm_bts *bts = priv->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (event) {</span><br><span style="color: hsl(120, 100%, 40%);">+      case ABIS_LINK_EV_SIGN_LINK_OML_UP:</span><br><span style="color: hsl(120, 100%, 40%);">+           osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_CONNECTED, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case ABIS_LINK_EV_SIGN_LINK_DOWN:</span><br><span style="color: hsl(120, 100%, 40%);">+             reset_oml_link(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+          osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_CONNECTING, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+           break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(0);</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%);">+static void abis_link_connected_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%);">+     drain_oml_queue(g_bts);</span><br><span style="color: hsl(120, 100%, 40%);">+       bts_link_estab(g_bts);</span><br><span> }</span><br><span> </span><br><span> static void abis_link_connected(struct osmo_fsm_inst *fi, uint32_t event, void *data)</span><br><span>@@ -144,35 +202,16 @@</span><br><span>     struct abis_link_fsm_priv *priv = fi->priv;</span><br><span>       struct gsm_bts *bts = priv->bts;</span><br><span>  struct gsm_bts_trx *trx;</span><br><span style="color: hsl(0, 100%, 40%);">-        bool oml_rsl_was_connected = false;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>  OSMO_ASSERT(event == ABIS_LINK_EV_SIGN_LINK_DOWN);</span><br><span> </span><br><span>       /* First remove the OML signalling link */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (bts->oml_link) {</span><br><span style="color: hsl(0, 100%, 40%);">-         struct timespec now;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            e1inp_sign_link_destroy(bts->oml_link);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              /* Log a special notice if the OML connection was dropped relatively quickly. */</span><br><span style="color: hsl(0, 100%, 40%);">-                if (bts->oml_conn_established_timestamp.tv_sec != 0 && clock_gettime(CLOCK_MONOTONIC, &now) == 0 &&</span><br><span style="color: hsl(0, 100%, 40%);">-                  bts->oml_conn_established_timestamp.tv_sec + OSMO_BTS_OML_CONN_EARLY_DISCONNECT >= now.tv_sec) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      LOGP(DABIS, LOGL_FATAL, "OML link was closed early within %" PRIu64 " seconds. "</span><br><span style="color: hsl(0, 100%, 40%);">-                         "If this situation persists, please check your BTS and BSC configuration files for errors. "</span><br><span style="color: hsl(0, 100%, 40%);">-                          "A common error is a mismatch between unit_id configuration parameters of BTS and BSC.\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                            (uint64_t) (now.tv_sec - bts->oml_conn_established_timestamp.tv_sec));</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-               bts->oml_link = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-                oml_rsl_was_connected = true;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-       memset(&bts->oml_conn_established_timestamp, 0, sizeof(bts->oml_conn_established_timestamp));</span><br><span style="color: hsl(120, 100%, 40%);">+       reset_oml_link(bts);</span><br><span> </span><br><span>     /* Then iterate over the RSL signalling links */</span><br><span>     llist_for_each_entry(trx, &bts->trx_list, list) {</span><br><span>             if (trx->rsl_link) {</span><br><span>                      e1inp_sign_link_destroy(trx->rsl_link);</span><br><span>                   trx->rsl_link = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-                        oml_rsl_was_connected = true;</span><br><span>                }</span><br><span>    }</span><br><span> </span><br><span>@@ -180,10 +219,7 @@</span><br><span>          * to connect to an alternate BSC. Instead we will shut down the BTS process. This will ensure that all states</span><br><span>        * in the BTS (hardware and software) are reset properly. It is then up to the process management of the host</span><br><span>         * to restart osmo-bts. */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (oml_rsl_was_connected)</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_FAILED, 0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">-            osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_CONNECTING, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_FAILED, 0, 0);</span><br><span> }</span><br><span> </span><br><span> static void abis_link_failed_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)</span><br><span>@@ -216,19 +252,23 @@</span><br><span> static struct osmo_fsm_state abis_link_fsm_states[] = {</span><br><span>   [ABIS_LINK_ST_CONNECTING] = {</span><br><span>                .name = "CONNECTING",</span><br><span style="color: hsl(120, 100%, 40%);">+               .in_event_mask =</span><br><span style="color: hsl(120, 100%, 40%);">+                      S(ABIS_LINK_EV_SIGN_LINK_OML_UP) |</span><br><span style="color: hsl(120, 100%, 40%);">+                    S(ABIS_LINK_EV_SIGN_LINK_DOWN),</span><br><span>              .out_state_mask =</span><br><span>                    S(ABIS_LINK_ST_CONNECTING) |</span><br><span>                         S(ABIS_LINK_ST_CONNECTED) |</span><br><span>                  S(ABIS_LINK_ST_FAILED),</span><br><span>              .onenter = abis_link_connecting_onenter,</span><br><span style="color: hsl(120, 100%, 40%);">+              .action = abis_link_connecting,</span><br><span>      },</span><br><span>   [ABIS_LINK_ST_CONNECTED] = {</span><br><span>                 .name = "CONNECTED",</span><br><span>               .in_event_mask =</span><br><span>                     S(ABIS_LINK_EV_SIGN_LINK_DOWN),</span><br><span>              .out_state_mask =</span><br><span style="color: hsl(0, 100%, 40%);">-                       S(ABIS_LINK_ST_CONNECTING) |</span><br><span>                         S(ABIS_LINK_ST_FAILED),</span><br><span style="color: hsl(120, 100%, 40%);">+               .onenter = abis_link_connected_onenter,</span><br><span>              .action = abis_link_connected,</span><br><span>       },</span><br><span>   [ABIS_LINK_ST_FAILED] = {</span><br><span>@@ -262,19 +302,6 @@</span><br><span>     }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void drain_oml_queue(struct gsm_bts *bts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct msgb *msg, *msg2;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        llist_for_each_entry_safe(msg, msg2, &bts->oml_queue, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-            /* osmo-bts uses msg->trx internally, but libosmo-abis uses</span><br><span style="color: hsl(0, 100%, 40%);">-           * the signalling link at msg->dst */</span><br><span style="color: hsl(0, 100%, 40%);">-                llist_del(&msg->list);</span><br><span style="color: hsl(0, 100%, 40%);">-           msg->dst = bts->oml_link;</span><br><span style="color: hsl(0, 100%, 40%);">-         abis_sendmsg(msg);</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> int abis_bts_rsl_sendmsg(struct msgb *msg)</span><br><span> {</span><br><span>        OSMO_ASSERT(msg->trx);</span><br><span>@@ -309,8 +336,7 @@</span><br><span>                             sizeof(g_bts->oml_conn_established_timestamp));</span><br><span>            g_bts->osmo_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OSMO,</span><br><span>                                                         g_bts->c0, IPAC_PROTO_OSMO, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-            drain_oml_queue(g_bts);</span><br><span style="color: hsl(0, 100%, 40%);">-         bts_link_estab(g_bts);</span><br><span style="color: hsl(120, 100%, 40%);">+                osmo_fsm_inst_dispatch(g_bts->abis_link_fi, ABIS_LINK_EV_SIGN_LINK_OML_UP, NULL);</span><br><span>                 return g_bts->oml_link;</span><br><span> </span><br><span>       case E1INP_SIGN_RSL:</span><br><span>@@ -456,7 +482,7 @@</span><br><span>   abis_link_fsm_priv->model_name = model_name;</span><br><span>      bts->abis_link_fi->priv = abis_link_fsm_priv;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- osmo_fsm_inst_state_chg_ms(bts->abis_link_fi, ABIS_LINK_ST_CONNECTING, 1, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+      osmo_fsm_inst_state_chg(bts->abis_link_fi, ABIS_LINK_ST_CONNECTING, 0, 0);</span><br><span> </span><br><span>    return 0;</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/25457">change 25457</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/+/25457"/><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: I43e83b1b04fbaa1f87818c096e6ad3920801b1f6 </div>
<div style="display:none"> Gerrit-Change-Number: 25457 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Hoernchen <ewild@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: dexter <pmaier@sysmocom.de> </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: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: osmith <osmith@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>