diff options
author | Harald Welte <laforge@gnumonks.org> | 2011-06-24 22:05:46 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2011-06-24 22:05:46 +0200 |
commit | 7506e29c61cd160881ad79145f5981b3fdd8c145 (patch) | |
tree | 27d6611602f2a84caeef820dad332ac23b141491 /src/host | |
parent | 50c035c30906295b9ca9031a065b7a06776c8196 (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')
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/lapdm.h | 2 | ||||
-rw-r--r-- | src/host/layer23/src/common/lapdm.c | 85 |
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); |