summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2020-03-02 19:07:35 +0700
committerlaforge <laforge@osmocom.org>2020-03-16 10:32:42 +0000
commit8c760f8f056361fa08d5c89280e92486cb62ba0c (patch)
treebd7454a6c358326ff44d269a02b379d621d0e275
parentb9ab7150bfee7a46a5e2d920d30607c365b39b18 (diff)
trxcon/scheduler: refactor TDMA frame number calculation
Using TDMA frame number of a burst with bid=0 is fine for xCCH, but not for TCH and FACCH, because they use the block-diagonel interleaving. A single block on TCH may be interleaved over 8, 4 or even 6 consecutive bursts depending on its type. Since we now have the measurement history, we can attach TDMA frame number to each measurement set, and then look up N-th one when averaging the measurements in sched_trx_meas_avg(). Change-Id: I9221957297a6154edc1767a0e3753f5ee383173f
-rw-r--r--src/host/trxcon/sched_lchan_common.c6
-rw-r--r--src/host/trxcon/sched_lchan_pdtch.c14
-rw-r--r--src/host/trxcon/sched_lchan_tchf.c11
-rw-r--r--src/host/trxcon/sched_lchan_tchh.c21
-rw-r--r--src/host/trxcon/sched_lchan_xcch.c14
-rw-r--r--src/host/trxcon/sched_trx.c8
-rw-r--r--src/host/trxcon/sched_trx.h4
-rw-r--r--src/host/trxcon/trx_if.c1
8 files changed, 33 insertions, 46 deletions
diff --git a/src/host/trxcon/sched_lchan_common.c b/src/host/trxcon/sched_lchan_common.c
index 55ec7e95..ae43ca94 100644
--- a/src/host/trxcon/sched_lchan_common.c
+++ b/src/host/trxcon/sched_lchan_common.c
@@ -137,9 +137,11 @@ int sched_send_dt_ind(struct trx_instance *trx, struct trx_ts *ts,
dl_hdr.chan_nr = lchan_desc->chan_nr | ts->index;
dl_hdr.link_id = lchan_desc->link_id;
dl_hdr.band_arfcn = htons(trx->band_arfcn);
- dl_hdr.frame_nr = htonl(lchan->rx_first_fn);
dl_hdr.num_biterr = bit_error_count;
+ /* sched_trx_meas_avg() gives us TDMA frame number of the first burst */
+ dl_hdr.frame_nr = htonl(meas->fn);
+
/* RX level: 0 .. 63 in typical GSM notation (dBm + 110) */
dl_hdr.rx_level = dbm2rxlev(meas->rssi);
@@ -154,7 +156,7 @@ int sched_send_dt_ind(struct trx_instance *trx, struct trx_ts *ts,
/* Optional GSMTAP logging */
if (l2_len > 0 && (!traffic || lchan_desc->chan_nr == RSL_CHAN_OSMO_PDCH)) {
- sched_gsmtap_send(lchan->type, lchan->rx_first_fn, ts->index,
+ sched_gsmtap_send(lchan->type, meas->fn, ts->index,
trx->band_arfcn, meas->rssi, 0, l2, l2_len);
}
diff --git a/src/host/trxcon/sched_lchan_pdtch.c b/src/host/trxcon/sched_lchan_pdtch.c
index 4fd7d35d..b625d2f7 100644
--- a/src/host/trxcon/sched_lchan_pdtch.c
+++ b/src/host/trxcon/sched_lchan_pdtch.c
@@ -48,12 +48,10 @@ int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts,
uint8_t l2[GPRS_L2_MAX_LEN], *mask;
int n_errors, n_bits_total, rc;
sbit_t *buffer, *offset;
- uint32_t *first_fn;
size_t l2_len;
/* Set up pointers */
lchan_desc = &trx_lchan_desc[lchan->type];
- first_fn = &lchan->rx_first_fn;
mask = &lchan->rx_burst_mask;
buffer = lchan->rx_bursts;
@@ -61,10 +59,8 @@ int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts,
"fn=%u ts=%u bid=%u\n", lchan_desc->name, fn, ts->index, bid);
/* Reset internal state */
- if (bid == 0) {
- *first_fn = fn;
+ if (bid == 0)
*mask = 0x0;
- }
/* Update mask */
*mask |= (1 << bid);
@@ -88,8 +84,8 @@ int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts,
if ((*mask & 0xf) != 0xf) {
LOGP(DSCHD, LOGL_ERROR, "Received incomplete (%s) data frame at "
"fn=%u (%u/%u) for %s\n",
- burst_mask2str(mask, 4), *first_fn,
- (*first_fn) % ts->mf_layout->period,
+ burst_mask2str(mask, 4), lchan->meas_avg.fn,
+ lchan->meas_avg.fn % ts->mf_layout->period,
ts->mf_layout->period,
lchan_desc->name);
@@ -101,8 +97,8 @@ int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts,
NULL, &n_errors, &n_bits_total);
if (rc < 0) {
LOGP(DSCHD, LOGL_ERROR, "Received bad packet data frame "
- "at fn=%u (%u/%u) for %s\n", *first_fn,
- (*first_fn) % ts->mf_layout->period,
+ "at fn=%u (%u/%u) for %s\n", lchan->meas_avg.fn,
+ lchan->meas_avg.fn % ts->mf_layout->period,
ts->mf_layout->period,
lchan_desc->name);
}
diff --git a/src/host/trxcon/sched_lchan_tchf.c b/src/host/trxcon/sched_lchan_tchf.c
index 6531e11c..595101f5 100644
--- a/src/host/trxcon/sched_lchan_tchf.c
+++ b/src/host/trxcon/sched_lchan_tchf.c
@@ -50,12 +50,10 @@ int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts,
int n_errors = -1, n_bits_total, rc;
sbit_t *buffer, *offset;
uint8_t l2[128], *mask;
- uint32_t *first_fn;
size_t l2_len;
/* Set up pointers */
lchan_desc = &trx_lchan_desc[lchan->type];
- first_fn = &lchan->rx_first_fn;
mask = &lchan->rx_burst_mask;
buffer = lchan->rx_bursts;
@@ -63,10 +61,8 @@ int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts,
lchan_desc->name, fn, ts->index, bid);
/* Reset internal state */
- if (bid == 0) {
- *first_fn = fn;
+ if (bid == 0)
*mask = 0x00;
- }
/* Update mask */
*mask |= (1 << bid);
@@ -90,8 +86,8 @@ int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts,
if ((*mask & 0xf) != 0xf) {
LOGP(DSCHD, LOGL_ERROR, "Received incomplete (%s) traffic frame at "
"fn=%u (%u/%u) for %s\n",
- burst_mask2str(mask, 8), *first_fn,
- (*first_fn) % ts->mf_layout->period,
+ burst_mask2str(mask, 8), lchan->meas_avg.fn,
+ lchan->meas_avg.fn % ts->mf_layout->period,
ts->mf_layout->period,
lchan_desc->name);
@@ -152,6 +148,7 @@ bfi:
/* Didn't try to decode, fake measurements */
if (n_errors < 0) {
lchan->meas_avg = (struct trx_meas_set) {
+ .fn = lchan->meas_avg.fn,
.toa256 = 0,
.rssi = -110,
};
diff --git a/src/host/trxcon/sched_lchan_tchh.c b/src/host/trxcon/sched_lchan_tchh.c
index e7037fe5..f8229939 100644
--- a/src/host/trxcon/sched_lchan_tchh.c
+++ b/src/host/trxcon/sched_lchan_tchh.c
@@ -291,23 +291,19 @@ int rx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts,
/* Check decoding result */
if (rc < 4) {
- LOGP(DSCHD, LOGL_ERROR, "Received bad TCH frame (%s) ending at "
- "fn=%u on %s (rc=%d)\n", burst_mask2str(mask, 6),
- fn, lchan_desc->name, rc);
-
/* Calculate AVG of the measurements (assuming 4 bursts) */
sched_trx_meas_avg(lchan, 4);
+ LOGP(DSCHD, LOGL_ERROR, "Received bad TCH frame (%s) "
+ "at fn=%u on %s (rc=%d)\n", burst_mask2str(mask, 6),
+ lchan->meas_avg.fn, lchan_desc->name, rc);
+
/* Send BFI */
goto bfi;
} else if (rc == GSM_MACBLOCK_LEN) {
/* Skip decoding of the next 2 stolen bursts */
lchan->dl_ongoing_facch = true;
- /* Calculate TDMA frame number of the first burst */
- lchan->rx_first_fn = sched_tchh_block_dl_first_fn(lchan->type,
- fn, true); /* FACCH/H */
-
/* Calculate AVG of the measurements (FACCH/H takes 6 bursts) */
sched_trx_meas_avg(lchan, 6);
@@ -326,10 +322,6 @@ int rx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts,
sched_trx_meas_avg(lchan, 4);
}
- /* Calculate TDMA frame number of the first burst */
- lchan->rx_first_fn = sched_tchh_block_dl_first_fn(lchan->type,
- fn, false); /* TCH/H */
-
/* Send a traffic frame to the higher layers */
return sched_send_dt_ind(trx, ts, lchan, l2, l2_len,
n_errors, false, true);
@@ -346,6 +338,7 @@ bfi:
/* Didn't try to decode, fake measurements */
if (n_errors < 0) {
lchan->meas_avg = (struct trx_meas_set) {
+ .fn = sched_tchh_block_dl_first_fn(lchan->type, fn, false),
.toa256 = 0,
.rssi = -110,
};
@@ -354,10 +347,6 @@ bfi:
n_errors = 0;
}
- /* Calculate TDMA frame number of the first burst */
- lchan->rx_first_fn = sched_tchh_block_dl_first_fn(lchan->type,
- fn, false); /* TCH/H */
-
/* BFI is not applicable in signalling mode */
if (lchan->tch_mode == GSM48_CMODE_SIGN)
return sched_send_dt_ind(trx, ts, lchan, NULL, 0,
diff --git a/src/host/trxcon/sched_lchan_xcch.c b/src/host/trxcon/sched_lchan_xcch.c
index aa8d4ddd..cc14d2f0 100644
--- a/src/host/trxcon/sched_lchan_xcch.c
+++ b/src/host/trxcon/sched_lchan_xcch.c
@@ -48,11 +48,9 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
uint8_t l2[GSM_MACBLOCK_LEN], *mask;
int n_errors, n_bits_total, rc;
sbit_t *buffer, *offset;
- uint32_t *first_fn;
/* Set up pointers */
lchan_desc = &trx_lchan_desc[lchan->type];
- first_fn = &lchan->rx_first_fn;
mask = &lchan->rx_burst_mask;
buffer = lchan->rx_bursts;
@@ -60,10 +58,8 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
lchan_desc->name, fn, ts->index, bid);
/* Reset internal state */
- if (bid == 0) {
- *first_fn = fn;
+ if (bid == 0)
*mask = 0x0;
- }
/* Update mask */
*mask |= (1 << bid);
@@ -87,8 +83,8 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
if ((*mask & 0xf) != 0xf) {
LOGP(DSCHD, LOGL_ERROR, "Received incomplete (%s) data frame at "
"fn=%u (%u/%u) for %s\n",
- burst_mask2str(mask, 4), *first_fn,
- (*first_fn) % ts->mf_layout->period,
+ burst_mask2str(mask, 4), lchan->meas_avg.fn,
+ lchan->meas_avg.fn % ts->mf_layout->period,
ts->mf_layout->period,
lchan_desc->name);
/* NOTE: xCCH has an insane amount of redundancy for error
@@ -101,8 +97,8 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
rc = gsm0503_xcch_decode(l2, buffer, &n_errors, &n_bits_total);
if (rc) {
LOGP(DSCHD, LOGL_ERROR, "Received bad data frame at fn=%u "
- "(%u/%u) for %s\n", *first_fn,
- (*first_fn) % ts->mf_layout->period,
+ "(%u/%u) for %s\n", lchan->meas_avg.fn,
+ lchan->meas_avg.fn % ts->mf_layout->period,
ts->mf_layout->period,
lchan_desc->name);
diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c
index 081e3ca8..e6e759a6 100644
--- a/src/host/trxcon/sched_trx.c
+++ b/src/host/trxcon/sched_trx.c
@@ -464,7 +464,6 @@ static void sched_trx_reset_lchan(struct trx_lchan_state *lchan)
/* Reset internal state variables */
lchan->rx_burst_mask = 0x00;
lchan->tx_burst_mask = 0x00;
- lchan->rx_first_fn = 0;
/* Free burst memory */
talloc_free(lchan->rx_bursts);
@@ -747,6 +746,10 @@ void sched_trx_meas_avg(struct trx_lchan_state *lchan, unsigned int n)
toa256_sum += meas->toa256;
rssi_sum += meas->rssi;
+ /* Do not go below the first burst */
+ if (i + 1 == n)
+ break;
+
if (meas == MEAS_HIST_FIRST(hist))
meas = MEAS_HIST_LAST(hist);
else
@@ -756,4 +759,7 @@ void sched_trx_meas_avg(struct trx_lchan_state *lchan, unsigned int n)
/* Calculate the AVG */
lchan->meas_avg.toa256 = toa256_sum / n;
lchan->meas_avg.rssi = rssi_sum / n;
+
+ /* As a bonus, store TDMA frame number of the first burst */
+ lchan->meas_avg.fn = meas->fn;
}
diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h
index a4fc90fe..44f502cd 100644
--- a/src/host/trxcon/sched_trx.h
+++ b/src/host/trxcon/sched_trx.h
@@ -159,6 +159,8 @@ struct trx_multiframe {
};
struct trx_meas_set {
+ /*! \brief TDMA frame number of the first burst this set belongs to */
+ uint32_t fn;
/*! \brief ToA256 (Timing of Arrival, 1/256 of a symbol) */
int16_t toa256;
/*! \brief RSSI (Received Signal Strength Indication) */
@@ -182,8 +184,6 @@ struct trx_lchan_state {
/*! \brief Burst type: GMSK or 8PSK */
enum trx_burst_type burst_type;
- /*! \brief Frame number of first burst */
- uint32_t rx_first_fn;
/*! \brief Mask of received bursts */
uint8_t rx_burst_mask;
/*! \brief Mask of transmitted bursts */
diff --git a/src/host/trxcon/trx_if.c b/src/host/trxcon/trx_if.c
index 343c6ca4..20c64ec1 100644
--- a/src/host/trxcon/trx_if.c
+++ b/src/host/trxcon/trx_if.c
@@ -600,6 +600,7 @@ static int trx_data_rx_cb(struct osmo_fd *ofd, unsigned int what)
meas = (struct trx_meas_set) {
.toa256 = toa256,
.rssi = rssi,
+ .fn = fn,
};
/* Poke scheduler */