<p>Neels Hofmeyr <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/9668">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
Harald Welte: Looks good to me, approved
</div><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, 186 insertions(+), 161 deletions(-)<br><br></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 9e56f6b..70fce32 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>@@ -67,8 +67,13 @@</span><br><span> struct gsm_subscriber_connection;</span><br><span> struct gsm_network;</span><br><span> struct mgcp_conn_peer;</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> </span><br><span> void bsc_subscr_pick_codec(struct mgcp_conn_peer *conn_peer, struct gsm_subscriber_connection *conn);</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_queue_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 a16a4b7..2872493 100644</span><br><span>--- a/include/osmocom/bsc/gsm_data.h</span><br><span>+++ b/include/osmocom/bsc/gsm_data.h</span><br><span>@@ -119,9 +119,9 @@</span><br><span> /* buffer/cache for classmark of the ME of the subscriber */</span><br><span> struct gsm_classmark classmark;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* 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%);">+ /* Queue DTAP messages during handover/assignment (msgb_enqueue()/msgb_dequeue())*/</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head dtap_queue;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int dtap_queue_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..35e6977 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_queue_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_queue_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_queue_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_queue_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_queue_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_queue_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 66cdbba..3249270 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>@@ -145,6 +147,16 @@</span><br><span> }</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>@@ -256,26 +268,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>@@ -1005,8 +997,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>@@ -1037,7 +1027,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_queue_flush(conn, 0);</span><br><span> </span><br><span> penalty_timers_free(&conn->hodec2.penalty_timers);</span><br><span> </span><br><span>@@ -1130,7 +1120,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_queue);</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>@@ -1155,3 +1145,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_QUEUE_MSGB_CB_LINK_ID 0</span><br><span style="color: hsl(120, 100%, 40%);">+#define GSCON_DTAP_QUEUE_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_queue_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_queue_len >= 8) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMSC, LOGL_ERROR, "%s: Cannot queue more DTAP messages,"</span><br><span style="color: hsl(120, 100%, 40%);">+ " already reached sane maximum of %u queued messages\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ bsc_subscr_name(conn->bsub), conn->dtap_queue_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_queue_len ++;</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMSC, LOGL_DEBUG, "%s: Queueing DTAP message during handover/assignment (%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ bsc_subscr_name(conn->bsub), conn->dtap_queue_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ msg->cb[GSCON_DTAP_QUEUE_MSGB_CB_LINK_ID] = (unsigned long)link_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ msg->cb[GSCON_DTAP_QUEUE_MSGB_CB_ALLOW_SACCH] = allow_sacch ? 1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_enqueue(&conn->dtap_queue, 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_queue_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(DMSC, LOGL_ERROR, "%s: Cannot send queued 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_queue))) {</span><br><span style="color: hsl(120, 100%, 40%);">+ conn->dtap_queue_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_QUEUE_MSGB_CB_LINK_ID];</span><br><span style="color: hsl(120, 100%, 40%);">+ bool allow_sacch = !!msg->cb[GSCON_DTAP_QUEUE_MSGB_CB_ALLOW_SACCH];</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMSC, LOGL_DEBUG, "%s: Sending queued 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_queue_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_queue_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..e4a5ed5 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_queue_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: merged </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: 15 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>