Change in osmo-bts[master]: power_control: handle MS/BS Power control params on A-bis/RSL

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

fixeria gerrit-no-reply at lists.osmocom.org
Thu Jan 7 00:38:58 UTC 2021


fixeria has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bts/+/21906 )

Change subject: power_control: handle MS/BS Power control params on A-bis/RSL
......................................................................

power_control: handle MS/BS Power control params on A-bis/RSL

Change-Id: I5a901eca5a78a0335a6954064e602e65cda85390
Depends: I2f4ed56837dd479dbbd10c0a7df0ed7565d3946a
Related: SYS#4918
---
M src/common/rsl.c
1 file changed, 229 insertions(+), 14 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified



diff --git a/src/common/rsl.c b/src/common/rsl.c
index 29b64b4..bca365e 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -2,6 +2,7 @@
 
 /* (C) 2011 by Andreas Eversberg <jolly at eversberg.eu>
  * (C) 2011-2019 by Harald Welte <laforge at gnumonks.org>
+ * (C) 2020 by sysmocom - s.m.f.c. GmbH <info at sysmocom.de>
  *
  * All Rights Reserved
  *
@@ -698,6 +699,167 @@
 
 }
 
+/* Parser for ip.access specific MS/BS Power parameters */
+static int parse_power_ctrl_params(struct gsm_power_ctrl_params *params,
+				   const uint8_t *data, size_t data_len)
+{
+	const struct tlv_p_entry *ie;
+	struct tlv_parsed tp[2];
+	unsigned int i;
+	int rc;
+
+	/* There can be multiple RSL_IPAC_EIE_MEAS_AVG_CFG, so we use tlv_parse2() */
+	rc = tlv_parse2(&tp[0], ARRAY_SIZE(tp), &rsl_ipac_eie_tlvdef,
+			data, data_len, 0, 0);
+	if (rc < 0)
+		return rc;
+
+	/* Either of RSL_IPAC_EIE_{BS,MS}_PWR_CTL must be present */
+	if (TLVP_PRESENT(&tp[0], RSL_IPAC_EIE_BS_PWR_CTL) &&
+	    TLVP_PRESENT(&tp[0], RSL_IPAC_EIE_MS_PWR_CTL))
+		return -EINVAL;
+
+	/* (TV) Thresholds: {L,U}_RXLEV_XX_P and {L,U}_RXQUAL_XX_P */
+	if ((ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_BS_PWR_CTL)) != NULL ||
+	    (ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_MS_PWR_CTL)) != NULL) {
+		const struct ipac_preproc_pc_thresh *thresh;
+
+		thresh = (const struct ipac_preproc_pc_thresh *) ie->val;
+
+		params->rxlev_meas.lower_thresh = thresh->l_rxlev;
+		params->rxlev_meas.upper_thresh = thresh->u_rxlev;
+
+		params->rxqual_meas.lower_thresh = thresh->l_rxqual;
+		params->rxqual_meas.upper_thresh = thresh->u_rxqual;
+	}
+
+	/* (TV) PC Threshold Comparators */
+	if ((ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_PC_THRESH_COMP)) != NULL) {
+		const struct ipac_preproc_pc_comp *thresh_comp;
+
+		thresh_comp = (const struct ipac_preproc_pc_comp *) ie->val;
+
+		/* RxLev: P1, N1, P2, N2 (see 3GPP TS 45.008, A.3.2.1, a & b) */
+		params->rxlev_meas.lower_cmp_p = thresh_comp->p1;
+		params->rxlev_meas.lower_cmp_n = thresh_comp->n1;
+		params->rxlev_meas.upper_cmp_p = thresh_comp->p2;
+		params->rxlev_meas.upper_cmp_n = thresh_comp->n2;
+
+		/* RxQual: P3, N3, P4, N4 (see 3GPP TS 45.008, A.3.2.1, c & d) */
+		params->rxqual_meas.lower_cmp_p = thresh_comp->p3;
+		params->rxqual_meas.lower_cmp_n = thresh_comp->n3;
+		params->rxqual_meas.upper_cmp_p = thresh_comp->p4;
+		params->rxqual_meas.upper_cmp_n = thresh_comp->n4;
+
+		/* FIXME: TIMER_PWR_CON_INTERVAL (P_Con_INTERVAL) */
+
+		/* Power increase / reduce step size: POWER_{INC,RED}_STEP_SIZE */
+		params->inc_step_size_db = thresh_comp->inc_step_size;
+		params->red_step_size_db = thresh_comp->red_step_size;
+	}
+
+	/* (TLV) Measurement Averaging parameters for RxLev/RxQual */
+	for (i = 0; i < ARRAY_SIZE(tp); i++) {
+		const struct ipac_preproc_ave_cfg *ave_cfg;
+		struct gsm_power_ctrl_meas_params *mp;
+
+		ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_MEAS_AVG_CFG);
+		if (ie == NULL)
+			break;
+
+		if (ie->len < sizeof(*ave_cfg))
+			return -EINVAL;
+
+		ave_cfg = (const struct ipac_preproc_ave_cfg *) ie->val;
+
+		switch (ave_cfg->param_id) {
+		case IPAC_RXQUAL_AVE:
+			mp = &params->rxqual_meas;
+			break;
+		case IPAC_RXLEV_AVE:
+			mp = &params->rxlev_meas;
+			break;
+		default:
+			/* Skip unknown parameters */
+			continue;
+		}
+
+		mp->h_reqave = ave_cfg->h_reqave;
+		mp->h_reqt = ave_cfg->h_reqt;
+
+		mp->algo = ave_cfg->ave_method + 1;
+		switch (ave_cfg->ave_method) {
+		case IPAC_OSMO_EWMA_AVE:
+			if (ie->len > sizeof(*ave_cfg))
+				mp->ewma.alpha = ave_cfg->params[0];
+			break;
+
+		/* FIXME: not implemented */
+		case IPAC_UNWEIGHTED_AVE:
+		case IPAC_WEIGHTED_AVE:
+		case IPAC_MEDIAN_AVE:
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/* ip.access specific Measurement Pre-processing Defaults for MS/BS Power control */
+static int rsl_rx_meas_preproc_dft(struct gsm_bts_trx *trx, struct msgb *msg)
+{
+	const struct gsm_bts *bts = trx->bts;
+	struct gsm_power_ctrl_params *params;
+	const struct tlv_p_entry *ie;
+	struct tlv_parsed tp;
+	int rc;
+
+	LOGPTRX(trx, DRSL, LOGL_INFO, "Rx Measurement Pre-processing Defaults\n");
+
+	rc = rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg));
+	if (rc < 0) {
+		LOGPTRX(trx, DRSL, LOGL_ERROR, "Failed to parse ip.access specific "
+			"Measurement Pre-processing Defaults for MS/BS Power control\n");
+		return rsl_tx_error_report(trx, RSL_ERR_PROTO, NULL, NULL, msg);
+	}
+
+	/* TLV (O) BS Power Parameters IE */
+	if ((ie = TLVP_GET(&tp, RSL_IE_BS_POWER_PARAM)) != NULL) {
+		/* Allocate a new chunk and initialize with default values */
+		params = talloc_memdup(trx, &power_ctrl_params_def, sizeof(*params));
+
+		if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) == 0) {
+			/* Initially it points to the global defaults */
+			if (trx->bs_dpc_params != &bts->bs_dpc_params)
+				talloc_free(trx->bs_dpc_params);
+			trx->bs_dpc_params = params;
+		} else {
+			LOGPTRX(trx, DRSL, LOGL_ERROR, "Failed to parse BS Power Parameters IE\n");
+			rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT, NULL, NULL, msg);
+			talloc_free(params);
+		}
+	}
+
+	/* TLV (O) MS Power Parameters IE */
+	if ((ie = TLVP_GET(&tp, RSL_IE_MS_POWER_PARAM)) != NULL) {
+		/* Allocate a new chunk and initialize with default values */
+		params = talloc_memdup(trx, &power_ctrl_params_def, sizeof(*params));
+
+		if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) == 0) {
+			/* Initially it points to the global defaults */
+			if (trx->ms_dpc_params != &bts->ms_dpc_params)
+				talloc_free(trx->ms_dpc_params);
+			trx->ms_dpc_params = params;
+		} else {
+			LOGPTRX(trx, DRSL, LOGL_ERROR, "Failed to parse MS Power Parameters IE\n");
+			rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT, NULL, NULL, msg);
+			talloc_free(params);
+		}
+	}
+
+	return 0;
+}
+
 /* 8.5.6 IMMEDIATE ASSIGN COMMAND is received */
 static int rsl_rx_imm_ass(struct gsm_bts_trx *trx, struct msgb *msg)
 {
@@ -1125,6 +1287,7 @@
 	struct gsm_bts_trx_ts *ts = lchan->ts;
 	struct rsl_ie_chan_mode *cm;
 	struct tlv_parsed tp;
+	const struct tlv_p_entry *ie;
 	uint8_t type;
 	int rc;
 
@@ -1236,19 +1399,42 @@
 	if (TLVP_PRES_LEN(&tp, RSL_IE_TIMING_ADVANCE, 1))
 		lchan->rqd_ta = *TLVP_VAL(&tp, RSL_IE_TIMING_ADVANCE);
 
-	/* 9.3.31 MS Power Parameters */
-	if (TLVP_PRESENT(&tp, RSL_IE_MS_POWER_PARAM)) {
+	/* 9.3.31 (TLV) MS Power Parameters IE (vendor specific) */
+	if ((ie = TLVP_GET(&tp, RSL_IE_MS_POWER_PARAM)) != NULL) {
+		struct gsm_power_ctrl_params *params = &lchan->ms_dpc_params;
+
+		/* Parsed parameters will override per-TRX defaults */
+		memcpy(params, ts->trx->ms_dpc_params, sizeof(*params));
+
+		if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) != 0) {
+			LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Failed to parse MS Power Parameters IE\n");
+			return rsl_tx_chan_act_nack(lchan, RSL_ERR_IE_CONTENT);
+		}
+
 		/* Spec explicitly states BTS should only perform
 		* autonomous MS power control loop in BTS if 'MS Power
 		* Parameters' IE is present! */
 		lchan->ms_power_ctrl.fixed = false;
+		lchan->ms_power_ctrl.dpc_params = params;
 	}
 
