fixeria has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-bts/+/15812 )


Change subject: osmo-bts-trx/scheduler: refactor the first frame number 
calculation
......................................................................

osmo-bts-trx/scheduler: refactor the first frame number calculation

In I6bc511223069f66b49109d3267bee7bd89585713 we have introduced
the storage for Uplink measurements (so called "history"), where
we can also store TDMA frame numbers of the related bursts.

This approach allows to look up frame number of the first Uplink
burst of a decoded block from the history. Thus neither we need
to store frame number of bid=0 in the logical channel state,
nor use complicated and buggy formulas.

This is not a silver bullet, because in some cases the measurement
history may be incomplete (until we start handling NOPE.ind from
the transceiver, see OS#3428). In such cases we would still need
to look up the first frame number using the block mapping tables
defined in 3GPP TS 45.002.

Change-Id: Iae9a0135595b0c56752723669a4ed2fc91f25785
Related: OS#3803
---
M include/osmo-bts/scheduler.h
M src/osmo-bts-trx/scheduler_trx.c
2 files changed, 54 insertions(+), 35 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/12/15812/1

diff --git a/include/osmo-bts/scheduler.h b/include/osmo-bts/scheduler.h
index e6ec37d..f096374 100644
--- a/include/osmo-bts/scheduler.h
+++ b/include/osmo-bts/scheduler.h
@@ -72,6 +72,7 @@
 /* A set of measurements attached to a burst */
 struct l1sched_meas_set {
        struct llist_head       list;           /* Link to the measurement 
history */
+       uint32_t                fn;             /* TDMA frame-number */

        int16_t                 toa256;         /* Timing of Arrival (1/256 of 
a symbol) */
        int16_t                 ci_cb;          /* Carrier-to-Interference (cB) 
*/
@@ -85,7 +86,6 @@
        ubit_t                  *dl_bursts;     /* burst buffer for TX */
        enum trx_burst_type     dl_burst_type;  /* GMSK or 8PSK burst type */
        sbit_t                  *ul_bursts;     /* burst buffer for RX */
-       uint32_t                ul_first_fn;    /* fn of first burst */
        uint8_t                 ul_mask;        /* mask of received bursts */

        /* loss detection */
diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c
index ae23ddd..39f118d 100644
--- a/src/osmo-bts-trx/scheduler_trx.c
+++ b/src/osmo-bts-trx/scheduler_trx.c
@@ -898,6 +898,9 @@
        set = talloc(tall_bts_ctx, struct l1sched_meas_set);
        OSMO_ASSERT(set != NULL);

+       /* Attach TDMA frame number */
+       set->fn = bi->fn;
+
        set->toa256 = bi->toa256;
        set->rssi = bi->rssi;

@@ -962,6 +965,30 @@
        }
 }

+/* Get TDMA frame number of N-th measurement from the history. */
+static uint32_t l1sched_meas_get_fn(const struct l1sched_chan_state 
*chan_state,
+                                   unsigned int num)
+{
+       const struct llist_head *hist = &chan_state->meas.hist;
+       struct l1sched_meas_set *set;
+
+       /* There shall be at least one set */
+       OSMO_ASSERT(chan_state->meas.num > 0);
+
+       /* Try to find N-th measurement in the history */
+       llist_for_each_entry(set, hist, list) {
+               if (num == 0)
+                       return set->fn;
+               num -= 1;
+       }
+
+       /* Not enough measurements in the history? */
+       LOGP(DL1P, LOGL_NOTICE, "Failed to find TDMA frame number in the 
history, "
+                               "using frame number of the last burst\n");
+       set = llist_first_entry(hist, struct l1sched_meas_set, list);
+       return set->fn; /* return frame number of the last burst */
+}
+
 /*! \brief a single (SDCCH/SACCH) burst was received by the PHY, process it */
 int rx_data_fn(struct l1sched_trx *l1t, enum trx_chan_type chan,
               uint8_t bid, const struct trx_ul_burst_ind *bi)
@@ -969,11 +996,11 @@
        struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, bi->tn);
        struct l1sched_chan_state *chan_state = &l1ts->chan_state[chan];
        sbit_t *burst, **bursts_p = &chan_state->ul_bursts;
-       uint32_t *first_fn = &chan_state->ul_first_fn;
        uint8_t *mask = &chan_state->ul_mask;
        uint8_t l2[GSM_MACBLOCK_LEN], l2_len;
        struct l1sched_meas_set meas_set;
        int n_errors, n_bits_total;
+       uint32_t first_fn;
        uint16_t ber10k;
        int rc;

@@ -997,7 +1024,6 @@
        if (bid == 0) {
                memset(*bursts_p, 0, 464);
                *mask = 0x0;
-               *first_fn = bi->fn;
        }

        /* store the measurements */
@@ -1045,18 +1071,21 @@
        } else
                l2_len = GSM_MACBLOCK_LEN;

