Change in osmo-bts[master]: bts-trx: Implement MS Power control loop calculations using dBm inste...

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Tue Nov 12 14:18:08 UTC 2019


laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bts/+/15971 )

Change subject: bts-trx: Implement MS Power control loop calculations using dBm instead of ctl levels
......................................................................

bts-trx: Implement MS Power control loop calculations using dBm instead of ctl levels

Some bands, such as DCS1800, contain power levels such as 29, 30 and 31 not following same
unified sequence other power levels follow regarding conversion to dBm
values.
This makes extremly complex and prone to error comparing different power
levels. Let's instead use dBm values to calculate and crop desired new
value, and then convert it back to TS 05.05 ms power control level
value.

With this commit the control loop should be able to manage correctly the MS power
levels explained above.

Related: OS#4244
Change-Id: I0160637c5ffa606ee3081ad30be8e6f2a42b725b
---
M src/osmo-bts-trx/loops.c
M src/osmo-bts-trx/loops.h
2 files changed, 58 insertions(+), 31 deletions(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved



diff --git a/src/osmo-bts-trx/loops.c b/src/osmo-bts-trx/loops.c
index 4e77bca..b2b163a 100644
--- a/src/osmo-bts-trx/loops.c
+++ b/src/osmo-bts-trx/loops.c
@@ -23,11 +23,13 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #include <osmo-bts/gsm_data.h>
 #include <osmo-bts/logging.h>
 #include <osmo-bts/l1sap.h>
 #include <osmocom/core/bits.h>
+#include <osmocom/gsm/gsm_utils.h>
 
 #include "trx_if.h"
 #include "l1_if.h"
@@ -39,45 +41,70 @@
 
 /*! 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.
- *  \param[in] diff input delta value (in dB) */
+ *  \param[in] diff input delta value (in dB). How many dBs measured power
+ *  	       should be increased (+) or decreased (-) to reach expected power.
+ */
 static void ms_power_diff(struct gsm_lchan *lchan, int8_t diff)
 {
 	struct gsm_bts_trx *trx = lchan->ts->trx;
 	enum gsm_band band = trx->bts->band;
-	uint16_t arfcn = trx->arfcn;
 	int8_t new_power; /* TS 05.05 power level */
+	int8_t new_dbm, current_dbm, bsc_max_dbm, pwclass_max_dbm;
 
-	/* compute new target MS output power level based on current value subtracted by 'diff/2' */
-	new_power = lchan->ms_power_ctrl.current - (diff >> 1);
-
-	if (diff == 0)
+	/* power levels change in steps of 2 dB, so a smaller diff will end up in no change */
+	if (diff < 2 && diff > -2)
 		return;
 
-	/* ms transmit power level cannot become negative */
-	if (new_power < 0)
-		new_power = 0;
-
-	/* Don't ask for smaller ms power level than the one set by BSC upon RSL CHAN ACT */
-	if (new_power < lchan->ms_power)
-		new_power = lchan->ms_power;
-
-	/* saturate at the maximum possible power level for the given band */
-	// FIXME: to go above 1W, we need to know classmark of MS
-	if (arfcn >= 512 && arfcn <= 885) {
-		if (new_power > 15)
-			new_power = 15;
-	} else {
-		if (new_power > 19)
-			new_power = 19;
+	current_dbm = ms_pwr_dbm(band, lchan->ms_power_ctrl.current);
+	if (current_dbm < 0) {
+		LOGPLCHAN(lchan, DLOOP, LOGL_NOTICE,
+			  "Failed to calculate dBm for power ctl level %" PRIu8 " on band %s\n",
+			  lchan->ms_power_ctrl.current, gsm_band_name(band));
+		return;
+	}
+	bsc_max_dbm = ms_pwr_dbm(band, lchan->ms_power);
+	if (bsc_max_dbm < 0) {
+		LOGPLCHAN(lchan, DLOOP, LOGL_NOTICE,
+			  "Failed to calculate dBm for power ctl level %" PRIu8 " on band %s\n",
+			  lchan->ms_power, gsm_band_name(band));
+		return;
 	}
 
-	/* don't ever change more than MS_{LOWER,RAISE}_MAX during one loop iteration, i.e.
+	/* 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 (new_power > lchan->ms_power_ctrl.current + MS_LOWER_MAX)
-		new_power = lchan->ms_power_ctrl.current + MS_LOWER_MAX;
-	else if (new_power < lchan->ms_power_ctrl.current - MS_RAISE_MAX)
-		new_power = lchan->ms_power_ctrl.current - MS_RAISE_MAX;
+	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
+	   cope with any unsigned dbm value, regardless of band minimal value. */
+	if (new_dbm < 0)
+		new_dbm = 0;
+
+	/* Don't ask for smaller ms power level than the one set by BSC upon RSL CHAN ACT */
+	if (new_dbm > bsc_max_dbm)
+		new_dbm = bsc_max_dbm;
+
+	/* Make sure in no case the dBm value is higher than the one of ms
+	   power class 1 (the one with more output power) for the given band.
+	   Ideally we should catch the MS specific power class and apply it
+	   here, but for now let's assume the BSC sent us one taking the power
+	   class into account. */
+	pwclass_max_dbm = (int)ms_class_gmsk_dbm(band, 1);
+	if (pwclass_max_dbm >= 0 && new_dbm > pwclass_max_dbm)
+		new_dbm = pwclass_max_dbm;
+
+	new_power = ms_pwr_ctl_lvl(band, new_dbm);
+	if (new_power < 0) {
+		LOGPLCHAN(lchan, DLOOP, LOGL_NOTICE,
+			  "Failed to retrieve power level for %" PRId8 " dBm on band %d\n",
+			  new_dbm, band);
+		return;
+	}
 
 	if (lchan->ms_power_ctrl.current == new_power) {
 		LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "Keeping MS new_power at control level %d (%d dBm)\n",
@@ -138,8 +165,8 @@
 
 	/* if no burst was received from MS at clock */
 	if (chan_state->meas.rssi_count == 0) {
-		LOGPLCHAN(lchan, DLOOP, LOGL_NOTICE, "LOST SACCH frame, so we raise MS power\n");
-		ms_power_diff(lchan, MS_RAISE_MAX);
+		LOGPLCHAN(lchan, DLOOP, LOGL_NOTICE, "LOST SACCH frame, so we raise MS power output\n");
+		ms_power_diff(lchan, MS_RAISE_MAX_DB);
 		return;
 	}
 
diff --git a/src/osmo-bts-trx/loops.h b/src/osmo-bts-trx/loops.h
index 0db01d7..7869903 100644
--- a/src/osmo-bts-trx/loops.h
+++ b/src/osmo-bts-trx/loops.h
@@ -8,8 +8,8 @@
  */
 
 /* how much power levels do we raise/lower as maximum (1 level = 2 dB) */
-#define MS_RAISE_MAX 4
-#define MS_LOWER_MAX 2
+#define MS_RAISE_MAX_DB 4
+#define MS_LOWER_MAX_DB 8
 
 /*
  * loops api

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/15971
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: I0160637c5ffa606ee3081ad30be8e6f2a42b725b
Gerrit-Change-Number: 15971
Gerrit-PatchSet: 3
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20191112/4c900f34/attachment.htm>


More information about the gerrit-log mailing list