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