From 54283ba62665ce6410d9da0dddd9601bf9dd719a Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Thu, 26 Aug 2021 15:41:17 +0200 Subject: MS Power Control Loop: Support set up of C/I parameters for osmo-bts This commit extends existing VTY and RSL infrastructure to configure and manage MS Power Parameters used in MS Power Control loop, by adding support to set up Carrier-to-Interference (CI) parameters. Using C/I instead of existing RxQual is preferred due to extended granularity of C/I (bigger range than RxQual's 0-7). Furthermore, existing literature (such as "GSM/EDGE: Evolution and Performance" Table 10.3) provides detailed information about expected target values, even different values for different channel types. Hence, it was decided to support setting different MS Power Parameters for different channel types. These MS Power Parameters are Osmocom specific, ie. supported only by newish versions of osmo-bts. Older versions of osmo-bts should ignore the new IEs added just fine. The new IEs containing the MS POwer Parameters are not send for non osmo-bts BTSs, hence this commit is secure with regards to running osmo-bsc against an ip.access BTS such as nanoBTS. Related: SYS#4917 Depends: libosmocore.git Change-Id Iffef0611430ad6c90606149c398d80158633bbca Change-Id: I7e76ec47b323d469f777624b74b08752d1f5584f --- TODO-RELEASE | 1 + doc/manuals/chapters/power_control.adoc | 58 ++++++- include/osmocom/bsc/gsm_data.h | 7 + src/osmo-bsc/bts_ipaccess_nanobts.c | 8 +- src/osmo-bsc/bts_osmobts.c | 99 +++++++++++ src/osmo-bsc/bts_vty.c | 280 ++++++++++++++++++++++++++++---- src/osmo-bsc/gsm_data.c | 132 +++++++++++++++ tests/power_ctrl.vty | 24 +++ 8 files changed, 568 insertions(+), 41 deletions(-) diff --git a/TODO-RELEASE b/TODO-RELEASE index a9bf06c4d..8585c7bbc 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -13,3 +13,4 @@ libosmogsm >1.5.1 introduced struct needed gsm0808_old_bss_to_new_ libosmo-mgcp-client >1.8.0 need osmo_mgcpc_ep_ci_get_remote_rtp_info() libosmovty >1.5.1 needs vty_read_config_filep() libosmosgsm >1.5.1 needs GSM_PCHAN_OSMO_DYN +libosmocore >1.5.1 RSL_IPAC_EIE_OSMO*, struct osmo_preproc_* diff --git a/doc/manuals/chapters/power_control.adoc b/doc/manuals/chapters/power_control.adoc index f2a0ec15c..30c36b127 100644 --- a/doc/manuals/chapters/power_control.adoc +++ b/doc/manuals/chapters/power_control.adoc @@ -29,7 +29,9 @@ interface, this is further described in the next sections. So far only the ip.access specific format is implemented, so it should be possible to enable power control for nanoBTS. OsmoBTS also accepts this format, but may -ignore some of the received parameters due to incomplete implementation. +ignore some of the received parameters due to incomplete implementation. On the +other hand, OsmoBTS may support some extra parameters coming in Osmocom specific +IEs not supported by nanoBTS, such as those configuring C/I measurement thresholds. ==== When the parameters come into effect? @@ -92,12 +94,18 @@ OsmoBSC(config-ms-power-ctrl)# list with-flags . lv step-size inc <2-6> red <2-4> . lv rxlev-thresh lower <0-63> upper <0-63> . lv rxqual-thresh lower <0-7> upper <0-7> + . lv ci-thresh (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) lower <0-30> upper <0-30> . lv rxlev-thresh-comp lower <0-31> <0-31> upper <0-31> <0-31> . lv rxqual-thresh-comp lower <0-31> <0-31> upper <0-31> <0-31> + . lv ci-thresh-comp (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) lower <0-31> <0-31> upper <0-31> <0-31> . lv no (rxlev-avg|rxqual-avg) . lv (rxlev-avg|rxqual-avg) params hreqave <1-31> hreqt <1-31> . lv (rxlev-avg|rxqual-avg) algo (unweighted|weighted|mod-median) . lv (rxlev-avg|rxqual-avg) algo osmo-ewma beta <1-99> + . lv no ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) + . lv ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) params hreqave <1-31> hreqt <1-31> + . lv ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) algo (unweighted|weighted|mod-median) + . lv ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) algo osmo-ewma beta <1-99> ---- NOTE: Flag `v` indicates that a given parameter is vendor specific, so different @@ -160,8 +168,9 @@ second Uplink SACCH block is skipped; value 2 corresponds to the interval of ==== Power change step size In order to slow down the reactivity of the power control loop and thus make it more -robust against sporadic fluctuations of the input values (RxLev and RxQual), the -transmit power on both Uplink and Downlink is changed gradually, step by step. +robust against sporadic fluctuations of the input values (RxLev and either +RxQual or C/I), the transmit power on both Uplink and Downlink is changed +gradually, step by step. OsmoBSC allows to configure the step sizes for both increasing and reducing directions separately. The corresponding power control loop would apply different delta values @@ -258,6 +267,43 @@ network <6> P3=5 out of N3=7 averages > L_RXQUAL_XX_P => increase power. <7> P4=15 out of N4=18 averages < U_RXQUAL_XX_P => decrease power. +==== Carrier-to-Interference (C/I) thresholds + +Carrier-to-Interference (C/I) provides a similar description of link quality to +that provided by RxQual. However, C/I provides higher granularity than RxQual +levels (0-7), hence providing the operator with a more refined way to set up +targets levels and thresholds. C/I measurements can only be used for MS Power +Control, since values are only available on the Uplink when computed by the BTS, +and the MS doesn't provide figure for the Downlink to the BTS/BSC during +measurement Reports. + +Usual C/I value range for MS uplink channels are between 0dB to 30dB, with 9dB +being a usual average target around cell edges. Furthermore, publicly available +studies conclude that different channel types with different codecs used have +different target C/I where signal is considered good enough. This means MS using +a given channel type with better codec capabilities can be instructed to +transmit at lower levels, hence reducing noise or channel interference among MS. + +OsmoBTS MS Power Control Loop algorithm supports using C/I computed +measurements. Related parameters can be configured similar to those of RxLev or +RxQual (see previous section), with the main difference being that instead of +having a global set of parameters, there's one set per channel type, hence +allowing different parametrization based on the channel type in use by the MS. + +.Example: C/I threshold comparators for AMR-FR +---- +network + bts 0 + ms-power-control + mode dyn-bts <1> + ci-thresh amr-fr lower 7 upper 11 <2> + ci-thresh-comp amr-fr lower 2 10 <3> upper 3 4 <4> +---- +<1> MS power control is to be performed by the BTS autonomously. +<2> L_CI_AMR_FR_XX_P=7, U_CI_AMR_FR_XX_P=11. +<3> P0=2 out of N1=10 averages < L_CI_AMR_FR_XX_P => increase power. +<4> P1=3 out of N2=4 averages > U_CI_AMR_FR_XX_P => decrease power. + ==== Measurement averaging process 3GPP 45.008, section A.3.1 requires that the measurement values reported by both @@ -270,7 +316,7 @@ corresponding power control loops in any of the following ways: (outliers) removed before the median calculation. The pre-processing is expected to be performed by both MS and BS power control -loops independently, for every input parameter (i.e. RxLev and RxQual). +loops independently, for every input parameter (i.e. RxLev, RxQual and C/I). ---- OsmoBSC(config-bs-power-ctrl)# rxlev-avg algo ? @@ -319,12 +365,16 @@ network rxlev-avg params hreqave 4 hreqt 6 <3> rxqual-avg algo osmo-ewma beta 50 <4> rxqual-avg params hreqave 2 hreqt 3 <5> + ci-avg amr-fr algo osmo-ewma beta 50 <6> + ci-avg amr-fr params hreqave 2 hreqt 3 <7> ---- <1> Both MS and BS power control is to be performed by the BTS autonomously. <2> Unweighted average is applied to RxLev values. <3> RxLev: Hreqave and Hreqt values: 4 out of 6 SACCH blocks produce an averaged measurement. <4> Osmocom specific EWMA is applied to RxQual values with smoothing factor = 50% (beta=0.5). <5> RxQual: Hreqave and Hreqt values: 2 out of 3 SACCH blocks produce an averaged measurement. +<6> Osmocom specific EWMA is applied to C/I values on AMR-FR channels with smoothing factor = 50% (beta=0.5). +<7> C/I AMR-FR: Hreqave and Hreqt values: 2 out of 3 SACCH blocks produce an averaged measurement. // TODO: Document other power control parameters: // OsmoBSC(config-net-bts)# ms max power <0-40> diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h index bed36f3e9..b16614695 100644 --- a/include/osmocom/bsc/gsm_data.h +++ b/include/osmocom/bsc/gsm_data.h @@ -1350,6 +1350,13 @@ struct gsm_power_ctrl_params { /* Measurement averaging parameters for RxLev & RxQual */ struct gsm_power_ctrl_meas_params rxqual_meas; struct gsm_power_ctrl_meas_params rxlev_meas; + /* Measurement averaging parameters for C/I: */ + struct gsm_power_ctrl_meas_params ci_fr_meas; + struct gsm_power_ctrl_meas_params ci_hr_meas; + struct gsm_power_ctrl_meas_params ci_amr_fr_meas; + struct gsm_power_ctrl_meas_params ci_amr_hr_meas; + struct gsm_power_ctrl_meas_params ci_sdcch_meas; + struct gsm_power_ctrl_meas_params ci_gprs_meas; }; extern const struct gsm_power_ctrl_params power_ctrl_params_def; diff --git a/src/osmo-bsc/bts_ipaccess_nanobts.c b/src/osmo-bsc/bts_ipaccess_nanobts.c index 8d2908f69..9607068d5 100644 --- a/src/osmo-bsc/bts_ipaccess_nanobts.c +++ b/src/osmo-bsc/bts_ipaccess_nanobts.c @@ -920,13 +920,17 @@ static void enc_power_params(struct msgb *msg, const struct gsm_power_ctrl_param thresh_comp->red_step_size = cp->red_step_size_db & 0x0f; } +void osmobts_enc_power_params_osmo_ext(struct msgb *msg, const struct gsm_power_ctrl_params *cp); static void add_power_params_ie(struct msgb *msg, enum abis_rsl_ie iei, + const struct gsm_bts_trx *trx, const struct gsm_power_ctrl_params *cp) { uint8_t *ie_len = msgb_tl_put(msg, iei); uint8_t msg_len = msgb_length(msg); enc_power_params(msg, cp); + if (iei == RSL_IE_MS_POWER_PARAM && is_osmobts(trx->bts)) + osmobts_enc_power_params_osmo_ext(msg, cp); *ie_len = msgb_length(msg) - msg_len; } @@ -958,9 +962,9 @@ static int power_ctrl_send_def_params(const struct gsm_bts_trx *trx) /* MS/BS Power Parameters IEs */ if (ms_power_ctrl->mode == GSM_PWR_CTRL_MODE_DYN_BTS) - add_power_params_ie(msg, RSL_IE_MS_POWER_PARAM, ms_power_ctrl); + add_power_params_ie(msg, RSL_IE_MS_POWER_PARAM, trx, ms_power_ctrl); if (bs_power_ctrl->mode == GSM_PWR_CTRL_MODE_DYN_BTS) - add_power_params_ie(msg, RSL_IE_BS_POWER_PARAM, bs_power_ctrl); + add_power_params_ie(msg, RSL_IE_BS_POWER_PARAM, trx, bs_power_ctrl); msg->dst = trx->rsl_link_primary; diff --git a/src/osmo-bsc/bts_osmobts.c b/src/osmo-bsc/bts_osmobts.c index 9813a265d..5007d2b90 100644 --- a/src/osmo-bsc/bts_osmobts.c +++ b/src/osmo-bsc/bts_osmobts.c @@ -44,6 +44,105 @@ extern struct gsm_bts_model bts_model_nanobts; static struct gsm_bts_model model_osmobts; +static void enc_osmo_meas_proc_params(struct msgb *msg, const struct gsm_power_ctrl_params *mp) +{ + struct osmo_preproc_ave_cfg *ave_cfg; + uint8_t *ie_len; + + /* No averaging => no Measurement Averaging parameters */ + if (mp->ci_fr_meas.algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE && + mp->ci_hr_meas.algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE && + mp->ci_amr_fr_meas.algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE && + mp->ci_amr_hr_meas.algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE && + mp->ci_sdcch_meas.algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE && + mp->ci_gprs_meas.algo == GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE) + return; + + /* (TLV) Measurement Averaging parameters for RxLev/RxQual */ + ie_len = msgb_tl_put(msg, RSL_IPAC_EIE_OSMO_MEAS_AVG_CFG); + + ave_cfg = (struct osmo_preproc_ave_cfg *) msgb_put(msg, sizeof(*ave_cfg)); + +#define ENC_PROC(PARAMS, TO, TYPE) do { \ + (TO)->TYPE.ave_enabled = (PARAMS)->TYPE##_meas.algo != GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE; \ + if ((TO)->TYPE.ave_enabled) { \ + /* H_REQAVE and H_REQT */ \ + (TO)->TYPE.h_reqave = (PARAMS)->TYPE##_meas.h_reqave & 0x1f; \ + (TO)->TYPE.h_reqt = (PARAMS)->TYPE##_meas.h_reqt & 0x1f; \ + /* Averaging method and parameters */ \ + (TO)->TYPE.ave_method = ((PARAMS)->TYPE##_meas.algo - 1) & 0x07; \ + switch ((PARAMS)->TYPE##_meas.algo) { \ + case GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA: \ + msgb_v_put(msg, (PARAMS)->TYPE##_meas.ewma.alpha); \ + break; \ + case GSM_PWR_CTRL_MEAS_AVG_ALGO_WEIGHTED: \ + case GSM_PWR_CTRL_MEAS_AVG_ALGO_MOD_MEDIAN: \ + /* FIXME: unknown format */ \ + break; \ + case GSM_PWR_CTRL_MEAS_AVG_ALGO_UNWEIGHTED: \ + case GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE: \ + /* No parameters here */ \ + break; \ + } \ + } \ + } while (0) + ENC_PROC(mp, ave_cfg, ci_fr); + ENC_PROC(mp, ave_cfg, ci_hr); + ENC_PROC(mp, ave_cfg, ci_amr_fr); + ENC_PROC(mp, ave_cfg, ci_amr_hr); + ENC_PROC(mp, ave_cfg, ci_sdcch); + ENC_PROC(mp, ave_cfg, ci_gprs); +#undef ENC_PROC + + /* Update length part of the containing IE */ + *ie_len = msg->tail - (ie_len + 1); +} + +/* Appends Osmocom specific extension IEs into RSL_IE_MS_POWER_PARAM */ +void osmobts_enc_power_params_osmo_ext(struct msgb *msg, const struct gsm_power_ctrl_params *cp) +{ + struct osmo_preproc_pc_thresh *osmo_thresh; + struct osmo_preproc_pc_comp *osmo_thresh_comp; + uint8_t *ie_len; + + /* (TLV) Measurement Averaging Configure (C/I) */ + enc_osmo_meas_proc_params(msg, cp); + + /* (TLV) Thresholds (C/I) */ + ie_len = msgb_tl_put(msg, RSL_IPAC_EIE_OSMO_MS_PWR_CTL); + osmo_thresh = (struct osmo_preproc_pc_thresh *) msgb_put(msg, sizeof(*osmo_thresh)); + #define ENC_THRESH_CI(TYPE) \ + osmo_thresh->l_##TYPE = cp->TYPE##_meas.lower_thresh; \ + osmo_thresh->u_##TYPE = cp->TYPE##_meas.upper_thresh + ENC_THRESH_CI(ci_fr); + ENC_THRESH_CI(ci_hr); + ENC_THRESH_CI(ci_amr_fr); + ENC_THRESH_CI(ci_amr_hr); + ENC_THRESH_CI(ci_sdcch); + ENC_THRESH_CI(ci_gprs); + #undef ENC_THRESH_CI + /* Update length part of the containing IE */ + *ie_len = msg->tail - (ie_len + 1); + + /* (TLV) PC Threshold Comparators (C/I) */ + ie_len = msgb_tl_put(msg, RSL_IPAC_EIE_OSMO_PC_THRESH_COMP); + osmo_thresh_comp = (struct osmo_preproc_pc_comp *) msgb_put(msg, sizeof(*osmo_thresh_comp)); + #define ENC_THRESH_CI(TYPE) \ + osmo_thresh_comp->TYPE.lower_p = cp->TYPE##_meas.lower_cmp_p & 0x1f; \ + osmo_thresh_comp->TYPE.lower_n = cp->TYPE##_meas.lower_cmp_n & 0x1f; \ + osmo_thresh_comp->TYPE.upper_p = cp->TYPE##_meas.upper_cmp_p & 0x1f; \ + osmo_thresh_comp->TYPE.upper_n = cp->TYPE##_meas.upper_cmp_n & 0x1f + ENC_THRESH_CI(ci_fr); + ENC_THRESH_CI(ci_hr); + ENC_THRESH_CI(ci_amr_fr); + ENC_THRESH_CI(ci_amr_hr); + ENC_THRESH_CI(ci_sdcch); + ENC_THRESH_CI(ci_gprs); + #undef ENC_THRESH_CI + /* Update length part of the containing IE */ + *ie_len = msg->tail - (ie_len + 1); +} + static int power_ctrl_set_c0_power_red(const struct gsm_bts *bts, const uint8_t red) { diff --git a/src/osmo-bsc/bts_vty.c b/src/osmo-bsc/bts_vty.c index ebc11b57f..dbfe5e46b 100644 --- a/src/osmo-bsc/bts_vty.c +++ b/src/osmo-bsc/bts_vty.c @@ -3034,6 +3034,8 @@ DEFUN_USRATTR(cfg_power_ctrl_step_size, "RxLev value (signal strength, 0 is worst, 63 is best)\n" #define POWER_CONTROL_MEAS_RXQUAL_DESC \ "RxQual value (signal quality, 0 is best, 7 is worst)\n" +#define POWER_CONTROL_MEAS_CI_DESC \ + "C/I value (Carrier-to-Interference (dB), 0 is worst, 30 is best)\n" DEFUN_USRATTR(cfg_power_ctrl_rxlev_thresh, cfg_power_ctrl_rxlev_thresh_cmd, @@ -3090,10 +3092,74 @@ DEFUN_USRATTR(cfg_power_ctrl_rxqual_thresh, return CMD_SUCCESS; } +#define VTY_CMD_CI_TYPE "(fr-efr|hr|amr-fr|amr-hr|sdcch|gprs)" +#define VTY_DESC_CI_TYPE \ + "Channel Type FR/EFR\n" \ + "Channel Type HR\n" \ + "Channel Type AMR FR\n" \ + "Channel Type AMR HR\n" \ + "Channel Type SDCCH\n" \ + "Channel Type (E)GPRS\n" +static struct gsm_power_ctrl_meas_params *ci_thresh_by_conn_type(struct gsm_power_ctrl_params *params, const char *type) +{ + if (!strcmp(type, "fr-efr")) + return ¶ms->ci_fr_meas; + if (!strcmp(type, "hr")) + return ¶ms->ci_hr_meas; + if (!strcmp(type, "amr-fr")) + return ¶ms->ci_amr_fr_meas; + if (!strcmp(type, "amr-hr")) + return ¶ms->ci_amr_hr_meas; + if (!strcmp(type, "sdcch")) + return ¶ms->ci_sdcch_meas; + if (!strcmp(type, "gprs")) + return ¶ms->ci_gprs_meas; + OSMO_ASSERT(false); + return NULL; +} + +DEFUN_USRATTR(cfg_power_ctrl_ci_thresh, + cfg_power_ctrl_ci_thresh_cmd, + X(BSC_VTY_ATTR_VENDOR_SPECIFIC) | + X(BSC_VTY_ATTR_NEW_LCHAN), + "ci-thresh " VTY_CMD_CI_TYPE " lower <0-30> upper <0-30>", + "Set target C/I thresholds (for dynamic mode), only available in ms-power-control\n" + VTY_DESC_CI_TYPE + "Lower C/I value\n" + "Lower " POWER_CONTROL_MEAS_RXQUAL_DESC + "Upper C/I value\n" + "Upper " POWER_CONTROL_MEAS_RXQUAL_DESC) +{ + struct gsm_power_ctrl_params *params = vty->index; + const char *type = argv[0]; + int lower = atoi(argv[1]); + int upper = atoi(argv[2]); + struct gsm_power_ctrl_meas_params *meas_params; + + if (params->dir != GSM_PWR_CTRL_DIR_UL) { + vty_out(vty, "%% C/I based power loop only possible in Uplink!%s", VTY_NEWLINE); + return CMD_WARNING; + } + + if (lower > upper) { + vty_out(vty, "%% Lower 'rxqual-rxqual' (%d) must be less than upper (%d)%s", + upper, lower, VTY_NEWLINE); + return CMD_WARNING; + } + + meas_params = ci_thresh_by_conn_type(params, type); + + meas_params->lower_thresh = lower; + meas_params->upper_thresh = upper; + + return CMD_SUCCESS; +} + #define POWER_CONTROL_MEAS_THRESH_COMP_CMD(meas) \ meas " lower <0-31> <0-31> upper <0-31> <0-31>" -#define POWER_CONTROL_MEAS_THRESH_COMP_DESC(meas, lp, ln, up, un) \ +#define POWER_CONTROL_MEAS_THRESH_COMP_DESC(meas, opt_param, lp, ln, up, un) \ "Set " meas " threshold comparators (for dynamic mode)\n" \ + opt_param \ "Lower " meas " threshold comparators (see 3GPP TS 45.008, A.3.2.1)\n" lp ln \ "Upper " meas " threshold comparators (see 3GPP TS 45.008, A.3.2.1)\n" up un @@ -3102,7 +3168,7 @@ DEFUN_USRATTR(cfg_power_ctrl_rxlev_thresh_comp, X(BSC_VTY_ATTR_VENDOR_SPECIFIC) | X(BSC_VTY_ATTR_NEW_LCHAN), POWER_CONTROL_MEAS_THRESH_COMP_CMD("rxlev-thresh-comp"), - POWER_CONTROL_MEAS_THRESH_COMP_DESC("RxLev", + POWER_CONTROL_MEAS_THRESH_COMP_DESC("RxLev", /*empty*/, "P1 (default 10)\n", "N1 (default 12)\n", "P2 (default 10)\n", "N2 (default 12)\n")) { @@ -3137,7 +3203,7 @@ DEFUN_USRATTR(cfg_power_ctrl_rxqual_thresh_comp, X(BSC_VTY_ATTR_VENDOR_SPECIFIC) | X(BSC_VTY_ATTR_NEW_LCHAN), POWER_CONTROL_MEAS_THRESH_COMP_CMD("rxqual-thresh-comp"), - POWER_CONTROL_MEAS_THRESH_COMP_DESC("RxQual", + POWER_CONTROL_MEAS_THRESH_COMP_DESC("RxQual", /*empty*/, "P3 (default 5)\n", "N3 (default 7)\n", "P4 (default 15)\n", "N4 (default 18)\n")) { @@ -3167,6 +3233,45 @@ DEFUN_USRATTR(cfg_power_ctrl_rxqual_thresh_comp, return CMD_SUCCESS; } +DEFUN_USRATTR(cfg_power_ctrl_ci_thresh_comp, + cfg_power_ctrl_ci_thresh_comp_cmd, + X(BSC_VTY_ATTR_VENDOR_SPECIFIC) | + X(BSC_VTY_ATTR_NEW_LCHAN), + POWER_CONTROL_MEAS_THRESH_COMP_CMD("ci-thresh-comp " VTY_CMD_CI_TYPE), + POWER_CONTROL_MEAS_THRESH_COMP_DESC("Carrier-to_interference (C/I)", + VTY_DESC_CI_TYPE, + "Lower P (default 5)\n", "Lower N (default 7)\n", + "Upper P (default 15)\n", "Upper N (default 18)\n")) +{ + struct gsm_power_ctrl_params *params = vty->index; + struct gsm_power_ctrl_meas_params *meas_params; + int lower_cmp_p = atoi(argv[1]); + int lower_cmp_n = atoi(argv[2]); + int upper_cmp_p = atoi(argv[3]); + int upper_cmp_n = atoi(argv[4]); + + if (lower_cmp_p > lower_cmp_n) { + vty_out(vty, "%% Lower C/I P %d must be less than N %d%s", + lower_cmp_p, lower_cmp_n, VTY_NEWLINE); + return CMD_WARNING; + } + + if (upper_cmp_p > upper_cmp_n) { + vty_out(vty, "%% Upper C/I P %d must be less than N %d%s", + upper_cmp_p, upper_cmp_n, VTY_NEWLINE); + return CMD_WARNING; + } + + meas_params = ci_thresh_by_conn_type(params, argv[0]); + + meas_params->lower_cmp_p = lower_cmp_p; + meas_params->lower_cmp_n = lower_cmp_n; + meas_params->upper_cmp_p = upper_cmp_p; + meas_params->upper_cmp_n = upper_cmp_n; + + return CMD_SUCCESS; +} + #define POWER_CONTROL_MEAS_AVG_CMD \ "(rxlev-avg|rxqual-avg)" #define POWER_CONTROL_MEAS_AVG_DESC \ @@ -3278,6 +3383,114 @@ DEFUN_USRATTR(cfg_power_ctrl_avg_osmo_ewma, return CMD_SUCCESS; } +/* C/I related power control measurements */ +#define POWER_CONTROL_CI_MEAS_AVG_DESC \ + "C/I (Carrier-to-Interference) measurement averaging (for dynamic mode)\n" + +DEFUN_USRATTR(cfg_power_ctrl_no_ci_avg, + cfg_power_ctrl_no_ci_avg_cmd, + X(BSC_VTY_ATTR_VENDOR_SPECIFIC) | + X(BSC_VTY_ATTR_NEW_LCHAN), + "no ci-avg " VTY_CMD_CI_TYPE, + NO_STR POWER_CONTROL_CI_MEAS_AVG_DESC VTY_DESC_CI_TYPE) +{ + struct gsm_power_ctrl_params *params = vty->index; + struct gsm_power_ctrl_meas_params *avg_params; + + avg_params = ci_thresh_by_conn_type(params, argv[0]); + avg_params->algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE; + + return CMD_SUCCESS; +} + +DEFUN_USRATTR(cfg_power_ctrl_ci_avg_params, + cfg_power_ctrl_ci_avg_params_cmd, + X(BSC_VTY_ATTR_VENDOR_SPECIFIC) | + X(BSC_VTY_ATTR_NEW_LCHAN), + "ci-avg " VTY_CMD_CI_TYPE " params hreqave <1-31> hreqt <1-31>", + POWER_CONTROL_CI_MEAS_AVG_DESC VTY_DESC_CI_TYPE + "Configure general averaging parameters\n" + "Hreqave: the period over which an average is produced\n" + "Hreqave value (so that Hreqave * Hreqt < 32)\n" + "Hreqt: the number of averaged results that are maintained\n" + "Hreqt value (so that Hreqave * Hreqt < 32)\n") +{ + struct gsm_power_ctrl_params *params = vty->index; + struct gsm_power_ctrl_meas_params *avg_params; + int h_reqave = atoi(argv[1]); + int h_reqt = atoi(argv[2]); + + if (h_reqave * h_reqt > 31) { + vty_out(vty, "%% Hreqave (%d) * Hreqt (%d) = %d must be < 32%s", + h_reqave, h_reqt, h_reqave * h_reqt, VTY_NEWLINE); + return CMD_WARNING; + } + + avg_params = ci_thresh_by_conn_type(params, argv[0]); + avg_params->h_reqave = h_reqave; + avg_params->h_reqt = h_reqt; + + return CMD_SUCCESS; +} + +DEFUN_USRATTR(cfg_power_ctrl_ci_avg_algo, + cfg_power_ctrl_ci_avg_algo_cmd, + X(BSC_VTY_ATTR_VENDOR_SPECIFIC) | + X(BSC_VTY_ATTR_NEW_LCHAN), + /* FIXME: add algorithm specific parameters */ + "ci-avg " VTY_CMD_CI_TYPE " algo (unweighted|weighted|mod-median)", + POWER_CONTROL_CI_MEAS_AVG_DESC VTY_DESC_CI_TYPE + "Select the averaging algorithm\n" + "Un-weighted average\n" "Weighted average\n" + "Modified median calculation\n") +{ + struct gsm_power_ctrl_params *params = vty->index; + struct gsm_power_ctrl_meas_params *avg_params; + + avg_params = ci_thresh_by_conn_type(params, argv[0]); + if (strcmp(argv[1], "unweighted") == 0) + avg_params->algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_UNWEIGHTED; + else if (strcmp(argv[1], "weighted") == 0) + avg_params->algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_WEIGHTED; + else if (strcmp(argv[1], "mod-median") == 0) + avg_params->algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_MOD_MEDIAN; + + return CMD_SUCCESS; +} + +DEFUN_USRATTR(cfg_power_ctrl_ci_avg_osmo_ewma, + cfg_power_ctrl_ci_avg_osmo_ewma_cmd, + X(BSC_VTY_ATTR_VENDOR_SPECIFIC) | + X(BSC_VTY_ATTR_NEW_LCHAN), + "ci-avg " VTY_CMD_CI_TYPE " algo osmo-ewma beta <1-99>", + POWER_CONTROL_CI_MEAS_AVG_DESC VTY_DESC_CI_TYPE + "Select the averaging algorithm\n" + "Exponentially Weighted Moving Average (EWMA)\n" + "Smoothing factor (in %): beta = (100 - alpha)\n" + "1% - lowest smoothing, 99% - highest smoothing\n") +{ + struct gsm_power_ctrl_params *params = vty->index; + struct gsm_power_ctrl_meas_params *avg_params; + const struct gsm_bts *bts; + + if (params->dir == GSM_PWR_CTRL_DIR_UL) + bts = container_of(params, struct gsm_bts, ms_power_ctrl); + else + bts = container_of(params, struct gsm_bts, bs_power_ctrl); + + if (bts->type != GSM_BTS_TYPE_OSMOBTS) { + vty_out(vty, "%% EWMA is an OsmoBTS specific algorithm, " + "it's not usable for other BTS types%s", VTY_NEWLINE); + return CMD_WARNING; + } + + avg_params = ci_thresh_by_conn_type(params, argv[0]); + avg_params->algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA; + avg_params->ewma.alpha = 100 - atoi(argv[1]); + + return CMD_SUCCESS; +} + static void vty_out_neigh_list(struct vty *vty, struct bitvec *bv) { int count = 0; @@ -3653,31 +3866,14 @@ static void config_write_bts_amr(struct vty *vty, struct gsm_bts *bts, vty_out(vty, "%*s" fmt, indent, "", ##args); static void config_write_power_ctrl_meas(struct vty *vty, unsigned int indent, - const struct gsm_power_ctrl_params *cp, - uint8_t ptype) + const struct gsm_power_ctrl_meas_params *mp, + const char *param, const char *param2) { - const struct gsm_power_ctrl_meas_params *mp; - const char *param; - - switch (ptype) { - case IPAC_RXLEV_AVE: - mp = &cp->rxlev_meas; - param = "rxlev"; - break; - case IPAC_RXQUAL_AVE: - mp = &cp->rxqual_meas; - param = "rxqual"; - break; - default: - /* Shall not happen */ - OSMO_ASSERT(0); - } - - cfg_out("%s-thresh lower %u upper %u%s", - param, mp->lower_thresh, mp->upper_thresh, + cfg_out("%s-thresh%s lower %u upper %u%s", + param, param2, mp->lower_thresh, mp->upper_thresh, VTY_NEWLINE); - cfg_out("%s-thresh-comp lower %u %u upper %u %u%s", - param, mp->lower_cmp_p, mp->lower_cmp_n, + cfg_out("%s-thresh-comp%s lower %u %u upper %u %u%s", + param, param2, mp->lower_cmp_p, mp->lower_cmp_n, mp->upper_cmp_p, mp->upper_cmp_n, VTY_NEWLINE); @@ -3686,23 +3882,23 @@ static void config_write_power_ctrl_meas(struct vty *vty, unsigned int indent, /* Do not print any averaging parameters */ return; /* we're done */ case GSM_PWR_CTRL_MEAS_AVG_ALGO_UNWEIGHTED: - cfg_out("%s-avg algo unweighted%s", param, VTY_NEWLINE); + cfg_out("%s-avg%s algo unweighted%s", param, param2, VTY_NEWLINE); break; case GSM_PWR_CTRL_MEAS_AVG_ALGO_WEIGHTED: - cfg_out("%s-avg algo weighted%s", param, VTY_NEWLINE); + cfg_out("%s-avg%s algo weighted%s", param, param2, VTY_NEWLINE); break; case GSM_PWR_CTRL_MEAS_AVG_ALGO_MOD_MEDIAN: - cfg_out("%s-avg algo mod-median%s", param, VTY_NEWLINE); + cfg_out("%s-avg%s algo mod-median%s", param, param2, VTY_NEWLINE); break; case GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA: - cfg_out("%s-avg algo osmo-ewma beta %u%s", - param, 100 - mp->ewma.alpha, + cfg_out("%s-avg%s algo osmo-ewma beta %u%s", + param, param2, 100 - mp->ewma.alpha, VTY_NEWLINE); break; } - cfg_out("%s-avg params hreqave %u hreqt %u%s", - param, mp->h_reqave, mp->h_reqt, + cfg_out("%s-avg%s params hreqave %u hreqt %u%s", + param, param2, mp->h_reqave, mp->h_reqt, VTY_NEWLINE); } @@ -3739,8 +3935,16 @@ static void config_write_power_ctrl(struct vty *vty, unsigned int indent, VTY_NEWLINE); /* Measurement processing / averaging parameters */ - config_write_power_ctrl_meas(vty, indent + 1, cp, IPAC_RXLEV_AVE); - config_write_power_ctrl_meas(vty, indent + 1, cp, IPAC_RXQUAL_AVE); + config_write_power_ctrl_meas(vty, indent + 1, &cp->rxlev_meas, "rxlev", ""); + config_write_power_ctrl_meas(vty, indent + 1, &cp->rxqual_meas, "rxqual", ""); + if (cp->dir == GSM_PWR_CTRL_DIR_UL) { + config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_fr_meas, "ci", " fr-efr"); + config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_hr_meas, "ci", " hr"); + config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_amr_fr_meas, "ci", " amr-fr"); + config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_amr_hr_meas, "ci", " amr-hr"); + config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_sdcch_meas, "ci", " sdcch"); + config_write_power_ctrl_meas(vty, indent + 1, &cp->ci_gprs_meas, "ci", " gprs"); + } break; } } @@ -4238,12 +4442,18 @@ int bts_vty_init(void) install_element(POWER_CTRL_NODE, &cfg_power_ctrl_step_size_cmd); install_element(POWER_CTRL_NODE, &cfg_power_ctrl_rxlev_thresh_cmd); install_element(POWER_CTRL_NODE, &cfg_power_ctrl_rxqual_thresh_cmd); + install_element(POWER_CTRL_NODE, &cfg_power_ctrl_ci_thresh_cmd); install_element(POWER_CTRL_NODE, &cfg_power_ctrl_rxlev_thresh_comp_cmd); install_element(POWER_CTRL_NODE, &cfg_power_ctrl_rxqual_thresh_comp_cmd); + install_element(POWER_CTRL_NODE, &cfg_power_ctrl_ci_thresh_comp_cmd); install_element(POWER_CTRL_NODE, &cfg_power_ctrl_no_avg_cmd); install_element(POWER_CTRL_NODE, &cfg_power_ctrl_avg_params_cmd); install_element(POWER_CTRL_NODE, &cfg_power_ctrl_avg_algo_cmd); install_element(POWER_CTRL_NODE, &cfg_power_ctrl_avg_osmo_ewma_cmd); + install_element(POWER_CTRL_NODE, &cfg_power_ctrl_no_ci_avg_cmd); + install_element(POWER_CTRL_NODE, &cfg_power_ctrl_ci_avg_params_cmd); + install_element(POWER_CTRL_NODE, &cfg_power_ctrl_ci_avg_algo_cmd); + install_element(POWER_CTRL_NODE, &cfg_power_ctrl_ci_avg_osmo_ewma_cmd); return bts_trx_vty_init(); diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c index 481329bff..02d9fd7cb 100644 --- a/src/osmo-bsc/gsm_data.c +++ b/src/osmo-bsc/gsm_data.c @@ -1189,6 +1189,138 @@ const struct gsm_power_ctrl_params power_ctrl_params_def = { /* Hreqt: the number of averaged results maintained */ .h_reqt = 6, /* TODO: investigate a reasonable default value */ }, + + /* C/I measurement parameters. + * Target C/I retrieved from "GSM/EDGE: Evolution and Performance" Table 10.3. + * Set lower and upper so that (lower + upper) / 2 is equal or slightly + * above the target. + */ + .ci_fr_meas = { /* FR: Target C/I = 15 dB, Soft blocking threshold = 10 dB */ + .lower_thresh = 13, + .upper_thresh = 17, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_FR_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_FR_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, + .ci_hr_meas = { /* HR: Target C/I = 18 dB, Soft blocking threshold = 13 dB */ + .lower_thresh = 16, + .upper_thresh = 21, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_HR_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_HR_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, + .ci_amr_fr_meas = { /* AMR-FR: Target C/I = 9 dB, Soft blocking threshold = 4 dB */ + .lower_thresh = 7, + .upper_thresh = 11, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_AMR_FR_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_AMR_FR_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, + .ci_amr_hr_meas = { /* AMR-HR: Target C/I = 15 dB, Soft blocking threshold = 10 dB */ + .lower_thresh = 13, + .upper_thresh = 17, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_AMR_HR_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_AMR_HR_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, + .ci_sdcch_meas = { /* SDCCH: Target C/I = 14 dB, Soft blocking threshold = 9 dB */ + .lower_thresh = 12, + .upper_thresh = 16, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_SDCCH_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_SDCCH_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, + .ci_gprs_meas = { /* GPRS: Target C/I = 20 dB, Soft blocking threshold = 15 dB */ + .lower_thresh = 18, + .upper_thresh = 24, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_GPRS_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_GPRS_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, }; enum rsl_cmod_spd chan_mode_to_rsl_cmod_spd(enum gsm48_chan_mode chan_mode) diff --git a/tests/power_ctrl.vty b/tests/power_ctrl.vty index ff387ce33..8cb695f16 100644 --- a/tests/power_ctrl.vty +++ b/tests/power_ctrl.vty @@ -33,12 +33,18 @@ OsmoBSC(config-bs-power-ctrl)# list with-flags . lv step-size inc <2-6> red <2-4> . lv rxlev-thresh lower <0-63> upper <0-63> . lv rxqual-thresh lower <0-7> upper <0-7> + . lv ci-thresh (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) lower <0-30> upper <0-30> . lv rxlev-thresh-comp lower <0-31> <0-31> upper <0-31> <0-31> . lv rxqual-thresh-comp lower <0-31> <0-31> upper <0-31> <0-31> + . lv ci-thresh-comp (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) lower <0-31> <0-31> upper <0-31> <0-31> . lv no (rxlev-avg|rxqual-avg) . lv (rxlev-avg|rxqual-avg) params hreqave <1-31> hreqt <1-31> . lv (rxlev-avg|rxqual-avg) algo (unweighted|weighted|mod-median) . lv (rxlev-avg|rxqual-avg) algo osmo-ewma beta <1-99> + . lv no ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) + . lv ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) params hreqave <1-31> hreqt <1-31> + . lv ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) algo (unweighted|weighted|mod-median) + . lv ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) algo osmo-ewma beta <1-99> OsmoBSC(config-bs-power-ctrl)# bs-power ? static Fixed BS Power reduction value (for static mode) @@ -104,12 +110,18 @@ OsmoBSC(config-ms-power-ctrl)# list with-flags . lv step-size inc <2-6> red <2-4> . lv rxlev-thresh lower <0-63> upper <0-63> . lv rxqual-thresh lower <0-7> upper <0-7> + . lv ci-thresh (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) lower <0-30> upper <0-30> . lv rxlev-thresh-comp lower <0-31> <0-31> upper <0-31> <0-31> . lv rxqual-thresh-comp lower <0-31> <0-31> upper <0-31> <0-31> + . lv ci-thresh-comp (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) lower <0-31> <0-31> upper <0-31> <0-31> . lv no (rxlev-avg|rxqual-avg) . lv (rxlev-avg|rxqual-avg) params hreqave <1-31> hreqt <1-31> . lv (rxlev-avg|rxqual-avg) algo (unweighted|weighted|mod-median) . lv (rxlev-avg|rxqual-avg) algo osmo-ewma beta <1-99> + . lv no ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) + . lv ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) params hreqave <1-31> hreqt <1-31> + . lv ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) algo (unweighted|weighted|mod-median) + . lv ci-avg (fr-efr|hr|amr-fr|amr-hr|sdcch|gprs) algo osmo-ewma beta <1-99> OsmoBSC(config-ms-power-ctrl)# ### Check default MS Power Parameters OsmoBSC(config-ms-power-ctrl)# show running-config @@ -124,6 +136,18 @@ OsmoBSC(config-ms-power-ctrl)# show running-config rxlev-thresh-comp lower 10 12 upper 19 20 rxqual-thresh lower 3 upper 0 rxqual-thresh-comp lower 5 7 upper 15 18 + ci-thresh fr-efr lower 13 upper 17 + ci-thresh-comp fr-efr lower 5 7 upper 15 18 + ci-thresh hr lower 16 upper 21 + ci-thresh-comp hr lower 5 7 upper 15 18 + ci-thresh amr-fr lower 7 upper 11 + ci-thresh-comp amr-fr lower 5 7 upper 15 18 + ci-thresh amr-hr lower 13 upper 17 + ci-thresh-comp amr-hr lower 5 7 upper 15 18 + ci-thresh sdcch lower 12 upper 16 + ci-thresh-comp sdcch lower 5 7 upper 15 18 + ci-thresh gprs lower 18 upper 24 + ci-thresh-comp gprs lower 5 7 upper 15 18 ... OsmoBSC(config-ms-power-ctrl)# bs-power static 30 -- cgit v1.2.3