<p>Neels Hofmeyr has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/9668">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">fix / clarify rsl dtap cache<br><br>In certain situations like handover or assignment, DTAP must not go out via RSL<br>directly but is cached to be submitted later. Make sure that all RSL DTAP<br>sending adheres to this:<br><br>gscon_submit_rsl_dtap() is the new "public" API to request an RSL DTAP to be<br>sent. Depending on the gscon's state, this ends up in the cache or is sent<br>directly. When caching, there is no way to tell whether sending will succeed or<br>not, so semantically it does not make sense to even return a result code. Just<br>return void. Change all "public" callers to gscon_submit_rsl_dtap().<br><br>Merge gsm0808_submit_dtap() and submit_dtap() guts to gsm0808_send_rsl_dtap(),<br>static in bsc_subscr_conn_fsm.c: directly send DTAP, assume a conn->lchan to be<br>present, or otherwise trigger a BSSMAP Clear Request.<br><br>The static submit_dtap() becomes a thin convenience wrapper.<br><br>Move ho_dtap_cache* functions to bsc_subscr_conn_fsm.c and rename to<br>gscon_dtap_cache_* -- they are not only for handover, also for assignment.<br><br>Function gsm0808_submit_dtap() m<br>Introduce function gscon_submit_rsl_dtap()<br><br>Change-Id: I6ffd7aa641c8905292c769400048c96aa0949585<br>---<br>M include/osmocom/bsc/bsc_subscr_conn_fsm.h<br>M include/osmocom/bsc/gsm_data.h<br>M src/osmo-bsc/bsc_api.c<br>M src/osmo-bsc/bsc_init.c<br>M src/osmo-bsc/bsc_subscr_conn_fsm.c<br>M src/osmo-bsc/gsm_04_08_utils.c<br>M src/osmo-bsc/gsm_04_80_utils.c<br>M src/osmo-bsc/osmo_bsc_api.c<br>M tests/bsc/bsc_test.c<br>9 files changed, 185 insertions(+), 160 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/68/9668/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/bsc/bsc_subscr_conn_fsm.h b/include/osmocom/bsc/bsc_subscr_conn_fsm.h</span><br><span>index e8226f4..0d373eb 100644</span><br><span>--- a/include/osmocom/bsc/bsc_subscr_conn_fsm.h</span><br><span>+++ b/include/osmocom/bsc/bsc_subscr_conn_fsm.h</span><br><span>@@ -66,6 +66,11 @@</span><br><span> </span><br><span> struct gsm_subscriber_connection;</span><br><span> struct gsm_network;</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb;</span><br><span> </span><br><span> /* Allocate a subscriber connection and its associated FSM */</span><br><span> struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *net);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void gscon_submit_rsl_dtap(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(120, 100%, 40%);">+                         struct msgb *msg, int link_id, int allow_sacch);</span><br><span style="color: hsl(120, 100%, 40%);">+void gscon_dtap_cache_flush(struct gsm_subscriber_connection *conn, int send);</span><br><span>diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h</span><br><span>index 76a1b30..6ee95f7 100644</span><br><span>--- a/include/osmocom/bsc/gsm_data.h</span><br><span>+++ b/include/osmocom/bsc/gsm_data.h</span><br><span>@@ -120,8 +120,8 @@</span><br><span>       struct gsm_classmark classmark;</span><br><span> </span><br><span>  /* Cache DTAP messages during handover/assignment (msgb_enqueue()/msgb_dequeue())*/</span><br><span style="color: hsl(0, 100%, 40%);">-     struct llist_head ho_dtap_cache;</span><br><span style="color: hsl(0, 100%, 40%);">-        unsigned int ho_dtap_cache_len;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct llist_head dtap_cache;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int dtap_cache_len;</span><br><span> </span><br><span>     struct {</span><br><span>             int failures;</span><br><span>diff --git a/src/osmo-bsc/bsc_api.c b/src/osmo-bsc/bsc_api.c</span><br><span>index 4cf11a4..2c799e3 100644</span><br><span>--- a/src/osmo-bsc/bsc_api.c</span><br><span>+++ b/src/osmo-bsc/bsc_api.c</span><br><span>@@ -33,6 +33,7 @@</span><br><span> #include <osmocom/bsc/bsc_subscriber.h></span><br><span> #include <osmocom/bsc/penalty_timers.h></span><br><span> #include <osmocom/bsc/osmo_bsc_sigtran.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bsc_subscr_conn_fsm.h></span><br><span> </span><br><span> #include <osmocom/gsm/protocol/gsm_08_08.h></span><br><span> #include <osmocom/gsm/gsm48.h></span><br><span>@@ -41,10 +42,6 @@</span><br><span> </span><br><span> #define GSM0808_T10_VALUE    6, 0</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#define HO_DTAP_CACHE_MSGB_CB_LINK_ID 0</span><br><span style="color: hsl(0, 100%, 40%);">-#define HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH 1</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void rll_ind_cb(struct gsm_lchan *, uint8_t, void *, enum bsc_rllr_ind);</span><br><span> static void handle_release(struct gsm_subscriber_connection *conn, struct  gsm_lchan *lchan);</span><br><span> static void handle_chan_ack(struct gsm_subscriber_connection *conn, struct  gsm_lchan *lchan);</span><br><span> static void handle_chan_nack(struct gsm_subscriber_connection *conn, struct  gsm_lchan *lchan);</span><br><span>@@ -116,97 +113,6 @@</span><br><span>     return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void ho_dtap_cache_add(struct gsm_subscriber_connection *conn, struct msgb *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                             int link_id, bool allow_sacch)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   if (conn->ho_dtap_cache_len >= 23) {</span><br><span style="color: hsl(0, 100%, 40%);">-              LOGP(DHO, LOGL_ERROR, "%s: Cannot cache more DTAP messages,"</span><br><span style="color: hsl(0, 100%, 40%);">-               " already reached sane maximum of %u cached messages\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              bsc_subscr_name(conn->bsub), conn->ho_dtap_cache_len);</span><br><span style="color: hsl(0, 100%, 40%);">-               msgb_free(msg);</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%);">-       conn->ho_dtap_cache_len ++;</span><br><span style="color: hsl(0, 100%, 40%);">-  LOGP(DHO, LOGL_DEBUG, "%s: Caching DTAP message during ho/ass (%u)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-             bsc_subscr_name(conn->bsub), conn->ho_dtap_cache_len);</span><br><span style="color: hsl(0, 100%, 40%);">-       msg->cb[HO_DTAP_CACHE_MSGB_CB_LINK_ID] = (unsigned long)link_id;</span><br><span style="color: hsl(0, 100%, 40%);">-     msg->cb[HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH] = allow_sacch ? 1 : 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    msgb_enqueue(&conn->ho_dtap_cache, 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%);">-void ho_dtap_cache_flush(struct gsm_subscriber_connection *conn, int send)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct msgb *msg;</span><br><span style="color: hsl(0, 100%, 40%);">-       unsigned int flushed_count = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (conn->secondary_lchan || conn->ho) {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGP(DHO, LOGL_ERROR, "%s: Cannot send cached DTAP messages, handover/assignment is still ongoing\n",</span><br><span style="color: hsl(0, 100%, 40%);">-              bsc_subscr_name(conn->bsub));</span><br><span style="color: hsl(0, 100%, 40%);">-           send = 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%);">-       while ((msg = msgb_dequeue(&conn->ho_dtap_cache))) {</span><br><span style="color: hsl(0, 100%, 40%);">-             conn->ho_dtap_cache_len --;</span><br><span style="color: hsl(0, 100%, 40%);">-          flushed_count ++;</span><br><span style="color: hsl(0, 100%, 40%);">-               if (send) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     int link_id = (int)msg->cb[HO_DTAP_CACHE_MSGB_CB_LINK_ID];</span><br><span style="color: hsl(0, 100%, 40%);">-                   bool allow_sacch = !!msg->cb[HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH];</span><br><span style="color: hsl(0, 100%, 40%);">-                     LOGP(DHO, LOGL_DEBUG, "%s: Sending cached DTAP message after handover/assignment (%u/%u)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                       bsc_subscr_name(conn->bsub), flushed_count, conn->ho_dtap_cache_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                        gsm0808_submit_dtap(conn, msg, link_id, allow_sacch);</span><br><span style="color: hsl(0, 100%, 40%);">-           } else</span><br><span style="color: hsl(0, 100%, 40%);">-                  msgb_free(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 style="color: hsl(0, 100%, 40%);">-/*! \brief process incoming 08.08 DTAP from MSC (send via BTS to MS) */</span><br><span style="color: hsl(0, 100%, 40%);">-int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct msgb *msg, int link_id, int allow_sacch)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        uint8_t sapi;</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%);">-   if (!conn->lchan) {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGP(DMSC, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-               "%s Called submit dtap without an lchan.\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                  bsc_subscr_name(conn->bsub));</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 style="color: hsl(0, 100%, 40%);">-       /* buffer message during assignment / handover */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (conn->secondary_lchan || conn->ho) {</span><br><span style="color: hsl(0, 100%, 40%);">-          ho_dtap_cache_add(conn, msg, link_id, !! allow_sacch);</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%);">-       sapi = link_id & 0x7;</span><br><span style="color: hsl(0, 100%, 40%);">-       msg->lchan = conn->lchan;</span><br><span style="color: hsl(0, 100%, 40%);">- msg->dst = msg->lchan->ts->trx->rsl_link;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* If we are on a TCH and need to submit a SMS (on SAPI=3) we need to use the SACH */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (allow_sacch && sapi != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         if (conn->lchan->type == GSM_LCHAN_TCH_F || conn->lchan->type == GSM_LCHAN_TCH_H)</span><br><span style="color: hsl(0, 100%, 40%);">-                   link_id |= 0x40;</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%);">-       msg->l3h = msg->data;</span><br><span style="color: hsl(0, 100%, 40%);">-     /* is requested SAPI already up? */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (conn->lchan->sapis[sapi] == LCHAN_SAPI_UNUSED) {</span><br><span style="color: hsl(0, 100%, 40%);">-              /* Establish L2 for additional SAPI */</span><br><span style="color: hsl(0, 100%, 40%);">-          OBSC_LINKID_CB(msg) = link_id;</span><br><span style="color: hsl(0, 100%, 40%);">-          if (rll_establish(msg->lchan, sapi, rll_ind_cb, msg) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-                 bsc_sapi_n_reject(conn, link_id);</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%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* Directly forward via RLL/RSL to BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-               return rsl_data_request(msg, link_id);</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> /*</span><br><span>  * \brief Check if the given channel is compatible with the mode/fullrate</span><br><span>  */</span><br><span>@@ -316,7 +222,7 @@</span><br><span>           /* FIXME: release old channel */</span><br><span> </span><br><span>                 /* send pending messages, if any */</span><br><span style="color: hsl(0, 100%, 40%);">-             ho_dtap_cache_flush(conn, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+         gscon_dtap_cache_flush(conn, 1);</span><br><span> </span><br><span>                 return;</span><br><span>      }</span><br><span>@@ -332,7 +238,7 @@</span><br><span>      conn->secondary_lchan = NULL;</span><br><span> </span><br><span>         /* send pending messages, if any */</span><br><span style="color: hsl(0, 100%, 40%);">-     ho_dtap_cache_flush(conn, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ gscon_dtap_cache_flush(conn, 1);</span><br><span> </span><br><span>         if (is_ipaccess_bts(conn_get_bts(conn)) && conn->lchan->tch_mode != GSM48_CMODE_SIGN)</span><br><span>          rsl_ipacc_crcx(conn->lchan);</span><br><span>@@ -359,7 +265,7 @@</span><br><span>                /* FIXME: release allocated new channel */</span><br><span> </span><br><span>               /* send pending messages, if any */</span><br><span style="color: hsl(0, 100%, 40%);">-             ho_dtap_cache_flush(conn, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+         gscon_dtap_cache_flush(conn, 1);</span><br><span> </span><br><span>                 return;</span><br><span>      }</span><br><span>@@ -377,7 +283,7 @@</span><br><span>      }</span><br><span> </span><br><span>        /* send pending messages, if any */</span><br><span style="color: hsl(0, 100%, 40%);">-     ho_dtap_cache_flush(conn, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ gscon_dtap_cache_flush(conn, 1);</span><br><span> </span><br><span>         gh = msgb_l3(msg);</span><br><span>   if (msgb_l3len(msg) - sizeof(*gh) != 1) {</span><br><span>@@ -443,7 +349,7 @@</span><br><span>      /* FIXME: release old channel */</span><br><span> </span><br><span>         /* send pending messages, if any */</span><br><span style="color: hsl(0, 100%, 40%);">-     ho_dtap_cache_flush(msg->lchan->conn, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+       gscon_dtap_cache_flush(msg->lchan->conn, 1);</span><br><span> }</span><br><span> </span><br><span> /* Chapter 9.1.17 Handover Failure */</span><br><span>@@ -465,7 +371,7 @@</span><br><span>   /* FIXME: release allocated new channel */</span><br><span> </span><br><span>       /* send pending messages, if any */</span><br><span style="color: hsl(0, 100%, 40%);">-     ho_dtap_cache_flush(msg->lchan->conn, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+       gscon_dtap_cache_flush(msg->lchan->conn, 1);</span><br><span> }</span><br><span> </span><br><span> </span><br><span>@@ -643,31 +549,6 @@</span><br><span>       return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void rll_ind_cb(struct gsm_lchan *lchan, uint8_t link_id, void *_data, enum bsc_rllr_ind rllr_ind)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct msgb *msg = _data;</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%);">-       * There seems to be a small window that the RLL timer can</span><br><span style="color: hsl(0, 100%, 40%);">-       * fire after a lchan_release call and before the S_CHALLOC_FREED</span><br><span style="color: hsl(0, 100%, 40%);">-        * is called. Check if a conn is set before proceeding.</span><br><span style="color: hsl(0, 100%, 40%);">-  */</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!lchan->conn)</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%);">- switch (rllr_ind) {</span><br><span style="color: hsl(0, 100%, 40%);">-     case BSC_RLLR_IND_EST_CONF:</span><br><span style="color: hsl(0, 100%, 40%);">-             rsl_data_request(msg, OBSC_LINKID_CB(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-             break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BSC_RLLR_IND_REL_IND:</span><br><span style="color: hsl(0, 100%, 40%);">-      case BSC_RLLR_IND_ERR_IND:</span><br><span style="color: hsl(0, 100%, 40%);">-      case BSC_RLLR_IND_TIMEOUT:</span><br><span style="color: hsl(0, 100%, 40%);">-              bsc_sapi_n_reject(lchan->conn, OBSC_LINKID_CB(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-         msgb_free(msg);</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(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal,</span><br><span>                              void *handler_data, void *signal_data)</span><br><span> {</span><br><span>diff --git a/src/osmo-bsc/bsc_init.c b/src/osmo-bsc/bsc_init.c</span><br><span>index 1fe4847..641b6db 100644</span><br><span>--- a/src/osmo-bsc/bsc_init.c</span><br><span>+++ b/src/osmo-bsc/bsc_init.c</span><br><span>@@ -35,6 +35,7 @@</span><br><span> #include <osmocom/bsc/bsc_msc_data.h></span><br><span> #include <osmocom/bsc/handover_cfg.h></span><br><span> #include <osmocom/bsc/gsm_04_08_utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/neighbor_ident.h></span><br><span> </span><br><span> #include <time.h></span><br><span> #include <limits.h></span><br><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 4f09ae6..e8fb6ed 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>@@ -34,6 +34,8 @@</span><br><span> #include <osmocom/bsc/bsc_subscr_conn_fsm.h></span><br><span> #include <osmocom/bsc/osmo_bsc.h></span><br><span> #include <osmocom/bsc/penalty_timers.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bsc_rll.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/abis_rsl.h></span><br><span> #include <osmocom/mgcp_client/mgcp_client_fsm.h></span><br><span> #include <osmocom/core/byteswap.h></span><br><span> </span><br><span>@@ -120,6 +122,16 @@</span><br><span>  {0, NULL}</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* forward MT DTAP from BSSAP side to RSL side */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline void submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg,</span><br><span style="color: hsl(120, 100%, 40%);">+                             struct osmo_fsm_inst *fi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_ASSERT(fi);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(conn);</span><br><span style="color: hsl(120, 100%, 40%);">+    gscon_submit_rsl_dtap(conn, msg, OBSC_LINKID_CB(msg), 1);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Send data SCCP message through SCCP connection. All sigtran messages</span><br><span>  * that are send from this FSM must use this function. Never use</span><br><span>  * osmo_bsc_sigtran_send() directly since this would defeat the checks</span><br><span>@@ -231,26 +243,6 @@</span><br><span>       sigtran_send(conn, resp, fi);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* forward MT DTAP from BSSAP side to RSL side */</span><br><span style="color: hsl(0, 100%, 40%);">-static void submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg, struct osmo_fsm_inst *fi)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- struct msgb *resp = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(fi);</span><br><span style="color: hsl(0, 100%, 40%);">-        OSMO_ASSERT(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-       OSMO_ASSERT(conn);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = gsm0808_submit_dtap(conn, msg, OBSC_LINKID_CB(msg), 1);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (rc != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGPFSML(fi, LOGL_ERROR, "Tx BSSMAP CLEAR REQUEST to MSC\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         resp = gsm0808_create_clear_rqst(GSM0808_CAUSE_EQUIPMENT_FAILURE);</span><br><span style="color: hsl(0, 100%, 40%);">-              sigtran_send(conn, resp, fi);</span><br><span style="color: hsl(0, 100%, 40%);">-           osmo_fsm_inst_state_chg(fi, ST_ACTIVE, 0, 0);</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 style="color: hsl(0, 100%, 40%);">-</span><br><span> /* forward MO DTAP from RSL side to BSSAP side */</span><br><span> static void forward_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg, struct osmo_fsm_inst *fi)</span><br><span> {</span><br><span>@@ -972,8 +964,6 @@</span><br><span>   }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void ho_dtap_cache_flush(struct gsm_subscriber_connection *conn, int send);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static void gscon_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)</span><br><span> {</span><br><span>    struct gsm_subscriber_connection *conn = fi->priv;</span><br><span>@@ -1004,7 +994,7 @@</span><br><span>         }</span><br><span> </span><br><span>        /* drop pending messages */</span><br><span style="color: hsl(0, 100%, 40%);">-     ho_dtap_cache_flush(conn, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ gscon_dtap_cache_flush(conn, 0);</span><br><span> </span><br><span>         penalty_timers_free(&conn->hodec2.penalty_timers);</span><br><span> </span><br><span>@@ -1097,7 +1087,7 @@</span><br><span>                return NULL;</span><br><span> </span><br><span>     conn->network = net;</span><br><span style="color: hsl(0, 100%, 40%);">- INIT_LLIST_HEAD(&conn->ho_dtap_cache);</span><br><span style="color: hsl(120, 100%, 40%);">+ INIT_LLIST_HEAD(&conn->dtap_cache);</span><br><span>   /* BTW, penalty timers will be initialized on-demand. */</span><br><span>     conn->sccp.conn_id = -1;</span><br><span> </span><br><span>@@ -1122,3 +1112,143 @@</span><br><span>    llist_add_tail(&conn->entry, &net->subscr_conns);</span><br><span>      return conn;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void gsm0808_send_rsl_dtap(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(120, 100%, 40%);">+                                  struct msgb *msg, int link_id, int allow_sacch);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define GSCON_DTAP_CACHE_MSGB_CB_LINK_ID 0</span><br><span style="color: hsl(120, 100%, 40%);">+#define GSCON_DTAP_CACHE_MSGB_CB_ALLOW_SACCH 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void gscon_dtap_cache_add(struct gsm_subscriber_connection *conn, struct msgb *msg,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 int link_id, bool allow_sacch)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    if (conn->dtap_cache_len >= 23) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGP(DHO, LOGL_ERROR, "%s: Cannot cache more DTAP messages,"</span><br><span style="color: hsl(120, 100%, 40%);">+                     " already reached sane maximum of %u cached messages\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    bsc_subscr_name(conn->bsub), conn->dtap_cache_len);</span><br><span style="color: hsl(120, 100%, 40%);">+                msgb_free(msg);</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%);">+     conn->dtap_cache_len ++;</span><br><span style="color: hsl(120, 100%, 40%);">+   LOGP(DHO, LOGL_DEBUG, "%s: Caching DTAP message during ho/ass (%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           bsc_subscr_name(conn->bsub), conn->dtap_cache_len);</span><br><span style="color: hsl(120, 100%, 40%);">+        msg->cb[GSCON_DTAP_CACHE_MSGB_CB_LINK_ID] = (unsigned long)link_id;</span><br><span style="color: hsl(120, 100%, 40%);">+        msg->cb[GSCON_DTAP_CACHE_MSGB_CB_ALLOW_SACCH] = allow_sacch ? 1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+       msgb_enqueue(&conn->dtap_cache, 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%);">+void gscon_dtap_cache_flush(struct gsm_subscriber_connection *conn, int send)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+     unsigned int flushed_count = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (conn->secondary_lchan || conn->ho) {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGP(DHO, LOGL_ERROR, "%s: Cannot send cached DTAP messages, handover/assignment is still ongoing\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    bsc_subscr_name(conn->bsub));</span><br><span style="color: hsl(120, 100%, 40%);">+         send = 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%);">+   while ((msg = msgb_dequeue(&conn->dtap_cache))) {</span><br><span style="color: hsl(120, 100%, 40%);">+              conn->dtap_cache_len --;</span><br><span style="color: hsl(120, 100%, 40%);">+           flushed_count ++;</span><br><span style="color: hsl(120, 100%, 40%);">+             if (send) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   int link_id = (int)msg->cb[GSCON_DTAP_CACHE_MSGB_CB_LINK_ID];</span><br><span style="color: hsl(120, 100%, 40%);">+                      bool allow_sacch = !!msg->cb[GSCON_DTAP_CACHE_MSGB_CB_ALLOW_SACCH];</span><br><span style="color: hsl(120, 100%, 40%);">+                        LOGP(DHO, LOGL_DEBUG, "%s: Sending cached DTAP message after handover/assignment (%u/%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                             bsc_subscr_name(conn->bsub), flushed_count, conn->dtap_cache_len);</span><br><span style="color: hsl(120, 100%, 40%);">+                 gsm0808_send_rsl_dtap(conn, msg, link_id, allow_sacch);</span><br><span style="color: hsl(120, 100%, 40%);">+               } else</span><br><span style="color: hsl(120, 100%, 40%);">+                        msgb_free(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 style="color: hsl(120, 100%, 40%);">+static void rll_ind_cb(struct gsm_lchan *lchan, uint8_t link_id, void *_data, enum bsc_rllr_ind rllr_ind)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct msgb *msg = _data;</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%);">+     * There seems to be a small window that the RLL timer can</span><br><span style="color: hsl(120, 100%, 40%);">+     * fire after a lchan_release call and before the S_CHALLOC_FREED</span><br><span style="color: hsl(120, 100%, 40%);">+      * is called. Check if a conn is set before proceeding.</span><br><span style="color: hsl(120, 100%, 40%);">+        */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!lchan->conn)</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%);">+     switch (rllr_ind) {</span><br><span style="color: hsl(120, 100%, 40%);">+   case BSC_RLLR_IND_EST_CONF:</span><br><span style="color: hsl(120, 100%, 40%);">+           rsl_data_request(msg, OBSC_LINKID_CB(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+           break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSC_RLLR_IND_REL_IND:</span><br><span style="color: hsl(120, 100%, 40%);">+    case BSC_RLLR_IND_ERR_IND:</span><br><span style="color: hsl(120, 100%, 40%);">+    case BSC_RLLR_IND_TIMEOUT:</span><br><span style="color: hsl(120, 100%, 40%);">+            bsc_sapi_n_reject(lchan->conn, OBSC_LINKID_CB(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+               msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</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%);">+/*! \brief process incoming 08.08 DTAP from MSC (send via BTS to MS) */</span><br><span style="color: hsl(120, 100%, 40%);">+static void gsm0808_send_rsl_dtap(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(120, 100%, 40%);">+                              struct msgb *msg, int link_id, int allow_sacch)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t sapi;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct msgb *resp = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!conn->lchan) {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGP(DMSC, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+                     "%s Called submit dtap without an lchan.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                bsc_subscr_name(conn->bsub));</span><br><span style="color: hsl(120, 100%, 40%);">+         msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+               rc = -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+         goto failed_to_send;</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%);">+   sapi = link_id & 0x7;</span><br><span style="color: hsl(120, 100%, 40%);">+     msg->lchan = conn->lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+       msg->dst = msg->lchan->ts->trx->rsl_link;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* If we are on a TCH and need to submit a SMS (on SAPI=3) we need to use the SACH */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (allow_sacch && sapi != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (conn->lchan->type == GSM_LCHAN_TCH_F || conn->lchan->type == GSM_LCHAN_TCH_H)</span><br><span style="color: hsl(120, 100%, 40%);">+                 link_id |= 0x40;</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%);">+   msg->l3h = msg->data;</span><br><span style="color: hsl(120, 100%, 40%);">+   /* is requested SAPI already up? */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (conn->lchan->sapis[sapi] == LCHAN_SAPI_UNUSED) {</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Establish L2 for additional SAPI */</span><br><span style="color: hsl(120, 100%, 40%);">+                OBSC_LINKID_CB(msg) = link_id;</span><br><span style="color: hsl(120, 100%, 40%);">+                rc = rll_establish(msg->lchan, sapi, rll_ind_cb, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+                       bsc_sapi_n_reject(conn, link_id);</span><br><span style="color: hsl(120, 100%, 40%);">+                     goto failed_to_send;</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%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Directly forward via RLL/RSL to BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = rsl_data_request(msg, link_id);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (rc)</span><br><span style="color: hsl(120, 100%, 40%);">+                       goto failed_to_send;</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%);">+failed_to_send:</span><br><span style="color: hsl(120, 100%, 40%);">+    LOGPFSML(conn->fi, LOGL_ERROR, "Tx BSSMAP CLEAR REQUEST to MSC\n");</span><br><span style="color: hsl(120, 100%, 40%);">+      resp = gsm0808_create_clear_rqst(GSM0808_CAUSE_EQUIPMENT_FAILURE);</span><br><span style="color: hsl(120, 100%, 40%);">+    sigtran_send(conn, resp, conn->fi);</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_fsm_inst_state_chg(conn->fi, ST_ACTIVE, 0, 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%);">+void gscon_submit_rsl_dtap(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(120, 100%, 40%);">+                          struct msgb *msg, int link_id, int allow_sacch)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /* buffer message during assignment / handover */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (conn->secondary_lchan || conn->ho) {</span><br><span style="color: hsl(120, 100%, 40%);">+                gscon_dtap_cache_add(conn, msg, link_id, !! allow_sacch);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   gsm0808_send_rsl_dtap(conn, msg, link_id, allow_sacch);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/osmo-bsc/gsm_04_08_utils.c b/src/osmo-bsc/gsm_04_08_utils.c</span><br><span>index e9aeb55..c548500 100644</span><br><span>--- a/src/osmo-bsc/gsm_04_08_utils.c</span><br><span>+++ b/src/osmo-bsc/gsm_04_08_utils.c</span><br><span>@@ -34,7 +34,7 @@</span><br><span> #include <osmocom/bsc/debug.h></span><br><span> #include <osmocom/bsc/paging.h></span><br><span> #include <osmocom/bsc/signal.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/bsc_api.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bsc_subscr_conn_fsm.h></span><br><span> #include <osmocom/bsc/gsm_04_08_utils.h></span><br><span> </span><br><span> /* should ip.access BTS use direct RTP streams between each other (1),</span><br><span>@@ -600,7 +600,8 @@</span><br><span> </span><br><span>    DEBUGP(DMM, "-> CM SERVICE ACK\n");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    return gsm0808_submit_dtap(conn, msg, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  gscon_submit_rsl_dtap(conn, msg, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span> }</span><br><span> </span><br><span> /* 9.2.6 CM service reject */</span><br><span>@@ -617,7 +618,8 @@</span><br><span> </span><br><span>        DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        return gsm0808_submit_dtap(conn, msg, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  gscon_submit_rsl_dtap(conn, msg, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span> }</span><br><span> </span><br><span> /* 9.1.29 RR Status */</span><br><span>@@ -644,7 +646,8 @@</span><br><span>   struct msgb *msg = gsm48_create_rr_status(cause);</span><br><span>    if (!msg)</span><br><span>            return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      return gsm0808_submit_dtap(conn, msg, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  gscon_submit_rsl_dtap(conn, msg, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span> }</span><br><span> </span><br><span> struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value)</span><br><span>diff --git a/src/osmo-bsc/gsm_04_80_utils.c b/src/osmo-bsc/gsm_04_80_utils.c</span><br><span>index d67f3c5..8de1262 100644</span><br><span>--- a/src/osmo-bsc/gsm_04_80_utils.c</span><br><span>+++ b/src/osmo-bsc/gsm_04_80_utils.c</span><br><span>@@ -20,7 +20,7 @@</span><br><span>  */</span><br><span> </span><br><span> #include <osmocom/gsm/gsm0480.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/bsc/bsc_api.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/bsc_subscr_conn_fsm.h></span><br><span> </span><br><span> int bsc_send_ussd_notify(struct gsm_subscriber_connection *conn, int level,</span><br><span>                         const char *text)</span><br><span>@@ -28,7 +28,8 @@</span><br><span>       struct msgb *msg = gsm0480_create_ussd_notify(level, text);</span><br><span>  if (!msg)</span><br><span>            return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      return gsm0808_submit_dtap(conn, msg, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  gscon_submit_rsl_dtap(conn, msg, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span> }</span><br><span> </span><br><span> int bsc_send_ussd_release_complete(struct gsm_subscriber_connection *conn)</span><br><span>@@ -36,5 +37,6 @@</span><br><span>         struct msgb *msg = gsm0480_create_ussd_release_complete();</span><br><span>   if (!msg)</span><br><span>            return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      return gsm0808_submit_dtap(conn, msg, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  gscon_submit_rsl_dtap(conn, msg, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span> }</span><br><span>diff --git a/src/osmo-bsc/osmo_bsc_api.c b/src/osmo-bsc/osmo_bsc_api.c</span><br><span>index a86b4f9..d409c93 100644</span><br><span>--- a/src/osmo-bsc/osmo_bsc_api.c</span><br><span>+++ b/src/osmo-bsc/osmo_bsc_api.c</span><br><span>@@ -86,7 +86,7 @@</span><br><span>  }</span><br><span> </span><br><span>        msg->lchan = conn->lchan;</span><br><span style="color: hsl(0, 100%, 40%);">- gsm0808_submit_dtap(conn, msg, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ gscon_submit_rsl_dtap(conn, msg, 0, 0);</span><br><span> }</span><br><span> </span><br><span> static int bsc_filter_initial(struct osmo_bsc_data *bsc,</span><br><span>diff --git a/tests/bsc/bsc_test.c b/tests/bsc/bsc_test.c</span><br><span>index 950eaf5..b05ca54 100644</span><br><span>--- a/tests/bsc/bsc_test.c</span><br><span>+++ b/tests/bsc/bsc_test.c</span><br><span>@@ -249,3 +249,6 @@</span><br><span>                 const uint8_t *cm2, uint8_t cm2_len,</span><br><span>                 const uint8_t *cm3, uint8_t cm3_len) {}</span><br><span> void bsc_mr_config(struct gsm_subscriber_connection *conn, struct gsm_lchan *lchan, int full_rate) {}</span><br><span style="color: hsl(120, 100%, 40%);">+void gscon_submit_rsl_dtap(struct gsm_subscriber_connection *conn,</span><br><span style="color: hsl(120, 100%, 40%);">+                          struct msgb *msg, int link_id, int allow_sacch) {}</span><br><span style="color: hsl(120, 100%, 40%);">+void gscon_dtap_cache_flush(struct gsm_subscriber_connection *conn, int send) {}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/9668">change 9668</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/9668"/><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-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I6ffd7aa641c8905292c769400048c96aa0949585 </div>
<div style="display:none"> Gerrit-Change-Number: 9668 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>