+       /* Get frame number of the first burst (1/4) */
+       first_fn = l1sched_meas_get_fn(chan_state, 4);
+
        /* Average measurements of the last 4 bursts */
        l1sched_meas_average(chan_state, &meas_set, 4);
        /* Nothing to store for the next block */
        l1sched_meas_squeeze(chan_state, 0);

        /* Send uplink measurement information to L2 */
-       l1if_process_meas_res(l1t->trx, bi->tn, *first_fn,
+       l1if_process_meas_res(l1t->trx, bi->tn, first_fn,
                              trx_chan_desc[chan].chan_nr | bi->tn,
                              n_errors, n_bits_total,
                              meas_set.rssi, meas_set.toa256);
        ber10k = compute_ber10k(n_bits_total, n_errors);
-       return _sched_compose_ph_data_ind(l1t, bi->tn, *first_fn,
+       return _sched_compose_ph_data_ind(l1t, bi->tn, first_fn,
                                          chan, l2, l2_len,
                                          meas_set.rssi, meas_set.toa256,
                                          meas_set.ci_cb, ber10k,
@@ -1070,11 +1099,11 @@
        struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, bi->tn);
        struct l1sched_chan_state *chan_state = &l1ts->chan_state[chan];
        sbit_t *burst, **bursts_p = &chan_state->ul_bursts;
-       uint32_t *first_fn = &chan_state->ul_first_fn;
        uint8_t *mask = &chan_state->ul_mask;
        uint8_t l2[EGPRS_0503_MAX_BYTES];
        struct l1sched_meas_set meas_set;
        int n_errors, n_bursts_bits, n_bits_total;
+       uint32_t first_fn;
        uint16_t ber10k;
        int rc;

@@ -1095,7 +1124,6 @@
        if (bid == 0) {
                memset(*bursts_p, 0, GSM0503_EGPRS_BURSTS_NBITS);
                *mask = 0x0;
-               *first_fn = bi->fn;
        }
 
        /* store the measurements */
@@ -1143,13 +1171,16 @@
                                  &n_errors, &n_bits_total);
        }

+       /* Get frame number of the first burst (1/4) */
+       first_fn = l1sched_meas_get_fn(chan_state, 4);
+
        /* Average measurements of the last 4 bursts */
        l1sched_meas_average(chan_state, &meas_set, 4);
        /* Nothing to store for the next block */
        l1sched_meas_squeeze(chan_state, 0);

        /* Send uplink measurement information to L2 */
-       l1if_process_meas_res(l1t->trx, bi->tn, *first_fn,
+       l1if_process_meas_res(l1t->trx, bi->tn, first_fn,
                trx_chan_desc[chan].chan_nr | bi->tn,
                n_errors, n_bits_total,
                meas_set.rssi, meas_set.toa256);
@@ -1163,7 +1194,7 @@

        ber10k = compute_ber10k(n_bits_total, n_errors);
        return _sched_compose_ph_data_ind(l1t, bi->tn,
-                                         *first_fn, chan, l2, rc,
+                                         first_fn, chan, l2, rc,
                                          meas_set.rssi, meas_set.toa256,
                                          meas_set.ci_cb, ber10k,
                                          PRES_INFO_BOTH);
@@ -1176,12 +1207,12 @@
        struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, bi->tn);
        struct l1sched_chan_state *chan_state = &l1ts->chan_state[chan];
        sbit_t *burst, **bursts_p = &chan_state->ul_bursts;
-       uint32_t *first_fn = &chan_state->ul_first_fn;
        uint8_t *mask = &chan_state->ul_mask;
        uint8_t rsl_cmode = chan_state->rsl_cmode;
        uint8_t tch_mode = chan_state->tch_mode;
        uint8_t tch_data[128]; /* just to be safe */
        struct l1sched_meas_set meas_set;
+       uint32_t first_fn;
        int rc, amr = 0;
        int n_errors, n_bits_total;
        bool bfi_flag = false;
@@ -1208,7 +1239,6 @@
        if (bid == 0) {
                memset(*bursts_p + 464, 0, 464);
                *mask = 0x0;
-               *first_fn = bi->fn;
        }
 
        /* store the measurements */
@@ -1275,13 +1305,16 @@
        }
        memcpy(*bursts_p, *bursts_p + 464, 464);

+       /* Get frame number of the first burst (1/8) */
+       first_fn = l1sched_meas_get_fn(chan_state, 8);
+
        /* Average measurements of the last 8 bursts */
        l1sched_meas_average(chan_state, &meas_set, 8);
        /* Keep measurements of the last 4 bursts */
        l1sched_meas_squeeze(chan_state, 4);

        /* Send uplink measurement information to L2 */