-	/* 9.3.32 BS Power Parameters */
-	if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER_PARAM)) {
+	/* 9.3.32 (TLV) BS Power Parameters IE (vendor specific) */
+	if ((ie = TLVP_GET(&tp, RSL_IE_BS_POWER_PARAM)) != NULL) {
+		struct gsm_power_ctrl_params *params = &lchan->bs_dpc_params;
+
+		/* Parsed parameters will override per-TRX defaults */
+		memcpy(params, ts->trx->bs_dpc_params, sizeof(*params));
+
+		/* Parsed parameters will override per-TRX defaults */
+		if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) != 0) {
+			LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Failed to parse BS Power Parameters IE\n");
+			return rsl_tx_chan_act_nack(lchan, RSL_ERR_IE_CONTENT);
+		}
+
 		/* NOTE: it's safer to start from 0 */
 		lchan->bs_power_ctrl.current = 0;
 		lchan->bs_power_ctrl.fixed = false;
+		lchan->bs_power_ctrl.dpc_params = params;
 	}
 
 	/* 9.3.16 Physical Context */
@@ -1721,6 +1907,7 @@
 	struct abis_rsl_dchan_hdr *dch = msgb_l2(msg);
 	struct gsm_lchan *lchan = msg->lchan;
 	struct gsm_bts *bts = lchan->ts->trx->bts;
