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
This commit is contained in:
parent
2660c0412d
commit
935e5d76dd
|
@ -100,6 +100,10 @@ struct gsm_subscriber_connection {
|
||||||
|
|
||||||
/* buffer/cache for classmark of the ME of the subscriber */
|
/* buffer/cache for classmark of the ME of the subscriber */
|
||||||
struct gsm_classmark classmark;
|
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) {
|
static inline struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn) {
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
|
|
||||||
#define GSM0808_T10_VALUE 6, 0
|
#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 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);
|
static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id);
|
||||||
|
@ -274,10 +276,54 @@ struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_lchan *lcha
|
||||||
conn->lchan = lchan;
|
conn->lchan = lchan;
|
||||||
conn->bts = lchan->ts->trx->bts;
|
conn->bts = lchan->ts->trx->bts;
|
||||||
lchan->conn = conn;
|
lchan->conn = conn;
|
||||||
|
INIT_LLIST_HEAD(&conn->ho_dtap_cache);
|
||||||
llist_add_tail(&conn->entry, &net->subscr_conns);
|
llist_add_tail(&conn->entry, &net->subscr_conns);
|
||||||
return conn;
|
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)
|
void bsc_subscr_con_free(struct gsm_subscriber_connection *conn)
|
||||||
{
|
{
|
||||||
if (!conn)
|
if (!conn)
|
||||||
|
@ -301,6 +347,9 @@ void bsc_subscr_con_free(struct gsm_subscriber_connection *conn)
|
||||||
conn->secondary_lchan->conn = NULL;
|
conn->secondary_lchan->conn = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* drop pending messages */
|
||||||
|
ho_dtap_cache_flush(conn, 0);
|
||||||
|
|
||||||
llist_del(&conn->entry);
|
llist_del(&conn->entry);
|
||||||
talloc_free(conn);
|
talloc_free(conn);
|
||||||
}
|
}
|
||||||
|
@ -325,6 +374,12 @@ int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn,
|
||||||
return -1;
|
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;
|
sapi = link_id & 0x7;
|
||||||
msg->lchan = conn->lchan;
|
msg->lchan = conn->lchan;
|
||||||
msg->dst = msg->lchan->ts->trx->rsl_link;
|
msg->dst = msg->lchan->ts->trx->rsl_link;
|
||||||
|
@ -458,6 +513,9 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn,
|
||||||
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_ASSIGNMENT_COMPL, &sig);
|
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_ASSIGNMENT_COMPL, &sig);
|
||||||
/* FIXME: release old channel */
|
/* FIXME: release old channel */
|
||||||
|
|
||||||
|
/* send pending messages, if any */
|
||||||
|
ho_dtap_cache_flush(conn, 1);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,6 +538,9 @@ static void handle_ass_compl(struct gsm_subscriber_connection *conn,
|
||||||
conn->lchan = conn->secondary_lchan;
|
conn->lchan = conn->secondary_lchan;
|
||||||
conn->secondary_lchan = NULL;
|
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)
|
if (is_ipaccess_bts(conn_get_bts(conn)) && conn->lchan->tch_mode != GSM48_CMODE_SIGN)
|
||||||
rsl_ipacc_crcx(conn->lchan);
|
rsl_ipacc_crcx(conn->lchan);
|
||||||
|
|
||||||
|
@ -508,6 +569,9 @@ static void handle_ass_fail(struct gsm_subscriber_connection *conn,
|
||||||
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_ASSIGNMENT_FAIL, &sig);
|
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_ASSIGNMENT_FAIL, &sig);
|
||||||
/* FIXME: release allocated new channel */
|
/* FIXME: release allocated new channel */
|
||||||
|
|
||||||
|
/* send pending messages, if any */
|
||||||
|
ho_dtap_cache_flush(conn, 1);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,6 +587,9 @@ static void handle_ass_fail(struct gsm_subscriber_connection *conn,
|
||||||
conn->secondary_lchan = NULL;
|
conn->secondary_lchan = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* send pending messages, if any */
|
||||||
|
ho_dtap_cache_flush(conn, 1);
|
||||||
|
|
||||||
gh = msgb_l3(msg);
|
gh = msgb_l3(msg);
|
||||||
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
|
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
|
||||||
LOGP(DMSC, LOGL_ERROR, "assignment failure unhandled: %zu\n",
|
LOGP(DMSC, LOGL_ERROR, "assignment failure unhandled: %zu\n",
|
||||||
|
@ -588,6 +655,9 @@ static void handle_rr_ho_compl(struct msgb *msg)
|
||||||
sig.mr = NULL;
|
sig.mr = NULL;
|
||||||
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_COMPL, &sig);
|
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_COMPL, &sig);
|
||||||
/* FIXME: release old channel */
|
/* FIXME: release old channel */
|
||||||
|
|
||||||
|
/* send pending messages, if any */
|
||||||
|
ho_dtap_cache_flush(msg->lchan->conn, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Chapter 9.1.17 Handover Failure */
|
/* Chapter 9.1.17 Handover Failure */
|
||||||
|
@ -603,6 +673,9 @@ static void handle_rr_ho_fail(struct msgb *msg)
|
||||||
sig.mr = NULL;
|
sig.mr = NULL;
|
||||||
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_FAIL, &sig);
|
osmo_signal_dispatch(SS_LCHAN, S_LCHAN_HANDOVER_FAIL, &sig);
|
||||||
/* FIXME: release allocated new channel */
|
/* FIXME: release allocated new channel */
|
||||||
|
|
||||||
|
/* send pending messages, if any */
|
||||||
|
ho_dtap_cache_flush(msg->lchan->conn, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue