diff options
-rw-r--r-- | src/common/power_control.c | 21 | ||||
-rw-r--r-- | tests/power/power_test.c | 52 | ||||
-rw-r--r-- | tests/power/power_test.ok | 19 |
3 files changed, 83 insertions, 9 deletions
diff --git a/src/common/power_control.c b/src/common/power_control.c index d08ed5e5..d2a6c1dd 100644 --- a/src/common/power_control.c +++ b/src/common/power_control.c @@ -30,6 +30,11 @@ #include <osmo-bts/measurement.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/l1sap.h> +#include <osmo-bts/power_control.h> + +/* how many dB do we raise/lower as maximum (1 ms power level = 2 dB) */ +#define MS_RAISE_MAX_DB 4 +#define MS_LOWER_MAX_DB 8 /*! compute the new MS POWER LEVEL communicated to the MS and store it in lchan. * \param lchan logical channel for which to compute (and in which to store) new power value. @@ -51,10 +56,6 @@ int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan, if (lchan->ms_power_ctrl.fixed) return 0; - /* How many dBs measured power should be increased (+) or decreased (-) - to reach expected power. */ - diff = bts->ul_power_target - rxLevel; - current_dbm = ms_pwr_dbm(band, ms_power); if (current_dbm < 0) { LOGPLCHAN(lchan, DLOOP, LOGL_NOTICE, @@ -70,6 +71,18 @@ int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan, return 0; } + /* How many dBs measured power should be increased (+) or decreased (-) + to reach expected power. */ + diff = bts->ul_power_target - rxLevel; + + /* don't ever change more than MS_{LOWER,RAISE}_MAX_DBM during one loop + iteration, i.e. reduce the speed at which the MS transmit power can + change. A higher value means a lower level (and vice versa) */ + if (diff > MS_RAISE_MAX_DB) + diff = MS_RAISE_MAX_DB; + else if (diff < -MS_LOWER_MAX_DB) + diff = -MS_LOWER_MAX_DB; + new_dbm = current_dbm + diff; /* Make sure new_dbm is never negative. ms_pwr_ctl_lvl() can later on diff --git a/tests/power/power_test.c b/tests/power/power_test.c index 30fbb643..9b1a762b 100644 --- a/tests/power/power_test.c +++ b/tests/power/power_test.c @@ -58,22 +58,64 @@ static void test_power_loop(void) lchan->state = LCHAN_S_NONE; lchan->ms_power_ctrl.current = ms_pwr_ctl_lvl(GSM_BAND_1800, 0); OSMO_ASSERT(lchan->ms_power_ctrl.current == 15); + lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 26); + OSMO_ASSERT(lchan->ms_power_ctrl.max == 2); /* Simply clamping */ apply_power_test(lchan, -60, 0, 15); /* * Now 15 dB too little and we should power it up. Could be a - * power level of 7 or 8 for 15 dBm + * power level of 7 or 8 for 15 dBm. However, since we limit peace at + * which we change values, expect several steps of MS_RAISE_MAX_DB/2 levels: */ + apply_power_test(lchan, -90, 1, 13); + apply_power_test(lchan, -90, 1, 11); + apply_power_test(lchan, -90, 1, 9); apply_power_test(lchan, -90, 1, 7); - - /* It should be clamped to level 0 and 30 dBm */ - apply_power_test(lchan, -100, 1, 0); + apply_power_test(lchan, -90, 1, 5); + + /* Check good RSSI value keeps it at same power level: */ + apply_power_test(lchan, bts.ul_power_target, 0, 5); + + apply_power_test(lchan, -90, 1, 3); + apply_power_test(lchan, -90, 1, 2); /* .max is pwr lvl 2 */ + apply_power_test(lchan, -90, 0, 2); /* .max is pwr lvl 2 */ + + lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 30); + OSMO_ASSERT(lchan->ms_power_ctrl.max == 0); + apply_power_test(lchan, -90, 1, 0); /* .max is pwr lvl 0 */ + apply_power_test(lchan, -90, 0, 0); /* .max is pwr lvl 0 */ + + lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 36); + OSMO_ASSERT(lchan->ms_power_ctrl.max == 29); + apply_power_test(lchan, -90, 1, 30); + apply_power_test(lchan, -90, 1, 29); + apply_power_test(lchan, -90, 0, 29); + + /* Check good RSSI value keeps it at same power level: */ + apply_power_test(lchan, bts.ul_power_target, 0, 29); + + /* Now go down, steps are double size in this direction: */ + apply_power_test(lchan, -45, 1, 1); + apply_power_test(lchan, -45, 1, 5); + apply_power_test(lchan, -45, 1, 9); + + /* Go down only one level down and up: */ + apply_power_test(lchan, bts.ul_power_target + 2, 1, 10); + apply_power_test(lchan, bts.ul_power_target - 2, 1, 9); + + /* Check if BSC requesting a low max power is applied after loop calculation: */ + lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 2); + OSMO_ASSERT(lchan->ms_power_ctrl.max == 14); + apply_power_test(lchan, bts.ul_power_target + 2, 1, 14); + /* Set back a more normal max: */ + lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 30); + OSMO_ASSERT(lchan->ms_power_ctrl.max == 0); /* Fix it and jump down */ lchan->ms_power_ctrl.fixed = true; - apply_power_test(lchan, -60, 0, 0); + apply_power_test(lchan, -60, 0, 14); /* And leave it again */ lchan->ms_power_ctrl.fixed = false; diff --git a/tests/power/power_test.ok b/tests/power/power_test.ok index cf0a38b4..335a3d3b 100644 --- a/tests/power/power_test.ok +++ b/tests/power/power_test.ok @@ -1,7 +1,26 @@ Testing power loop... power control [0]: MS current power 15 +power control [1]: MS current power 13 +power control [1]: MS current power 11 +power control [1]: MS current power 9 power control [1]: MS current power 7 +power control [1]: MS current power 5 +power control [0]: MS current power 5 +power control [1]: MS current power 3 +power control [1]: MS current power 2 +power control [0]: MS current power 2 power control [1]: MS current power 0 power control [0]: MS current power 0 +power control [1]: MS current power 30 +power control [1]: MS current power 29 +power control [0]: MS current power 29 +power control [0]: MS current power 29 +power control [1]: MS current power 1 +power control [1]: MS current power 5 +power control [1]: MS current power 9 +power control [1]: MS current power 10 +power control [1]: MS current power 9 +power control [1]: MS current power 14 +power control [0]: MS current power 14 power control [1]: MS current power 15 Power loop test OK |