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/.

laforge gerrit-no-reply at lists.osmocom.org
Mon Mar 16 10:32:42 UTC 2020


laforge has submitted this change. ( 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

It may happen that one or more Downlink bursts are lost on their
way to the MS due to a variety of reasons. Modern transceivers
supporting TRXDv1 protocol would substitute lost bursts with
so-called NOPE indications. Hovewer, neither fake_trx.py nor
grgsm_trx do support this feature at the moment.

We can still detect and compensate TDMA frame loss per logical
channels in the same way as it's already done in osmo-bts-trx.
In short, we should keep TDMA frame number of the last received
burst in the logical channel state, and using the appropriate
multiframe layout, check if there were any gaps between TDMA
frame number of the current burst and the stored one.

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

Approvals:
  laforge: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified



diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c
index e6e759a..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_SUM(ts->mf_last_fn, 1);
-	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;
-
-		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: 6
Gerrit-Owner: fixeria <axilirator at gmail.com>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <axilirator at gmail.com>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200316/2f5fad70/attachment.htm>


More information about the gerrit-log mailing list