aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2019-11-22 14:00:19 +0100
committerPhilipp Maier <pmaier@sysmocom.de>2020-01-03 12:56:00 +0100
commit66c17cfc2d5d2a68de0484562cef46d142dd2f4b (patch)
treea40ffeedf88785f0699e212971f020e558d2bb6d
parenta2392f0f9e07e6220c943b458360f1fddc1528b6 (diff)
rsl: ensure measurement reports are sent
osmo-bts currently does not generate a measurement report in case the SACCH of the related traffic channel is lost. This is a problem because the moment when reception gets bad measurmenet reporting is crucial to carry out handover decisions effectively. The presence of a SACCH block controls the conclusion of the measurement interval and the sending of the RSL measurement report. The latter one not only requires a measurmenet indication, it also requires a fully intact SACCH block. Lets use the NOPE / IDLE indications from V1 of the TRXD protocol to ensure a SACCH block is always reported up to l1sap.c. In cases where the SACCH is bad, trigger the sending of the RSL measurement report manually without attaching the measurmenet data from the MS (which we do not have in this case) Related: OS#2975 Depends: osmo-ttcn3-hacks Ib2f511991349ab15e02db9c5e45f0df3645835a4 Change-Id: Idfa8ef94e8cf131ff234dac8f93f337051663ae2
-rw-r--r--include/osmo-bts/rsl.h2
-rw-r--r--src/common/l1sap.c11
-rw-r--r--src/common/rsl.c11
-rw-r--r--src/common/scheduler.c15
-rw-r--r--src/osmo-bts-trx/scheduler_trx.c10
5 files changed, 41 insertions, 8 deletions
diff --git a/include/osmo-bts/rsl.h b/include/osmo-bts/rsl.h
index 186018eb..ff6c2a86 100644
--- a/include/osmo-bts/rsl.h
+++ b/include/osmo-bts/rsl.h
@@ -45,4 +45,6 @@ void ipacc_dyn_pdch_complete(struct gsm_bts_trx_ts *ts, int rc);
int rsl_tx_cbch_load_indication(struct gsm_bts *bts, bool ext_cbch, bool overflow, uint8_t amount);
+int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const struct lapdm_entity *le);
+
#endif // _RSL_H */
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index b6e21faf..49302573 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -1238,8 +1238,17 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
/* bad frame */
if (len == 0) {
- if (L1SAP_IS_LINK_SACCH(link_id))
+ if (L1SAP_IS_LINK_SACCH(link_id)) {
+ /* In case we loose a SACCH block, we must take care
+ * that the related measurement report is sent via RSL.
+ * This is a fallback method. The report will also
+ * lack the measurement report from the MS side. See
+ * also rsl.c:lapdm_rll_tx_cb() */
+ le = &lchan->lapdm_ch.lapdm_acch;
+ rsl_tx_meas_res(lchan, NULL, 0, le);
+
radio_link_timeout(lchan, 1);
+ }
return -EINVAL;
}
diff --git a/src/common/rsl.c b/src/common/rsl.c
index b315d30f..d7e35654 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -2834,8 +2834,8 @@ struct osmo_bts_supp_meas_info {
uint16_t toa256_std_dev;
} __attribute__((packed));
-/* 8.4.8 MEASUREMENT RESult */
-static int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const struct lapdm_entity *le)
+/* Compose and send 8.4.8 MEASUREMENT RESult via RSL */
+int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const struct lapdm_entity *le)
{
struct msgb *msg;
uint8_t meas_res[16];
@@ -2895,9 +2895,12 @@ static int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, con
msgb_tv_fixed_put(msg, RSL_IE_L1_INFO, 2, lchan->meas.l1_info);
lchan->meas.flags &= ~LC_UL_M_F_L1_VALID;
}
- msgb_tl16v_put(msg, RSL_IE_L3_INFO, l3_len, l3);
+
+ if (l3 && l3_len > 0)
+ msgb_tl16v_put(msg, RSL_IE_L3_INFO, l3_len, l3);
if (ms_to_valid(lchan)) {
- msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, ms_to2rsl(lchan, le));
+ if (l3 && l3_len > 0)
+ msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, ms_to2rsl(lchan, le));
lchan->ms_t_offs = -1;
lchan->p_offs = -1;
}
diff --git a/src/common/scheduler.c b/src/common/scheduler.c
index fe93c32b..3713b063 100644
--- a/src/common/scheduler.c
+++ b/src/common/scheduler.c
@@ -365,6 +365,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCHTH_0] = {
.name = "SACCH/TH(0)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -376,6 +377,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCHTH_1] = {
.name = "SACCH/TH(1)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -387,6 +389,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH4_0] = {
.name = "SACCH/4(0)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -398,6 +401,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH4_1] = {
.name = "SACCH/4(1)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -409,6 +413,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH4_2] = {
.name = "SACCH/4(2)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -420,6 +425,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH4_3] = {
.name = "SACCH/4(3)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -431,6 +437,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH8_0] = {
.name = "SACCH/8(0)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -442,6 +449,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH8_1] = {
.name = "SACCH/8(1)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -453,6 +461,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH8_2] = {
.name = "SACCH/8(2)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -464,6 +473,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH8_3] = {
.name = "SACCH/8(3)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -475,6 +485,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH8_4] = {
.name = "SACCH/8(4)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -486,6 +497,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH8_5] = {
.name = "SACCH/8(5)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -497,6 +509,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH8_6] = {
.name = "SACCH/8(6)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -508,6 +521,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_SACCH8_7] = {
.name = "SACCH/8(7)", /* 3GPP TS 05.02, section 3.3.4.1 */
@@ -519,6 +533,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = {
.rts_fn = rts_data_fn,
.dl_fn = tx_data_fn,
.ul_fn = rx_data_fn,
+ .nope_fn = rx_data_fn,
},
[TRXC_PDTCH] = {
.name = "PDTCH", /* 3GPP TS 05.02, sections 3.2.4, 3.3.2.4 */
diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c
index c3608bf5..2785d097 100644
--- a/src/osmo-bts-trx/scheduler_trx.c
+++ b/src/osmo-bts-trx/scheduler_trx.c
@@ -945,10 +945,14 @@ int rx_data_fn(struct l1sched_trx *l1t, enum trx_chan_type chan,
(*ci_cb_num)++;
}
- /* copy burst to buffer of 4 bursts */
+ /* Copy burst to buffer of 4 bursts. If the burst indication contains
+ * no data, ensure that the buffer does not stay uninitalized */
burst = *bursts_p + bid * 116;
- memcpy(burst, bi->burst + 3, 58);
- memcpy(burst + 58, bi->burst + 87, 58);
+ if (bi->burst_len > 0) {
+ memcpy(burst, bi->burst + 3, 58);
+ memcpy(burst + 58, bi->burst + 87, 58);
+ } else
+ memset(burst, 0, 58 * 2);
/* send burst information to loops process */
if (L1SAP_IS_LINK_SACCH(trx_chan_desc[chan].link_id)) {