<p>fixeria has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/21683">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Implement ip.access coding of MS/BS Power Control Parameters<br><br>Change-Id: I3798a6a02132bafe8f1fef6e93bbb42036d76ac9<br>Related: SYS#4918<br>---<br>M include/osmocom/bsc/bts.h<br>M include/osmocom/bsc/bts_trx.h<br>M src/osmo-bsc/abis_rsl.c<br>M src/osmo-bsc/bts_ipaccess_nanobts.c<br>M src/osmo-bsc/bts_trx.c<br>5 files changed, 302 insertions(+), 6 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/83/21683/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h</span><br><span>index 2b05418..ff246f6 100644</span><br><span>--- a/include/osmocom/bsc/bts.h</span><br><span>+++ b/include/osmocom/bsc/bts.h</span><br><span>@@ -188,6 +188,10 @@</span><br><span>        void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx);</span><br><span>  void (*config_write_ts)(struct vty *vty, struct gsm_bts_trx_ts *ts);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      /* MS/BS Power Control paramaters encoding functions (optional) */</span><br><span style="color: hsl(120, 100%, 40%);">+    void (*enc_ms_power_params)(struct msgb *msg, const struct gsm_bts_trx *trx);</span><br><span style="color: hsl(120, 100%, 40%);">+ void (*enc_bs_power_params)(struct msgb *msg, const struct gsm_bts_trx *trx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      /* Should SI2bis and SI2ter be disabled by default on this BTS model? */</span><br><span>     bool force_combined_si;</span><br><span> </span><br><span>diff --git a/include/osmocom/bsc/bts_trx.h b/include/osmocom/bsc/bts_trx.h</span><br><span>index 5888c63..eff3fdd 100644</span><br><span>--- a/include/osmocom/bsc/bts_trx.h</span><br><span>+++ b/include/osmocom/bsc/bts_trx.h</span><br><span>@@ -22,6 +22,74 @@</span><br><span>    struct gsm_abis_mo mo;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* MS/BS Power related measurement averaging algo */</span><br><span style="color: hsl(120, 100%, 40%);">+enum trx_power_ctrl_meas_avg_algo {</span><br><span style="color: hsl(120, 100%, 40%);">+   TRX_PWR_CTRL_MEAS_AVG_ALGO_NONE                 = 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+       TRX_PWR_CTRL_MEAS_AVG_ALGO_UNWEIGHTED           = 0x01,</span><br><span style="color: hsl(120, 100%, 40%);">+       TRX_PWR_CTRL_MEAS_AVG_ALGO_WEIGHTED             = 0x02,</span><br><span style="color: hsl(120, 100%, 40%);">+       TRX_PWR_CTRL_MEAS_AVG_ALGO_MOD_MEDIAN           = 0x03,</span><br><span style="color: hsl(120, 100%, 40%);">+       /* EWMA is an Osmocom specific algo */</span><br><span style="color: hsl(120, 100%, 40%);">+        TRX_PWR_CTRL_MEAS_AVG_ALGO_EWMA                 = 0x04,</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%);">+/* MS/BS Power related measurement parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+struct trx_power_ctrl_meas_params {</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Thresholds (see 3GPP TS 45.008, section A.3.2.1) */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t lower_thresh; /* lower (decreasing) direction */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t upper_thresh; /* upper (increasing) direction */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Threshold Comparators for lower (decreasing) direction */</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t lower_cmp_p; /* P1 for RxLev, P3 for RxQual */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t lower_cmp_n; /* N1 for RxLev, N3 for RxQual */</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Threshold Comparators for upper (increasing) direction */</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t upper_cmp_p; /* P2 for RxLev, P4 for RxQual */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t upper_cmp_n; /* N2 for RxLev, N4 for RxQual */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Hreqave and Hreqt (see 3GPP TS 45.008, Annex A) */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t h_reqave;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t h_reqt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* AVG algorithm and its specific parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+       enum trx_power_ctrl_meas_avg_algo algo;</span><br><span style="color: hsl(120, 100%, 40%);">+       union {</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Exponentially Weighted Moving Average */</span><br><span style="color: hsl(120, 100%, 40%);">+           struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* Smoothing factor: higher the value - less smoothing */</span><br><span style="color: hsl(120, 100%, 40%);">+                     uint8_t alpha; /* 1 .. 99 (in %) */</span><br><span style="color: hsl(120, 100%, 40%);">+           } ewma;</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%);">+enum trx_power_ctrl_dir {</span><br><span style="color: hsl(120, 100%, 40%);">+   TRX_PWR_CTRL_DIR_UL, /* MS Power Control */</span><br><span style="color: hsl(120, 100%, 40%);">+   TRX_PWR_CTRL_DIR_DL, /* BS Power Control */</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%);">+enum trx_power_ctrl_mode {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Do not send MS/BS Power Control IEs */</span><br><span style="color: hsl(120, 100%, 40%);">+     TRX_PWR_CTRL_MODE_NONE = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Send MS/BS Power IE only (with target level) */</span><br><span style="color: hsl(120, 100%, 40%);">+    TRX_PWR_CTRL_MODE_STATIC,</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Send MS/BS Power [Parameters] IEs (dynamic mode) */</span><br><span style="color: hsl(120, 100%, 40%);">+        TRX_PWR_CTRL_MODE_DYN_BTS,</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%);">+/* MS/BS Power Control Parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+struct trx_power_ctrl_params {</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Power Control direction: Uplink or Downlink */</span><br><span style="color: hsl(120, 100%, 40%);">+     enum trx_power_ctrl_dir dir;</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Power Control mode to be used by the BTS */</span><br><span style="color: hsl(120, 100%, 40%);">+        enum trx_power_ctrl_mode mode;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Power change step size (dynamic mode only) */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t inc_step_size_db; /* increasing direction */</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t red_step_size_db; /* reducing direction */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Measurement averaging parameters for RxLev & RxQual */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct trx_power_ctrl_meas_params rxqual_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct trx_power_ctrl_meas_params rxlev_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* One TRX in a BTS */</span><br><span> struct gsm_bts_trx {</span><br><span>        /* list header in bts->trx_list */</span><br><span>@@ -51,6 +119,10 @@</span><br><span>  int nominal_power;              /* in dBm */</span><br><span>         unsigned int max_power_red;     /* in actual dB */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        /* MS/BS Power Control parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+  struct trx_power_ctrl_params ms_power_ctrl;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct trx_power_ctrl_params bs_power_ctrl;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        union {</span><br><span>              struct {</span><br><span>                     struct {</span><br><span>diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c</span><br><span>index f8ea5a5..0793bea 100644</span><br><span>--- a/src/osmo-bsc/abis_rsl.c</span><br><span>+++ b/src/osmo-bsc/abis_rsl.c</span><br><span>@@ -486,6 +486,39 @@</span><br><span>     }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void enc_power_control_params(struct msgb *msg,</span><br><span style="color: hsl(120, 100%, 40%);">+                                 const struct gsm_bts_trx *trx,</span><br><span style="color: hsl(120, 100%, 40%);">+                                enum trx_power_ctrl_dir dir)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  const struct gsm_bts_model *model = trx->bts->model;</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%);">+    /* Since IE {MS,BS}_POWER_PARAM content is operator dependent, it's not</span><br><span style="color: hsl(120, 100%, 40%);">+    * known if non-osmocom BTS models will support an empty IE, so let's</span><br><span style="color: hsl(120, 100%, 40%);">+      * better skip sending it unless we know for sure what each expects. */</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (dir) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case TRX_PWR_CTRL_DIR_UL:</span><br><span style="color: hsl(120, 100%, 40%);">+             if (trx->ms_power_ctrl.mode != TRX_PWR_CTRL_MODE_DYN_BTS)</span><br><span style="color: hsl(120, 100%, 40%);">+                  return;</span><br><span style="color: hsl(120, 100%, 40%);">+               if (model->enc_ms_power_params == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+                    return;</span><br><span style="color: hsl(120, 100%, 40%);">+               ie_len = msgb_tl_put(msg, RSL_IE_MS_POWER_PARAM);</span><br><span style="color: hsl(120, 100%, 40%);">+             model->enc_ms_power_params(msg, trx);</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case TRX_PWR_CTRL_DIR_DL:</span><br><span style="color: hsl(120, 100%, 40%);">+             if (trx->bs_power_ctrl.mode != TRX_PWR_CTRL_MODE_DYN_BTS)</span><br><span style="color: hsl(120, 100%, 40%);">+                  return;</span><br><span style="color: hsl(120, 100%, 40%);">+               if (model->enc_bs_power_params == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+                    return;</span><br><span style="color: hsl(120, 100%, 40%);">+               ie_len = msgb_tl_put(msg, RSL_IE_BS_POWER_PARAM);</span><br><span style="color: hsl(120, 100%, 40%);">+             model->enc_bs_power_params(msg, trx);</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> /* Chapter 8.4.1 */</span><br><span> int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref)</span><br><span> {</span><br><span>@@ -573,12 +606,10 @@</span><br><span>  msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power);</span><br><span>       msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);</span><br><span>       msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);</span><br><span style="color: hsl(0, 100%, 40%);">-    /* indicate MS power control to be performed by BTS: */</span><br><span style="color: hsl(0, 100%, 40%);">- if (bts->type == GSM_BTS_TYPE_OSMOBTS)</span><br><span style="color: hsl(0, 100%, 40%);">-               msgb_tl_put(msg, RSL_IE_MS_POWER_PARAM);</span><br><span style="color: hsl(0, 100%, 40%);">-        /* else: Since IE MS_POWER_PARAM content is operator dependent, it's not</span><br><span style="color: hsl(0, 100%, 40%);">-       known if non-osmocom BTS models will support an empty IE, so let's</span><br><span style="color: hsl(0, 100%, 40%);">-          better skip sending it unless we know for sure what each expects. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* BS/MS Power Control Parameters (if supported by BTS model) */</span><br><span style="color: hsl(120, 100%, 40%);">+      enc_power_control_params(msg, trx, TRX_PWR_CTRL_DIR_DL);</span><br><span style="color: hsl(120, 100%, 40%);">+      enc_power_control_params(msg, trx, TRX_PWR_CTRL_DIR_UL);</span><br><span> </span><br><span>         mr_config_for_bts(lchan, msg);</span><br><span>       rep_acch_cap_for_bts(lchan, msg);</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 c84d750..179e9b5 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>@@ -52,6 +52,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 void enc_ms_power_params(struct msgb *msg, const struct gsm_bts_trx *trx);</span><br><span style="color: hsl(120, 100%, 40%);">+static void enc_bs_power_params(struct msgb *msg, const struct gsm_bts_trx *trx);</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 +70,8 @@</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%);">+ .enc_ms_power_params = &enc_ms_power_params,</span><br><span style="color: hsl(120, 100%, 40%);">+      .enc_bs_power_params = &enc_bs_power_params,</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 +806,131 @@</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%);">+/* ip.access specific Power Control IEs */</span><br><span style="color: hsl(120, 100%, 40%);">+enum ipaccess_power_ctrl_param_iei {</span><br><span style="color: hsl(120, 100%, 40%);">+    POWER_CTRL_MEAS_AVG_PARAMS_IEI          = 0x04,</span><br><span style="color: hsl(120, 100%, 40%);">+       POWER_CTRL_BS_THRESH_IEI                = 0x05,</span><br><span style="color: hsl(120, 100%, 40%);">+       POWER_CTRL_MS_THRESH_IEI                = 0x06,</span><br><span style="color: hsl(120, 100%, 40%);">+       POWER_CTRL_THRESH_COMP_IEI              = 0x0a,</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%);">+enum ipaccess_power_meas_param_type {</span><br><span style="color: hsl(120, 100%, 40%);">+  POWER_MEAS_PARAM_RXLEV                  = 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+       POWER_MEAS_PARAM_RXQUAL                 = 0x01,</span><br><span style="color: hsl(120, 100%, 40%);">+       POWER_MEAS_PARAM_MS_BTS_DIST            = 0x02,</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_meas_avg_params(struct msgb *msg,</span><br><span style="color: hsl(120, 100%, 40%);">+                              const struct trx_power_ctrl_params *params,</span><br><span style="color: hsl(120, 100%, 40%);">+                           enum ipaccess_power_meas_param_type ptype)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct trx_power_ctrl_meas_params *mp;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t *ie_len, u8;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (ptype) {</span><br><span style="color: hsl(120, 100%, 40%);">+      case POWER_MEAS_PARAM_RXLEV:</span><br><span style="color: hsl(120, 100%, 40%);">+          mp = &params->rxlev_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case POWER_MEAS_PARAM_RXQUAL:</span><br><span style="color: hsl(120, 100%, 40%);">+         mp = &params->rxqual_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        /* FIXME: MS/BTS Distance is not supported */</span><br><span style="color: hsl(120, 100%, 40%);">+ case POWER_MEAS_PARAM_MS_BTS_DIST:</span><br><span style="color: hsl(120, 100%, 40%);">+    default:</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(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%);">+   /* No averaging => no Measurement Averaging parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (mp->algo == TRX_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, POWER_CTRL_MEAS_AVG_PARAMS_IEI);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Parameter ID and H_REQAVE */</span><br><span style="color: hsl(120, 100%, 40%);">+       u8 = ((ptype & 0x07) << 5) | (mp->h_reqave & 0x1f);</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_v_put(msg, u8);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Algorithm ID and H_REQT */</span><br><span style="color: hsl(120, 100%, 40%);">+ u8 = ((mp->algo - 1) << 5) | (mp->h_reqt & 0x1f);</span><br><span style="color: hsl(120, 100%, 40%);">+     msgb_v_put(msg, u8);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Averaging parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (mp->algo) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case TRX_PWR_CTRL_MEAS_AVG_ALGO_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 TRX_PWR_CTRL_MEAS_AVG_ALGO_WEIGHTED:</span><br><span style="color: hsl(120, 100%, 40%);">+     case TRX_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 TRX_PWR_CTRL_MEAS_AVG_ALGO_UNWEIGHTED:</span><br><span style="color: hsl(120, 100%, 40%);">+   case TRX_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 trx_power_ctrl_params *params)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t u8;</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(params->mode == TRX_PWR_CTRL_MODE_DYN_BTS);</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 (params->dir == TRX_PWR_CTRL_DIR_UL)</span><br><span style="color: hsl(120, 100%, 40%);">+            msgb_v_put(msg, POWER_CTRL_MS_THRESH_IEI);</span><br><span style="color: hsl(120, 100%, 40%);">+    else</span><br><span style="color: hsl(120, 100%, 40%);">+          msgb_v_put(msg, POWER_CTRL_BS_THRESH_IEI);</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%);">+       msgb_v_put(msg, params->rxlev_meas.lower_thresh & 0x3f);</span><br><span style="color: hsl(120, 100%, 40%);">+       msgb_v_put(msg, params->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%);">+      u8 = ((params->rxqual_meas.lower_thresh & 0x07) << 4)</span><br><span style="color: hsl(120, 100%, 40%);">+       | ((params->rxqual_meas.upper_thresh & 0x07) << 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_v_put(msg, u8);</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, POWER_CTRL_THRESH_COMP_IEI);</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%);">+  msgb_v_put(msg, params->rxlev_meas.lower_cmp_p & 0x1f);</span><br><span style="color: hsl(120, 100%, 40%);">+        msgb_v_put(msg, params->rxlev_meas.lower_cmp_n & 0x1f);</span><br><span style="color: hsl(120, 100%, 40%);">+        msgb_v_put(msg, params->rxlev_meas.upper_cmp_p & 0x1f);</span><br><span style="color: hsl(120, 100%, 40%);">+        msgb_v_put(msg, params->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%);">+ msgb_v_put(msg, params->rxqual_meas.lower_cmp_p & 0x1f);</span><br><span style="color: hsl(120, 100%, 40%);">+       msgb_v_put(msg, params->rxqual_meas.lower_cmp_n & 0x1f);</span><br><span style="color: hsl(120, 100%, 40%);">+       msgb_v_put(msg, params->rxqual_meas.upper_cmp_p & 0x1f);</span><br><span style="color: hsl(120, 100%, 40%);">+       msgb_v_put(msg, params->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%);">+  msgb_v_put(msg, 0x00); /* 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%);">+      u8 = ((params->inc_step_size_db & 0x0f) << 4)</span><br><span style="color: hsl(120, 100%, 40%);">+       | ((params->red_step_size_db & 0x0f) << 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_v_put(msg, u8);</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_avg_params(msg, params, POWER_MEAS_PARAM_RXLEV);</span><br><span style="color: hsl(120, 100%, 40%);">+     enc_meas_avg_params(msg, params, POWER_MEAS_PARAM_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%);">+static void enc_ms_power_params(struct msgb *msg, const struct gsm_bts_trx *trx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  enc_power_params(msg, &trx->ms_power_ctrl);</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_bs_power_params(struct msgb *msg, const struct gsm_bts_trx *trx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  enc_power_params(msg, &trx->bs_power_ctrl);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/osmo-bsc/bts_trx.c b/src/osmo-bsc/bts_trx.c</span><br><span>index 0e52238..f1dd0fb 100644</span><br><span>--- a/src/osmo-bsc/bts_trx.c</span><br><span>+++ b/src/osmo-bsc/bts_trx.c</span><br><span>@@ -32,6 +32,54 @@</span><br><span> #include <osmocom/bsc/debug.h></span><br><span> #include <osmocom/bsc/nm_common_fsm.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Default MS/BS Power Control parameters (see 3GPP TS 45.008, table A.1) */</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct trx_power_ctrl_params power_ctrl_params_def = {</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Static Power Control is the safe default */</span><br><span style="color: hsl(120, 100%, 40%);">+        .mode = TRX_PWR_CTRL_MODE_STATIC,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Power increasing/reducing step size */</span><br><span style="color: hsl(120, 100%, 40%);">+     .inc_step_size_db = 4, /* 2, 4, or 6 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+    .red_step_size_db = 2, /* 2 or 4 dB */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* RxLev measurement parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+    .rxlev_meas = {</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Thresholds for RxLev (see 3GPP TS 45.008, A.3.2.1) */</span><br><span style="color: hsl(120, 100%, 40%);">+              .lower_thresh = 32, /* L_RXLEV_XX_P (-78 dBm) */</span><br><span style="color: hsl(120, 100%, 40%);">+              .upper_thresh = 38, /* U_RXLEV_XX_P (-72 dBm) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+             * out of LOWER_CMP_N averages are lower than L_RXLEV_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+         .lower_cmp_p = 10, /* P1 as in 3GPP TS 45.008, A.3.2.1 (case a) */</span><br><span style="color: hsl(120, 100%, 40%);">+            .lower_cmp_n = 12, /* N1 as in 3GPP TS 45.008, A.3.2.1 (case a) */</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+             * out of UPPER_CMP_N averages are greater than L_RXLEV_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+               .upper_cmp_p = 19, /* P2 as in 3GPP TS 45.008, A.3.2.1 (case b) */</span><br><span style="color: hsl(120, 100%, 40%);">+            .upper_cmp_n = 20, /* N2 as in 3GPP TS 45.008, A.3.2.1 (case b) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          /* No averaging (filtering) by default */</span><br><span style="color: hsl(120, 100%, 40%);">+             .algo = TRX_PWR_CTRL_MEAS_AVG_ALGO_NONE,</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%);">+  /* RxQual measurement parameters */</span><br><span style="color: hsl(120, 100%, 40%);">+   .rxqual_meas = {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Thresholds for RxQual (see 3GPP TS 45.008, A.3.2.1) */</span><br><span style="color: hsl(120, 100%, 40%);">+             .lower_thresh = 0, /* L_RXQUAL_XX_P (BER < 0.2%) */</span><br><span style="color: hsl(120, 100%, 40%);">+                .upper_thresh = 3, /* U_RXQUAL_XX_P (0.8% <= BER < 1.6%) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+             * out of LOWER_CMP_N averages are lower than L_RXLEV_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+         .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+             .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages</span><br><span style="color: hsl(120, 100%, 40%);">+             * out of UPPER_CMP_N averages are greater than L_RXLEV_XX_P */</span><br><span style="color: hsl(120, 100%, 40%);">+               .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+            .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          /* No averaging (filtering) by default */</span><br><span style="color: hsl(120, 100%, 40%);">+             .algo = TRX_PWR_CTRL_MEAS_AVG_ALGO_NONE,</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> static int gsm_bts_trx_talloc_destructor(struct gsm_bts_trx *trx)</span><br><span> {</span><br><span>   unsigned int i;</span><br><span>@@ -120,6 +168,14 @@</span><br><span>       if (trx->nr != 0)</span><br><span>                 trx->nominal_power = bts->c0->nominal_power;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     /* MS Power Control parameters (defaults) */</span><br><span style="color: hsl(120, 100%, 40%);">+  trx->ms_power_ctrl = power_ctrl_params_def;</span><br><span style="color: hsl(120, 100%, 40%);">+        trx->ms_power_ctrl.dir = TRX_PWR_CTRL_DIR_UL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* BS Power Control parameters (defaults) */</span><br><span style="color: hsl(120, 100%, 40%);">+  trx->bs_power_ctrl = power_ctrl_params_def;</span><br><span style="color: hsl(120, 100%, 40%);">+        trx->bs_power_ctrl.dir = TRX_PWR_CTRL_DIR_DL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   llist_add_tail(&trx->list, &bts->trx_list);</span><br><span> </span><br><span>        return trx;</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: 1 </div>
<div style="display:none"> Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>