aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/abis.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2016-01-18 10:14:54 +0100
committerHarald Welte <laforge@gnumonks.org>2016-02-03 18:45:39 +0100
commit131ab36e3a0455d406062c1549f864d728bc90d6 (patch)
treefd7f25341bf6d75d5cae620dc7d85e410540b0ba /src/common/abis.c
parent2ed116efeca67987257d4c2d95fd3c9ac873d57d (diff)
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.
Diffstat (limited to 'src/common/abis.c')
-rw-r--r--src/common/abis.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/common/abis.c b/src/common/abis.c
index a08f9f3b..f0c9fc4d 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;