[PATCH 2/8] tbf: Separate the easy path out of the receive path

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/osmocom-net-gprs@lists.osmocom.org/.

Holger Freyther hfreyther at sysmocom.de
Wed Oct 16 14:23:42 UTC 2013


From: Holger Hans Peter Freyther <holger at moiji-mobile.com>

* Create a look up routine for the TBF that will allow us to
  easily find a TBF by IMSI...
* Separate the code that works on an existing TBF.
---
 src/tbf.cpp | 119 +++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 70 insertions(+), 49 deletions(-)

diff --git a/src/tbf.cpp b/src/tbf.cpp
index 816fdb8..d242b52 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -29,66 +29,87 @@ extern "C" {
 #include <errno.h>
 #include <string.h>
 
+static struct gprs_rlcmac_tbf *tbf_lookup_dl(const uint32_t tlli, const char *imsi)
+{
+	/* TODO: look up by IMSI first, then tlli, then old_tlli */
+	return tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF);
+}
+
+static int tbf_append_data(struct gprs_rlcmac_tbf *tbf,
+				struct gprs_rlcmac_bts *bts,
+				const uint8_t ms_class,
+				const uint16_t pdu_delay_csec,
+				const uint8_t *data, const uint16_t len)
+{
+	LOGP(DRLCMAC, LOGL_INFO, "TBF: APPEND TFI: %u TLLI: 0x%08x\n", tbf->tfi, tbf->tlli);
+	if (tbf->state == GPRS_RLCMAC_WAIT_RELEASE) {
+		LOGP(DRLCMAC, LOGL_DEBUG, "TBF in WAIT RELEASE state "
+			"(T3193), so reuse TBF\n");
+		memcpy(tbf->llc_frame, data, len);
+		tbf->llc_length = len;
+		/* reset rlc states */
+		memset(&tbf->dir.dl, 0, sizeof(tbf->dir.dl));
+		/* keep to flags */
+		tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK;
+		tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH);
+		if (!tbf->ms_class && ms_class)
+			tbf->ms_class = ms_class;
+		tbf_update(tbf);
+		gprs_rlcmac_trigger_downlink_assignment(tbf, tbf, NULL);
+	} else {
+		/* the TBF exists, so we must write it in the queue
+		 * we prepend lifetime in front of PDU */
+		struct timeval *tv;
+		struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv),
+			"llc_pdu_queue");
+		if (!llc_msg)
+			return -ENOMEM;
+		tv = (struct timeval *)msgb_put(llc_msg, sizeof(*tv));
+
+		uint16_t delay_csec;
+		if (bts->force_llc_lifetime)
+			delay_csec = bts->force_llc_lifetime;
+		else
+			delay_csec = pdu_delay_csec;
+		/* keep timestap at 0 for infinite delay */
+		if (delay_csec != 0xffff) {
+			/* calculate timestamp of timeout */
+			gettimeofday(tv, NULL);
+			tv->tv_usec += (delay_csec % 100) * 10000;
+			tv->tv_sec += delay_csec / 100;
+			if (tv->tv_usec > 999999) {
+				tv->tv_usec -= 1000000;
+				tv->tv_sec++;
+			}
+		}
+		memcpy(msgb_put(llc_msg, len), data, len);
+		msgb_enqueue(&tbf->llc_queue, llc_msg);
+		/* set ms class for updating TBF */
+		if (!tbf->ms_class && ms_class)
+			tbf->ms_class = ms_class;
+	}
+
+	return 0;
+}
+
 /**
  * TODO: split into unit test-able parts...
  */
 int tbf_handle(struct gprs_rlcmac_bts *bts,
 		const uint32_t tlli, const char *imsi,
-		const uint8_t ms_class, const uint16_t pdu_delay_csec,
+		const uint8_t ms_class, const uint16_t delay_csec,
 		const uint8_t *data, const uint16_t len)
 {
 	struct gprs_rlcmac_tbf *tbf;
 	int8_t tfi; /* must be signed */
 
 	/* check for existing TBF */
-	if ((tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) {
-		LOGP(DRLCMAC, LOGL_INFO, "TBF: APPEND TFI: %u TLLI: 0x%08x\n", tbf->tfi, tbf->tlli);
-		if (tbf->state == GPRS_RLCMAC_WAIT_RELEASE) {
-			LOGP(DRLCMAC, LOGL_DEBUG, "TBF in WAIT RELEASE state "
-				"(T3193), so reuse TBF\n");
-			memcpy(tbf->llc_frame, data, len);
-			tbf->llc_length = len;
-			memset(&tbf->dir.dl, 0, sizeof(tbf->dir.dl)); /* reset
-								rlc states */
-			tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; /* keep
-				to flags */
-			tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH);
-			if (!tbf->ms_class && ms_class)
-				tbf->ms_class = ms_class;
-			tbf_update(tbf);
-			gprs_rlcmac_trigger_downlink_assignment(tbf, tbf, NULL);
-		} else {
-			/* the TBF exists, so we must write it in the queue
-			 * we prepend lifetime in front of PDU */
-			struct timeval *tv;
-			struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv),
-				"llc_pdu_queue");
-			if (!llc_msg)
-				return -ENOMEM;
-			tv = (struct timeval *)msgb_put(llc_msg, sizeof(*tv));
-
-			uint16_t delay_csec;
-			if (bts->force_llc_lifetime)
-				delay_csec = bts->force_llc_lifetime;
-			else
-				delay_csec = pdu_delay_csec;
-			/* keep timestap at 0 for infinite delay */
-			if (delay_csec != 0xffff) {
-				/* calculate timestamp of timeout */
-				gettimeofday(tv, NULL);
-				tv->tv_usec += (delay_csec % 100) * 10000;
-				tv->tv_sec += delay_csec / 100;
-				if (tv->tv_usec > 999999) {
-					tv->tv_usec -= 1000000;
-					tv->tv_sec++;
-				}
-			}
-			memcpy(msgb_put(llc_msg, len), data, len);
-			msgb_enqueue(&tbf->llc_queue, llc_msg);
-			/* set ms class for updating TBF */
-			if (!tbf->ms_class && ms_class)
-				tbf->ms_class = ms_class;
-		}
+	tbf = tbf_lookup_dl(tlli, imsi);
+	if (tbf) {
+		int rc = tbf_append_data(tbf, bts, ms_class,
+						delay_csec, data, len);
+		if (rc < 0)
+			return rc;
 	} else {
 		uint8_t trx, ta, ss;
 		int8_t use_trx;
-- 
1.8.4.rc3





More information about the osmocom-net-gprs mailing list