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.orgReview 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