-       l1if_process_meas_res(l1t->trx, bi->tn, *first_fn,
+       l1if_process_meas_res(l1t->trx, bi->tn, first_fn,
                              trx_chan_desc[chan].chan_nr | bi->tn,
                              n_errors, n_bits_total,
                              meas_set.rssi, meas_set.toa256);
@@ -1308,9 +1341,7 @@
        /* FACCH */
        if (rc == GSM_MACBLOCK_LEN) {
                uint16_t ber10k = compute_ber10k(n_bits_total, n_errors);
-               _sched_compose_ph_data_ind(l1t, bi->tn,
-                       /* FIXME: this calculation is wrong */
-                       (bi->fn + GSM_HYPERFRAME - 7) % GSM_HYPERFRAME, chan,
+               _sched_compose_ph_data_ind(l1t, bi->tn, first_fn, chan,
                        tch_data + amr, GSM_MACBLOCK_LEN,
                        meas_set.rssi, meas_set.toa256,
                        meas_set.ci_cb, ber10k,
@@ -1368,10 +1399,7 @@

        /* TCH or BFI */
 compose_l1sap:
-       return _sched_compose_tch_ind(l1t, bi->tn,
-               /* FIXME: this calculation is wrong */
-               (bi->fn + GSM_HYPERFRAME - 7) % GSM_HYPERFRAME, chan,
-               tch_data, rc);
+       return _sched_compose_tch_ind(l1t, bi->tn, first_fn, chan, tch_data, 
rc);
 }

 /*! \brief a single TCH/H burst was received by the PHY, process it */
@@ -1381,12 +1409,12 @@
        struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, bi->tn);
        struct l1sched_chan_state *chan_state = &l1ts->chan_state[chan];
        sbit_t *burst, **bursts_p = &chan_state->ul_bursts;
-       uint32_t *first_fn = &chan_state->ul_first_fn;
        uint8_t *mask = &chan_state->ul_mask;
        uint8_t rsl_cmode = chan_state->rsl_cmode;
        uint8_t tch_mode = chan_state->tch_mode;
        uint8_t tch_data[128]; /* just to be safe */
        struct l1sched_meas_set meas_set;
+       uint32_t first_fn;
        int rc, amr = 0;
        int n_errors, n_bits_total;
        bool bfi_flag = false;
@@ -1418,7 +1446,6 @@
        if (bid == 0) {
                memset(*bursts_p + 464, 0, 232);
                *mask = 0x0;
-               *first_fn = bi->fn;
        }

        /* store the measurements */
@@ -1496,6 +1523,9 @@
        memcpy(*bursts_p, *bursts_p + 232, 232);
        memcpy(*bursts_p + 232, *bursts_p + 464, 232);

+       /* Get frame number of the first burst (either 1/4 or 1/6) */
+       first_fn = l1sched_meas_get_fn(chan_state, rc == GSM_MACBLOCK_LEN ? 6 : 
4);
+
        /* Average measurements of either the last 4 bursts (speech),
         * or the last 6 bursts (in case if FACCH/H was received). */
        l1sched_meas_average(chan_state, &meas_set, rc == GSM_MACBLOCK_LEN ? 6 
: 4);
@@ -1503,8 +1533,7 @@
        l1sched_meas_squeeze(chan_state, 2);

        /* Send uplink measurement information to L2 */
-       l1if_process_meas_res(l1t->trx, bi->tn,
-               *first_fn /* FIXME: this is wrong */,
+       l1if_process_meas_res(l1t->trx, bi->tn, first_fn,
                trx_chan_desc[chan].chan_nr | bi->tn,
                n_errors, n_bits_total,
                meas_set.rssi, meas_set.toa256);
@@ -1532,9 +1561,7 @@
        if (rc == GSM_MACBLOCK_LEN) {
                chan_state->ul_ongoing_facch = 1;
                uint16_t ber10k = compute_ber10k(n_bits_total, n_errors);
-               _sched_compose_ph_data_ind(l1t, bi->tn,
-                       /* FIXME: what the hell is this?!? */
-                       (bi->fn + GSM_HYPERFRAME - 10 - ((bi->fn % 26) >= 19)) 
% GSM_HYPERFRAME, chan,
+               _sched_compose_ph_data_ind(l1t, bi->tn, first_fn, chan,
                        tch_data + amr, GSM_MACBLOCK_LEN,
                        meas_set.rssi, meas_set.toa256,
                        meas_set.ci_cb, ber10k,
@@ -1589,15 +1616,7 @@

 compose_l1sap:
        /* TCH or BFI */
-       /* Note on FN 19 or 20: If we received the last burst of a frame,
-        * it actually starts at FN 8 or 9. A burst starting there, overlaps
-        * with the slot 12, so an extra FN must be subtracted to get correct
-        * start of frame.
-        */
-       return _sched_compose_tch_ind(l1t, bi->tn,
-               /* FIXME: what the hell is this?!? */
-               (bi->fn + GSM_HYPERFRAME - 10 - ((bi->fn%26)==19) - 
((bi->fn%26)==20)) % GSM_HYPERFRAME,
-               chan, tch_data, rc);
+       return _sched_compose_tch_ind(l1t, bi->tn, first_fn, chan, tch_data, 
rc);
 }

 /* schedule all frames of all TRX for given FN */

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

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: Iae9a0135595b0c56752723669a4ed2fc91f25785
Gerrit-Change-Number: 15812
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <axilira...@gmail.com>
Gerrit-MessageType: newchange

Reply via email to