aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Chemeris <Alexander.Chemeris@gmail.com>2015-06-10 00:45:08 -0400
committerAlexander Chemeris <Alexander.Chemeris@gmail.com>2015-07-20 20:09:44 -0400
commitadf26f69751480e3bc0c1e8895188509bd5bd518 (patch)
treef25788ada052e94ff178e91f762d66f8e252bf94
parentceaf0616d22a764738e76daf9684a0cf846c8745 (diff)
trx: Process undecodable frames coming from osmo-trx.
The purpose is to support RSSI measurements even when we can't decode a burst. This commit also cleans up and abstracts some of the code in scheduler.c
-rw-r--r--src/osmo-bts-trx/l1_if.h1
-rw-r--r--src/osmo-bts-trx/loops.c5
-rw-r--r--src/osmo-bts-trx/loops.h2
-rw-r--r--src/osmo-bts-trx/scheduler.c255
-rw-r--r--src/osmo-bts-trx/scheduler.h6
-rw-r--r--src/osmo-bts-trx/trx_if.c3
6 files changed, 180 insertions, 92 deletions
diff --git a/src/osmo-bts-trx/l1_if.h b/src/osmo-bts-trx/l1_if.h
index 278537e1..cc853184 100644
--- a/src/osmo-bts-trx/l1_if.h
+++ b/src/osmo-bts-trx/l1_if.h
@@ -60,6 +60,7 @@ struct trx_chan_state {
float rssi_sum; /* sum of RSSI values */
uint8_t toa_num; /* number of TOA values */
float toa_sum; /* sum of TOA values */
+ float last_toa; /* last valid TOA */
/* loss detection */
uint8_t lost; /* (SACCH) loss detection */
diff --git a/src/osmo-bts-trx/loops.c b/src/osmo-bts-trx/loops.c
index fa380555..661519ae 100644
--- a/src/osmo-bts-trx/loops.c
+++ b/src/osmo-bts-trx/loops.c
@@ -211,7 +211,7 @@ int ta_val(struct trx_l1h *l1h, struct gsm_lchan *lchan, uint8_t chan_nr,
}
int trx_loop_sacch_input(struct trx_l1h *l1h, uint8_t chan_nr,
- struct trx_chan_state *chan_state, int8_t rssi, float toa)
+ struct trx_chan_state *chan_state, int8_t rssi, float toa, int bad_burst)
{
struct gsm_lchan *lchan = &l1h->trx->ts[L1SAP_CHAN2TS(chan_nr)]
.lchan[l1sap_chan2ss(chan_nr)];
@@ -219,7 +219,8 @@ int trx_loop_sacch_input(struct trx_l1h *l1h, uint8_t chan_nr,
if (trx_ms_power_loop)
ms_power_val(chan_state, rssi);
- if (trx_ta_loop)
+ /* TOA is only valid for good frames, ignore if bad_burst */
+ if (trx_ta_loop && !bad_burst)
ta_val(l1h, lchan, chan_nr, chan_state, toa);
return 0;
diff --git a/src/osmo-bts-trx/loops.h b/src/osmo-bts-trx/loops.h
index 27b0ef23..2f855983 100644
--- a/src/osmo-bts-trx/loops.h
+++ b/src/osmo-bts-trx/loops.h
@@ -18,7 +18,7 @@ extern int8_t trx_target_rssi;
extern int trx_ta_loop;
int trx_loop_sacch_input(struct trx_l1h *l1h, uint8_t chan_nr,
- struct trx_chan_state *chan_state, int8_t rssi, float toa);
+ struct trx_chan_state *chan_state, int8_t rssi, float toa, int bad_burst);
int trx_loop_sacch_clock(struct trx_l1h *l1h, uint8_t chan_nr,
struct trx_chan_state *chan_state);
diff --git a/src/osmo-bts-trx/scheduler.c b/src/osmo-bts-trx/scheduler.c
index 8d0c8343..b44a1573 100644
--- a/src/osmo-bts-trx/scheduler.c
+++ b/src/osmo-bts-trx/scheduler.c
@@ -71,7 +71,7 @@ typedef ubit_t *trx_sched_dl_func(struct trx_l1h *l1h, uint8_t tn,
uint32_t fn, enum trx_chan_type chan, uint8_t bid);
typedef int trx_sched_ul_func(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
- float toa);
+ float toa, int bad_burst);
static int rts_data_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan);
@@ -95,19 +95,19 @@ static ubit_t *tx_tchh_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid);
static int rx_rach_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
- float toa);
+ float toa, int bad_burst);
static int rx_data_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
- float toa);
+ float toa, int bad_burst);
static int rx_pdtch_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
- float toa);
+ float toa, int bad_burst);
static int rx_tchf_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
- float toa);
+ float toa, int bad_burst);
static int rx_tchh_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
- float toa);
+ float toa, int bad_burst);
static ubit_t dummy_burst[148] = {
0,0,0,
@@ -222,6 +222,7 @@ int trx_sched_init(struct trx_l1h *l1h)
for (i = 0; i < _TRX_CHAN_MAX; i++) {
chan_state = &l1h->chan_states[tn][i];
chan_state->active = 0;
+ chan_state->last_toa = 0.0;
}
}
@@ -665,6 +666,8 @@ got_msg:
if (++(l1h->chan_states[tn][chan].lost) > 1) {
/* TODO: Should we pass old TOA here? Otherwise we risk
* unnecessary decreasing TA */
+ /* TODO: Why is this here? How is uplink measurement related
+ * to downlink messages? */
/* Send uplnk measurement information to L2 */
l1if_process_meas_res(l1h->trx, tn, fn, trx_chan_desc[chan].chan_nr | tn,
@@ -1171,15 +1174,77 @@ send_burst:
* RX on uplink (indication to upper layer)
*/
+/* Update UL channel state - mask, RSSI and TOA */
+static void rx_update_chan_state(struct trx_chan_state *chan_state, uint8_t bid,
+ int8_t rssi, float toa, int bad_burst)
+{
+ uint8_t *mask = &chan_state->ul_mask;
+ float *rssi_sum = &chan_state->rssi_sum;
+ uint8_t *rssi_num = &chan_state->rssi_num;
+ float *toa_sum = &chan_state->toa_sum;
+ uint8_t *toa_num = &chan_state->toa_num;
+ float *last_toa = &chan_state->last_toa;
+
+ /* clear burst */
+ if (bid == 0) {
+ *mask = 0x0;
+ *rssi_sum = 0;
+ *rssi_num = 0;
+ *toa_sum = 0;
+ *toa_num = 0;
+ }
+
+ /* update rssi average */
+ *rssi_sum += rssi;
+ (*rssi_num)++;
+
+ /* TOA and bits are valid only if it's a good frame */
+ if (bad_burst == IND_GOOD_BURST) {
+ /* update mask */
+ *mask |= (1 << bid);
+
+ /* update TOA average */
+ *toa_sum += toa;
+ (*toa_num)++;
+
+ /* update last valid TOA */
+ *last_toa = *toa_sum / *toa_num;
+ }
+}
+
+/* Return RSSI average */
+static float rx_chan_rssi_avg(struct trx_chan_state *chan_state)
+{
+ /* this function must be called after we have received at least
+ * one burst, no matter good or bad */
+ OSMO_ASSERT(chan_state->rssi_num > 0);
+ return chan_state->rssi_sum / chan_state->rssi_num;
+}
+
+/* Return TOA average */
+static float rx_chan_toa_avg(struct trx_chan_state *chan_state)
+{
+ if (chan_state->toa_num == 0) {
+ return chan_state->last_toa;
+ } else {
+ return chan_state->toa_sum / chan_state->toa_num;
+ }
+}
+
static int rx_rach_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
- float toa)
+ float toa, int bad_burst)
{
uint8_t chan_nr;
struct osmo_phsap_prim l1sap;
uint8_t ra;
int rc;
+ /* Ignore bad bursts on RACH channels */
+ if (bad_burst != IND_GOOD_BURST) {
+ return 0;
+ }
+
chan_nr = trx_chan_desc[chan].chan_nr | tn;
LOGP(DL1C, LOGL_NOTICE, "Received Access Burst on %s fn=%u toa=%.2f\n",
@@ -1215,27 +1280,25 @@ static int rx_rach_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
static int rx_data_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
- float toa)
+ float toa, int bad_burst)
{
struct trx_chan_state *chan_state = &l1h->chan_states[tn][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;
- float *rssi_sum = &chan_state->rssi_sum;
- uint8_t *rssi_num = &chan_state->rssi_num;
- float *toa_sum = &chan_state->toa_sum;
- uint8_t *toa_num = &chan_state->toa_num;
uint8_t l2[23], l2_len;
int n_errors, n_bits_total;
int rc;
/* handle rach, if handover rach detection is turned on */
if (chan_state->ho_rach_detect == 1)
- return rx_rach_fn(l1h, tn, fn, chan, bid, bits, rssi, toa);
+ return rx_rach_fn(l1h, tn, fn, chan, bid, bits, rssi, toa, bad_burst);
LOGP(DL1C, LOGL_DEBUG, "Data received %s fn=%u ts=%u trx=%u bid=%u\n",
trx_chan_desc[chan].name, fn, tn, l1h->trx->nr, bid);
+ rx_update_chan_state(chan_state, bid, rssi, toa, bad_burst);
+
/* alloc burst memory, if not already */
if (!*bursts_p) {
*bursts_p = talloc_zero_size(tall_bts_ctx, 464);
@@ -1246,36 +1309,36 @@ static int rx_data_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
/* clear burst & store frame number of first burst */
if (bid == 0) {
memset(*bursts_p, 0, 464);
- *mask = 0x0;
- *first_fn = fn;
- *rssi_sum = 0;
- *rssi_num = 0;
- *toa_sum = 0;
- *toa_num = 0;
}
- /* update mask + rssi */
- *mask |= (1 << bid);
- *rssi_sum += rssi;
- (*rssi_num)++;
- *toa_sum += toa;
- (*toa_num)++;
-
- /* copy burst to buffer of 4 bursts */
- burst = *bursts_p + bid * 116;
- memcpy(burst, bits + 3, 58);
- memcpy(burst + 58, bits + 87, 58);
+ /* TOA and bits are valid only if it's a good frame */
+ if (bad_burst == IND_GOOD_BURST) {
+ /* copy burst to buffer of 4 bursts */
+ burst = *bursts_p + bid * 116;
+ memcpy(burst, bits + 3, 58);
+ memcpy(burst + 58, bits + 87, 58);
+ }
/* send burst information to loops process */
if (L1SAP_IS_LINK_SACCH(trx_chan_desc[chan].link_id)) {
trx_loop_sacch_input(l1h, trx_chan_desc[chan].chan_nr | tn,
- chan_state, rssi, toa);
+ chan_state, rssi, toa, bad_burst);
}
/* wait until complete set of bursts */
if (bid != 3)
return 0;
+ /* check if we received anything at all */
+ if ((*mask & 0xf) == 0x0) {
+ /* Send uplnk measurement information to L2 */
+ /* Indicate real RSSI, 100% BER, last valid TOA */
+ l1if_process_meas_res(l1h->trx, tn, fn, trx_chan_desc[chan].chan_nr | tn,
+ 0, 0,
+ rx_chan_rssi_avg(chan_state), rx_chan_toa_avg(chan_state));
+ return 0;
+ }
+
/* check for complete set of bursts */
if ((*mask & 0xf) != 0xf) {
LOGP(DL1C, LOGL_NOTICE, "Received incomplete data frame at "
@@ -1304,22 +1367,20 @@ static int rx_data_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
/* Send uplnk measurement information to L2 */
l1if_process_meas_res(l1h->trx, tn, fn, trx_chan_desc[chan].chan_nr | tn,
- n_errors, n_bits_total, *rssi_sum / *rssi_num, *toa_sum / *toa_num);
+ n_errors, n_bits_total,
+ rx_chan_rssi_avg(chan_state), rx_chan_toa_avg(chan_state));
- return compose_ph_data_ind(l1h, tn, *first_fn, chan, l2, l2_len, *rssi_sum / *rssi_num);
+ return compose_ph_data_ind(l1h, tn, *first_fn, chan, l2, l2_len,
+ rx_chan_rssi_avg(chan_state));
}
static int rx_pdtch_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
- float toa)
+ float toa, int bad_burst)
{
struct trx_chan_state *chan_state = &l1h->chan_states[tn][chan];
sbit_t *burst, **bursts_p = &chan_state->ul_bursts;
uint8_t *mask = &chan_state->ul_mask;
- float *rssi_sum = &chan_state->rssi_sum;
- uint8_t *rssi_num = &chan_state->rssi_num;
- float *toa_sum = &chan_state->toa_sum;
- uint8_t *toa_num = &chan_state->toa_num;
uint8_t l2[54+1];
int n_errors, n_bits_total;
int rc;
@@ -1327,6 +1388,8 @@ static int rx_pdtch_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
LOGP(DL1C, LOGL_DEBUG, "PDTCH received %s fn=%u ts=%u trx=%u bid=%u\n",
trx_chan_desc[chan].name, fn, tn, l1h->trx->nr, bid);
+ rx_update_chan_state(chan_state, bid, rssi, toa, bad_burst);
+
/* alloc burst memory, if not already */
if (!*bursts_p) {
*bursts_p = talloc_zero_size(tall_bts_ctx, 464);
@@ -1337,29 +1400,30 @@ static int rx_pdtch_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
/* clear burst */
if (bid == 0) {
memset(*bursts_p, 0, 464);
- *mask = 0x0;
- *rssi_sum = 0;
- *rssi_num = 0;
- *toa_sum = 0;
- *toa_num = 0;
}
- /* update mask + rssi */
- *mask |= (1 << bid);
- *rssi_sum += rssi;
- (*rssi_num)++;
- *toa_sum += toa;
- (*toa_num)++;
-
- /* copy burst to buffer of 4 bursts */
- burst = *bursts_p + bid * 116;
- memcpy(burst, bits + 3, 58);
- memcpy(burst + 58, bits + 87, 58);
+ /* TOA and bits are valid only if it's a good frame */
+ if (bad_burst == IND_GOOD_BURST) {
+ /* copy burst to buffer of 4 bursts */
+ burst = *bursts_p + bid * 116;
+ memcpy(burst, bits + 3, 58);
+ memcpy(burst + 58, bits + 87, 58);
+ }
/* wait until complete set of bursts */
if (bid != 3)
return 0;
+ /* check if we received anything at all */
+ if ((*mask & 0xf) == 0x0) {
+ /* Send uplnk measurement information to L2 */
+ /* Indicate real RSSI, 100% BER, last valid TOA */
+ l1if_process_meas_res(l1h->trx, tn, fn, trx_chan_desc[chan].chan_nr | tn,
+ 0, 0,
+ rx_chan_rssi_avg(chan_state), rx_chan_toa_avg(chan_state));
+ return 0;
+ }
+
/* check for complete set of bursts */
if ((*mask & 0xf) != 0xf) {
LOGP(DL1C, LOGL_NOTICE, "Received incomplete PDTCH block "
@@ -1374,7 +1438,8 @@ static int rx_pdtch_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
/* Send uplnk measurement information to L2 */
l1if_process_meas_res(l1h->trx, tn, fn, trx_chan_desc[chan].chan_nr | tn,
- n_errors, n_bits_total, *rssi_sum / *rssi_num, *toa_sum / *toa_num);
+ n_errors, n_bits_total,
+ rx_chan_rssi_avg(chan_state), rx_chan_toa_avg(chan_state));
if (rc <= 0) {
LOGP(DL1C, LOGL_NOTICE, "Received bad PDTCH block ending at "
@@ -1386,12 +1451,12 @@ static int rx_pdtch_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
l2[0] = 7; /* valid frame */
return compose_ph_data_ind(l1h, tn, (fn + 2715648 - 3) % 2715648, chan,
- l2, rc + 1, *rssi_sum / *rssi_num);
+ l2, rc + 1, rx_chan_rssi_avg(chan_state));
}
static int rx_tchf_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
- float toa)
+ float toa, int bad_burst)
{
struct trx_chan_state *chan_state = &l1h->chan_states[tn][chan];
sbit_t *burst, **bursts_p = &chan_state->ul_bursts;
@@ -1404,11 +1469,13 @@ static int rx_tchf_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
/* handle rach, if handover rach detection is turned on */
if (chan_state->ho_rach_detect == 1)
- return rx_rach_fn(l1h, tn, fn, chan, bid, bits, rssi, toa);
+ return rx_rach_fn(l1h, tn, fn, chan, bid, bits, rssi, toa, bad_burst);
LOGP(DL1C, LOGL_DEBUG, "TCH/F received %s fn=%u ts=%u trx=%u bid=%u\n",
trx_chan_desc[chan].name, fn, tn, l1h->trx->nr, bid);
+ rx_update_chan_state(chan_state, bid, rssi, toa, bad_burst);
+
/* alloc burst memory, if not already */
if (!*bursts_p) {
*bursts_p = talloc_zero_size(tall_bts_ctx, 928);
@@ -1419,21 +1486,29 @@ static int rx_tchf_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
/* clear burst */
if (bid == 0) {
memset(*bursts_p + 464, 0, 464);
- *mask = 0x0;
}
- /* update mask */
- *mask |= (1 << bid);
-
- /* copy burst to end of buffer of 8 bursts */
- burst = *bursts_p + bid * 116 + 464;
- memcpy(burst, bits + 3, 58);
- memcpy(burst + 58, bits + 87, 58);
+ if (bad_burst == IND_GOOD_BURST) {
+ /* copy burst to end of buffer of 8 bursts */
+ burst = *bursts_p + bid * 116 + 464;
+ memcpy(burst, bits + 3, 58);
+ memcpy(burst + 58, bits + 87, 58);
+ }
/* wait until complete set of bursts */
if (bid != 3)
return 0;
+ /* check if we received anything at all */
+ if ((*mask & 0xf) == 0x0) {
+ /* Send uplnk measurement information to L2 */
+ /* Indicate real RSSI, 100% BER, last valid TOA */
+ l1if_process_meas_res(l1h->trx, tn, fn, trx_chan_desc[chan].chan_nr | tn,
+ 0, 0,
+ rx_chan_rssi_avg(chan_state), rx_chan_toa_avg(chan_state));
+ return 0;
+ }
+
/* check for complete set of bursts */
if ((*mask & 0xf) != 0xf) {
LOGP(DL1C, LOGL_NOTICE, "Received incomplete TCH frame ending "
@@ -1483,7 +1558,8 @@ static int rx_tchf_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
/* Send uplnk measurement information to L2 */
l1if_process_meas_res(l1h->trx, tn, fn, trx_chan_desc[chan].chan_nr|tn,
- n_errors, n_bits_total, rssi, toa);
+ n_errors, n_bits_total,
+ rx_chan_rssi_avg(chan_state), rx_chan_toa_avg(chan_state));
/* Check if the frame is bad */
if (rc < 0) {
@@ -1501,7 +1577,7 @@ static int rx_tchf_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
/* FACCH */
if (rc == 23) {
compose_ph_data_ind(l1h, tn, (fn + 2715648 - 7) % 2715648, chan,
- tch_data + amr, 23, rssi);
+ tch_data + amr, 23, rx_chan_rssi_avg(chan_state));
bfi:
if (rsl_cmode == RSL_CMOD_SPD_SPEECH) {
/* indicate bad frame */
@@ -1541,7 +1617,7 @@ bfi:
static int rx_tchh_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi,
- float toa)
+ float toa, int bad_burst)
{
struct trx_chan_state *chan_state = &l1h->chan_states[tn][chan];
sbit_t *burst, **bursts_p = &chan_state->ul_bursts;
@@ -1554,11 +1630,13 @@ static int rx_tchh_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
/* handle rach, if handover rach detection is turned on */
if (chan_state->ho_rach_detect == 1)
- return rx_rach_fn(l1h, tn, fn, chan, bid, bits, rssi, toa);
+ return rx_rach_fn(l1h, tn, fn, chan, bid, bits, rssi, toa, bad_burst);
LOGP(DL1C, LOGL_DEBUG, "TCH/H received %s fn=%u ts=%u trx=%u bid=%u\n",
trx_chan_desc[chan].name, fn, tn, l1h->trx->nr, bid);
+ rx_update_chan_state(chan_state, bid, rssi, toa, bad_burst);
+
/* alloc burst memory, if not already */
if (!*bursts_p) {
*bursts_p = talloc_zero_size(tall_bts_ctx, 696);
@@ -1569,12 +1647,8 @@ static int rx_tchh_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
/* clear burst */
if (bid == 0) {
memset(*bursts_p + 464, 0, 232);
- *mask = 0x0;
}
- /* update mask */
- *mask |= (1 << bid);
-
/* copy burst to end of buffer of 6 bursts */
burst = *bursts_p + bid * 116 + 464;
memcpy(burst, bits + 3, 58);
@@ -1584,6 +1658,16 @@ static int rx_tchh_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
if (bid != 1)
return 0;
+ /* check if we received anything at all */
+ if ((*mask & 0xf) == 0x0) {
+ /* Send uplnk measurement information to L2 */
+ /* Indicate real RSSI, 100% BER, last valid TOA */
+ l1if_process_meas_res(l1h->trx, tn, fn, trx_chan_desc[chan].chan_nr | tn,
+ 0, 0,
+ rx_chan_rssi_avg(chan_state), rx_chan_toa_avg(chan_state));
+ return 0;
+ }
+
/* check for complete set of bursts */
if ((*mask & 0x3) != 0x3) {
LOGP(DL1C, LOGL_NOTICE, "Received incomplete TCH frame ending "
@@ -1646,7 +1730,8 @@ static int rx_tchh_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
/* Send uplnk measurement information to L2 */
l1if_process_meas_res(l1h->trx, tn, fn, trx_chan_desc[chan].chan_nr|tn,
- n_errors, n_bits_total, rssi, toa);
+ n_errors, n_bits_total,
+ rx_chan_rssi_avg(chan_state), rx_chan_toa_avg(chan_state));
/* Check if the frame is bad */
if (rc < 0) {
@@ -1666,7 +1751,7 @@ static int rx_tchh_fn(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
chan_state->ul_ongoing_facch = 1;
compose_ph_data_ind(l1h, tn,
(fn + 2715648 - 10 - ((fn % 26) >= 19)) % 2715648, chan,
- tch_data + amr, 23, rssi);
+ tch_data + amr, 23, rx_chan_rssi_avg(chan_state));
bfi:
if (rsl_cmode == RSL_CMOD_SPD_SPEECH) {
/* indicate bad frame */
@@ -2746,7 +2831,7 @@ if (0) if (chan != TRXC_IDLE) // hack
/* process uplink burst */
int trx_sched_ul_burst(struct trx_l1h *l1h, uint8_t tn, uint32_t current_fn,
- sbit_t *bits, int8_t rssi, float toa)
+ sbit_t *bits, int8_t rssi, float toa, int bad_burst)
{
struct trx_sched_frame *frame;
uint8_t offset, period, bid;
@@ -2768,6 +2853,8 @@ int trx_sched_ul_burst(struct trx_l1h *l1h, uint8_t tn, uint32_t current_fn,
fn = current_fn;
while (42) {
+ int cur_bad_burst = (fn != current_fn) || bad_burst;
+
/* get frame from multiframe */
period = l1h->mf_period[tn];
offset = fn % period;
@@ -2786,8 +2873,8 @@ int trx_sched_ul_burst(struct trx_l1h *l1h, uint8_t tn, uint32_t current_fn,
if (!func)
goto next_frame;
- /* put burst to function */
- if (fn == current_fn) {
+ /* put burst to function if it's a valid burst */
+ if (!cur_bad_burst) {
/* decrypt */
if (bits && l1h->chan_states[tn][chan].ul_encr_algo) {
ubit_t ks[114];
@@ -2803,15 +2890,9 @@ int trx_sched_ul_burst(struct trx_l1h *l1h, uint8_t tn, uint32_t current_fn,
bits[i + 88] = - bits[i + 88];
}
}
-
- func(l1h, tn, fn, chan, bid, bits, rssi, toa);
- } else if (chan != TRXC_RACH
- && !l1h->chan_states[tn][chan].ho_rach_detect) {
- sbit_t spare[148];
-
- memset(spare, 0, 148);
- func(l1h, tn, fn, chan, bid, spare, -128, 0);
}
+ /* send burst to the upper layer */
+ func(l1h, tn, fn, chan, bid, bits, rssi, toa, cur_bad_burst);
next_frame:
/* reached current fn */
diff --git a/src/osmo-bts-trx/scheduler.h b/src/osmo-bts-trx/scheduler.h
index ce7ddad8..928f0c62 100644
--- a/src/osmo-bts-trx/scheduler.h
+++ b/src/osmo-bts-trx/scheduler.h
@@ -16,8 +16,12 @@ int trx_sched_tch_req(struct trx_l1h *l1h, struct osmo_phsap_prim *l1sap);
int trx_sched_clock(uint32_t fn);
+/* Defines for the "bad_burst" parameter */
+#define IND_GOOD_BURST 0
+#define IND_BAD_BURST 1
+
int trx_sched_ul_burst(struct trx_l1h *l1h, uint8_t tn, uint32_t fn,
- sbit_t *bits, int8_t rssi, float toa);
+ sbit_t *bits, int8_t rssi, float toa, int bad_burst);
/* set multiframe scheduler to given pchan */
int trx_sched_set_pchan(struct trx_l1h *l1h, uint8_t tn,
diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c
index 69ad8415..d572557a 100644
--- a/src/osmo-bts-trx/trx_if.c
+++ b/src/osmo-bts-trx/trx_if.c
@@ -411,6 +411,7 @@ static int trx_data_read_cb(struct osmo_fd *ofd, unsigned int what)
uint32_t fn;
sbit_t bits[148];
int i;
+ int bad_burst = IND_GOOD_BURST;
len = recv(ofd->fd, buf, sizeof(buf), 0);
if (len <= 0)
@@ -454,7 +455,7 @@ static int trx_data_read_cb(struct osmo_fd *ofd, unsigned int what)
fprintf(stderr, "%s\n", deb);
#endif
- trx_sched_ul_burst(l1h, tn, fn, bits, rssi, toa);
+ trx_sched_ul_burst(l1h, tn, fn, bits, rssi, toa, bad_burst);
return 0;
}