diff options
Diffstat (limited to 'src/gb/gprs_ns2_fr.c')
-rw-r--r-- | src/gb/gprs_ns2_fr.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/gb/gprs_ns2_fr.c b/src/gb/gprs_ns2_fr.c index 78abddc0..cae03eed 100644 --- a/src/gb/gprs_ns2_fr.c +++ b/src/gb/gprs_ns2_fr.c @@ -105,7 +105,9 @@ struct priv_bind { struct { /* file-descriptor for AF_PACKET socket */ struct osmo_fd ofd; - /* list of msgb (backlog) */ + /* LMI bucket (we only store the last LMI message, no need to queue */ + struct msgb *lmi_msg; + /* list of NS msgb (backlog) */ struct llist_head list; /* timer to trigger next attempt of AF_PACKET write */ struct osmo_timer_list timer; @@ -173,6 +175,7 @@ static void free_bind(struct gprs_ns2_vc_bind *bind) llist_for_each_entry_safe(msg, msg2, &priv->backlog.list, list) { msgb_free(msg); } + msgb_free(priv->backlog.lmi_msg); osmo_fr_link_free(priv->link); osmo_fd_close(&priv->backlog.ofd); @@ -357,6 +360,7 @@ static void enqueue_at_tail(struct gprs_ns2_vc_bind *bind, struct msgb *msg) /* enqueue to backlog (LMI, signaling) or drop (userdata msg) */ static int backlog_enqueue_or_free(struct gprs_ns2_vc_bind *bind, struct msgb *msg) { + struct priv_bind *priv = bind->priv; uint8_t dlci = msg->data[0]; uint8_t ns_pdu_type; uint16_t bvci; @@ -367,8 +371,9 @@ static int backlog_enqueue_or_free(struct gprs_ns2_vc_bind *bind, struct msgb *m /* we want to enqueue only Q.933 LMI traffic or NS signaling; NOT user traffic */ switch (dlci) { case LMI_Q933A_DLCI: - /* enqueue Q.933 LMI at head of queue */ - enqueue_at_head(bind, msg); + /* always store only the last LMI message in the lmi_msg bucket */ + msgb_free(priv->backlog.lmi_msg); + priv->backlog.lmi_msg = msg; return 0; default: if (msgb_length(msg) < 3) @@ -405,6 +410,15 @@ static void fr_backlog_timer_cb(void *data) struct priv_bind *priv = bind->priv; int i, rc; + /* first try to get rid of the LMI message, if any */ + if (priv->backlog.lmi_msg) { + rc = fr_netif_write_one(bind, priv->backlog.lmi_msg); + if (rc < 0) + goto restart_timer; + /* fr_netif_write_one() has just free'd it */ + priv->backlog.lmi_msg = NULL; + } + /* attempt to send up to 10 messages in every timer */ for (i = 0; i < 10; i++) { struct msgb *msg = msgb_dequeue(&priv->backlog.list); @@ -420,6 +434,7 @@ static void fr_backlog_timer_cb(void *data) osmo_stat_item_dec(bind->statg->items[NS2_BIND_STAT_BACKLOG_LEN], 1); } +restart_timer: /* re-start timer if we still have data in the queue */ if (!llist_empty(&priv->backlog.list)) osmo_timer_schedule(&priv->backlog.timer, 0, priv->backlog.retry_us); |