aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2021-07-06 03:36:03 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2021-07-11 20:28:02 +0200
commite5a761c6b86a5d5e1422bd491fb38bf30cf43bc6 (patch)
treee54050c5491269190795c5b13e4dda07890db135
parent9de09c974fc1916023f17996822a29b41bcefb61 (diff)
RES IND: parse msg and store interference levels in lchans
Also show the current interference levels of unused lchans in the vty. Related: SYS#5313 Change-Id: Iccc1391e8419604bb09e464db8455e053dfbc982
-rw-r--r--include/osmocom/bsc/gsm_data.h11
-rw-r--r--src/osmo-bsc/abis_rsl.c71
-rw-r--r--src/osmo-bsc/bsc_vty.c25
-rw-r--r--src/osmo-bsc/lchan_fsm.c2
4 files changed, 106 insertions, 3 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index b07345de0..063294432 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -646,6 +646,9 @@ struct lchan_modify_info {
bool vamos;
};
+#define INTERF_DBM_UNKNOWN 0
+#define INTERF_BAND_UNKNOWN 0xff
+
struct gsm_lchan {
/* The TS that we're part of */
struct gsm_bts_trx_ts *ts;
@@ -781,6 +784,14 @@ struct gsm_lchan {
/* Whether this lchan is activated/modified into a mode that allows VAMOS multiplexing at this moment */
bool enabled;
} vamos;
+
+ /* dBm value of interference level as reported in the most recent Resource Indication, if any for this lchan. Or
+ * INTERF_DBM_UNKNOWN if this lchan was not included in the most recent Resource Indication.
+ * The range is typically -115 to -85 dBm, here stored 1:1 as a signed integer, to ease comparison. */
+ int16_t interf_dbm;
+ /* Actual reported interference band index, or INTERF_BAND_UNKNOWN if this lchan was not included in the most
+ * recent Resource Indication. */
+ uint8_t interf_band;
};
/* One Timeslot in a TRX */
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index f0adc566f..f941d7e2b 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -1467,6 +1467,75 @@ static int rsl_rx_error_rep(struct msgb *msg)
return 0;
}
+static int rsl_rx_resource_indication(struct msgb *msg)
+{
+ struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
+ struct tlv_parsed tp;
+ struct e1inp_sign_link *sign_link = msg->dst;
+ struct tlv_p_entry *res_info_ie;
+ struct gsm_bts_trx *trx = sign_link->trx;
+ struct gsm_lchan *lchan;
+ int ts_nr;
+ int i;
+
+ rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg) - sizeof(*rslh));
+
+ LOGP(DRSL, LOGL_DEBUG, "%s Rx Resource Indication\n", gsm_trx_name(trx));
+
+ /* First clear out all ratings, because only the last resource indication counts. If we can't parse the message,
+ * then there are no ratings. */
+ for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
+ struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
+ lchan->interf_dbm = INTERF_DBM_UNKNOWN;
+ lchan->interf_band = INTERF_BAND_UNKNOWN;
+ }
+ }
+
+ res_info_ie = TLVP_GET_MINLEN(&tp, RSL_IE_RESOURCE_INFO, 2);
+ if (!res_info_ie) {
+ LOGP(DRSL, LOGL_ERROR, "Rx Resource Indication: missing Resource Info IE\n");
+ return -ENOENT;
+ }
+
+ /* The IE value is defined in 3GPP TS 48.058 9.3.21 Resource Information:
+ * one octet channel nr, one octet interference level, channel nr, interference level, ...
+ * Where channel nr is cbits + tn (as usual),
+ * and interference level is a 3bit value in the most significant bits of the octet.
+ * Evaluate each pair and update interference ratings for all lchans in this trx. */
+
+ /* There must be an even amount of octets in the value */
+ if (res_info_ie->len & 1) {
+ LOGP(DRSL, LOGL_ERROR, "Rx Resource Indication: Resource Info IE has odd length\n");
+ return -EINVAL;
+ }
+
+ /* Now iterate the reported levels and update corresponding lchans */
+ for (i = 0; i < res_info_ie->len; i += 2) {
+ struct gsm_bts *bts = trx->bts;
+ uint8_t chan_nr = res_info_ie->val[i];
+ uint8_t interf_band = res_info_ie->val[i + 1] >> 5;
+
+ lchan = lchan_lookup(trx, chan_nr, "Abis RSL Rx Resource Indication: ");
+ if (!lchan)
+ continue;
+
+ /* Store the actual received index */
+ lchan->interf_band = interf_band;
+ /* Clamp the index to 5 before accessing array of interference band bounds */
+ interf_band = OSMO_MIN(interf_band, ARRAY_SIZE(bts->interf_meas_params.bounds_dbm)-1);
+ /* FIXME: when testing with ip.access nanoBTS, we observe a value range of 1..6. According to spec, it
+ * seems like values 0..5 are intended: 3GPP TS 48.058 9.3.21 Resource Information says:
+ * "The Interf Band field (bits 6-8) indicates in binary the interference level expressed as one of five
+ * possible interference level bands as defined by O&M."
+ * and 3GPP TS 52.021 9.4.25 "Interference level Boundaries" (OML) defines values 0, X1, X2, X3, X4, X5.
+ * If nanoBTS sends 6, the above code clamps it to 5, so that we lose one band in accuracy. */
+ lchan->interf_dbm = -((int16_t)bts->interf_meas_params.bounds_dbm[interf_band]);
+ }
+
+ return 0;
+}
+
static int abis_rsl_rx_trx(struct msgb *msg)
{
struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
@@ -1479,7 +1548,7 @@ static int abis_rsl_rx_trx(struct msgb *msg)
break;
case RSL_MT_RF_RES_IND:
/* interference on idle channels of TRX */
- //DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(sign_link->trx));
+ rc = rsl_rx_resource_indication(msg);
break;
case RSL_MT_OVERLOAD:
/* indicate CCCH / ACCH / processor overload */
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 070b66081..07c8a9c9e 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -1682,6 +1682,14 @@ static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
- lchan->bs_power_db,
ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power),
VTY_NEWLINE);
+
+ vty_out(vty, " Interference Level: ");
+ if (lchan->interf_dbm == INTERF_DBM_UNKNOWN)
+ vty_out(vty, "unknown");
+ else
+ vty_out(vty, "%d dBm (%u)", lchan->interf_dbm, lchan->interf_band);
+ vty_out(vty, "%s", VTY_NEWLINE);
+
vty_out(vty, " Channel Mode / Codec: %s%s",
gsm48_chan_mode_name(lchan->current_ch_mode_rate.chan_mode),
VTY_NEWLINE);
@@ -1733,8 +1741,21 @@ static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
gsm_pchan_name(lchan->ts->pchan_on_init));
vty_out_dyn_ts_status(vty, lchan->ts);
- vty_out(vty, ", Lchan %u, Type %s%s TSC-s%dc%u, State %s - L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
- lchan->nr,
+ vty_out(vty, ", Lchan %u", lchan->nr);
+
+ if (lchan_state_is(lchan, LCHAN_ST_UNUSED)) {
+ vty_out(vty, ", Type %s, State %s - Interference Level: ",
+ gsm_pchan_name(lchan->ts->pchan_is),
+ lchan_state_name(lchan));
+ if (lchan->interf_dbm == INTERF_DBM_UNKNOWN)
+ vty_out(vty, "unknown");
+ else
+ vty_out(vty, "%d dBm (%u)", lchan->interf_dbm, lchan->interf_band);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ return;
+ }
+
+ vty_out(vty, ", Type %s%s TSC-s%dc%u, State %s - L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
gsm_lchant_name(lchan->type),
lchan->vamos.enabled ? " (VAMOS)" : "",
lchan->tsc_set > 0 ? lchan->tsc_set : 1,
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index e1dacb3af..7b89b2db5 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -488,6 +488,8 @@ static void lchan_reset(struct gsm_lchan *lchan)
.release.rr_cause = GSM48_RR_CAUSE_NORMAL,
.tsc_set = 1,
+ .interf_dbm = INTERF_DBM_UNKNOWN,
+ .interf_band = INTERF_BAND_UNKNOWN,
};
}