<p>fixeria <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/21906">View Change</a></p><div style="white-space:pre-wrap">Approvals:
laforge: Looks good to me, approved
pespin: Looks good to me, but someone else must approve
Jenkins Builder: Verified
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">power_control: handle MS/BS Power control params on A-bis/RSL<br><br>Change-Id: I5a901eca5a78a0335a6954064e602e65cda85390<br>Depends: I2f4ed56837dd479dbbd10c0a7df0ed7565d3946a<br>Related: SYS#4918<br>---<br>M src/common/rsl.c<br>1 file changed, 229 insertions(+), 14 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/common/rsl.c b/src/common/rsl.c</span><br><span>index 29b64b4..bca365e 100644</span><br><span>--- a/src/common/rsl.c</span><br><span>+++ b/src/common/rsl.c</span><br><span>@@ -2,6 +2,7 @@</span><br><span> </span><br><span> /* (C) 2011 by Andreas Eversberg <jolly@eversberg.eu></span><br><span> * (C) 2011-2019 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de></span><br><span> *</span><br><span> * All Rights Reserved</span><br><span> *</span><br><span>@@ -698,6 +699,167 @@</span><br><span> </span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Parser for ip.access specific MS/BS Power parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+static int parse_power_ctrl_params(struct gsm_power_ctrl_params *params,</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t *data, size_t data_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct tlv_p_entry *ie;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct tlv_parsed tp[2];</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* There can be multiple RSL_IPAC_EIE_MEAS_AVG_CFG, so we use tlv_parse2() */</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = tlv_parse2(&tp[0], ARRAY_SIZE(tp), &rsl_ipac_eie_tlvdef,</span><br><span style="color: hsl(120, 100%, 40%);">+ data, data_len, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Either of RSL_IPAC_EIE_{BS,MS}_PWR_CTL must be present */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (TLVP_PRESENT(&tp[0], RSL_IPAC_EIE_BS_PWR_CTL) &&</span><br><span style="color: hsl(120, 100%, 40%);">+ TLVP_PRESENT(&tp[0], RSL_IPAC_EIE_MS_PWR_CTL))</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* (TV) Thresholds: {L,U}_RXLEV_XX_P and {L,U}_RXQUAL_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_BS_PWR_CTL)) != NULL ||</span><br><span style="color: hsl(120, 100%, 40%);">+ (ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_MS_PWR_CTL)) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct ipac_preproc_pc_thresh *thresh;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ thresh = (const struct ipac_preproc_pc_thresh *) ie->val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxlev_meas.lower_thresh = thresh->l_rxlev;</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxlev_meas.upper_thresh = thresh->u_rxlev;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxqual_meas.lower_thresh = thresh->l_rxqual;</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxqual_meas.upper_thresh = thresh->u_rxqual;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* (TV) PC Threshold Comparators */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_PC_THRESH_COMP)) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct ipac_preproc_pc_comp *thresh_comp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ thresh_comp = (const struct ipac_preproc_pc_comp *) ie->val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* RxLev: P1, N1, P2, N2 (see 3GPP TS 45.008, A.3.2.1, a & b) */</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxlev_meas.lower_cmp_p = thresh_comp->p1;</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxlev_meas.lower_cmp_n = thresh_comp->n1;</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxlev_meas.upper_cmp_p = thresh_comp->p2;</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxlev_meas.upper_cmp_n = thresh_comp->n2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* RxQual: P3, N3, P4, N4 (see 3GPP TS 45.008, A.3.2.1, c & d) */</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxqual_meas.lower_cmp_p = thresh_comp->p3;</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxqual_meas.lower_cmp_n = thresh_comp->n3;</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxqual_meas.upper_cmp_p = thresh_comp->p4;</span><br><span style="color: hsl(120, 100%, 40%);">+ params->rxqual_meas.upper_cmp_n = thresh_comp->n4;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: TIMER_PWR_CON_INTERVAL (P_Con_INTERVAL) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Power increase / reduce step size: POWER_{INC,RED}_STEP_SIZE */</span><br><span style="color: hsl(120, 100%, 40%);">+ params->inc_step_size_db = thresh_comp->inc_step_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ params->red_step_size_db = thresh_comp->red_step_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* (TLV) Measurement Averaging parameters for RxLev/RxQual */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < ARRAY_SIZE(tp); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct ipac_preproc_ave_cfg *ave_cfg;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_meas_params *mp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_MEAS_AVG_CFG);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ie == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ie->len < sizeof(*ave_cfg))</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ave_cfg = (const struct ipac_preproc_ave_cfg *) ie->val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (ave_cfg->param_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case IPAC_RXQUAL_AVE:</span><br><span style="color: hsl(120, 100%, 40%);">+ mp = ¶ms->rxqual_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case IPAC_RXLEV_AVE:</span><br><span style="color: hsl(120, 100%, 40%);">+ mp = ¶ms->rxlev_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Skip unknown parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ mp->h_reqave = ave_cfg->h_reqave;</span><br><span style="color: hsl(120, 100%, 40%);">+ mp->h_reqt = ave_cfg->h_reqt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ mp->algo = ave_cfg->ave_method + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (ave_cfg->ave_method) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case IPAC_OSMO_EWMA_AVE:</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ie->len > sizeof(*ave_cfg))</span><br><span style="color: hsl(120, 100%, 40%);">+ mp->ewma.alpha = ave_cfg->params[0];</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: not implemented */</span><br><span style="color: hsl(120, 100%, 40%);">+ case IPAC_UNWEIGHTED_AVE:</span><br><span style="color: hsl(120, 100%, 40%);">+ case IPAC_WEIGHTED_AVE:</span><br><span style="color: hsl(120, 100%, 40%);">+ case IPAC_MEDIAN_AVE:</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* ip.access specific Measurement Pre-processing Defaults for MS/BS Power control */</span><br><span style="color: hsl(120, 100%, 40%);">+static int rsl_rx_meas_preproc_dft(struct gsm_bts_trx *trx, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct gsm_bts *bts = trx->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_params *params;</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct tlv_p_entry *ie;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct tlv_parsed tp;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPTRX(trx, DRSL, LOGL_INFO, "Rx Measurement Pre-processing Defaults\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPTRX(trx, DRSL, LOGL_ERROR, "Failed to parse ip.access specific "</span><br><span style="color: hsl(120, 100%, 40%);">+ "Measurement Pre-processing Defaults for MS/BS Power control\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return rsl_tx_error_report(trx, RSL_ERR_PROTO, NULL, NULL, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* TLV (O) BS Power Parameters IE */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ie = TLVP_GET(&tp, RSL_IE_BS_POWER_PARAM)) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Allocate a new chunk and initialize with default values */</span><br><span style="color: hsl(120, 100%, 40%);">+ params = talloc_memdup(trx, &power_ctrl_params_def, sizeof(*params));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initially it points to the global defaults */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (trx->bs_dpc_params != &bts->bs_dpc_params)</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(trx->bs_dpc_params);</span><br><span style="color: hsl(120, 100%, 40%);">+ trx->bs_dpc_params = params;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPTRX(trx, DRSL, LOGL_ERROR, "Failed to parse BS Power Parameters IE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT, NULL, NULL, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(params);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* TLV (O) MS Power Parameters IE */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ie = TLVP_GET(&tp, RSL_IE_MS_POWER_PARAM)) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Allocate a new chunk and initialize with default values */</span><br><span style="color: hsl(120, 100%, 40%);">+ params = talloc_memdup(trx, &power_ctrl_params_def, sizeof(*params));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initially it points to the global defaults */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (trx->ms_dpc_params != &bts->ms_dpc_params)</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(trx->ms_dpc_params);</span><br><span style="color: hsl(120, 100%, 40%);">+ trx->ms_dpc_params = params;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPTRX(trx, DRSL, LOGL_ERROR, "Failed to parse MS Power Parameters IE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT, NULL, NULL, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(params);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* 8.5.6 IMMEDIATE ASSIGN COMMAND is received */</span><br><span> static int rsl_rx_imm_ass(struct gsm_bts_trx *trx, struct msgb *msg)</span><br><span> {</span><br><span>@@ -1125,6 +1287,7 @@</span><br><span> struct gsm_bts_trx_ts *ts = lchan->ts;</span><br><span> struct rsl_ie_chan_mode *cm;</span><br><span> struct tlv_parsed tp;</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct tlv_p_entry *ie;</span><br><span> uint8_t type;</span><br><span> int rc;</span><br><span> </span><br><span>@@ -1236,19 +1399,42 @@</span><br><span> if (TLVP_PRES_LEN(&tp, RSL_IE_TIMING_ADVANCE, 1))</span><br><span> lchan->rqd_ta = *TLVP_VAL(&tp, RSL_IE_TIMING_ADVANCE);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* 9.3.31 MS Power Parameters */</span><br><span style="color: hsl(0, 100%, 40%);">- if (TLVP_PRESENT(&tp, RSL_IE_MS_POWER_PARAM)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 9.3.31 (TLV) MS Power Parameters IE (vendor specific) */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ie = TLVP_GET(&tp, RSL_IE_MS_POWER_PARAM)) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_params *params = &lchan->ms_dpc_params;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Parsed parameters will override per-TRX defaults */</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(params, ts->trx->ms_dpc_params, sizeof(*params));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Failed to parse MS Power Parameters IE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return rsl_tx_chan_act_nack(lchan, RSL_ERR_IE_CONTENT);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Spec explicitly states BTS should only perform</span><br><span> * autonomous MS power control loop in BTS if 'MS Power</span><br><span> * Parameters' IE is present! */</span><br><span> lchan->ms_power_ctrl.fixed = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->ms_power_ctrl.dpc_params = params;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* 9.3.32 BS Power Parameters */</span><br><span style="color: hsl(0, 100%, 40%);">- if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER_PARAM)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 9.3.32 (TLV) BS Power Parameters IE (vendor specific) */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ie = TLVP_GET(&tp, RSL_IE_BS_POWER_PARAM)) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_params *params = &lchan->bs_dpc_params;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Parsed parameters will override per-TRX defaults */</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(params, ts->trx->bs_dpc_params, sizeof(*params));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Parsed parameters will override per-TRX defaults */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Failed to parse BS Power Parameters IE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return rsl_tx_chan_act_nack(lchan, RSL_ERR_IE_CONTENT);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* NOTE: it's safer to start from 0 */</span><br><span> lchan->bs_power_ctrl.current = 0;</span><br><span> lchan->bs_power_ctrl.fixed = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->bs_power_ctrl.dpc_params = params;</span><br><span> }</span><br><span> </span><br><span> /* 9.3.16 Physical Context */</span><br><span>@@ -1721,6 +1907,7 @@</span><br><span> struct abis_rsl_dchan_hdr *dch = msgb_l2(msg);</span><br><span> struct gsm_lchan *lchan = msg->lchan;</span><br><span> struct gsm_bts *bts = lchan->ts->trx->bts;</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct tlv_p_entry *ie;</span><br><span> struct tlv_parsed tp;</span><br><span> uint8_t pwr;</span><br><span> int max_pwr, curr_pwr;</span><br><span>@@ -1736,14 +1923,25 @@</span><br><span> </span><br><span> LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Rx MS POWER CONTROL %" PRIu8 "\n", pwr);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* 9.3.31 MS Power Parameters (O) */</span><br><span style="color: hsl(0, 100%, 40%);">- if (TLVP_PRESENT(&tp, RSL_IE_MS_POWER_PARAM)) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Spec explicitly states BTS should only perform</span><br><span style="color: hsl(0, 100%, 40%);">- * autonomous MS power control loop in BTS if 'MS Power</span><br><span style="color: hsl(0, 100%, 40%);">- * Parameters' IE is present! */</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->ms_power_ctrl.fixed = false;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- lchan->ms_power_ctrl.fixed = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Spec explicitly states BTS should only perform autonomous MS Power</span><br><span style="color: hsl(120, 100%, 40%);">+ * control loop in BTS if 'MS Power Parameters' IE is present! */</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->ms_power_ctrl.fixed = !TLVP_PRESENT(&tp, RSL_IE_MS_POWER_PARAM);</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->ms_power_ctrl.dpc_params = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 9.3.31 (TLV) MS Power Parameters IE (vendor specific) */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ie = TLVP_GET(&tp, RSL_IE_MS_POWER_PARAM)) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_params *params = &lchan->ms_dpc_params;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Parsed parameters will override per-TRX defaults */</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(params, msg->trx->ms_dpc_params, sizeof(*params));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Parsed parameters will override per-TRX defaults */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Failed to parse MS Power Parameters IE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return rsl_tx_chan_act_nack(lchan, RSL_ERR_IE_CONTENT);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->ms_power_ctrl.dpc_params = params;</span><br><span> }</span><br><span> </span><br><span> /* Only set current to max if actual value of current</span><br><span>@@ -1773,6 +1971,7 @@</span><br><span> {</span><br><span> struct abis_rsl_dchan_hdr *dch = msgb_l2(msg);</span><br><span> struct gsm_lchan *lchan = msg->lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct tlv_p_entry *ie;</span><br><span> struct tlv_parsed tp;</span><br><span> uint8_t old, new;</span><br><span> </span><br><span>@@ -1790,13 +1989,26 @@</span><br><span> new = BS_POWER2DB(*TLVP_VAL(&tp, RSL_IE_BS_POWER));</span><br><span> old = lchan->bs_power_ctrl.current;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* 9.3.31 MS Power Parameters (O) */</span><br><span style="color: hsl(0, 100%, 40%);">- if (TLVP_PRESENT(&tp, RSL_IE_BS_POWER_PARAM)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* 9.3.32 (TLV) BS Power Parameters IE (vendor specific) */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((ie = TLVP_GET(&tp, RSL_IE_BS_POWER_PARAM)) != NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_params *params = &lchan->bs_dpc_params;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Parsed parameters will override per-TRX defaults */</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(params, msg->trx->bs_dpc_params, sizeof(*params));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Parsed parameters will override per-TRX defaults */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Failed to parse BS Power Parameters IE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return rsl_tx_chan_act_nack(lchan, RSL_ERR_IE_CONTENT);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* NOTE: it's safer to start from 0 */</span><br><span> lchan->bs_power_ctrl.current = 0;</span><br><span> lchan->bs_power_ctrl.max = new;</span><br><span> lchan->bs_power_ctrl.fixed = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->bs_power_ctrl.dpc_params = params;</span><br><span> } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->bs_power_ctrl.dpc_params = NULL;</span><br><span> lchan->bs_power_ctrl.current = new;</span><br><span> lchan->bs_power_ctrl.fixed = true;</span><br><span> }</span><br><span>@@ -3242,6 +3454,9 @@</span><br><span> case RSL_MT_SACCH_FILL:</span><br><span> ret = rsl_rx_sacch_fill(trx, msg);</span><br><span> break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case RSL_MT_IPAC_MEAS_PREPROC_DFT:</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = rsl_rx_meas_preproc_dft(trx, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> default:</span><br><span> LOGP(DRSL, LOGL_NOTICE, "undefined RSL TRX msg_type 0x%02x\n",</span><br><span> th->msg_type);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/21906">change 21906</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-bts/+/21906"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-bts </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I5a901eca5a78a0335a6954064e602e65cda85390 </div>
<div style="display:none"> Gerrit-Change-Number: 21906 </div>
<div style="display:none"> Gerrit-PatchSet: 5 </div>
<div style="display:none"> Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>