Change in osmocom-bb[master]: trxcon/scheduler: substitute lost TDMA frames on Downlink

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/gerrit-log@lists.osmocom.org/.

fixeria gerrit-no-reply at lists.osmocom.org
Wed Mar 4 15:20:36 UTC 2020


fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/17352 )


Change subject: trxcon/scheduler: substitute lost TDMA frames on Downlink
......................................................................

trxcon/scheduler: substitute lost TDMA frames on Downlink

Change-Id: I3551d79796a3730565c2c70577e9d134e636f275
---
M src/host/trxcon/sched_trx.c
M src/host/trxcon/sched_trx.h
2 files changed, 100 insertions(+), 55 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/52/17352/1

diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c
index 95839f7..ba75b6f 100644
--- a/src/host/trxcon/sched_trx.c
+++ b/src/host/trxcon/sched_trx.c
@@ -321,9 +321,6 @@
 	if (ts == NULL)
 		return -EINVAL;
 
-	/* Flush TS frame counter */
-	ts->mf_last_fn = 0;
-
 	/* Undefine multiframe layout */
 	ts->mf_layout = NULL;
 
@@ -491,6 +488,9 @@
 
 	/* Reset ciphering state */
 	memset(&lchan->a5, 0x00, sizeof(lchan->a5));
+
+	/* Reset TDMA frame statistics */
+	memset(&lchan->tdma, 0x00, sizeof(lchan->tdma));
 }
 
 int sched_trx_deactivate_lchan(struct trx_ts *ts, enum trx_lchan_type chan)
@@ -610,8 +610,65 @@
 	}
 }
 
+static int subst_frame_loss(struct trx_lchan_state *lchan,
+			    trx_lchan_rx_func *handler,
+			    uint32_t fn)
+{
+	const struct trx_multiframe *mf;
+	const struct trx_frame *fp;
+	unsigned int elapsed, i;
+
+	/* Wait until at least one TDMA frame is processed */
+	if (lchan->tdma.num_proc == 0)
+		return -EAGAIN;
+
+	/* Short alias for the current multiframe */
+	mf = lchan->ts->mf_layout;
+
+	/* How many frames elapsed since the last one? */
+	elapsed = TDMA_FN_SUB(fn, lchan->tdma.last_proc);
+	if (elapsed > mf->period) {
+		LOGP(DSCHD, LOGL_NOTICE, "Too many (>%u) contiguous TDMA frames elapsed (%u) "
+					 "since the last processed fn=%u\n", mf->period,
+					 elapsed, lchan->tdma.last_proc);
+	} else if (elapsed == 0) {
+		LOGP(DSCHD, LOGL_ERROR, "No TDMA frames elapsed since the last processed "
+					"fn=%u, must be a bug?\n", lchan->tdma.last_proc);
+		return -EIO;
+	}
+
+	/* TODO: make bits constant */
+	static sbit_t bits[148] = { 0 };
+	struct trx_meas_set fake_meas = {
+		.fn = lchan->tdma.last_proc,
+		.rssi = -120,
+		.toa256 = 0,
+	};
+
+	/* Traverse from fp till the current frame */
+	for (i = 0; i < elapsed - 1; i++) {
+		fp = &mf->frames[TDMA_FN_INC(&fake_meas.fn) % mf->period];
+		if (fp->dl_chan != lchan->type)
+			continue;
+
+		LOGP(DSCHD, LOGL_NOTICE, "Substituting lost TDMA frame %u on %s\n",
+		     fake_meas.fn, trx_lchan_desc[lchan->type].name);
+
+		handler(lchan->ts->trx, lchan->ts, lchan,
+			fake_meas.fn, fp->dl_bid,
+			bits, &fake_meas);
+
+		/* Update TDMA frame statistics */
+		lchan->tdma.last_proc = fake_meas.fn;
+		lchan->tdma.num_proc++;
+		lchan->tdma.num_lost++;
+	}
+
+	return 0;
+}
+
 int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t tn,
-	uint32_t burst_fn, sbit_t *bits, uint16_t nbits,
+	uint32_t fn, sbit_t *bits, uint16_t nbits,
 	const struct trx_meas_set *meas)
 {
 	struct trx_lchan_state *lchan;
@@ -620,7 +677,6 @@
 
 	trx_lchan_rx_func *handler;
 	enum trx_lchan_type chan;
-	uint32_t fn, elapsed;
 	uint8_t offset, bid;
 
 	/* Check whether required timeslot is allocated and configured */
@@ -631,61 +687,42 @@
 		return -EINVAL;
 	}
 
