diff options
author | Harald Welte <laforge@gnumonks.org> | 2015-09-06 12:33:16 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2015-09-22 16:39:05 +0200 |
commit | 819b50e1a7b506a0a394cc71a795f0a9ce4083c1 (patch) | |
tree | 290806d3a1bc7f64a0e7a8e1cc5b48bfd6578164 /src/common | |
parent | f449842053d333f6f9f41d3123262e8e05375acb (diff) |
move MS power control handling from sysmobts to common part
MS uplink power control is required in pretty much any BTS, and we
cannot assume that they PHY / L1 will always take care of it by
itself. So the correspondign code is moved to common/power_control.c
and called from the generic part of L1SAP.
The corresponding VTY paramter has been moved from the sysmobts-specific
trx VTY node to the common BTS VTY node.
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/Makefile.am | 2 | ||||
-rw-r--r-- | src/common/bts.c | 1 | ||||
-rw-r--r-- | src/common/l1sap.c | 2 | ||||
-rw-r--r-- | src/common/power_control.c | 99 | ||||
-rw-r--r-- | src/common/vty.c | 15 |
5 files changed, 118 insertions, 1 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 56648b14..d2580f93 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -8,4 +8,4 @@ libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \ load_indication.c pcu_sock.c handover.c msg_utils.c \ load_indication.c pcu_sock.c handover.c msg_utils.c \ tx_power.c bts_ctrl_commands.c bts_ctrl_lookup.c \ - l1sap.c cbch.c + l1sap.c cbch.c power_control.c diff --git a/src/common/bts.c b/src/common/bts.c index 9abbe121..77302e2f 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -99,6 +99,7 @@ int bts_init(struct gsm_bts *bts) /* configurable via VTY */ btsb->paging_state = paging_init(btsb, 200, 0); + btsb->ul_power_target = -75; /* dBm default */ /* configurable via OML */ btsb->load.ccch.load_ind_period = 112; diff --git a/src/common/l1sap.c b/src/common/l1sap.c index ca785fe4..1cb752e3 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -783,6 +783,8 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, lchan->meas.l1_info[0] |= ((data[0] >> 5) & 1) << 2; lchan->meas.l1_info[1] = data[1]; lchan->meas.flags |= LC_UL_M_F_L1_VALID; + + lchan_ms_pwr_ctrl(lchan, data[0] & 0x1f, data_ind->rssi); } else le = &lchan->lapdm_ch.lapdm_dcch; diff --git a/src/common/power_control.c b/src/common/power_control.c new file mode 100644 index 00000000..78d2702b --- /dev/null +++ b/src/common/power_control.c @@ -0,0 +1,99 @@ +/* MS Power Control Loop L1 */ + +/* (C) 2014 by Holger Hans Peter Freyther + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdint.h> +#include <unistd.h> +#include <errno.h> + +#include <osmo-bts/logging.h> +#include <osmo-bts/bts.h> +#include <osmo-bts/gsm_data.h> +#include <osmo-bts/measurement.h> +#include <osmo-bts/bts_model.h> +#include <osmo-bts/l1sap.h> + +/* + * Check if manual power control is needed + * Check if fixed power was selected + * Check if the MS is already using our level if not + * the value is bogus.. + * TODO: Add a timeout.. e.g. if the ms is not capable of reaching + * the value we have set. + */ +int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan, + const uint8_t ms_power, const int rxLevel) +{ + int rx; + int cur_dBm, new_dBm, new_pwr; + struct gsm_bts *bts = lchan->ts->trx->bts; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + const enum gsm_band band = bts->band; + + if (!trx_ms_pwr_ctrl_is_osmo(lchan->ts->trx)) + return 0; + if (lchan->ms_power_ctrl.fixed) + return 0; + + /* The phone hasn't reached the power level yet */ + if (lchan->ms_power_ctrl.current != ms_power) + return 0; + + /* + * What is the difference between what we want and received? + * Ignore a margin that is within the range of measurement + * and MS output issues. + */ + rx = btsb->ul_power_target - rxLevel; + if (rx >= 0 && rx < 1) + return 0; + if (rx < 0 && rx > -1) + return 0; + + /* We don't really care about the truncation of int + float */ + cur_dBm = ms_pwr_dbm(band, ms_power); + new_dBm = cur_dBm + rx; + + /* Clamp negative values and do it depending on the band */ + if (new_dBm < 0) + new_dBm = 0; + + switch (band) { + case GSM_BAND_1800: + /* If MS_TX_PWR_MAX_CCH is set the values 29, + * 30, 31 are not used. Avoid specifying a dBm + * that would lead to these power levels. The + * phone might not be able to reach them. */ + if (new_dBm > 30) + new_dBm = 30; + break; + default: + break; + } + + new_pwr = ms_pwr_ctl_lvl(band, new_dBm); + if (lchan->ms_power_ctrl.current != new_pwr) { + lchan->ms_power_ctrl.current = new_pwr; + bts_model_adjst_ms_pwr(lchan); + return 1; + } + + return 0; +} diff --git a/src/common/vty.c b/src/common/vty.c index 8479e5a0..e3fd57df 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -207,6 +207,7 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts) VTY_NEWLINE); vty_out(vty, " paging lifetime %u%s", paging_get_lifetime(btsb->paging_state), VTY_NEWLINE); + vty_out(vty, " uplink-power-target %d%s", btsb->ul_power_target, VTY_NEWLINE); if (btsb->agch_queue_thresh_level != GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT || btsb->agch_queue_low_level != GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT || btsb->agch_queue_high_level != GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT) @@ -441,6 +442,19 @@ DEFUN(cfg_bts_agch_queue_mgmt_default, return CMD_SUCCESS; } +DEFUN(cfg_bts_ul_power_target, cfg_bts_ul_power_target_cmd, + "uplink-power-target <-110-0>", + "Set the nominal target Rx Level for uplink power control loop\n" + "Target uplink Rx level in dBm\n") +{ + struct gsm_bts *bts = vty->index; + struct gsm_bts_role_bts *btsb = bts_role_bts(bts); + + btsb->ul_power_target = atoi(argv[0]); + + return CMD_SUCCESS; +} + #define DB_DBM_STR \ "Unit is dB (decibels)\n" \ "Unit is mdB (milli-decibels, or rather 1/10000 bel)\n" @@ -782,6 +796,7 @@ int bts_vty_init(struct gsm_bts *bts, const struct log_info *cat) install_element(BTS_NODE, &cfg_bts_paging_lifetime_cmd); install_element(BTS_NODE, &cfg_bts_agch_queue_mgmt_default_cmd); install_element(BTS_NODE, &cfg_bts_agch_queue_mgmt_params_cmd); + install_element(BTS_NODE, &cfg_bts_ul_power_target_cmd); install_element(BTS_NODE, &cfg_trx_gsmtap_sapi_cmd); install_element(BTS_NODE, &cfg_trx_no_gsmtap_sapi_cmd); |