+	const struct tlv_p_entry *ie;
 	struct tlv_parsed tp;
 	uint8_t pwr;
 	int max_pwr, curr_pwr;
@@ -1736,14 +1923,25 @@
 
 	LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Rx MS POWER CONTROL %" PRIu8 "\n", pwr);
 
-	/* 9.3.31 MS Power Parameters (O) */
-	if (TLVP_PRESENT(&tp, RSL_IE_MS_POWER_PARAM)) {
-		/* Spec explicitly states BTS should only perform
-		* autonomous MS power control loop in BTS if 'MS Power
-		* Parameters' IE is present! */
-		lchan->ms_power_ctrl.fixed = false;
-	} else {
-		lchan->ms_power_ctrl.fixed = true;
+	/* Spec explicitly states BTS should only perform autonomous MS Power
+	 * control loop in BTS if 'MS Power Parameters' IE is present! */
+	lchan->ms_power_ctrl.fixed = !TLVP_PRESENT(&tp, RSL_IE_MS_POWER_PARAM);
+	lchan->ms_power_ctrl.dpc_params = NULL;
+
+	/* 9.3.31 (TLV) MS Power Parameters IE (vendor specific) */
+	if ((ie = TLVP_GET(&tp, RSL_IE_MS_POWER_PARAM)) != NULL) {
+		struct gsm_power_ctrl_params *params = &lchan->ms_dpc_params;
+
+		/* Parsed parameters will override per-TRX defaults */
+		memcpy(params, msg->trx->ms_dpc_params, sizeof(*params));
+
+		/* Parsed parameters will override per-TRX defaults */
+		if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) != 0) {
+			LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Failed to parse MS Power Parameters IE\n");
+			return rsl_tx_chan_act_nack(lchan, RSL_ERR_IE_CONTENT);
+		}
+
+		lchan->ms_power_ctrl.dpc_params = params;
 	}
 
 	/* Only set current to max if actual value of current
@@ -1773,6 +1971,7 @@
 {
 	struct abis_rsl_dchan_hdr *dch = msgb_l2(msg);
 	struct gsm_lchan *lchan = msg->lchan;
+	const struct tlv_p_entry *ie;
 	struct tlv_parsed tp;
 	uint8_t old, new;
 
@@ -1790,13 +1989,26 @@
 	new = BS_POWER2DB(*TLVP_VAL(&tp, RSL_IE_BS_POWER));
 	old = lchan->bs_power_ctrl.current;
 
-	/* 9.3.31 MS Power Parameters (O) */
-	if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER_PARAM)) {
+	/* 9.3.32 (TLV) BS Power Parameters IE (vendor specific) */
+	if ((ie = TLVP_GET(&tp, RSL_IE_BS_POWER_PARAM)) != NULL) {
+		struct gsm_power_ctrl_params *params = &lchan->bs_dpc_params;
+
+		/* Parsed parameters will override per-TRX defaults */
+		memcpy(params, msg->trx->bs_dpc_params, sizeof(*params));
+
+		/* Parsed parameters will override per-TRX defaults */
+		if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) != 0) {
+			LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Failed to parse BS Power Parameters IE\n");
+			return rsl_tx_chan_act_nack(lchan, RSL_ERR_IE_CONTENT);
+		}
+
 		/* NOTE: it's safer to start from 0 */
 		lchan->bs_power_ctrl.current = 0;
 		lchan->bs_power_ctrl.max = new;
 		lchan->bs_power_ctrl.fixed = false;
+		lchan->bs_power_ctrl.dpc_params = params;
 	} else {
+		lchan->bs_power_ctrl.dpc_params = NULL;
 		lchan->bs_power_ctrl.current = new;
 		lchan->bs_power_ctrl.fixed = true;
 	}
@@ -3242,6 +3454,9 @@
 	case RSL_MT_SACCH_FILL:
 		ret = rsl_rx_sacch_fill(trx, msg);
 		break;
+	case RSL_MT_IPAC_MEAS_PREPROC_DFT:
+		ret = rsl_rx_meas_preproc_dft(trx, msg);
+		break;
 	default:
 		LOGP(DRSL, LOGL_NOTICE, "undefined RSL TRX msg_type 0x%02x\n",
 			th->msg_type);

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/21906
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: I5a901eca5a78a0335a6954064e602e65cda85390
Gerrit-Change-Number: 21906
Gerrit-PatchSet: 5
Gerrit-Owner: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210107/0e26454e/attachment.htm>


More information about the gerrit-log mailing list