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>