diff options
author | Alexander Chemeris <Alexander.Chemeris@gmail.com> | 2015-06-10 00:45:08 -0400 |
---|---|---|
committer | Alexander Chemeris <Alexander.Chemeris@gmail.com> | 2015-07-20 20:09:44 -0400 |
commit | adf26f69751480e3bc0c1e8895188509bd5bd518 (patch) | |
tree | f25788ada052e94ff178e91f762d66f8e252bf94 | |
parent | ceaf0616d22a764738e76daf9684a0cf846c8745 (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.h | 1 | ||||
-rw-r--r-- | src/osmo-bts-trx/loops.c | 5 | ||||
-rw-r--r-- | src/osmo-bts-trx/loops.h | 2 | ||||
-rw-r--r-- | src/osmo-bts-trx/scheduler.c | 255 | ||||
-rw-r--r-- | src/osmo-bts-trx/scheduler.h | 6 | ||||
-rw-r--r-- | src/osmo-bts-trx/trx_if.c | 3 |
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; } |