diff --git a/src/host/trxcon/sched_lchan_common.c b/src/host/trxcon/sched_lchan_common.c index 55ec7e959..ae43ca94a 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 4fd7d35d7..b625d2f7a 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 6531e11c1..595101f50 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 e7037fe52..f82299399 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 aa8d4ddd6..cc14d2f0c 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 081e3ca89..e6e759a68 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 a4fc90fe5..44f502cd2 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 343c6ca41..20c64ec12 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 */