From 2060b5b7cc3b63b64e651d3cda5ed50b44593a05 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Mon, 2 Mar 2020 02:55:01 +0700 Subject: [PATCH] trxcon/scheduler: refactor Downlink measurement processing So far we used to store the sums of ToA and RSSI measurements in the logical channel state, and after decoding of a block, we did calculate the average. This approach works fine for xCCH and PDTCH, but when it comes to block-diagonal interleaving (which is used on TCH/F and TCH/H channels), the results are incorrect. The problem is that a burst on TCH may carry 57 bits of one encoded frame and 57 bits of another. Instead of calculating the sum of measurements on the fly, let's push them into a circular buffer (the measurement history), and keep them there even after decoding of a block. This would allow us to calculate the average of N last measurements depending on the interleaving type. A single circular buffer can hold up to 8 unique measurements, so the recent measurements would basically override the oldest ones. Change-Id: I211ee3314f0a284112a4deddc0e93028f4a27cef --- src/host/trxcon/sched_lchan_common.c | 15 +++----- src/host/trxcon/sched_lchan_desc.c | 10 +++--- src/host/trxcon/sched_lchan_pdtch.c | 16 ++++----- src/host/trxcon/sched_lchan_sch.c | 4 +-- src/host/trxcon/sched_lchan_tchf.c | 25 ++++++++------ src/host/trxcon/sched_lchan_tchh.c | 34 +++++++++++-------- src/host/trxcon/sched_lchan_xcch.c | 16 ++++----- src/host/trxcon/sched_trx.c | 51 ++++++++++++++++++++++++++-- src/host/trxcon/sched_trx.h | 34 +++++++++++++------ src/host/trxcon/trx_if.c | 9 ++++- 10 files changed, 140 insertions(+), 74 deletions(-) diff --git a/src/host/trxcon/sched_lchan_common.c b/src/host/trxcon/sched_lchan_common.c index 813f31574..55ec7e959 100644 --- a/src/host/trxcon/sched_lchan_common.c +++ b/src/host/trxcon/sched_lchan_common.c @@ -126,9 +126,9 @@ int sched_send_dt_ind(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint8_t *l2, size_t l2_len, int bit_error_count, bool dec_failed, bool traffic) { + const struct trx_meas_set *meas = &lchan->meas_avg; const struct trx_lchan_desc *lchan_desc; struct l1ctl_info_dl dl_hdr; - int dbm_avg = 0; /* Set up pointers */ lchan_desc = &trx_lchan_desc[lchan->type]; @@ -140,15 +140,8 @@ int sched_send_dt_ind(struct trx_instance *trx, struct trx_ts *ts, dl_hdr.frame_nr = htonl(lchan->rx_first_fn); dl_hdr.num_biterr = bit_error_count; - /* Convert average RSSI to RX level */ - if (lchan->meas.num) { - /* RX level: 0 .. 63 in typical GSM notation (dBm + 110) */ - dbm_avg = lchan->meas.rssi_sum / lchan->meas.num; - dl_hdr.rx_level = dbm2rxlev(dbm_avg); - } else { - /* No measurements, assuming the worst */ - dl_hdr.rx_level = 0; - } + /* RX level: 0 .. 63 in typical GSM notation (dBm + 110) */ + dl_hdr.rx_level = dbm2rxlev(meas->rssi); /* FIXME: set proper values */ dl_hdr.snr = 0; @@ -162,7 +155,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, - trx->band_arfcn, dbm_avg, 0, l2, l2_len); + trx->band_arfcn, meas->rssi, 0, l2, l2_len); } return 0; diff --git a/src/host/trxcon/sched_lchan_desc.c b/src/host/trxcon/sched_lchan_desc.c index b22a18b81..1184e5be6 100644 --- a/src/host/trxcon/sched_lchan_desc.c +++ b/src/host/trxcon/sched_lchan_desc.c @@ -31,35 +31,35 @@ /* Forward declaration of handlers */ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, - sbit_t *bits, int8_t rssi, int16_t toa256); + sbit_t *bits, const struct trx_meas_set *meas); int tx_data_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid); int rx_sch_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, - sbit_t *bits, int8_t rssi, int16_t toa256); + sbit_t *bits, const struct trx_meas_set *meas); int tx_rach_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid); int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, - sbit_t *bits, int8_t rssi, int16_t toa256); + sbit_t *bits, const struct trx_meas_set *meas); int tx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid); int rx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, - sbit_t *bits, int8_t rssi, int16_t toa256); + sbit_t *bits, const struct trx_meas_set *meas); int tx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid); int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, - sbit_t *bits, int8_t rssi, int16_t toa256); + sbit_t *bits, const struct trx_meas_set *meas); int tx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid); diff --git a/src/host/trxcon/sched_lchan_pdtch.c b/src/host/trxcon/sched_lchan_pdtch.c index 83a6f53b8..4fd7d35d7 100644 --- a/src/host/trxcon/sched_lchan_pdtch.c +++ b/src/host/trxcon/sched_lchan_pdtch.c @@ -2,7 +2,7 @@ * OsmocomBB <-> SDR connection bridge * TDMA scheduler: handlers for DL / UL bursts on logical channels * - * (C) 2018 by Vadim Yanitskiy + * (C) 2018-2020 by Vadim Yanitskiy * * All Rights Reserved * @@ -42,7 +42,7 @@ int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, - sbit_t *bits, int8_t rssi, int16_t toa256) + sbit_t *bits, const struct trx_meas_set *meas) { const struct trx_lchan_desc *lchan_desc; uint8_t l2[GPRS_L2_MAX_LEN], *mask; @@ -62,9 +62,6 @@ int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts, /* Reset internal state */ if (bid == 0) { - /* Clean up old measurements */ - memset(&lchan->meas, 0x00, sizeof(lchan->meas)); - *first_fn = fn; *mask = 0x0; } @@ -72,10 +69,8 @@ int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts, /* Update mask */ *mask |= (1 << bid); - /* Update measurements */ - lchan->meas.toa256_sum += toa256; - lchan->meas.rssi_sum += rssi; - lchan->meas.num++; + /* Store the measurements */ + sched_trx_meas_push(lchan, meas); /* Copy burst to buffer of 4 bursts */ offset = buffer + bid * 116; @@ -86,6 +81,9 @@ int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts, if (bid != 3) return 0; + /* Calculate AVG of the measurements */ + sched_trx_meas_avg(lchan, 4); + /* Check for complete set of bursts */ if ((*mask & 0xf) != 0xf) { LOGP(DSCHD, LOGL_ERROR, "Received incomplete (%s) data frame at " diff --git a/src/host/trxcon/sched_lchan_sch.c b/src/host/trxcon/sched_lchan_sch.c index 9eed506bc..17f68b0bd 100644 --- a/src/host/trxcon/sched_lchan_sch.c +++ b/src/host/trxcon/sched_lchan_sch.c @@ -70,7 +70,7 @@ static void decode_sb(struct gsm_time *time, uint8_t *bsic, uint8_t *sb_info) int rx_sch_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, - sbit_t *bits, int8_t rssi, int16_t toa256) + sbit_t *bits, const struct trx_meas_set *meas) { sbit_t payload[2 * 39]; struct gsm_time time; @@ -117,7 +117,7 @@ int rx_sch_fn(struct trx_instance *trx, struct trx_ts *ts, data->link_id = trx_lchan_desc[lchan->type].link_id; data->band_arfcn = htons(trx->band_arfcn); data->frame_nr = htonl(fn); - data->rx_level = -rssi; + data->rx_level = -(meas->rssi); /* FIXME: set proper values */ data->num_biterr = 0; diff --git a/src/host/trxcon/sched_lchan_tchf.c b/src/host/trxcon/sched_lchan_tchf.c index 0109280b0..d2cf030ec 100644 --- a/src/host/trxcon/sched_lchan_tchf.c +++ b/src/host/trxcon/sched_lchan_tchf.c @@ -2,7 +2,7 @@ * OsmocomBB <-> SDR connection bridge * TDMA scheduler: handlers for DL / UL bursts on logical channels * - * (C) 2017 by Vadim Yanitskiy + * (C) 2017-2020 by Vadim Yanitskiy * * All Rights Reserved * @@ -44,7 +44,7 @@ int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, - sbit_t *bits, int8_t rssi, int16_t toa256) + sbit_t *bits, const struct trx_meas_set *meas) { const struct trx_lchan_desc *lchan_desc; int n_errors = -1, n_bits_total, rc; @@ -64,9 +64,6 @@ int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts, /* Reset internal state */ if (bid == 0) { - /* Clean up old measurements */ - memset(&lchan->meas, 0x00, sizeof(lchan->meas)); - *first_fn = fn; *mask = 0x00; } @@ -74,10 +71,8 @@ int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts, /* Update mask */ *mask |= (1 << bid); - /* Update mask and RSSI */ - lchan->meas.rssi_sum += rssi; - lchan->meas.toa256_sum += toa256; - lchan->meas.num++; + /* Store the measurements */ + sched_trx_meas_push(lchan, meas); /* Copy burst to end of buffer of 8 bursts */ offset = buffer + bid * 116 + 464; @@ -88,6 +83,9 @@ int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts, if (bid != 3) return 0; + /* Calculate AVG of the measurements */ + sched_trx_meas_avg(lchan, 8); + /* Check for complete set of bursts */ if ((*mask & 0xf) != 0xf) { LOGP(DSCHD, LOGL_ERROR, "Received incomplete (%s) traffic frame at " @@ -150,9 +148,14 @@ int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts, n_errors, false, true); bfi: - /* Didn't try to decode */ - if (n_errors < 0) + /* Didn't try to decode, fake measurements */ + if (n_errors < 0) { + lchan->meas_avg = (struct trx_meas_set) { + .toa256 = 0, + .rssi = -110, + }; n_errors = 116 * 4; + } /* BFI is not applicable in signalling mode */ if (lchan->tch_mode == GSM48_CMODE_SIGN) diff --git a/src/host/trxcon/sched_lchan_tchh.c b/src/host/trxcon/sched_lchan_tchh.c index 82886706e..599dd2046 100644 --- a/src/host/trxcon/sched_lchan_tchh.c +++ b/src/host/trxcon/sched_lchan_tchh.c @@ -2,7 +2,7 @@ * OsmocomBB <-> SDR connection bridge * TDMA scheduler: handlers for DL / UL bursts on logical channels * - * (C) 2018 by Vadim Yanitskiy + * (C) 2018-2020 by Vadim Yanitskiy * (C) 2018 by Harald Welte * * All Rights Reserved @@ -200,7 +200,7 @@ uint32_t sched_tchh_block_dl_first_fn(enum trx_lchan_type chan, int rx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, - sbit_t *bits, int8_t rssi, int16_t toa256) + sbit_t *bits, const struct trx_meas_set *meas) { const struct trx_lchan_desc *lchan_desc; int n_errors = -1, n_bits_total, rc; @@ -234,16 +234,8 @@ int rx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts, /* Update mask */ *mask |= (1 << bid); - /** - * FIXME: properly update measurements - * - * Since TCH/H channel is using block-diagonal interleaving, - * a single burst may carry 57 bits of one encoded frame, - * and 57 bits of another. This should be taken into account. - */ - lchan->meas.rssi_sum += rssi; - lchan->meas.toa256_sum += toa256; - lchan->meas.num++; + /* Store the measurements */ + sched_trx_meas_push(lchan, meas); /* Copy burst to the end of buffer of 6 bursts */ offset = buffer + bid * 116 + 464; @@ -303,6 +295,9 @@ int rx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts, "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); + /* Send BFI */ goto bfi; } else if (rc == GSM_MACBLOCK_LEN) { @@ -313,6 +308,9 @@ int rx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts, 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); + /* FACCH/H received, forward to the higher layers */ sched_send_dt_ind(trx, ts, lchan, l2, GSM_MACBLOCK_LEN, n_errors, false, false); @@ -322,6 +320,9 @@ int rx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts, } else { /* A good TCH frame received */ l2_len = rc; + + /* Calculate AVG of the measurements (traffic takes 4 bursts) */ + sched_trx_meas_avg(lchan, 4); } /* Calculate TDMA frame number of the first burst */ @@ -341,9 +342,14 @@ bfi_shift: *mask = *mask << 2; bfi: - /* Didn't try to decode */ - if (n_errors < 0) + /* Didn't try to decode, fake measurements */ + if (n_errors < 0) { + lchan->meas_avg = (struct trx_meas_set) { + .toa256 = 0, + .rssi = -110, + }; n_errors = 116 * 2; + } /* Calculate TDMA frame number of the first burst */ lchan->rx_first_fn = sched_tchh_block_dl_first_fn(lchan->type, diff --git a/src/host/trxcon/sched_lchan_xcch.c b/src/host/trxcon/sched_lchan_xcch.c index 34fe5ce8e..aa8d4ddd6 100644 --- a/src/host/trxcon/sched_lchan_xcch.c +++ b/src/host/trxcon/sched_lchan_xcch.c @@ -2,7 +2,7 @@ * OsmocomBB <-> SDR connection bridge * TDMA scheduler: handlers for DL / UL bursts on logical channels * - * (C) 2017 by Vadim Yanitskiy + * (C) 2017-2020 by Vadim Yanitskiy * * All Rights Reserved * @@ -42,7 +42,7 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, - sbit_t *bits, int8_t rssi, int16_t toa256) + sbit_t *bits, const struct trx_meas_set *meas) { const struct trx_lchan_desc *lchan_desc; uint8_t l2[GSM_MACBLOCK_LEN], *mask; @@ -61,9 +61,6 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts, /* Reset internal state */ if (bid == 0) { - /* Clean up old measurements */ - memset(&lchan->meas, 0x00, sizeof(lchan->meas)); - *first_fn = fn; *mask = 0x0; } @@ -71,10 +68,8 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts, /* Update mask */ *mask |= (1 << bid); - /* Update measurements */ - lchan->meas.rssi_sum += rssi; - lchan->meas.toa256_sum += toa256; - lchan->meas.num++; + /* Store the measurements */ + sched_trx_meas_push(lchan, meas); /* Copy burst to buffer of 4 bursts */ offset = buffer + bid * 116; @@ -85,6 +80,9 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts, if (bid != 3) return 0; + /* Calculate AVG of the measurements */ + sched_trx_meas_avg(lchan, 4); + /* Check for complete set of bursts */ if ((*mask & 0xf) != 0xf) { LOGP(DSCHD, LOGL_ERROR, "Received incomplete (%s) data frame at " diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c index b7914b621..081e3ca89 100644 --- a/src/host/trxcon/sched_trx.c +++ b/src/host/trxcon/sched_trx.c @@ -613,7 +613,7 @@ static void sched_trx_a5_burst_enc(struct trx_lchan_state *lchan, int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t tn, uint32_t burst_fn, sbit_t *bits, uint16_t nbits, - int8_t rssi, int16_t toa256) + const struct trx_meas_set *meas) { struct trx_lchan_state *lchan; const struct trx_frame *frame; @@ -674,7 +674,7 @@ int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t tn, sched_trx_a5_burst_dec(lchan, fn, bits); /* Put burst to handler */ - handler(trx, ts, lchan, fn, bid, bits, rssi, toa256); + handler(trx, ts, lchan, fn, bid, bits, meas); } next_frame: @@ -710,3 +710,50 @@ int sched_trx_handle_tx_burst(struct trx_instance *trx, return 0; } + +#define MEAS_HIST_FIRST(hist) \ + (&hist->buf[0]) +#define MEAS_HIST_LAST(hist) \ + (MEAS_HIST_FIRST(hist) + ARRAY_SIZE(hist->buf) - 1) + +/* Add a new set of measurements to the history */ +void sched_trx_meas_push(struct trx_lchan_state *lchan, const struct trx_meas_set *meas) +{ + struct trx_lchan_meas_hist *hist = &lchan->meas_hist; + + /* Find a new position where to store the measurements */ + if (hist->head == MEAS_HIST_LAST(hist) || hist->head == NULL) + hist->head = MEAS_HIST_FIRST(hist); + else + hist->head++; + + *hist->head = *meas; +} + +/* Calculate the AVG of n measurements from the history */ +void sched_trx_meas_avg(struct trx_lchan_state *lchan, unsigned int n) +{ + struct trx_lchan_meas_hist *hist = &lchan->meas_hist; + struct trx_meas_set *meas = hist->head; + int toa256_sum = 0; + int rssi_sum = 0; + int i; + + OSMO_ASSERT(n > 0 && n <= ARRAY_SIZE(hist->buf)); + OSMO_ASSERT(meas != NULL); + + /* Traverse backwards up to n entries, calculate the sum */ + for (i = 0; i < n; i++) { + toa256_sum += meas->toa256; + rssi_sum += meas->rssi; + + if (meas == MEAS_HIST_FIRST(hist)) + meas = MEAS_HIST_LAST(hist); + else + meas--; + } + + /* Calculate the AVG */ + lchan->meas_avg.toa256 = toa256_sum / n; + lchan->meas_avg.rssi = rssi_sum / n; +} diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h index 13fc678dc..a4fc90fe5 100644 --- a/src/host/trxcon/sched_trx.h +++ b/src/host/trxcon/sched_trx.h @@ -40,6 +40,7 @@ /* Forward declaration to avoid mutual include */ struct trx_lchan_state; +struct trx_meas_set; struct trx_instance; struct trx_ts; @@ -99,7 +100,7 @@ enum trx_lchan_type { typedef int trx_lchan_rx_func(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, sbit_t *bits, - int8_t rssi, int16_t toa256); + const struct trx_meas_set *meas); typedef int trx_lchan_tx_func(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, @@ -157,6 +158,19 @@ struct trx_multiframe { const struct trx_frame *frames; }; +struct trx_meas_set { + /*! \brief ToA256 (Timing of Arrival, 1/256 of a symbol) */ + int16_t toa256; + /*! \brief RSSI (Received Signal Strength Indication) */ + int8_t rssi; +}; + +/* Simple ring buffer (up to 8 unique measurements) */ +struct trx_lchan_meas_hist { + struct trx_meas_set buf[8]; + struct trx_meas_set *head; +}; + /* States each channel on a multiframe */ struct trx_lchan_state { /*! \brief Channel type */ @@ -190,14 +204,10 @@ struct trx_lchan_state { /*! \brief pending FACCH/H blocks on Uplink */ uint8_t ul_facch_blocks; - struct { - /*! \brief Number of measurements */ - unsigned int num; - /*! \brief Sum of RSSI values */ - float rssi_sum; - /*! \brief Sum of TOA values */ - int32_t toa256_sum; - } meas; + /*! \brief Downlink measurements history */ + struct trx_lchan_meas_hist meas_hist; + /*! \brief AVG measurements of the last received block */ + struct trx_meas_set meas_avg; /*! \brief SACCH state */ struct { @@ -347,7 +357,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, - int8_t rssi, int16_t toa256); + 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, uint32_t fn, ubit_t *bits); @@ -381,3 +391,7 @@ bool sched_tchh_block_map_fn(enum trx_lchan_type chan, sched_tchh_block_map_fn(chan, fn, ul, 1, 1) #define sched_tchh_facch_end(chan, fn, ul) \ sched_tchh_block_map_fn(chan, fn, ul, 1, 0) + +/* Measurement history */ +void sched_trx_meas_push(struct trx_lchan_state *lchan, const struct trx_meas_set *meas); +void sched_trx_meas_avg(struct trx_lchan_state *lchan, unsigned int n); diff --git a/src/host/trxcon/trx_if.c b/src/host/trxcon/trx_if.c index 55d70341b..343c6ca41 100644 --- a/src/host/trxcon/trx_if.c +++ b/src/host/trxcon/trx_if.c @@ -555,6 +555,7 @@ rsp_error: static int trx_data_rx_cb(struct osmo_fd *ofd, unsigned int what) { struct trx_instance *trx = ofd->data; + struct trx_meas_set meas; uint8_t buf[256]; sbit_t bits[148]; int8_t rssi, tn; @@ -595,8 +596,14 @@ static int trx_data_rx_cb(struct osmo_fd *ofd, unsigned int what) LOGP(DTRXD, LOGL_DEBUG, "RX burst tn=%u fn=%u rssi=%d toa=%d\n", tn, fn, rssi, toa256); + /* Group the measurements together */ + meas = (struct trx_meas_set) { + .toa256 = toa256, + .rssi = rssi, + }; + /* Poke scheduler */ - sched_trx_handle_rx_burst(trx, tn, fn, bits, 148, rssi, toa256); + sched_trx_handle_rx_burst(trx, tn, fn, bits, 148, &meas); /* Correct local clock counter */ if (fn % 51 == 0)