aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmo-bts/measurement.h2
-rw-r--r--include/osmo-bts/rsl.h2
-rw-r--r--src/common/l1sap.c3
-rw-r--r--src/common/measurement.c32
-rw-r--r--src/common/rsl.c33
5 files changed, 44 insertions, 28 deletions
diff --git a/include/osmo-bts/measurement.h b/include/osmo-bts/measurement.h
index 45f275f1..481b7bed 100644
--- a/include/osmo-bts/measurement.h
+++ b/include/osmo-bts/measurement.h
@@ -20,4 +20,6 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn);
int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn);
+int handle_ms_meas_report(struct gsm_lchan *lchan, struct gsm48_hdr *gh, unsigned int len);
+
#endif
diff --git a/include/osmo-bts/rsl.h b/include/osmo-bts/rsl.h
index 4e79de5e..16630067 100644
--- a/include/osmo-bts/rsl.h
+++ b/include/osmo-bts/rsl.h
@@ -34,6 +34,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);
+int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, int timing_offset);
#endif // _RSL_H */
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index 2ebd39a2..7e04a3ae 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -1606,8 +1606,7 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx,
* lack the measurement report from the MS side. See
* also rsl.c:lapdm_rll_tx_cb() */
LOGPGT(DL1P, LOGL_INFO, &g_time, "Lost SACCH block, faking meas reports and ms pwr\n");
- le = &lchan->lapdm_ch.lapdm_acch;
- rsl_tx_meas_res(lchan, NULL, 0, le);
+ handle_ms_meas_report(lchan, NULL, 0);
radio_link_timeout(lchan, true);
lchan_ms_ta_ctrl(lchan, lchan->ta_ctrl.current, lchan->meas.ms_toa256);
diff --git a/src/common/measurement.c b/src/common/measurement.c
index a1c91a9d..5b46f794 100644
--- a/src/common/measurement.c
+++ b/src/common/measurement.c
@@ -776,3 +776,35 @@ void lchan_meas_reset(struct gsm_lchan *lchan)
memset(&lchan->meas, 0, sizeof(lchan->meas));
lchan->meas.last_fn = LCHAN_FN_DUMMY;
}
+
+static inline uint8_t ms_to2rsl(const struct gsm_lchan *lchan, const struct lapdm_entity *le)
+{
+ return (lchan->ms_t_offs >= 0) ? lchan->ms_t_offs : (lchan->p_offs - le->ta);
+}
+
+static inline bool ms_to_valid(const struct gsm_lchan *lchan)
+{
+ return (lchan->ms_t_offs >= 0) || (lchan->p_offs >= 0);
+}
+
+/* Called every time a Measurement Result (TS 08.58 8.4.8) is received from
+ * lower layers and has to be forwarded to BSC */
+int handle_ms_meas_report(struct gsm_lchan *lchan, struct gsm48_hdr *gh, unsigned int len)
+{
+ int timing_offset, rc;
+ struct lapdm_entity *le;
+
+ le = &lchan->lapdm_ch.lapdm_acch;
+
+ timing_offset = ms_to_valid(lchan) ? ms_to2rsl(lchan, le) : -1;
+ rc = rsl_tx_meas_res(lchan, (uint8_t *)gh, len, timing_offset);
+
+ /* Reset state for next iteration */
+ lchan->meas.res_nr++;
+ lchan->tch.dtx.dl_active = false;
+ lchan->meas.flags &= ~LC_UL_M_F_OSMO_EXT_VALID;
+ lchan->meas.flags &= ~LC_UL_M_F_L1_VALID;
+ lchan->ms_t_offs = -1;
+ lchan->p_offs = -1;
+ return rc;
+}
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 742270d3..e13160e1 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -3490,16 +3490,6 @@ static int handle_gprs_susp_req(struct msgb *msg)
return rc;
}
-static inline uint8_t ms_to2rsl(const struct gsm_lchan *lchan, const struct lapdm_entity *le)
-{
- return (lchan->ms_t_offs >= 0) ? lchan->ms_t_offs : (lchan->p_offs - le->ta);
-}
-
-static inline bool ms_to_valid(const struct gsm_lchan *lchan)
-{
- return (lchan->ms_t_offs >= 0) || (lchan->p_offs >= 0);
-}
-
struct osmo_bts_supp_meas_info {
int16_t toa256_mean;
int16_t toa256_min;
@@ -3507,8 +3497,8 @@ struct osmo_bts_supp_meas_info {
uint16_t toa256_std_dev;
} __attribute__((packed));
-/* 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)
+/* Compose and send 8.4.8 MEASUREMENT RESult via RSL. (timing_offset=-1 -> not present) */
+int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, int timing_offset)
{
struct msgb *msg;
uint8_t meas_res[16];
@@ -3534,13 +3524,12 @@ int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const stru
lchan->meas.ul_res.full.rx_qual,
lchan->meas.ul_res.sub.rx_qual,
lchan->meas.l1_info.ms_pwr,
- lchan->meas.l1_info.ta, l3_len, ms_to2rsl(lchan, le) - MEAS_MAX_TIMING_ADVANCE);
+ lchan->meas.l1_info.ta, l3_len, timing_offset - MEAS_MAX_TIMING_ADVANCE);
- msgb_tv_put(msg, RSL_IE_MEAS_RES_NR, lchan->meas.res_nr++);
+ msgb_tv_put(msg, RSL_IE_MEAS_RES_NR, lchan->meas.res_nr);
size_t ie_len = gsm0858_rsl_ul_meas_enc(&lchan->meas.ul_res,
lchan->tch.dtx.dl_active,
meas_res);
- lchan->tch.dtx.dl_active = false;
if (ie_len >= 3) {
if (bts->supp_meas_toa256 && lchan->meas.flags & LC_UL_M_F_OSMO_EXT_VALID) {
struct osmo_bts_supp_meas_info *smi;
@@ -3558,24 +3547,18 @@ int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const stru
smi->toa256_min = htons(ta256 + lchan->meas.ext.toa256_min);
smi->toa256_max = htons(ta256 + lchan->meas.ext.toa256_max);
smi->toa256_std_dev = htons(lchan->meas.ext.toa256_std_dev);
- lchan->meas.flags &= ~LC_UL_M_F_OSMO_EXT_VALID;
}
msgb_tlv_put(msg, RSL_IE_UPLINK_MEAS, ie_len, meas_res);
- lchan->meas.flags &= ~LC_UL_M_F_RES_VALID;
}
msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power_ctrl.current / 2);
if (lchan->meas.flags & LC_UL_M_F_L1_VALID) {
msgb_tv_fixed_put(msg, RSL_IE_L1_INFO, sizeof(lchan->meas.l1_info), (uint8_t*)&lchan->meas.l1_info);
- lchan->meas.flags &= ~LC_UL_M_F_L1_VALID;
}
- if (l3 && l3_len > 0)
+ if (l3 && l3_len > 0) {
msgb_tl16v_put(msg, RSL_IE_L3_INFO, l3_len, l3);
- if (ms_to_valid(lchan)) {
- 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;
+ if (timing_offset != -1)
+ msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, timing_offset);
}
rsl_dch_push_hdr(msg, RSL_MT_MEAS_RES, chan_nr);
@@ -3629,7 +3612,7 @@ int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx)
}
repeated_dl_facch_active_decision(lchan, msgb_l3(msg), msgb_l3len(msg));
- rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg), le);
+ rc = handle_ms_meas_report(lchan, (struct gsm48_hdr *)msgb_l3(msg), msgb_l3len(msg));
msgb_free(msg);
return rc;
} else if (rslms_is_gprs_susp_req(msg)) {