<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/25298">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">WIP: Support set up of C/I parameters for osmo-bts MS Power Control Loop<br><br>This commit extends existing VTY and RSL infrastructure to configure and<br>manage MS Power Parameters used in MS Power Control loop, by adding<br>support to set up Carrier-to-Interference (CI) parameters.<br><br>Using C/I instead of existing RxQual is preferred due to extended<br>granularity of C/I (bigger range than RxQual's 0-7).<br>Furthermore, existing literature (such as "GSM/EDGE: Evolution and Performance"<br>Table 10.3) provides detailed information about expected target values,<br>even different values for different channel types. Hence, it was decided<br>to support setting different MS Power Parameters for different channel<br>types.<br><br>These MS Power Parameters are Osmocom specific, ie. supported only by<br>newish versions of osmo-bts. Older versions of osmo-bts should ignore<br>the new IEs added just fine. The new IEs containing the MS POwer<br>Parameters are not send for non osmo-bts BTSs, hence this commit is<br>secure with regards to running  osmo-bsc against an ip.access BTS such<br>as nanoBTS.<br><br>TODO: Update user manual!!!!<br><br>Related: SYS#4917<br>Change-Id: I7e76ec47b323d469f777624b74b08752d1f5584f<br>---<br>M doc/manuals/chapters/power_control.adoc<br>M include/osmocom/bsc/gsm_data.h<br>M src/osmo-bsc/bts_ipaccess_nanobts.c<br>M src/osmo-bsc/bts_vty.c<br>M src/osmo-bsc/gsm_data.c<br>M tests/power_ctrl.vty<br>6 files changed, 446 insertions(+), 35 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/98/25298/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/manuals/chapters/power_control.adoc b/doc/manuals/chapters/power_control.adoc</span><br><span>index 4d212f1..7b3272d 100644</span><br><span>--- a/doc/manuals/chapters/power_control.adoc</span><br><span>+++ b/doc/manuals/chapters/power_control.adoc</span><br><span>@@ -106,6 +106,8 @@</span><br><span> </span><br><span> ==== Power control mode</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+# THIS SECTION NEEDS UPDATE WHEN ADDING C/I SUPPORT!</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> Three power control modes exist:</span><br><span> </span><br><span> ----</span><br><span>diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h</span><br><span>index db0f249..234c814 100644</span><br><span>--- a/include/osmocom/bsc/gsm_data.h</span><br><span>+++ b/include/osmocom/bsc/gsm_data.h</span><br><span>@@ -1343,6 +1343,13 @@</span><br><span>       /* Measurement averaging parameters for RxLev & RxQual */</span><br><span>        struct gsm_power_ctrl_meas_params rxqual_meas;</span><br><span>       struct gsm_power_ctrl_meas_params rxlev_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Measurement averaging parameters for C/I: */</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_power_ctrl_meas_params ci_fr_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_meas_params ci_hr_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_meas_params ci_amr_fr_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gsm_power_ctrl_meas_params ci_amr_hr_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct gsm_power_ctrl_meas_params ci_sdcch_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_power_ctrl_meas_params ci_gprs_meas;</span><br><span> };</span><br><span> </span><br><span> extern const struct gsm_power_ctrl_params power_ctrl_params_def;</span><br><span>diff --git a/src/osmo-bsc/bts_ipaccess_nanobts.c b/src/osmo-bsc/bts_ipaccess_nanobts.c</span><br><span>index 8d2908f..d26f13f 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>@@ -867,10 +867,65 @@</span><br><span>       *ie_len = msg->tail - (ie_len + 1);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void enc_osmo_meas_proc_params(struct msgb *msg, const struct gsm_power_ctrl_params *mp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_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->ci_fr_meas.algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE &&</span><br><span style="color: hsl(120, 100%, 40%);">+          mp->ci_hr_meas.algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE &&</span><br><span style="color: hsl(120, 100%, 40%);">+          mp->ci_amr_fr_meas.algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE &&</span><br><span style="color: hsl(120, 100%, 40%);">+      mp->ci_amr_hr_meas.algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE &&</span><br><span style="color: hsl(120, 100%, 40%);">+      mp->ci_sdcch_meas.algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE &&</span><br><span style="color: hsl(120, 100%, 40%);">+       mp->ci_gprs_meas.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_OSMO_MEAS_AVG_CFG);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  ave_cfg = (struct osmo_preproc_ave_cfg *) msgb_put(msg, sizeof(*ave_cfg));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define ENC_PROC(PARAMS, TO, TYPE) do { \</span><br><span style="color: hsl(120, 100%, 40%);">+       (TO)->TYPE.ave_enabled = (PARAMS)->TYPE##_meas.algo != GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE; \</span><br><span style="color: hsl(120, 100%, 40%);">+       if ((TO)->TYPE.ave_enabled) { \</span><br><span style="color: hsl(120, 100%, 40%);">+            /* H_REQAVE and H_REQT */ \</span><br><span style="color: hsl(120, 100%, 40%);">+           (TO)->TYPE.h_reqave = (PARAMS)->TYPE##_meas.h_reqave & 0x1f; \</span><br><span style="color: hsl(120, 100%, 40%);">+              (TO)->TYPE.h_reqt = (PARAMS)->TYPE##_meas.h_reqt & 0x1f; \</span><br><span style="color: hsl(120, 100%, 40%);">+          /* Averaging method and parameters */ \</span><br><span style="color: hsl(120, 100%, 40%);">+               (TO)->TYPE.ave_method = ((PARAMS)->TYPE##_meas.algo - 1) & 0x07; \</span><br><span style="color: hsl(120, 100%, 40%);">+          switch ((PARAMS)->TYPE##_meas.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, (PARAMS)->TYPE##_meas.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%);">+   } while (0)</span><br><span style="color: hsl(120, 100%, 40%);">+   ENC_PROC(mp, ave_cfg, ci_fr);</span><br><span style="color: hsl(120, 100%, 40%);">+ ENC_PROC(mp, ave_cfg, ci_hr);</span><br><span style="color: hsl(120, 100%, 40%);">+ ENC_PROC(mp, ave_cfg, ci_amr_fr);</span><br><span style="color: hsl(120, 100%, 40%);">+     ENC_PROC(mp, ave_cfg, ci_amr_hr);</span><br><span style="color: hsl(120, 100%, 40%);">+     ENC_PROC(mp, ave_cfg, ci_sdcch);</span><br><span style="color: hsl(120, 100%, 40%);">+      ENC_PROC(mp, ave_cfg, ci_gprs);</span><br><span style="color: hsl(120, 100%, 40%);">+#undef ENC_PROC</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> static void enc_power_params(struct msgb *msg, const struct gsm_power_ctrl_params *cp)</span><br><span> {</span><br><span>   struct ipac_preproc_pc_comp *thresh_comp;</span><br><span>    struct ipac_preproc_pc_thresh *thresh;</span><br><span style="color: hsl(120, 100%, 40%);">+        bool add_ci_ext;</span><br><span> </span><br><span>         /* These parameters are valid for dynamic mode only */</span><br><span>       OSMO_ASSERT(cp->mode == GSM_PWR_CTRL_MODE_DYN_BTS);</span><br><span>@@ -918,6 +973,55 @@</span><br><span>        /* Change step limitations: POWER_{INC,RED}_STEP_SIZE */</span><br><span>     thresh_comp->inc_step_size = cp->inc_step_size_db & 0x0f;</span><br><span>  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%);">+ if (cp->dir == GSM_PWR_CTRL_DIR_UL) {</span><br><span style="color: hsl(120, 100%, 40%);">+              const struct gsm_bts *bts = container_of(cp, struct gsm_bts, ms_power_ctrl);</span><br><span style="color: hsl(120, 100%, 40%);">+          add_ci_ext = is_osmobts(bts);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              add_ci_ext = false;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (add_ci_ext) {</span><br><span style="color: hsl(120, 100%, 40%);">+             struct osmo_preproc_pc_thresh *osmo_thresh;</span><br><span style="color: hsl(120, 100%, 40%);">+           struct osmo_preproc_pc_comp *osmo_thresh_comp;</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%);">+            /* (TLV) Measurement Averaging Configure (C/I) */</span><br><span style="color: hsl(120, 100%, 40%);">+             enc_osmo_meas_proc_params(msg, cp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* (TLV) Thresholds (C/I) */</span><br><span style="color: hsl(120, 100%, 40%);">+          ie_len = msgb_tl_put(msg, RSL_IPAC_EIE_OSMO_MS_PWR_CTL);</span><br><span style="color: hsl(120, 100%, 40%);">+              osmo_thresh = (struct osmo_preproc_pc_thresh *) msgb_put(msg, sizeof(*osmo_thresh));</span><br><span style="color: hsl(120, 100%, 40%);">+          #define ENC_THRESH_CI(TYPE) \</span><br><span style="color: hsl(120, 100%, 40%);">+                 osmo_thresh->l_##TYPE = cp->TYPE##_meas.lower_thresh; \</span><br><span style="color: hsl(120, 100%, 40%);">+                 osmo_thresh->u_##TYPE = cp->TYPE##_meas.upper_thresh</span><br><span style="color: hsl(120, 100%, 40%);">+            ENC_THRESH_CI(ci_fr);</span><br><span style="color: hsl(120, 100%, 40%);">+         ENC_THRESH_CI(ci_hr);</span><br><span style="color: hsl(120, 100%, 40%);">+         ENC_THRESH_CI(ci_amr_fr);</span><br><span style="color: hsl(120, 100%, 40%);">+             ENC_THRESH_CI(ci_amr_hr);</span><br><span style="color: hsl(120, 100%, 40%);">+             ENC_THRESH_CI(ci_sdcch);</span><br><span style="color: hsl(120, 100%, 40%);">+              ENC_THRESH_CI(ci_gprs);</span><br><span style="color: hsl(120, 100%, 40%);">+               #undef ENC_THRESH_CI</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%);">+              /* (TLV) PC Threshold Comparators (C/I) */</span><br><span style="color: hsl(120, 100%, 40%);">+            ie_len = msgb_tl_put(msg, RSL_IPAC_EIE_OSMO_PC_THRESH_COMP);</span><br><span style="color: hsl(120, 100%, 40%);">+          osmo_thresh_comp = (struct osmo_preproc_pc_comp *) msgb_put(msg, sizeof(*osmo_thresh_comp));</span><br><span style="color: hsl(120, 100%, 40%);">+          #define ENC_THRESH_CI(TYPE) \</span><br><span style="color: hsl(120, 100%, 40%);">+                 osmo_thresh_comp->TYPE.lower_p = cp->TYPE##_meas.lower_cmp_p & 0x1f; \</span><br><span style="color: hsl(120, 100%, 40%);">+                      osmo_thresh_comp->TYPE.lower_n = cp->TYPE##_meas.lower_cmp_n & 0x1f; \</span><br><span style="color: hsl(120, 100%, 40%);">+                      osmo_thresh_comp->TYPE.upper_p = cp->TYPE##_meas.upper_cmp_p & 0x1f; \</span><br><span style="color: hsl(120, 100%, 40%);">+                      osmo_thresh_comp->TYPE.upper_n = cp->TYPE##_meas.upper_cmp_n & 0x1f</span><br><span style="color: hsl(120, 100%, 40%);">+         ENC_THRESH_CI(ci_fr);</span><br><span style="color: hsl(120, 100%, 40%);">+         ENC_THRESH_CI(ci_hr);</span><br><span style="color: hsl(120, 100%, 40%);">+         ENC_THRESH_CI(ci_amr_fr);</span><br><span style="color: hsl(120, 100%, 40%);">+             ENC_THRESH_CI(ci_amr_hr);</span><br><span style="color: hsl(120, 100%, 40%);">+             ENC_THRESH_CI(ci_sdcch);</span><br><span style="color: hsl(120, 100%, 40%);">+              ENC_THRESH_CI(ci_gprs);</span><br><span style="color: hsl(120, 100%, 40%);">+               #undef ENC_THRESH_CI</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> }</span><br><span> </span><br><span> static void add_power_params_ie(struct msgb *msg, enum abis_rsl_ie iei,</span><br><span>diff --git a/src/osmo-bsc/bts_vty.c b/src/osmo-bsc/bts_vty.c</span><br><span>index 2b7b42b..e9df22f 100644</span><br><span>--- a/src/osmo-bsc/bts_vty.c</span><br><span>+++ b/src/osmo-bsc/bts_vty.c</span><br><span>@@ -3000,6 +3000,8 @@</span><br><span>   "RxLev value (signal strength, 0 is worst, 63 is best)\n"</span><br><span> #define POWER_CONTROL_MEAS_RXQUAL_DESC \</span><br><span>      "RxQual value (signal quality, 0 is best, 7 is worst)\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define POWER_CONTROL_MEAS_CI_DESC \</span><br><span style="color: hsl(120, 100%, 40%);">+      "C/I value (Carrier-to-Interference (dB), 0 is worst, 30 is best)\n"</span><br><span> </span><br><span> DEFUN_USRATTR(cfg_power_ctrl_rxlev_thresh,</span><br><span>           cfg_power_ctrl_rxlev_thresh_cmd,</span><br><span>@@ -3056,10 +3058,74 @@</span><br><span>     return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define VTY_CMD_CI_TYPE "(fr-efr|hr|amr-fr|amr-hr|sdcch|gprs)"</span><br><span style="color: hsl(120, 100%, 40%);">+#define VTY_DESC_CI_TYPE \</span><br><span style="color: hsl(120, 100%, 40%);">+    "Channel Type FR/EFR\n" \</span><br><span style="color: hsl(120, 100%, 40%);">+   "Channel Type HR\n" \</span><br><span style="color: hsl(120, 100%, 40%);">+       "Channel Type AMR FR\n" \</span><br><span style="color: hsl(120, 100%, 40%);">+   "Channel Type AMR HR\n" \</span><br><span style="color: hsl(120, 100%, 40%);">+   "Channel Type SDCCH\n" \</span><br><span style="color: hsl(120, 100%, 40%);">+    "Channel Type (E)GPRS\n"</span><br><span style="color: hsl(120, 100%, 40%);">+static struct gsm_power_ctrl_meas_params *ci_thresh_by_conn_type(struct gsm_power_ctrl_params *params, const char *type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!strcmp(type, "fr-efr"))</span><br><span style="color: hsl(120, 100%, 40%);">+                return &params->ci_fr_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!strcmp(type, "hr"))</span><br><span style="color: hsl(120, 100%, 40%);">+            return &params->ci_hr_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!strcmp(type, "amr-fr"))</span><br><span style="color: hsl(120, 100%, 40%);">+                return &params->ci_amr_fr_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!strcmp(type, "amr-hr"))</span><br><span style="color: hsl(120, 100%, 40%);">+                return &params->ci_amr_hr_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!strcmp(type, "sdcch"))</span><br><span style="color: hsl(120, 100%, 40%);">+         return &params->ci_sdcch_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcmp(type, "gprs"))</span><br><span style="color: hsl(120, 100%, 40%);">+          return &params->ci_gprs_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+   return NULL;</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%);">+DEFUN_USRATTR(cfg_power_ctrl_ci_thresh,</span><br><span style="color: hsl(120, 100%, 40%);">+          cfg_power_ctrl_ci_thresh_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+         X(BSC_VTY_ATTR_VENDOR_SPECIFIC) |</span><br><span style="color: hsl(120, 100%, 40%);">+             X(BSC_VTY_ATTR_NEW_LCHAN),</span><br><span style="color: hsl(120, 100%, 40%);">+            "ci-thresh " VTY_CMD_CI_TYPE " lower <0-30> upper <0-30>",</span><br><span style="color: hsl(120, 100%, 40%);">+            "Set target C/I thresholds (for dynamic mode), only available in ms-power-control\n"</span><br><span style="color: hsl(120, 100%, 40%);">+        VTY_DESC_CI_TYPE</span><br><span style="color: hsl(120, 100%, 40%);">+              "Lower C/I value\n"</span><br><span style="color: hsl(120, 100%, 40%);">+         "Lower " POWER_CONTROL_MEAS_RXQUAL_DESC</span><br><span style="color: hsl(120, 100%, 40%);">+             "Upper C/I value\n"</span><br><span style="color: hsl(120, 100%, 40%);">+         "Upper " POWER_CONTROL_MEAS_RXQUAL_DESC)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm_power_ctrl_params *params = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *type = argv[0];</span><br><span style="color: hsl(120, 100%, 40%);">+   int lower = atoi(argv[1]);</span><br><span style="color: hsl(120, 100%, 40%);">+    int upper = atoi(argv[2]);</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm_power_ctrl_meas_params *meas_params;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (params->dir != GSM_PWR_CTRL_DIR_UL) {</span><br><span style="color: hsl(120, 100%, 40%);">+          vty_out(vty, "%% C/I based power loop only possible in Uplink!%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+            return CMD_WARNING;</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%);">+   if (lower > upper) {</span><br><span style="color: hsl(120, 100%, 40%);">+               vty_out(vty, "%% Lower 'rxqual-rxqual' (%d) must be less than upper (%d)%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                        upper, lower, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+           return CMD_WARNING;</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%);">+   meas_params = ci_thresh_by_conn_type(params, type);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_params->lower_thresh = lower;</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_params->upper_thresh = upper;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define POWER_CONTROL_MEAS_THRESH_COMP_CMD(meas) \</span><br><span>       meas " lower <0-31> <0-31> upper <0-31> <0-31>"</span><br><span style="color: hsl(0, 100%, 40%);">-#define POWER_CONTROL_MEAS_THRESH_COMP_DESC(meas, lp, ln, up, un) \</span><br><span style="color: hsl(120, 100%, 40%);">+#define POWER_CONTROL_MEAS_THRESH_COMP_DESC(meas, opt_param, lp, ln, up, un) \</span><br><span>         "Set " meas " threshold comparators (for dynamic mode)\n" \</span><br><span style="color: hsl(120, 100%, 40%);">+       opt_param \</span><br><span>  "Lower " meas " threshold comparators (see 3GPP TS 45.008, A.3.2.1)\n" lp ln \</span><br><span>   "Upper " meas " threshold comparators (see 3GPP TS 45.008, A.3.2.1)\n" up un</span><br><span> </span><br><span>@@ -3068,7 +3134,7 @@</span><br><span>               X(BSC_VTY_ATTR_VENDOR_SPECIFIC) |</span><br><span>            X(BSC_VTY_ATTR_NEW_LCHAN),</span><br><span>           POWER_CONTROL_MEAS_THRESH_COMP_CMD("rxlev-thresh-comp"),</span><br><span style="color: hsl(0, 100%, 40%);">-              POWER_CONTROL_MEAS_THRESH_COMP_DESC("RxLev",</span><br><span style="color: hsl(120, 100%, 40%);">+        POWER_CONTROL_MEAS_THRESH_COMP_DESC("RxLev",,</span><br><span>                "P1 (default 10)\n", "N1 (default 12)\n",</span><br><span>                "P2 (default 10)\n", "N2 (default 12)\n"))</span><br><span> {</span><br><span>@@ -3103,7 +3169,7 @@</span><br><span>        X(BSC_VTY_ATTR_VENDOR_SPECIFIC) |</span><br><span>            X(BSC_VTY_ATTR_NEW_LCHAN),</span><br><span>           POWER_CONTROL_MEAS_THRESH_COMP_CMD("rxqual-thresh-comp"),</span><br><span style="color: hsl(0, 100%, 40%);">-             POWER_CONTROL_MEAS_THRESH_COMP_DESC("RxQual",</span><br><span style="color: hsl(120, 100%, 40%);">+       POWER_CONTROL_MEAS_THRESH_COMP_DESC("RxQual",,</span><br><span>               "P3 (default 5)\n", "N3 (default 7)\n",</span><br><span>          "P4 (default 15)\n", "N4 (default 18)\n"))</span><br><span> {</span><br><span>@@ -3133,6 +3199,45 @@</span><br><span>         return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN_USRATTR(cfg_power_ctrl_ci_thresh_comp,</span><br><span style="color: hsl(120, 100%, 40%);">+          cfg_power_ctrl_ci_thresh_comp_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+            X(BSC_VTY_ATTR_VENDOR_SPECIFIC) |</span><br><span style="color: hsl(120, 100%, 40%);">+             X(BSC_VTY_ATTR_NEW_LCHAN),</span><br><span style="color: hsl(120, 100%, 40%);">+            POWER_CONTROL_MEAS_THRESH_COMP_CMD("ci-thresh-comp " VTY_CMD_CI_TYPE),</span><br><span style="color: hsl(120, 100%, 40%);">+              POWER_CONTROL_MEAS_THRESH_COMP_DESC("Carrier-to_interference (C/I)",</span><br><span style="color: hsl(120, 100%, 40%);">+          VTY_DESC_CI_TYPE,</span><br><span style="color: hsl(120, 100%, 40%);">+             "Lower P (default 5)\n", "Upper N (default 7)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+         "Upper P (default 15)\n", "Upper N (default 18)\n"))</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm_power_ctrl_params *params = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_meas_params *meas_params;</span><br><span style="color: hsl(120, 100%, 40%);">+       int lower_cmp_p = atoi(argv[1]);</span><br><span style="color: hsl(120, 100%, 40%);">+      int lower_cmp_n = atoi(argv[2]);</span><br><span style="color: hsl(120, 100%, 40%);">+      int upper_cmp_p = atoi(argv[3]);</span><br><span style="color: hsl(120, 100%, 40%);">+      int upper_cmp_n = atoi(argv[4]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (lower_cmp_p > lower_cmp_n) {</span><br><span style="color: hsl(120, 100%, 40%);">+           vty_out(vty, "%% Lower C/I P %d must be less than N %d%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                  lower_cmp_p, lower_cmp_n, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+               return CMD_WARNING;</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%);">+   if (upper_cmp_p > upper_cmp_n) {</span><br><span style="color: hsl(120, 100%, 40%);">+           vty_out(vty, "%% Upper C/I P %d must be less than N %d%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                  lower_cmp_p, lower_cmp_n, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+               return CMD_WARNING;</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%);">+   meas_params = ci_thresh_by_conn_type(params, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      meas_params->lower_cmp_p = lower_cmp_p;</span><br><span style="color: hsl(120, 100%, 40%);">+    meas_params->lower_cmp_n = lower_cmp_n;</span><br><span style="color: hsl(120, 100%, 40%);">+    meas_params->upper_cmp_p = upper_cmp_p;</span><br><span style="color: hsl(120, 100%, 40%);">+    meas_params->upper_cmp_n = upper_cmp_n;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #define POWER_CONTROL_MEAS_AVG_CMD \</span><br><span>     "(rxlev-avg|rxqual-avg)"</span><br><span> #define POWER_CONTROL_MEAS_AVG_DESC \</span><br><span>@@ -3244,6 +3349,114 @@</span><br><span>        return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* C/I related power control measurements */</span><br><span style="color: hsl(120, 100%, 40%);">+#define POWER_CONTROL_CI_MEAS_AVG_DESC \</span><br><span style="color: hsl(120, 100%, 40%);">+  "C/I (Carrier-toInterference) measurement averaging (for dynamic mode)\n"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN_USRATTR(cfg_power_ctrl_no_ci_avg,</span><br><span style="color: hsl(120, 100%, 40%);">+              cfg_power_ctrl_no_ci_avg_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+         X(BSC_VTY_ATTR_VENDOR_SPECIFIC) |</span><br><span style="color: hsl(120, 100%, 40%);">+             X(BSC_VTY_ATTR_NEW_LCHAN),</span><br><span style="color: hsl(120, 100%, 40%);">+            "no ci-avg " VTY_CMD_CI_TYPE,</span><br><span style="color: hsl(120, 100%, 40%);">+       NO_STR POWER_CONTROL_CI_MEAS_AVG_DESC VTY_DESC_CI_TYPE)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct gsm_power_ctrl_params *params = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_meas_params *avg_params;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      avg_params = ci_thresh_by_conn_type(params, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+ avg_params->algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return CMD_SUCCESS;</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%);">+DEFUN_USRATTR(cfg_power_ctrl_ci_avg_params,</span><br><span style="color: hsl(120, 100%, 40%);">+       cfg_power_ctrl_ci_avg_params_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+             X(BSC_VTY_ATTR_VENDOR_SPECIFIC) |</span><br><span style="color: hsl(120, 100%, 40%);">+             X(BSC_VTY_ATTR_NEW_LCHAN),</span><br><span style="color: hsl(120, 100%, 40%);">+            "ci-avg " VTY_CMD_CI_TYPE " params hreqave <1-31> hreqt <1-31>",</span><br><span style="color: hsl(120, 100%, 40%);">+              POWER_CONTROL_CI_MEAS_AVG_DESC VTY_DESC_CI_TYPE</span><br><span style="color: hsl(120, 100%, 40%);">+       "Configure general averaging parameters\n"</span><br><span style="color: hsl(120, 100%, 40%);">+          "Hreqave: the period over which an average is produced\n"</span><br><span style="color: hsl(120, 100%, 40%);">+           "Hreqave value (so that Hreqave * Hreqt < 32)\n"</span><br><span style="color: hsl(120, 100%, 40%);">+         "Hreqt: the number of averaged results that are maintained\n"</span><br><span style="color: hsl(120, 100%, 40%);">+       "Hreqt value (so that Hreqave * Hreqt < 32)\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_params *params = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_meas_params *avg_params;</span><br><span style="color: hsl(120, 100%, 40%);">+        int h_reqave = atoi(argv[1]);</span><br><span style="color: hsl(120, 100%, 40%);">+ int h_reqt = atoi(argv[2]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (h_reqave * h_reqt > 31) {</span><br><span style="color: hsl(120, 100%, 40%);">+              vty_out(vty, "%% Hreqave (%d) * Hreqt (%d) = %d must be < 32%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                 h_reqave, h_reqt, h_reqave * h_reqt, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+            return CMD_WARNING;</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%);">+   avg_params = ci_thresh_by_conn_type(params, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+ avg_params->h_reqave = h_reqave;</span><br><span style="color: hsl(120, 100%, 40%);">+   avg_params->h_reqt = h_reqt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return CMD_SUCCESS;</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%);">+DEFUN_USRATTR(cfg_power_ctrl_ci_avg_algo,</span><br><span style="color: hsl(120, 100%, 40%);">+         cfg_power_ctrl_ci_avg_algo_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+       X(BSC_VTY_ATTR_VENDOR_SPECIFIC) |</span><br><span style="color: hsl(120, 100%, 40%);">+             X(BSC_VTY_ATTR_NEW_LCHAN),</span><br><span style="color: hsl(120, 100%, 40%);">+            /* FIXME: add algorithm specific parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+        "ci-avg " VTY_CMD_CI_TYPE " algo (unweighted|weighted|mod-median)",</span><br><span style="color: hsl(120, 100%, 40%);">+       POWER_CONTROL_CI_MEAS_AVG_DESC VTY_DESC_CI_TYPE</span><br><span style="color: hsl(120, 100%, 40%);">+       "Select the averaging algorithm\n"</span><br><span style="color: hsl(120, 100%, 40%);">+          "Un-weighted average\n" "Weighted average\n"</span><br><span style="color: hsl(120, 100%, 40%);">+              "Modified median calculation\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm_power_ctrl_params *params = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_meas_params *avg_params;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      avg_params = ci_thresh_by_conn_type(params, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strcmp(argv[1], "unweighted") == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+             avg_params->algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_UNWEIGHTED;</span><br><span style="color: hsl(120, 100%, 40%);">+  else if (strcmp(argv[1], "weighted") == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          avg_params->algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_WEIGHTED;</span><br><span style="color: hsl(120, 100%, 40%);">+    else if (strcmp(argv[1], "mod-median") == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                avg_params->algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_MOD_MEDIAN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return CMD_SUCCESS;</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%);">+DEFUN_USRATTR(cfg_power_ctrl_ci_avg_osmo_ewma,</span><br><span style="color: hsl(120, 100%, 40%);">+            cfg_power_ctrl_ci_avg_osmo_ewma_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+          X(BSC_VTY_ATTR_VENDOR_SPECIFIC) |</span><br><span style="color: hsl(120, 100%, 40%);">+             X(BSC_VTY_ATTR_NEW_LCHAN),</span><br><span style="color: hsl(120, 100%, 40%);">+            "ci-avg " VTY_CMD_CI_TYPE " algo osmo-ewma beta <1-99>",</span><br><span style="color: hsl(120, 100%, 40%);">+            POWER_CONTROL_CI_MEAS_AVG_DESC VTY_DESC_CI_TYPE</span><br><span style="color: hsl(120, 100%, 40%);">+       "Select the averaging algorithm\n"</span><br><span style="color: hsl(120, 100%, 40%);">+          "Exponentially Weighted Moving Average (EWMA)\n"</span><br><span style="color: hsl(120, 100%, 40%);">+            "Smoothing factor (in %): beta = (100 - alpha)\n"</span><br><span style="color: hsl(120, 100%, 40%);">+           "1% - lowest smoothing, 99% - highest smoothing\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct gsm_power_ctrl_params *params = vty->index;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_power_ctrl_meas_params *avg_params;</span><br><span style="color: hsl(120, 100%, 40%);">+        const struct gsm_bts *bts;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (params->dir == GSM_PWR_CTRL_DIR_UL)</span><br><span style="color: hsl(120, 100%, 40%);">+            bts = container_of(params, struct gsm_bts, ms_power_ctrl);</span><br><span style="color: hsl(120, 100%, 40%);">+    else</span><br><span style="color: hsl(120, 100%, 40%);">+          bts = container_of(params, struct gsm_bts, bs_power_ctrl);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (bts->type != GSM_BTS_TYPE_OSMOBTS) {</span><br><span style="color: hsl(120, 100%, 40%);">+           vty_out(vty, "%% EWMA is an OsmoBTS specific algorithm, "</span><br><span style="color: hsl(120, 100%, 40%);">+                   "it's not usable for other BTS types%s", VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+          return CMD_WARNING;</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%);">+   avg_params = ci_thresh_by_conn_type(params, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+ avg_params->algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA;</span><br><span style="color: hsl(120, 100%, 40%);">+   avg_params->ewma.alpha = 100 - atoi(argv[1]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void vty_out_neigh_list(struct vty *vty, struct bitvec *bv)</span><br><span> {</span><br><span>  int count = 0;</span><br><span>@@ -3619,31 +3832,14 @@</span><br><span>     vty_out(vty, "%*s" fmt, indent, "", ##args);</span><br><span> </span><br><span> static void config_write_power_ctrl_meas(struct vty *vty, unsigned int indent,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   const struct gsm_power_ctrl_params *cp,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         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%);">+                                  const char *param, const char *param2)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    const struct gsm_power_ctrl_meas_params *mp;</span><br><span style="color: hsl(0, 100%, 40%);">-    const char *param;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      switch (ptype) {</span><br><span style="color: hsl(0, 100%, 40%);">-        case IPAC_RXLEV_AVE:</span><br><span style="color: hsl(0, 100%, 40%);">-            mp = &cp->rxlev_meas;</span><br><span style="color: hsl(0, 100%, 40%);">-            param = "rxlev";</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case IPAC_RXQUAL_AVE:</span><br><span style="color: hsl(0, 100%, 40%);">-           mp = &cp->rxqual_meas;</span><br><span style="color: hsl(0, 100%, 40%);">-           param = "rxqual";</span><br><span style="color: hsl(0, 100%, 40%);">-             break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                /* Shall not happen */</span><br><span style="color: hsl(0, 100%, 40%);">-          OSMO_ASSERT(0);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       cfg_out("%s-thresh lower %u upper %u%s",</span><br><span style="color: hsl(0, 100%, 40%);">-              param, mp->lower_thresh, mp->upper_thresh,</span><br><span style="color: hsl(120, 100%, 40%);">+      cfg_out("%s-thresh%s lower %u upper %u%s",</span><br><span style="color: hsl(120, 100%, 40%);">+          param, param2, mp->lower_thresh, mp->upper_thresh,</span><br><span>             VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-   cfg_out("%s-thresh-comp lower %u %u upper %u %u%s",</span><br><span style="color: hsl(0, 100%, 40%);">-           param, mp->lower_cmp_p, mp->lower_cmp_n,</span><br><span style="color: hsl(120, 100%, 40%);">+        cfg_out("%s-thresh-comp%s lower %u %u upper %u %u%s",</span><br><span style="color: hsl(120, 100%, 40%);">+               param, param2, mp->lower_cmp_p, mp->lower_cmp_n,</span><br><span>               mp->upper_cmp_p, mp->upper_cmp_n,</span><br><span>              VTY_NEWLINE);</span><br><span> </span><br><span>@@ -3652,23 +3848,23 @@</span><br><span>          /* Do not print any averaging parameters */</span><br><span>          return; /* we're done */</span><br><span>         case GSM_PWR_CTRL_MEAS_AVG_ALGO_UNWEIGHTED:</span><br><span style="color: hsl(0, 100%, 40%);">-             cfg_out("%s-avg algo unweighted%s", param, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+            cfg_out("%s-avg%s algo unweighted%s", param, param2, VTY_NEWLINE);</span><br><span>                 break;</span><br><span>       case GSM_PWR_CTRL_MEAS_AVG_ALGO_WEIGHTED:</span><br><span style="color: hsl(0, 100%, 40%);">-               cfg_out("%s-avg algo weighted%s", param, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+              cfg_out("%s-avg%s algo weighted%s", param, param2, VTY_NEWLINE);</span><br><span>           break;</span><br><span>       case GSM_PWR_CTRL_MEAS_AVG_ALGO_MOD_MEDIAN:</span><br><span style="color: hsl(0, 100%, 40%);">-             cfg_out("%s-avg algo mod-median%s", param, VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+            cfg_out("%s-avg%s algo mod-median%s", param, param2, VTY_NEWLINE);</span><br><span>                 break;</span><br><span>       case GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA:</span><br><span style="color: hsl(0, 100%, 40%);">-              cfg_out("%s-avg algo osmo-ewma beta %u%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                    param, 100 - mp->ewma.alpha,</span><br><span style="color: hsl(120, 100%, 40%);">+               cfg_out("%s-avg%s algo osmo-ewma beta %u%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                        param, param2, 100 - mp->ewma.alpha,</span><br><span>                      VTY_NEWLINE);</span><br><span>                break;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   cfg_out("%s-avg params hreqave %u hreqt %u%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                param, mp->h_reqave, mp->h_reqt,</span><br><span style="color: hsl(120, 100%, 40%);">+        cfg_out("%s-avg%s params hreqave %u hreqt %u%s",</span><br><span style="color: hsl(120, 100%, 40%);">+            param, param2, mp->h_reqave, mp->h_reqt,</span><br><span>               VTY_NEWLINE);</span><br><span> }</span><br><span> </span><br><span>@@ -3705,8 +3901,14 @@</span><br><span>                      VTY_NEWLINE);</span><br><span> </span><br><span>            /* Measurement processing / averaging parameters */</span><br><span style="color: hsl(0, 100%, 40%);">-             config_write_power_ctrl_meas(vty, indent + 1, cp, IPAC_RXLEV_AVE);</span><br><span style="color: hsl(0, 100%, 40%);">-              config_write_power_ctrl_meas(vty, indent + 1, cp, IPAC_RXQUAL_AVE);</span><br><span style="color: hsl(120, 100%, 40%);">+           config_write_power_ctrl_meas(vty, indent + 1, &cp->rxlev_meas, "rxlev", "");</span><br><span style="color: hsl(120, 100%, 40%);">+               config_write_power_ctrl_meas(vty, indent + 1, &cp->rxqual_meas, "rxqual", "");</span><br><span style="color: hsl(120, 100%, 40%);">+             config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_fr_meas, "ci", " fr");</span><br><span style="color: hsl(120, 100%, 40%);">+               config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_hr_meas, "ci", " hr");</span><br><span style="color: hsl(120, 100%, 40%);">+               config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_amr_fr_meas, "ci", " amr-fr");</span><br><span style="color: hsl(120, 100%, 40%);">+               config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_amr_hr_meas, "ci", " amr-hr");</span><br><span style="color: hsl(120, 100%, 40%);">+               config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_sdcch_meas, "ci", " sdcch");</span><br><span style="color: hsl(120, 100%, 40%);">+         config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_gprs_meas, "ci", " gprs");</span><br><span>          break;</span><br><span>       }</span><br><span> }</span><br><span>@@ -4199,12 +4401,18 @@</span><br><span>     install_element(POWER_CTRL_NODE, &cfg_power_ctrl_step_size_cmd);</span><br><span>         install_element(POWER_CTRL_NODE, &cfg_power_ctrl_rxlev_thresh_cmd);</span><br><span>      install_element(POWER_CTRL_NODE, &cfg_power_ctrl_rxqual_thresh_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+      install_element(POWER_CTRL_NODE, &cfg_power_ctrl_ci_thresh_cmd);</span><br><span>         install_element(POWER_CTRL_NODE, &cfg_power_ctrl_rxlev_thresh_comp_cmd);</span><br><span>         install_element(POWER_CTRL_NODE, &cfg_power_ctrl_rxqual_thresh_comp_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(POWER_CTRL_NODE, &cfg_power_ctrl_ci_thresh_comp_cmd);</span><br><span>    install_element(POWER_CTRL_NODE, &cfg_power_ctrl_no_avg_cmd);</span><br><span>    install_element(POWER_CTRL_NODE, &cfg_power_ctrl_avg_params_cmd);</span><br><span>        install_element(POWER_CTRL_NODE, &cfg_power_ctrl_avg_algo_cmd);</span><br><span>  install_element(POWER_CTRL_NODE, &cfg_power_ctrl_avg_osmo_ewma_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+      install_element(POWER_CTRL_NODE, &cfg_power_ctrl_no_ci_avg_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+  install_element(POWER_CTRL_NODE, &cfg_power_ctrl_ci_avg_params_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+      install_element(POWER_CTRL_NODE, &cfg_power_ctrl_ci_avg_algo_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+        install_element(POWER_CTRL_NODE, &cfg_power_ctrl_ci_avg_osmo_ewma_cmd);</span><br><span> </span><br><span> </span><br><span>  return bts_trx_vty_init();</span><br><span>diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c</span><br><span>index e976a5b..2fb98dd 100644</span><br><span>--- a/src/osmo-bsc/gsm_data.c</span><br><span>+++ b/src/osmo-bsc/gsm_data.c</span><br><span>@@ -1189,6 +1189,72 @@</span><br><span>                 /* Hreqt: the number of averaged results maintained */</span><br><span>               .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span>      },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* C/I measurement parameters.</span><br><span style="color: hsl(120, 100%, 40%);">+         * Target C/I retrieved from "GSM/EDGE: Evolution and Performance" Table 10.3.</span><br><span style="color: hsl(120, 100%, 40%);">+       * Set lower and upper so that (lower + upper) / 2 is equal or slightly</span><br><span style="color: hsl(120, 100%, 40%);">+        * above the target.</span><br><span style="color: hsl(120, 100%, 40%);">+   */</span><br><span style="color: hsl(120, 100%, 40%);">+   .ci_fr_meas = { /* Target C/I = 15 dB, Soft blocking threshold = 10 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+             .lower_thresh = 13,</span><br><span style="color: hsl(120, 100%, 40%);">+           .upper_thresh = 17,</span><br><span style="color: hsl(120, 100%, 40%);">+           /* FIXME: C/I averaging is not yet implemented */</span><br><span style="color: hsl(120, 100%, 40%);">+             .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+           .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+                .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+       },</span><br><span style="color: hsl(120, 100%, 40%);">+    .ci_hr_meas = { /* Target C/I = 18 dB, Soft blocking threshold = 13 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+             .lower_thresh = 16,</span><br><span style="color: hsl(120, 100%, 40%);">+           .upper_thresh = 21,</span><br><span style="color: hsl(120, 100%, 40%);">+           /* FIXME: C/I averaging is not yet implemented */</span><br><span style="color: hsl(120, 100%, 40%);">+             .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+           .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+                .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+       },</span><br><span style="color: hsl(120, 100%, 40%);">+    .ci_amr_fr_meas = { /* Target C/I = 9 dB, Soft blocking threshold = 4 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+           .lower_thresh = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+            .upper_thresh = 11,</span><br><span style="color: hsl(120, 100%, 40%);">+           /* FIXME: C/I averaging is not yet implemented */</span><br><span style="color: hsl(120, 100%, 40%);">+             .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+           .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+                .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+       },</span><br><span style="color: hsl(120, 100%, 40%);">+    .ci_amr_hr_meas = { /* Target C/I = 15 dB, Soft blocking threshold = 10 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+         .lower_thresh = 13,</span><br><span style="color: hsl(120, 100%, 40%);">+           .upper_thresh = 17,</span><br><span style="color: hsl(120, 100%, 40%);">+           /* FIXME: C/I averaging is not yet implemented */</span><br><span style="color: hsl(120, 100%, 40%);">+             .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+           .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+                .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+       },</span><br><span style="color: hsl(120, 100%, 40%);">+    .ci_sdcch_meas = { /* Target C/I = 14 dB, Soft blocking threshold = 9 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+           .lower_thresh = 12,</span><br><span style="color: hsl(120, 100%, 40%);">+           .upper_thresh = 16,</span><br><span style="color: hsl(120, 100%, 40%);">+           /* FIXME: C/I averaging is not yet implemented */</span><br><span style="color: hsl(120, 100%, 40%);">+             .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+           .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+                .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+       },</span><br><span style="color: hsl(120, 100%, 40%);">+    .ci_gprs_meas = { /* Target C/I = 20 dB, Soft blocking threshold = 15 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+           .lower_thresh = 18,</span><br><span style="color: hsl(120, 100%, 40%);">+           .upper_thresh = 24,</span><br><span style="color: hsl(120, 100%, 40%);">+           /* FIXME: C/I averaging is not yet implemented */</span><br><span style="color: hsl(120, 100%, 40%);">+             .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Hreqave: the period over which an average is produced */</span><br><span style="color: hsl(120, 100%, 40%);">+           .h_reqave = 4, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Hreqt: the number of averaged results maintained */</span><br><span style="color: hsl(120, 100%, 40%);">+                .h_reqt = 6, /* TODO: investigate a reasonable default value */</span><br><span style="color: hsl(120, 100%, 40%);">+       },</span><br><span> };</span><br><span> </span><br><span> enum rsl_cmod_spd chan_mode_to_rsl_cmod_spd(enum gsm48_chan_mode chan_mode)</span><br><span>diff --git a/tests/power_ctrl.vty b/tests/power_ctrl.vty</span><br><span>index ff387ce..4760114 100644</span><br><span>--- a/tests/power_ctrl.vty</span><br><span>+++ b/tests/power_ctrl.vty</span><br><span>@@ -33,12 +33,18 @@</span><br><span>   . lv  step-size inc <2-6> red <2-4></span><br><span>   . lv  rxlev-thresh lower <0-63> upper <0-63></span><br><span>   . lv  rxqual-thresh lower <0-7> upper <0-7></span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  ci-thresh (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) lower <0-30> upper <0-30></span><br><span>   . lv  rxlev-thresh-comp lower <0-31> <0-31> upper <0-31> <0-31></span><br><span>   . lv  rxqual-thresh-comp lower <0-31> <0-31> upper <0-31> <0-31></span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  ci-thresh-comp (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) lower <0-31> <0-31> upper <0-31> <0-31></span><br><span>   . lv  no (rxlev-avg|rxqual-avg)</span><br><span>   . lv  (rxlev-avg|rxqual-avg) params hreqave <1-31> hreqt <1-31></span><br><span>   . lv  (rxlev-avg|rxqual-avg) algo (unweighted|weighted|mod-median)</span><br><span>   . lv  (rxlev-avg|rxqual-avg) algo osmo-ewma beta <1-99></span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  no ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs)</span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) params hreqave <1-31> hreqt <1-31></span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) algo (unweighted|weighted|mod-median)</span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) algo osmo-ewma beta <1-99></span><br><span> </span><br><span> OsmoBSC(config-bs-power-ctrl)# bs-power ?</span><br><span>   static   Fixed BS Power reduction value (for static mode)</span><br><span>@@ -69,6 +75,18 @@</span><br><span>    rxlev-thresh-comp lower 10 12 upper 19 20</span><br><span>    rxqual-thresh lower 3 upper 0</span><br><span>    rxqual-thresh-comp lower 5 7 upper 15 18</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh fr lower 13 upper 17</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh-comp fr lower 0 0 upper 0 0</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh hr lower 16 upper 21</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh-comp hr lower 0 0 upper 0 0</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh amr-fr lower 7 upper 11</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh-comp amr-fr lower 0 0 upper 0 0</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh amr-hr lower 13 upper 17</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh-comp amr-hr lower 0 0 upper 0 0</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh sdcch lower 12 upper 16</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh-comp sdcch lower 0 0 upper 0 0</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh gprs lower 18 upper 24</span><br><span style="color: hsl(120, 100%, 40%);">+   ci-thresh-comp gprs lower 0 0 upper 0 0</span><br><span>   ms-power-control</span><br><span>    mode dyn-bts</span><br><span> ...</span><br><span>@@ -104,12 +122,18 @@</span><br><span>   . lv  step-size inc <2-6> red <2-4></span><br><span>   . lv  rxlev-thresh lower <0-63> upper <0-63></span><br><span>   . lv  rxqual-thresh lower <0-7> upper <0-7></span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  ci-thresh (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) lower <0-30> upper <0-30></span><br><span>   . lv  rxlev-thresh-comp lower <0-31> <0-31> upper <0-31> <0-31></span><br><span>   . lv  rxqual-thresh-comp lower <0-31> <0-31> upper <0-31> <0-31></span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  ci-thresh-comp (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) lower <0-31> <0-31> upper <0-31> <0-31></span><br><span>   . lv  no (rxlev-avg|rxqual-avg)</span><br><span>   . lv  (rxlev-avg|rxqual-avg) params hreqave <1-31> hreqt <1-31></span><br><span>   . lv  (rxlev-avg|rxqual-avg) algo (unweighted|weighted|mod-median)</span><br><span>   . lv  (rxlev-avg|rxqual-avg) algo osmo-ewma beta <1-99></span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  no ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs)</span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) params hreqave <1-31> hreqt <1-31></span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) algo (unweighted|weighted|mod-median)</span><br><span style="color: hsl(120, 100%, 40%);">+  . lv  ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) algo osmo-ewma beta <1-99></span><br><span> </span><br><span> OsmoBSC(config-ms-power-ctrl)# ### Check default MS Power Parameters</span><br><span> OsmoBSC(config-ms-power-ctrl)# show running-config</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bsc/+/25298">change 25298</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/+/25298"/><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: I7e76ec47b323d469f777624b74b08752d1f5584f </div>
<div style="display:none"> Gerrit-Change-Number: 25298 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>