[PATCH] osmo-bsc[master]: HO: add queue to cache DTAP messages during handover/assignment

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Fri Jan 19 03:04:12 UTC 2018


Review at  https://gerrit.osmocom.org/5919

HO: add queue to cache DTAP messages during handover/assignment

Add ho_dtap_cache to gsm_subscriber_connection, a stock msgb queue to be used
with msgb_enqueue() and msgb_dequeue().

Keep a counter of queue length, to enforce a sane maximum counter for cached
messages. So far a hardcoded maximum of 23 messages will be cached.

Have balanced ho_dtap_cache_add() and ho_dtap_cache_flush() functions.

The original patch was by jolly, but I have basically completely replaced it
with the simpler msgb queue pattern.

Change-Id: I6e4d93628befb3d97e5cee0343cd9f8ba0b8620c
---
M include/osmocom/bsc/gsm_data.h
M src/libbsc/bsc_api.c
2 files changed, 77 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/19/5919/1

diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 6659b72..4e07f26 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -100,6 +100,10 @@
 
 	/* buffer/cache for classmark of the ME of the subscriber */
 	struct gsm_classmark classmark;
+
+	/* Cache DTAP messages during handover/assignment (msgb_enqueue()/msgb_dequeue())*/
+	struct llist_head ho_dtap_cache;
+	unsigned int ho_dtap_cache_len;
 };
 
 static inline struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn) {
diff --git a/src/libbsc/bsc_api.c b/src/libbsc/bsc_api.c
index 545cf36..2a0bf8f 100644
--- a/src/libbsc/bsc_api.c
+++ b/src/libbsc/bsc_api.c
@@ -39,6 +39,8 @@
 
 #define GSM0808_T10_VALUE    6, 0
 
+#define HO_DTAP_CACHE_MSGB_CB_LINK_ID 0
+#define HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH 1
 
 static void rll_ind_cb(struct gsm_lchan *, uint8_t, void *, enum bsc_rllr_ind);
 static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id);
@@ -270,8 +272,52 @@
 	conn->lchan = lchan;
 	conn->bts = lchan->ts->trx->bts;
 	lchan->conn = conn;
+	INIT_LLIST_HEAD(&conn->ho_dtap_cache);
 	llist_add_tail(&conn->entry, &net->subscr_conns);
 	return conn;
+}
+
+static void ho_dtap_cache_add(struct gsm_subscriber_connection *conn, struct msgb *msg,
+			      int link_id, bool allow_sacch)
+{
+	if (conn->ho_dtap_cache_len >= 23) {
+		LOGP(DHO, LOGL_ERROR, "%s: Cannot cache more DTAP messages,"
+		     " already reached sane maximum of %u cached messages\n",
+		     bsc_subscr_name(conn->bsub), conn->ho_dtap_cache_len);
+		msgb_free(msg);
+		return;
+	}
+	conn->ho_dtap_cache_len ++;
+	LOGP(DHO, LOGL_DEBUG, "%s: Caching DTAP message during ho/ass (%u)\n",
+	     bsc_subscr_name(conn->bsub), conn->ho_dtap_cache_len);
+	msg->cb[HO_DTAP_CACHE_MSGB_CB_LINK_ID] = (unsigned long)link_id;
+	msg->cb[HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH] = allow_sacch ? 1 : 0;
+	msgb_enqueue(&conn->ho_dtap_cache, msg);
+}
+
+static void ho_dtap_cache_flush(struct gsm_subscriber_connection *conn, int send)
+{
+	struct msgb *msg;
+	unsigned int flushed_count = 0;
+
+	if (conn->secondary_lchan || conn->ho_lchan) {
+		LOGP(DHO, LOGL_ERROR, "%s: Cannot send cached DTAP messages, handover/assignment is still ongoing\n",
+		     bsc_subscr_name(conn->bsub));
+		send = 0;
+	}
+
+	while ((msg = msgb_dequeue(&conn->ho_dtap_cache))) {
+		conn->ho_dtap_cache_len --;
+		flushed_count ++;
+		if (send) {
+			int link_id = (int)msg->cb[HO_DTAP_CACHE_MSGB_CB_LINK_ID];
+			bool allow_sacch = !!msg->cb[HO_DTAP_CACHE_MSGB_CB_ALLOW_SACCH];
+			LOGP(DHO, LOGL_DEBUG, "%s: Sending cached DTAP message after handover/assignment (%u/%u)\n",
+			     bsc_subscr_name(conn->bsub), flushed_count, conn->ho_dtap_cache_len);
+			gsm0808_submit_dtap(conn, msg, link_id, allow_sacch);
+		} else
+			msgb_free(msg);
+	}
 }
 
 void bsc_subscr_con_free(struct gsm_subscriber_connection *conn)
