From 131ab36e3a0455d406062c1549f864d728bc90d6 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 18 Jan 2016 10:14:54 +0100 Subject: [PATCH] abis: Add a queue of OML messages When the oml_link is down or not yet established, we currently lost any OML messages that were scheduled for transmission to the BSC. Let's prevent that by keeping a queue of OML messages, which is drained at the time the OML link comes up again. --- include/osmo-bts/gsm_data.h | 1 + src/common/abis.c | 29 +++++++++++++++++++++++++---- src/common/bts.c | 1 + 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index 825123802..6a7bca876 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -84,6 +84,7 @@ struct gsm_bts_role_bts { struct paging_state *paging_state; char *bsc_oml_host; + struct llist_head oml_queue; unsigned int rtp_jitter_buf_ms; struct { uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */ diff --git a/src/common/abis.c b/src/common/abis.c index a08f9f3b6..f0c9fc4d7 100644 --- a/src/common/abis.c +++ b/src/common/abis.c @@ -54,11 +54,31 @@ static struct gsm_bts *g_bts; int abis_oml_sendmsg(struct msgb *msg) { struct gsm_bts *bts = msg->trx->bts; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); - /* osmo-bts uses msg->trx internally, but libosmo-abis uses - * the signalling link at msg->dst */ - msg->dst = bts->oml_link; - return abis_sendmsg(msg); + if (!bts->oml_link) { + llist_add_tail(&msg->list, &btsb->oml_queue); + return 0; + } else { + /* osmo-bts uses msg->trx internally, but libosmo-abis uses + * the signalling link at msg->dst */ + msg->dst = bts->oml_link; + return abis_sendmsg(msg); + } +} + +static void drain_oml_queue(struct gsm_bts *bts) +{ + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + struct msgb *msg, *msg2; + + llist_for_each_entry_safe(msg, msg2, &btsb->oml_queue, list) { + /* osmo-bts uses msg->trx internally, but libosmo-abis uses + * the signalling link at msg->dst */ + llist_del(&msg->list); + msg->dst = bts->oml_link; + abis_sendmsg(msg); + } } int abis_bts_rsl_sendmsg(struct msgb *msg) @@ -83,6 +103,7 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line, sign_link = g_bts->oml_link = e1inp_sign_link_create(&line->ts[E1INP_SIGN_OML-1], E1INP_SIGN_OML, NULL, 255, 0); + drain_oml_queue(g_bts); sign_link->trx = g_bts->c0; bts_link_estab(g_bts); break; diff --git a/src/common/bts.c b/src/common/bts.c index 56d260d76..43f4c255c 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -164,6 +164,7 @@ int bts_init(struct gsm_bts *bts) } INIT_LLIST_HEAD(&btsb->smscb_state.queue); + INIT_LLIST_HEAD(&btsb->oml_queue); return rc; }