Change in osmo-bsc[master]: bsc: Adapt maximum MS Power Ctrl level based on band and MS Power class

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 19 00:52:18 UTC 2019


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

Change subject: bsc: Adapt maximum MS Power Ctrl level based on band and MS Power class
......................................................................

bsc: Adapt maximum MS Power Ctrl level based on band and MS Power class

Related: OS#4244
Change-Id: I6bff440b7797e710bca5af94fae546e5d55e6972
---
M include/osmocom/bsc/abis_rsl.h
M include/osmocom/bsc/gsm_data.h
M src/osmo-bsc/abis_rsl.c
M src/osmo-bsc/gsm_08_08.c
M src/osmo-bsc/gsm_data.c
M src/osmo-bsc/lchan_fsm.c
6 files changed, 133 insertions(+), 14 deletions(-)

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



diff --git a/include/osmocom/bsc/abis_rsl.h b/include/osmocom/bsc/abis_rsl.h
index f7db779..b43e3ae 100644
--- a/include/osmocom/bsc/abis_rsl.h
+++ b/include/osmocom/bsc/abis_rsl.h
@@ -85,7 +85,7 @@
 			  const uint8_t *data, int len);
 
 int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db);
-int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm);
+int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan);
 
 /* SMSCB functionality */
 int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index fe626b1..040e36d 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -309,6 +309,9 @@
 		/* pointer to "other" connection, if Call Leg Relocation was successful */
 		struct gsm_subscriber_connection *other;
 	} lcls;
+
+	/* MS Power Class, TS 05.05 sec 4.1.1 "Mobile station". 0 means unset. */
+	uint8_t ms_power_class:3;
 };
 
 
@@ -1374,6 +1377,9 @@
 	return conn->lchan->ts->trx->bts;
 }
 
+void conn_update_ms_power_class(struct gsm_subscriber_connection *conn, uint8_t power_class);
+void lchan_update_ms_power_ctrl_level(struct gsm_lchan *lchan, int ms_power_dbm);
+
 enum {
 	BTS_CTR_CHREQ_TOTAL,
 	BTS_CTR_CHREQ_NO_CHANNEL,
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 8df0e81..80f54b3 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -293,26 +293,16 @@
 	return abis_rsl_sendmsg(msg);
 }
 
-int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm)
+int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan)
 {
 	struct gsm_bts_trx *trx = lchan->ts->trx;
 	struct gsm_bts *bts = trx->bts;
 	struct abis_rsl_dchan_hdr *dh;
 	struct msgb *msg;
 	uint8_t chan_nr = gsm_lchan2chan_nr(lchan);
-	int ctl_lvl;
-
-	ctl_lvl = ms_pwr_ctl_lvl(bts->band, dbm);
-	if (ctl_lvl < 0)
-		return ctl_lvl;
 
 	msg = rsl_msgb_alloc();
 
-	lchan->ms_power = ctl_lvl;
-
-	if (fpc)
-		lchan->ms_power |= 0x20;
-
 	dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
 	init_dchan_hdr(dh, RSL_MT_MS_POWER_CONTROL);
 	dh->chan_nr = chan_nr;
diff --git a/src/osmo-bsc/gsm_08_08.c b/src/osmo-bsc/gsm_08_08.c
index ad67c3f..3efc665 100644
--- a/src/osmo-bsc/gsm_08_08.c
+++ b/src/osmo-bsc/gsm_08_08.c
@@ -395,12 +395,16 @@
 	return 0;
 }
 
+/* TS 04.08 sec 9.2.15 "Location updating request" */
 static void handle_lu_request(struct gsm_subscriber_connection *conn,
 			      struct msgb *msg)
 {
 	struct gsm48_hdr *gh;
 	struct gsm48_loc_upd_req *lu;
 	struct gsm48_loc_area_id lai;
+	int8_t rc8;
+	struct gsm_bts *bts = conn_get_bts(conn);
+
 
 	if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*lu)) {
 		LOGP(DMSC, LOGL_ERROR, "LU too small to look at: %u\n", msgb_l3len(msg));
@@ -416,6 +420,47 @@
 		LOGP(DMSC, LOGL_DEBUG, "Marking con for welcome USSD.\n");
 		conn->new_subscriber = 1;
 	}