-	/* Calculate how many frames have been elapsed */
-	elapsed = TDMA_FN_SUB(burst_fn, ts->mf_last_fn);
+	/* Get frame from multiframe */
+	offset = fn % ts->mf_layout->period;
+	frame = ts->mf_layout->frames + offset;
 
-	/**
-	 * If not too many frames have been elapsed,
-	 * start counting from last fn + 1
-	 */
-	if (elapsed < 10)
-		fn = TDMA_FN_INC(ts->mf_last_fn);
-	else
-		fn = burst_fn;
+	/* Get required info from frame */
+	bid = frame->dl_bid;
+	chan = frame->dl_chan;
+	handler = trx_lchan_desc[chan].rx_fn;
 
-	while (1) {
-		/* Get frame from multiframe */
-		offset = fn % ts->mf_layout->period;
-		frame = ts->mf_layout->frames + offset;
+	/* Omit bursts which have no handler, like IDLE bursts.
+	 * TODO: handle noise indications during IDLE frames. */
+	if (!handler)
+		return -ENODEV;
 
-		/* Get required info from frame */
-		bid = frame->dl_bid;
-		chan = frame->dl_chan;
-		handler = trx_lchan_desc[chan].rx_fn;
+	/* Find required channel state */
+	lchan = sched_trx_find_lchan(ts, chan);
+	if (lchan == NULL)
+		return -ENODEV;
 
-		/* Omit bursts which have no handler, like IDLE bursts */
-		if (!handler)
-			goto next_frame;
+	/* Ensure that channel is active */
+	if (!lchan->active)
+		return 0;
 
-		/* Find required channel state */
-		lchan = sched_trx_find_lchan(ts, chan);
-		if (lchan == NULL)
-			goto next_frame;
+	/* Compensate lost TDMA frames (if any) */
+	subst_frame_loss(lchan, handler, fn);
 
-		/* Ensure that channel is active */
-		if (!lchan->active)
-			goto next_frame;
+	/* Perform A5/X decryption if required */
+	if (lchan->a5.algo)
+		sched_trx_a5_burst_dec(lchan, fn, bits);
 
-		/* Reached current fn */
-		if (fn == burst_fn) {
-			/* Perform A5/X decryption if required */
-			if (lchan->a5.algo)
-				sched_trx_a5_burst_dec(lchan, fn, bits);
+	/* Put burst to handler */
+	handler(trx, ts, lchan, fn, bid, bits, meas);
 
-			/* Put burst to handler */
-			handler(trx, ts, lchan, fn, bid, bits, meas);
-		}
-
-next_frame:
-		/* Reached current fn */
-		if (fn == burst_fn)
-			break;
-
-		fn = TDMA_FN_INC(fn);
-	}
-
-	/* Set last processed frame number */
-	ts->mf_last_fn = fn;
+	/* Update TDMA frame statistics */
+	lchan->tdma.last_proc = fn;
+	lchan->tdma.num_proc++;
 
 	return 0;
 }
diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h
index 44f502c..cf63df1 100644
--- a/src/host/trxcon/sched_trx.h
+++ b/src/host/trxcon/sched_trx.h
@@ -209,6 +209,16 @@
 	/*! \brief AVG measurements of the last received block */
 	struct trx_meas_set meas_avg;
 
+	/*! \brief TDMA loss detection state */
+	struct {
+		/*! \brief Last processed TDMA frame number */
+		uint32_t last_proc;
+		/*! \brief Number of processed TDMA frames */
+		unsigned long num_proc;
+		/*! \brief Number of lost TDMA frames */
+		unsigned long num_lost;
+	} tdma;
+
 	/*! \brief SACCH state */
 	struct {
 		/*! \brief Cached measurement report (last received) */
@@ -255,8 +265,6 @@
 struct trx_ts {
 	/*! \brief Timeslot index within a frame (0..7) */
 	uint8_t index;
-	/*! \brief Last received frame number */
-	uint32_t mf_last_fn;
 
 	/*! \brief Pointer to multiframe layout */
 	const struct trx_multiframe *mf_layout;
@@ -356,7 +364,7 @@
 void sched_prim_flush_queue(struct llist_head *list);
 
 int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t tn,
-	uint32_t burst_fn, sbit_t *bits, uint16_t nbits,
+	uint32_t fn, sbit_t *bits, uint16_t nbits,
 	const struct trx_meas_set *meas);
 int sched_trx_handle_tx_burst(struct trx_instance *trx,
 	struct trx_ts *ts, struct trx_lchan_state *lchan,

-- 
To view, visit https://gerrit.osmocom.org/c/osmocom-bb/+/17352
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: I3551d79796a3730565c2c70577e9d134e636f275
Gerrit-Change-Number: 17352
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <axilirator at gmail.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200304/8a81efd1/attachment.htm>


More information about the gerrit-log mailing list