summaryrefslogtreecommitdiffstats
path: root/src/host/layer23
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-06-24 22:05:46 +0200
committerHarald Welte <laforge@gnumonks.org>2011-06-24 22:05:46 +0200
commit7506e29c61cd160881ad79145f5981b3fdd8c145 (patch)
tree27d6611602f2a84caeef820dad332ac23b141491 /src/host/layer23
parent50c035c30906295b9ca9031a065b7a06776c8196 (diff)
lapdm: introduce a new lapdm_phsap_dequeue_prim()
This function can be called by a TDMA-driven L1 which will never actually want to receive unsolicited/asynchronous PH-DATA.req primitives, but who will simply directly poll the LAPDm transmit queue by calling the abovementioned function
Diffstat (limited to 'src/host/layer23')
-rw-r--r--src/host/layer23/include/osmocom/bb/common/lapdm.h2
-rw-r--r--src/host/layer23/src/common/lapdm.c85
2 files changed, 56 insertions, 31 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/lapdm.h b/src/host/layer23/include/osmocom/bb/common/lapdm.h
index 946ca278..2e78aeee 100644
--- a/src/host/layer23/include/osmocom/bb/common/lapdm.h
+++ b/src/host/layer23/include/osmocom/bb/common/lapdm.h
@@ -181,4 +181,6 @@ void lapdm_channel_reset(struct lapdm_channel *lc);
void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags);
void lapdm_channel_set_flags(struct lapdm_channel *lc, unsigned int flags);
+int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp);
+
#endif /* _OSMOCOM_LAPDM_H */
diff --git a/src/host/layer23/src/common/lapdm.c b/src/host/layer23/src/common/lapdm.c
index e5e23f31..fd395ef1 100644
--- a/src/host/layer23/src/common/lapdm.c
+++ b/src/host/layer23/src/common/lapdm.c
@@ -331,23 +331,12 @@ static int tx_ph_data_enqueue(struct lapdm_datalink *dl, struct msgb *msg,
return le->l1_prim_cb(&pp.oph, le->l1_ctx);
}
-/* get next frame from the tx queue. because the ms has multiple datalinks,
- * each datalink's queue is read round-robin.
- */
-static int l2_ph_data_conf(struct msgb *msg, struct lapdm_entity *le)
+static struct msgb *tx_dequeue_msgb(struct lapdm_entity *le)
{
struct lapdm_datalink *dl;
int last = le->last_tx_dequeue;
int i = last, n = ARRAY_SIZE(le->datalink);
- struct osmo_phsap_prim pp;
- uint8_t n201;
-
- /* we may send again */
- le->tx_pending = 0;
-
- /* free confirm message */
- if (msg)
- msgb_free(msg);
+ struct msgb *msg = NULL;
/* round-robin dequeue */
do {
@@ -358,7 +347,58 @@ static int l2_ph_data_conf(struct msgb *msg, struct lapdm_entity *le)
break;
} while (i != last);
- if (!msg) {
+ if (msg) {
+ /* Set last dequeue position */
+ le->last_tx_dequeue = i;
+ }
+
+ return msg;
+}
+
+/* dequeue a msg that's pending transmission via L1 and wrap it into
+ * a osmo_phsap_prim */
+int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp)
+{
+ struct msgb *msg;
+ uint8_t n201;
+
+ msg = tx_dequeue_msgb(le);
+ if (!msg)
+ return -ENODEV;
+
+ /* if we have a message, send PH-DATA.req */
+ osmo_prim_init(&pp->oph, SAP_GSM_PH, PRIM_PH_DATA,
+ PRIM_OP_REQUEST, msg);
+
+ /* Pull chan_nr and link_id */
+ pp->u.data.chan_nr = *msg->data;
+ msgb_pull(msg, 1);
+ pp->u.data.link_id = *msg->data;
+ msgb_pull(msg, 1);
+ n201 = *msg->data;
+ msgb_pull(msg, 1);
+
+ /* Pad the frame, we can transmit now */
+ lapdm_pad_msgb(msg, n201);
+
+ return 0;
+}
+
+/* get next frame from the tx queue. because the ms has multiple datalinks,
+ * each datalink's queue is read round-robin.
+ */
+static int l2_ph_data_conf(struct msgb *msg, struct lapdm_entity *le)
+{
+ struct osmo_phsap_prim pp;
+
+ /* we may send again */
+ le->tx_pending = 0;
+
+ /* free confirm message */
+ if (msg)
+ msgb_free(msg);
+
+ if (lapdm_phsap_dequeue_prim(le, &pp) < 0) {
/* no message in all queues */
/* If user didn't request PH-EMPTY_FRAME.req, abort */
@@ -370,24 +410,7 @@ static int l2_ph_data_conf(struct msgb *msg, struct lapdm_entity *le)
PRIM_PH_EMPTY_FRAME,
PRIM_OP_REQUEST, NULL);
} else {
- /* if we have a message, send PH-DATA.req */
- osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_DATA,
- PRIM_OP_REQUEST, msg);
-
- /* Pull chan_nr and link_id */
- pp.u.data.chan_nr = *msg->data;
- msgb_pull(msg, 1);
- pp.u.data.link_id = *msg->data;
- msgb_pull(msg, 1);
- n201 = *msg->data;
- msgb_pull(msg, 1);
-
- /* Set last dequeue position */
- le->last_tx_dequeue = i;
-
- /* Pad the frame, we can transmit now */
le->tx_pending = 1;
- lapdm_pad_msgb(msg, n201);
}
return le->l1_prim_cb(&pp.oph, le->l1_ctx);