laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/34987?usp=email )
(
14 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: LAPDm: Add an extra queue for UI frames ......................................................................
LAPDm: Add an extra queue for UI frames
The extra queue is used to transmit the UI frame only when there is no frame in the regular TX queue. This allows to give LAPD frames prioity over UI frame.
Related: OS#4074 Change-Id: I00c8ee73be8b7c564a4dee3fca3e893484f567da --- M TODO-RELEASE M include/osmocom/gsm/lapdm.h M src/gsm/lapdm.c 3 files changed, 52 insertions(+), 1 deletion(-)
Approvals: Jenkins Builder: Verified daniel: Looks good to me, approved laforge: Looks good to me, but someone else must approve
diff --git a/TODO-RELEASE b/TODO-RELEASE index 226450b..fa7bc57 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -11,3 +11,4 @@ core ADD gsmtap_inst_fd2() core, DEPRECATE gsmtap_inst_fd() isdn ABI change add states and flags for external T200 handling gsm ABI change add T200 timer states to lapdm_datalink +gsm ABI change add UI queue to struct lapdm_datalink diff --git a/include/osmocom/gsm/lapdm.h b/include/osmocom/gsm/lapdm.h index db66680..08b808c 100644 --- a/include/osmocom/gsm/lapdm.h +++ b/include/osmocom/gsm/lapdm.h @@ -34,6 +34,7 @@
struct lapdm_entity *entity; /*!< LAPDm entity we are part of */
+ struct llist_head tx_ui_queue; /*!< UI frames to L1 */ uint32_t t200_fn; /*!< T200 timer in frames */ uint32_t t200_timeout; /*!< T200 timeout frame number */ }; diff --git a/src/gsm/lapdm.c b/src/gsm/lapdm.c index d609317..28644c2 100644 --- a/src/gsm/lapdm.c +++ b/src/gsm/lapdm.c @@ -200,6 +200,7 @@ lapdm_dl_init(&le->datalink[i], le, (t200_ms) ? t200_ms[i] : 0, n200, name); } else lapdm_dl_init(&le->datalink[i], le, (t200_ms) ? t200_ms[i] : 0, n200, NULL); + INIT_LLIST_HEAD(&le->datalink[i].tx_ui_queue); }
lapdm_entity_set_mode(le, mode); @@ -296,6 +297,7 @@ for (i = 0; i < ARRAY_SIZE(le->datalink); i++) { dl = &le->datalink[i]; lapd_dl_exit(&dl->dl); + msgb_queue_free(&dl->tx_ui_queue); } }
@@ -390,6 +392,33 @@ return le->l1_prim_cb(&pp.oph, le->l1_ctx); }
+static int tx_ph_data_enqueue_ui(struct lapdm_datalink *dl, struct msgb *msg, + uint8_t chan_nr, uint8_t link_id, uint8_t pad) +{ + struct lapdm_entity *le = dl->entity; + struct osmo_phsap_prim pp; + + /* if there is a pending message, queue it */ + if (le->tx_pending || le->flags & LAPDM_ENT_F_POLLING_ONLY) { + *msgb_push(msg, 1) = pad; + *msgb_push(msg, 1) = link_id; + *msgb_push(msg, 1) = chan_nr; + msgb_enqueue(&dl->tx_ui_queue, msg); + return 0; + } + + osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_DATA, + PRIM_OP_REQUEST, msg); + pp.u.data.chan_nr = chan_nr; + pp.u.data.link_id = link_id; + + /* send the frame now */ + le->tx_pending = 0; /* disabled flow control */ + lapdm_pad_msgb(msg, pad); + + return le->l1_prim_cb(&pp.oph, le->l1_ctx); +} + /* Get transmit frame from queue, if any. In polling mode, indicate RTS to LAPD and start T200, if pending. */ static struct msgb *tx_dequeue_msgb(struct lapdm_datalink *dl, uint32_t fn) { @@ -420,6 +449,11 @@ msg = msgb_dequeue(&dl->dl.tx_queue); if (msg) LOGDL(&dl->dl, LOGL_INFO, "Sending frame from TX queue. (FN %"PRIu32")\n", fn); + else { + msg = msgb_dequeue(&dl->tx_ui_queue); + if (msg) + LOGDL(&dl->dl, LOGL_INFO, "Sending UI frame from TX queue. (FN %"PRIu32")\n", fn); + } return msg; }
@@ -1183,7 +1217,7 @@ }
/* Tramsmit */ - return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, 23); + return tx_ph_data_enqueue_ui(dl, msg, chan_nr, link_id, 23); }
/* L3 requests transfer of acknowledged information */ @@ -1580,6 +1614,7 @@ for (i = 0; i < ARRAY_SIZE(le->datalink); i++) { dl = &le->datalink[i]; lapd_dl_reset(&dl->dl); + msgb_queue_free(&dl->tx_ui_queue); } }