+
+	rc8 = osmo_gsm48_rfpowercap2powerclass(bts->band, lu->classmark1.pwr_lev);
+	if (rc8 < 0) {
+		LOGP(DMSC, LOGL_NOTICE,
+		     "Unable to decode RF power capability %x from classmark1 during LU.\n",
+		     lu->classmark1.pwr_lev);
+		rc8 = 0;
+	}
+	conn_update_ms_power_class(conn, rc8);
+}
+
+
+/* TS 04.08 sec 9.2.15 "Location updating request" */
+static void handle_cm_serv_req(struct gsm_subscriber_connection *conn,
+			      struct msgb *msg)
+{
+	struct gsm48_hdr *gh;
+	struct gsm48_service_request *serv_req;
+	struct gsm48_classmark2* cm2;
+	int8_t rc8;
+	struct gsm_bts *bts = conn_get_bts(conn);
+
+	if (msgb_l3len(msg) < sizeof(*gh) + sizeof(*serv_req)) {
+		LOGP(DMSC, LOGL_ERROR, "CM Serv Req too small to look at: %u\n", msgb_l3len(msg));
+		return;
+	}
+
+	gh = msgb_l3(msg);
+	serv_req = (struct gsm48_service_request *) gh->data;
+
+	cm2 = (struct gsm48_classmark2*)(((uint8_t*)&serv_req->classmark)+1);
+	/* FIXME: one classmark2 is available in libosmocore:
+	cm2 = &serv_req->classmark2; */
+	rc8 = osmo_gsm48_rfpowercap2powerclass(bts->band, cm2->pwr_lev);
+	if (rc8 < 0) {
+		LOGP(DMSC, LOGL_NOTICE,
+		     "Unable to decode RF power capability %x from classmark2 during CM Service Req.\n",
+		     cm2->pwr_lev);
+		rc8 = 0;
+	}
+	conn_update_ms_power_class(conn, rc8);
 }
 
 int bsc_scan_bts_msg(struct gsm_subscriber_connection *conn, struct msgb *msg)
@@ -427,6 +472,8 @@
 	if (pdisc == GSM48_PDISC_MM) {
 		if (mtype == GSM48_MT_MM_LOC_UPD_REQUEST)
 			handle_lu_request(conn, msg);
+		else if(mtype == GSM48_MT_MM_CM_SERV_REQ)
+			handle_cm_serv_req(conn, msg);
 	} else if (pdisc == GSM48_PDISC_RR) {
 		if (mtype == GSM48_MT_RR_PAG_RESP)
 			handle_page_resp(conn, msg);
@@ -677,8 +724,20 @@
 		   const uint8_t *cm2, uint8_t cm2_len,
 		   const uint8_t *cm3, uint8_t cm3_len)
 {
+	struct gsm48_classmark2 *cm2_parsed = (struct gsm48_classmark2 *)cm2;
+	int8_t rc8;
 	int rc;
 	struct msgb *resp;
+	struct gsm_bts *bts = conn_get_bts(conn);
+
+	rc8 = osmo_gsm48_rfpowercap2powerclass(bts->band, cm2_parsed->pwr_lev);
+	if (rc8 < 0) {
+		LOGP(DMSC, LOGL_NOTICE,
+		     "Unable to decode RF power capability %x from classmark1 during CM Update.\n",
+		     cm2_parsed->pwr_lev);
+		rc8 = 0;
+	}
+	conn_update_ms_power_class(conn, rc8);
 
 	if (!msc_connected(conn))
 		return;
diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c
index 1c2c4d8..2a77837 100644
--- a/src/osmo-bsc/gsm_data.c
+++ b/src/osmo-bsc/gsm_data.c
@@ -24,6 +24,7 @@
 #include <errno.h>
 #include <ctype.h>
 #include <stdbool.h>
+#include <inttypes.h>
 #include <netinet/in.h>
 #include <talloc.h>
 
@@ -1685,6 +1686,67 @@
 	return true;
 }
 
