summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Welte2011-06-24 13:56:48 +0200
committerHarald Welte2011-06-24 13:56:48 +0200
commitec71711ebf1a00bcbd6d9dba0d39a827a8dfecf7 (patch)
tree61ce3f730d5cdd7230c53692312b08398293ac56 /src
parentlapdm: Introduce LAPDM_MODE_{BTS,MS} to run on both sides (diff)
downloadosmocom-ec71711ebf1a00bcbd6d9dba0d39a827a8dfecf7.tar.gz
osmocom-ec71711ebf1a00bcbd6d9dba0d39a827a8dfecf7.tar.xz
osmocom-ec71711ebf1a00bcbd6d9dba0d39a827a8dfecf7.zip
introduce LAPDM entity flags for PH-EMPTY_FRAME.req and pollling
polling means that we never try to proactively generate a PH-DATA.req unless there was a PH-RTS.ind first.
Diffstat (limited to 'src')
-rw-r--r--src/host/layer23/include/osmocom/bb/common/lapdm.h7
-rw-r--r--src/host/layer23/src/common/lapdm.c61
2 files changed, 48 insertions, 20 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/lapdm.h b/src/host/layer23/include/osmocom/bb/common/lapdm.h
index 19eeeb7..946ca27 100644
--- a/src/host/layer23/include/osmocom/bb/common/lapdm.h
+++ b/src/host/layer23/include/osmocom/bb/common/lapdm.h
@@ -118,12 +118,16 @@ struct lapdm_cr_ent {
uint8_t resp;
};
+#define LAPDM_ENT_F_EMPTY_FRAME 0x0001
+#define LAPDM_ENT_F_POLLING_ONLY 0x0002
+
/* register message handler for messages that are sent from L2->L3 */
struct lapdm_entity {
struct lapdm_datalink datalink[_NR_DL_SAPI];
int last_tx_dequeue; /* last entity that was dequeued */
int tx_pending; /* currently a pending frame not confirmed by L1 */
enum lapdm_mode mode; /* are we in BTS mode or MS mode */
+ unsigned int flags;
struct {
/* filled-in once we set the lapdm_mode above */
@@ -174,4 +178,7 @@ int lapdm_channel_set_mode(struct lapdm_channel *lc, enum lapdm_mode mode);
void lapdm_entity_reset(struct lapdm_entity *le);
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);
+
#endif /* _OSMOCOM_LAPDM_H */
diff --git a/src/host/layer23/src/common/lapdm.c b/src/host/layer23/src/common/lapdm.c
index 8d15b52..fee221f 100644
--- a/src/host/layer23/src/common/lapdm.c
+++ b/src/host/layer23/src/common/lapdm.c
@@ -316,7 +316,7 @@ static int tx_ph_data_enqueue(struct lapdm_datalink *dl, struct msgb *msg,
pp.u.data.link_id = link_id;
/* if there is a pending message, queue it */
- if (le->tx_pending) {
+ if (le->tx_pending || le->flags & LAPDM_ENT_F_POLLING_ONLY) {
*msgb_push(msg, 1) = n201;
*msgb_push(msg, 1) = link_id;
*msgb_push(msg, 1) = chan_nr;
@@ -358,27 +358,37 @@ static int l2_ph_data_conf(struct msgb *msg, struct lapdm_entity *le)
break;
} while (i != last);
- /* no message in all queues */
- if (!msg)
- return 0;
-
- 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);
+ if (!msg) {
+ /* no message in all queues */
- /* Set last dequeue position */
- le->last_tx_dequeue = i;
+ /* If user didn't request PH-EMPTY_FRAME.req, abort */
+ if (!(le->flags & LAPDM_ENT_F_EMPTY_FRAME))
+ return 0;
- /* Pad the frame, we can transmit now */
- le->tx_pending = 1;
- lapdm_pad_msgb(msg, n201);
+ /* otherwise, send PH-EMPTY_FRAME.req */
+ osmo_prim_init(&pp.oph, SAP_GSM_PH,
+ 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);
}
@@ -2452,3 +2462,14 @@ void lapdm_channel_reset(struct lapdm_channel *lc)
lapdm_entity_reset(&lc->lapdm_dcch);
lapdm_entity_reset(&lc->lapdm_acch);
}
+
+void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags)
+{
+ le->flags = flags;
+}
+
+void lapdm_channel_set_flags(struct lapdm_channel *lc, unsigned int flags)
+{
+ lapdm_entity_set_flags(&lc->lapdm_dcch, flags);
+ lapdm_entity_set_flags(&lc->lapdm_acch, flags);
+}