@@ -297,6 +343,9 @@
 		conn->secondary_lchan->conn = NULL;
 	}
 
+	/* drop pending messages */
+	ho_dtap_cache_flush(conn, 0);
+
 	llist_del(&conn->entry);
 	talloc_free(conn);
 }
@@ -319,6 +368,12 @@
 		     "Called submit dtap without an lchan.\n");
 		msgb_free(msg);
 		return -1;
+	}
+
+	/* buffer message during assignment / handover */
+	if (conn->secondary_lchan || conn->ho_lchan) {
+		ho_dtap_cache_add(conn, msg, link_id, !! allow_sacch);
+		return 0;
 	}
 
 	sapi = link_id & 0x7;
@@ -454,6 +509,9 @@
 		osmo_signal_dispatch(SS_LCHAN, S_LCHAN_ASSIGNMENT_COMPL, &sig);
 		/* FIXME: release old channel */
 
+		/* send pending messages, if any */
+		ho_dtap_cache_flush(conn, 1);
+
 		return;
 	}
 
@@ -475,6 +533,9 @@
 	lchan_release(conn->lchan, 0, RSL_REL_LOCAL_END);
 	conn->lchan = conn->secondary_lchan;
 	conn->secondary_lchan = NULL;
+
+	/* send pending messages, if any */
+	ho_dtap_cache_flush(conn, 1);
 
 	if (is_ipaccess_bts(conn_get_bts(conn)) && conn->lchan->tch_mode != GSM48_CMODE_SIGN)
 		rsl_ipacc_crcx(conn->lchan);
@@ -504,6 +565,9 @@
 		osmo_signal_dispatch(SS_LCHAN, S_LCHAN_ASSIGNMENT_FAIL, &sig);
 		/* FIXME: release allocated new channel */
 
+		/* send pending messages, if any */
+		ho_dtap_cache_flush(conn, 1);
+
 		return;
 	}
 
@@ -518,6 +582,9 @@
 		lchan_release(conn->secondary_lchan, 0, RSL_REL_LOCAL_END);
 		conn->secondary_lchan = NULL;
 	}
+
+	/* send pending messages, if any */
+	ho_dtap_cache_flush(conn, 1);
 
 	gh = msgb_l3(msg);
 	if (msgb_l3len(msg) - sizeof(*gh) != 1) {
@@ -584,6 +651,9 @@
 	sig.mr = NULL;
 	osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_COMPL, &sig);
 	/* FIXME: release old channel */
+
+	/* send pending messages, if any */
+	ho_dtap_cache_flush(msg->lchan->conn, 1);
 }
 
 /* Chapter 9.1.17 Handover Failure */
@@ -599,6 +669,9 @@
 	sig.mr = NULL;
 	osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_FAIL, &sig);
 	/* FIXME: release allocated new channel */
+
+	/* send pending messages, if any */
+	ho_dtap_cache_flush(msg->lchan->conn, 1);
 }
 
 

-- 
To view, visit https://gerrit.osmocom.org/5919
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6e4d93628befb3d97e5cee0343cd9f8ba0b8620c
Gerrit-PatchSet: 1
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list