+void conn_update_ms_power_class(struct gsm_subscriber_connection *conn, uint8_t power_class)
+{
+	struct gsm_bts *bts = conn_get_bts(conn);
+	LOGP(DRLL, LOGL_DEBUG, "MS Power class update: %" PRIu8 " -> %" PRIu8 "\n",
+	     conn->ms_power_class, power_class);
+
+	conn->ms_power_class = power_class;
+
+	/* If there's an associated lchan, attempt to update its max power to be
+	   on track with band maximum values */
+	if (conn->lchan)
+		lchan_update_ms_power_ctrl_level(conn->lchan, bts->ms_max_power);
+}
+
+void lchan_update_ms_power_ctrl_level(struct gsm_lchan *lchan, int ms_power_dbm)
+{
+	struct gsm_bts *bts = lchan->ts->trx->bts;
+	struct gsm_subscriber_connection *conn = lchan->conn;
+	int max_pwr_dbm_pwclass, new_pwr;
+
+	LOG_LCHAN(lchan, LOGL_DEBUG,
+		  "MS Power level update requested: %d dBm\n", ms_power_dbm);
+
+	if (!conn)
+		goto ms_power_default;
+
+	if (conn->ms_power_class == 0)
+		goto ms_power_default;
+
+	if ((max_pwr_dbm_pwclass = (int)ms_class_gmsk_dbm(bts->band, conn->ms_power_class)) < 0) {
+		LOG_LCHAN(lchan, LOGL_INFO,
+			 "Failed getting max ms power for power class %" PRIu8
+			 " on band %s, providing default max ms power\n",
+			 conn->ms_power_class, gsm_band_name(bts->band));
+		goto ms_power_default;
+	}
+
+	/* Current configured max pwr is above maximum one allowed on
+	   current band + ms power class, so use that one. */
+	if (ms_power_dbm > max_pwr_dbm_pwclass)
+		ms_power_dbm = max_pwr_dbm_pwclass;
+
+ms_power_default:
+	if ((new_pwr = ms_pwr_ctl_lvl(bts->band, ms_power_dbm)) < 0) {
+		LOG_LCHAN(lchan, LOGL_INFO,
+			 "Failed getting max ms power level %d on band %s,"
+			 " providing default max ms power\n",
+			 ms_power_dbm, gsm_band_name(bts->band));
+		return;
+	}
+
+	LOG_LCHAN(lchan, LOGL_DEBUG,
+		  "MS Power level update (power class %" PRIu8 "): %" PRIu8 " -> %d\n",
+		  conn ? conn->ms_power_class : 0, lchan->ms_power, new_pwr);
+
+	lchan->ms_power = new_pwr;
+	/* FIXME: if chan is active and lchan->ms_power != new_pwr, consider
+	   sending an MS Power Control message (RSL) towards BTS to announce the
+	   new max ms power lvl, see rsl_chan_ms_power_ctrl() */
+}
+
 const struct value_string lchan_activate_mode_names[] = {
 	OSMO_VALUE_STRING(FOR_NONE),
 	OSMO_VALUE_STRING(FOR_MS_CHANNEL_REQUEST),
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index f2fef99..9ca73df 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -511,6 +511,7 @@
 	struct osmo_mgcpc_ep_ci *use_mgwep_ci;
 	struct gsm_lchan *old_lchan = lchan->activate.info.re_use_mgw_endpoint_from_lchan;
 	struct lchan_activate_info *info = &lchan->activate.info;
+	int ms_power_dbm;
 
 	if (lchan->release.requested) {
 		lchan_fail("Release requested while activating");
@@ -522,11 +523,12 @@
 	/* If there is a previous lchan, and the new lchan is on the same cell as previous one,
 	 * take over power and TA values. Otherwise, use max power and zero TA. */
 	if (old_lchan && old_lchan->ts->trx->bts == bts) {
-		lchan->ms_power = old_lchan->ms_power;
+		ms_power_dbm = ms_pwr_dbm(bts->band, old_lchan->ms_power);
+		lchan_update_ms_power_ctrl_level(lchan, ms_power_dbm >= 0 ? ms_power_dbm : bts->ms_max_power);
 		lchan->bs_power = old_lchan->bs_power;
 		lchan->rqd_ta = old_lchan->rqd_ta;
 	} else {
-		lchan->ms_power = ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
+		lchan_update_ms_power_ctrl_level(lchan, bts->ms_max_power);
 		/* Upon last entering the UNUSED state, from lchan_reset():
 		 * - bs_power is still zero, 0dB reduction, output power = Pn.
 		 * - TA is still zero, to be determined by RACH. */

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

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I6bff440b7797e710bca5af94fae546e5d55e6972
Gerrit-Change-Number: 15926
Gerrit-PatchSet: 7
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: fixeria <axilirator at gmail.com>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20191119/fdc474d5/attachment.htm>


More information about the gerrit-log mailing list