<p>fixeria <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/21683">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, but someone else must approve
  pespin: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">power_control: add encoder for ip.access nanoBTS and OsmoBTS<br><br>Change-Id: I3798a6a02132bafe8f1fef6e93bbb42036d76ac9<br>Related: SYS#4918<br>---<br>M src/osmo-bsc/bts_ipaccess_nanobts.c<br>1 file changed, 155 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/osmo-bsc/bts_ipaccess_nanobts.c b/src/osmo-bsc/bts_ipaccess_nanobts.c</span><br><span>index c84d750..27d8d64 100644</span><br><span>--- a/src/osmo-bsc/bts_ipaccess_nanobts.c</span><br><span>+++ b/src/osmo-bsc/bts_ipaccess_nanobts.c</span><br><span>@@ -1,6 +1,7 @@</span><br><span> /* ip.access nanoBTS specific code */</span><br><span> </span><br><span> /* (C) 2009-2018 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2020 by sysmocom s.f.m.c. GmbH <info@sysmocom.de></span><br><span>  *</span><br><span>  * All Rights Reserved</span><br><span>  *</span><br><span>@@ -52,6 +53,9 @@</span><br><span> static int bts_model_nanobts_start(struct gsm_network *net);</span><br><span> static void bts_model_nanobts_e1line_bind_ops(struct e1inp_line *line);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int power_ctrl_send_def_params(const struct gsm_bts_trx *trx);</span><br><span style="color: hsl(120, 100%, 40%);">+static int power_ctrl_enc_rsl_params(struct msgb *msg, const struct gsm_power_ctrl_params *cp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static char *get_oml_status(const struct gsm_bts *bts)</span><br><span> {</span><br><span>   if (bts->oml_link)</span><br><span>@@ -67,6 +71,11 @@</span><br><span>   .oml_rcvmsg = &abis_nm_rcvmsg,</span><br><span>   .oml_status = &get_oml_status,</span><br><span>   .e1line_bind_ops = bts_model_nanobts_e1line_bind_ops,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* MS/BS Power control specific API */</span><br><span style="color: hsl(120, 100%, 40%);">+        .power_ctrl_send_def_params = &power_ctrl_send_def_params,</span><br><span style="color: hsl(120, 100%, 40%);">+        .power_ctrl_enc_rsl_params = &power_ctrl_enc_rsl_params,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>       /* Some nanoBTS firmwares (if not all) don't support SI2ter and cause</span><br><span>     * problems on some MS if it is enabled, see OS#3063. Disable it by</span><br><span>   * default, can still be enabled through VTY cmd with same name.</span><br><span>@@ -801,3 +810,149 @@</span><br><span> {</span><br><span>         e1inp_line_bind_ops(line, &ipaccess_e1inp_line_ops);</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void enc_meas_proc_params(struct msgb *msg, uint8_t ptype,</span><br><span style="color: hsl(120, 100%, 40%);">+                            const 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%);">+      struct ipac_preproc_ave_cfg *ave_cfg;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *ie_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* No averaging => no Measurement Averaging parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (mp->algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE)</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</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%);">+ ie_len = msgb_tl_put(msg, RSL_IPAC_EIE_MEAS_AVG_CFG);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       ave_cfg = (struct ipac_preproc_ave_cfg *) msgb_put(msg, sizeof(*ave_cfg));</span><br><span style="color: hsl(120, 100%, 40%);">+    ave_cfg->param_id = ptype & 0x03;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* H_REQAVE and H_REQT */</span><br><span style="color: hsl(120, 100%, 40%);">+     ave_cfg->h_reqave = mp->h_reqave & 0x03;</span><br><span style="color: hsl(120, 100%, 40%);">+    ave_cfg->h_reqt = mp->h_reqt & 0x03;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Averaging method and parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+ ave_cfg->ave_method = (mp->algo - 1) & 0x07;</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (mp->algo) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA:</span><br><span style="color: hsl(120, 100%, 40%);">+            msgb_v_put(msg, mp->ewma.alpha);</span><br><span style="color: hsl(120, 100%, 40%);">+           break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM_PWR_CTRL_MEAS_AVG_ALGO_WEIGHTED:</span><br><span style="color: hsl(120, 100%, 40%);">+     case GSM_PWR_CTRL_MEAS_AVG_ALGO_MOD_MEDIAN:</span><br><span style="color: hsl(120, 100%, 40%);">+           /* FIXME: unknown format */</span><br><span style="color: hsl(120, 100%, 40%);">+           break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case GSM_PWR_CTRL_MEAS_AVG_ALGO_UNWEIGHTED:</span><br><span style="color: hsl(120, 100%, 40%);">+   case GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE:</span><br><span style="color: hsl(120, 100%, 40%);">+         /* No parameters here */</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%);">+   /* Update length part of the containing IE */</span><br><span style="color: hsl(120, 100%, 40%);">+ *ie_len = msg->tail - (ie_len + 1);</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%);">+static void enc_power_params(struct msgb *msg, const struct gsm_power_ctrl_params *cp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct ipac_preproc_pc_comp *thresh_comp;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct ipac_preproc_pc_thresh *thresh;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* These parameters are valid for dynamic mode only */</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(cp->mode == GSM_PWR_CTRL_MODE_DYN_BTS);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* (TLV) Measurement Averaging Configure */</span><br><span style="color: hsl(120, 100%, 40%);">+   enc_meas_proc_params(msg, IPAC_RXQUAL_AVE, &cp->rxqual_meas);</span><br><span style="color: hsl(120, 100%, 40%);">+  enc_meas_proc_params(msg, IPAC_RXLEV_AVE, &cp->rxlev_meas);</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 (cp->dir == GSM_PWR_CTRL_DIR_UL)</span><br><span style="color: hsl(120, 100%, 40%);">+                msgb_v_put(msg, RSL_IPAC_EIE_MS_PWR_CTL);</span><br><span style="color: hsl(120, 100%, 40%);">+     else</span><br><span style="color: hsl(120, 100%, 40%);">+          msgb_v_put(msg, RSL_IPAC_EIE_BS_PWR_CTL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   thresh = (struct ipac_preproc_pc_thresh *) msgb_put(msg, sizeof(*thresh));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* {L,U}_RXLEV_XX_P (see 3GPP TS 45.008, A.3.2.1, a & b) */</span><br><span style="color: hsl(120, 100%, 40%);">+       thresh->l_rxlev = cp->rxlev_meas.lower_thresh & 0x3f;</span><br><span style="color: hsl(120, 100%, 40%);">+       thresh->u_rxlev = cp->rxlev_meas.upper_thresh & 0x3f;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* {L,U}_RXQUAL_XX_P (see 3GPP TS 45.008, A.3.2.1, c & d) */</span><br><span style="color: hsl(120, 100%, 40%);">+      thresh->l_rxqual = cp->rxqual_meas.lower_thresh & 0x07;</span><br><span style="color: hsl(120, 100%, 40%);">+     thresh->u_rxqual = cp->rxqual_meas.upper_thresh & 0x07;</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%);">+   msgb_v_put(msg, RSL_IPAC_EIE_PC_THRESH_COMP);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       thresh_comp = (struct ipac_preproc_pc_comp *) msgb_put(msg, sizeof(*thresh_comp));</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%);">+  thresh_comp->p1 = cp->rxlev_meas.lower_cmp_p & 0x1f;</span><br><span style="color: hsl(120, 100%, 40%);">+        thresh_comp->n1 = cp->rxlev_meas.lower_cmp_n & 0x1f;</span><br><span style="color: hsl(120, 100%, 40%);">+        thresh_comp->p2 = cp->rxlev_meas.upper_cmp_p & 0x1f;</span><br><span style="color: hsl(120, 100%, 40%);">+        thresh_comp->n2 = cp->rxlev_meas.upper_cmp_n & 0x1f;</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%);">+ thresh_comp->p3 = cp->rxqual_meas.lower_cmp_p & 0x1f;</span><br><span style="color: hsl(120, 100%, 40%);">+       thresh_comp->n3 = cp->rxqual_meas.lower_cmp_n & 0x1f;</span><br><span style="color: hsl(120, 100%, 40%);">+       thresh_comp->p4 = cp->rxqual_meas.upper_cmp_p & 0x1f;</span><br><span style="color: hsl(120, 100%, 40%);">+       thresh_comp->n4 = cp->rxqual_meas.upper_cmp_n & 0x1f;</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%);">+  thresh_comp->pc_interval = 0; /* 0 .. 30 seconds */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Change step limitations: POWER_{INC,RED}_STEP_SIZE */</span><br><span style="color: hsl(120, 100%, 40%);">+      thresh_comp->inc_step_size = cp->inc_step_size_db & 0x0f;</span><br><span style="color: hsl(120, 100%, 40%);">+   thresh_comp->red_step_size = cp->red_step_size_db & 0x0f;</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%);">+static void add_power_params_ie(struct msgb *msg, enum abis_rsl_ie iei,</span><br><span style="color: hsl(120, 100%, 40%);">+                             const struct gsm_power_ctrl_params *cp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t *ie_len = msgb_tl_put(msg, iei);</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t msg_len = msgb_length(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ enc_power_params(msg, cp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  *ie_len = msgb_length(msg) - msg_len;</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%);">+static int power_ctrl_send_def_params(const struct gsm_bts_trx *trx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   const struct gsm_power_ctrl_params *ms_power_ctrl = &trx->bts->ms_power_ctrl;</span><br><span style="color: hsl(120, 100%, 40%);">+       const struct gsm_power_ctrl_params *bs_power_ctrl = &trx->bts->bs_power_ctrl;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct abis_rsl_common_hdr *ch;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Sending this message does not make sense if neither MS Power control</span><br><span style="color: hsl(120, 100%, 40%);">+        * nor BS Power control is to be performed by the BTS itself ('dyn-bts'). */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (ms_power_ctrl->mode != GSM_PWR_CTRL_MODE_DYN_BTS &&</span><br><span style="color: hsl(120, 100%, 40%);">+        bs_power_ctrl->mode != GSM_PWR_CTRL_MODE_DYN_BTS)</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%);">+   msg = rsl_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+       if (msg == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ch = (struct abis_rsl_common_hdr *) msgb_put(msg, sizeof(*ch));</span><br><span style="color: hsl(120, 100%, 40%);">+       ch->msg_discr = ABIS_RSL_MDISC_TRX;</span><br><span style="color: hsl(120, 100%, 40%);">+        ch->msg_type = RSL_MT_IPAC_MEAS_PREPROC_DFT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* BS/MS Power IEs (to be re-defined in channel specific messages) */</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_tv_put(msg, RSL_IE_MS_POWER, 0); /* dummy value */</span><br><span style="color: hsl(120, 100%, 40%);">+       msgb_tv_put(msg, RSL_IE_BS_POWER, 0); /* dummy value */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* MS/BS Power Parameters IEs */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ms_power_ctrl->mode == GSM_PWR_CTRL_MODE_DYN_BTS)</span><br><span style="color: hsl(120, 100%, 40%);">+              add_power_params_ie(msg, RSL_IE_MS_POWER_PARAM, ms_power_ctrl);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (bs_power_ctrl->mode == GSM_PWR_CTRL_MODE_DYN_BTS)</span><br><span style="color: hsl(120, 100%, 40%);">+              add_power_params_ie(msg, RSL_IE_BS_POWER_PARAM, bs_power_ctrl);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     msg->dst = trx->rsl_link;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return abis_rsl_sendmsg(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%);">+static int power_ctrl_enc_rsl_params(struct msgb *msg, const struct gsm_power_ctrl_params *cp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /* We send everything in "Measurement Pre-processing Defaults" */</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bsc/+/21683">change 21683</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-bsc/+/21683"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I3798a6a02132bafe8f1fef6e93bbb42036d76ac9 </div>
<div style="display:none"> Gerrit-Change-Number: 21683 </div>
<div style="display:none"> Gerrit-PatchSet: 6 </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>