[PATCH] osmo-bsc[master]: fix handling of state changes in acc ramping

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/.

Stefan Sperling gerrit-no-reply at lists.osmocom.org
Thu Apr 12 13:48:59 UTC 2018


fix handling of state changes in acc ramping

Take both the operative and administrative states into account
when deciding whether to start ACC ramping, and examine old/new
state values to avoid triggering ramping for a no-op state change.

This requires a fix to gsm_trx_lock_rf(): This function overwrote
the old administrative state of a trx before enqueuing a state
change request towards the BTS.
The BTS will confirm this request with an ACK, at which time a
signal is generated which the ACC ramp code listens to. We must
not overwrite the old state value until the signal has been handled,
otherwise the signal handler cannot tell what the old state was.

Tested with a virtphy setup.
Still needs to be tested with nanobts and osmo-bts.

Change-Id: Ib3291439655598fb5ddc891a3e4cc35b0bad250f
Related: OS#2591
---
M src/libbsc/abis_nm.c
M src/libbsc/acc_ramp.c
M src/libbsc/bsc_init.c
3 files changed, 72 insertions(+), 28 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/84/7784/2

diff --git a/src/libbsc/abis_nm.c b/src/libbsc/abis_nm.c
index 2ee2e24..66eba12 100644
--- a/src/libbsc/abis_nm.c
+++ b/src/libbsc/abis_nm.c
@@ -2844,13 +2844,17 @@
 {
 	uint8_t new_state = locked ? NM_STATE_LOCKED : NM_STATE_UNLOCKED;
 
-	LOGP(DNM, LOGL_NOTICE, "(bts=%d,trx=%d) Changing adm. state %s -> %s [%s]\n", trx->bts->nr, trx->nr,
+
+	if (!trx->bts || !trx->bts->oml_link) {
+		/* Set initial state which will be sent when BTS connects. */
+		trx->mo.nm_state.administrative = new_state;
+		return;
+	}
+
+	LOGP(DNM, LOGL_NOTICE, "(bts=%d,trx=%d) Requesting administrative state change %s -> %s [%s]\n",
+	    trx->bts->nr, trx->nr,
 	     get_value_string(abis_nm_adm_state_names, trx->mo.nm_state.administrative),
 	     get_value_string(abis_nm_adm_state_names, new_state), reason);
-
-	trx->mo.nm_state.administrative = new_state;
-	if (!trx->bts || !trx->bts->oml_link)
-		return;
 
 	abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER,
 			      trx->bts->bts_nr, trx->nr, 0xff,
diff --git a/src/libbsc/acc_ramp.c b/src/libbsc/acc_ramp.c
index 7116107..da61094 100644
--- a/src/libbsc/acc_ramp.c
+++ b/src/libbsc/acc_ramp.c
@@ -28,6 +28,7 @@
 #include <osmocom/bsc/gsm_data.h>
 #include <osmocom/bsc/chan_alloc.h>
 #include <osmocom/bsc/signal.h>
+#include <osmocom/bsc/abis_nm.h>
 
 /*
  * Check if an ACC has been permanently barred for a BTS,
@@ -144,6 +145,7 @@
 	struct nm_statechg_signal_data *nsd = signal_data;
 	struct acc_ramp *acc_ramp = handler_data;
 	struct gsm_bts_trx *trx = NULL;
+	bool trigger_ramping = false, abort_ramping = false;
 
 	/* Handled signals map to an Administrative State Change ACK, or a State Changed Event Report. */
 	if (signal != S_NM_STATECHG_ADM && signal != S_NM_STATECHG_OPER)
@@ -154,6 +156,17 @@
 
 	trx = nsd->obj;
 
+	if (signal == S_NM_STATECHG_ADM)
+		LOGP(DRSL, LOGL_DEBUG, "(bts=%d,trx=%d) ACC RAMP: administrative state %s -> %s\n",
+		    acc_ramp->bts->nr, trx->nr,
+		    get_value_string(abis_nm_adm_state_names, nsd->old_state->administrative),
+		    get_value_string(abis_nm_adm_state_names, nsd->new_state->administrative));
+	else if (signal == S_NM_STATECHG_OPER)
+		LOGP(DRSL, LOGL_DEBUG, "(bts=%d,trx=%d) ACC RAMP: operational state %s -> %s\n",
+		    acc_ramp->bts->nr, trx->nr,
+		    abis_nm_opstate_name(nsd->old_state->operational),
+		    abis_nm_opstate_name(nsd->new_state->operational));
+
 	/* We only care about state changes of the first TRX. */
 	if (trx->nr != 0)
 		return 0;
@@ -162,29 +175,54 @@
 	if (trx->rsl_link == NULL)
 		return 0;
 
-	/* Trigger or abort ACC ramping based on the new 'RF lock' state of this TRX. */
-	switch (nsd->new_state->administrative) {
-	case NM_STATE_UNLOCKED:
-		/*
-		 * Do not re-trigger ACC ramping if ramping is already in progress.
-		 * A BTS might send several "unlock" change events: One in the Administrative
-		 * State Change ACK, and/or another in a State Changed Event Report.
-		 * For instance, the nanobts is known to send both.
-		 */
-		if (!osmo_timer_pending(&acc_ramp->step_timer))
-			acc_ramp_trigger(acc_ramp);
-		break;
-	case NM_STATE_LOCKED:
-	case NM_STATE_SHUTDOWN:
-		acc_ramp_abort(acc_ramp);
-		break;
-	case NM_STATE_NULL:
-		break;
-	default:
-		LOGP(DRSL, LOGL_NOTICE, "(bts=%d) ACC RAMP: unrecognized administrative state '0x%x' reported for TRX 0\n",
-		    acc_ramp->bts->nr, nsd->new_state->administrative);
-		break;
+	/* Trigger or abort ACC ramping based on the new state of this TRX. */
+	if (nsd->old_state->administrative != nsd->new_state->administrative) {
+		switch (nsd->new_state->administrative) {
+		case NM_STATE_UNLOCKED:
+			if (trx_is_usable(trx)) /* cross-check with operational state */
+				trigger_ramping = true;
+			break;
+		case NM_STATE_LOCKED:
+		case NM_STATE_SHUTDOWN:
+			abort_ramping = true;
+			break;
+		case NM_STATE_NULL:
+			break;
+		default:
+			LOGP(DRSL, LOGL_NOTICE, "(bts=%d) ACC RAMP: unrecognized administrative state '0x%x' "
+			    "reported for TRX 0\n", acc_ramp->bts->nr, nsd->new_state->administrative);
+			break;
+		}
 	}
+	if (nsd->old_state->operational != nsd->new_state->operational) {
+		switch (nsd->new_state->operational) {
+		case NM_OPSTATE_ENABLED:
+			/* cross-check with administrative state */
+			if (trx->mo.nm_state.administrative == NM_STATE_UNLOCKED)
+				trigger_ramping = true;
+			break;
+		case NM_OPSTATE_DISABLED:
+			abort_ramping = true;
+			break;
+		case NM_OPSTATE_NULL:
+			break;
+		default:
+			LOGP(DRSL, LOGL_NOTICE, "(bts=%d) ACC RAMP: unrecognized operational state '0x%x' "
+			     "reported for TRX 0\n", acc_ramp->bts->nr, nsd->new_state->administrative);
+			break;
+		}
+	}
+
+	/*
+	 * Do not re-trigger ACC ramping if ramping is already in progress.
+	 * A BTS might send several "RF unlock" change events: One in the Administrative
+	 * State Change ACK, and/or another in a State Changed Event Report.
+	 * For instance, the nanobts is known to send both.
+	 */
+	if (trigger_ramping && !osmo_timer_pending(&acc_ramp->step_timer))
+		acc_ramp_trigger(acc_ramp);
+	else if (abort_ramping)
+		acc_ramp_abort(acc_ramp);
 
 	return 0;
 }
diff --git a/src/libbsc/bsc_init.c b/src/libbsc/bsc_init.c
index c357105..429d3c7 100644
--- a/src/libbsc/bsc_init.c
+++ b/src/libbsc/bsc_init.c
@@ -339,8 +339,10 @@
 	/*
 	 * Trigger ACC ramping before sending system information to BTS.
 	 * This ensures that RACH control in system information is configured correctly.
+	 * TRX 0 should be usable and unlocked, otherwise starting ACC ramping is pointless.
 	 */
-	acc_ramp_trigger(&trx->bts->acc_ramp);
+	if (trx_is_usable(trx) && trx->mo.nm_state.administrative == NM_STATE_UNLOCKED)
+		acc_ramp_trigger(&trx->bts->acc_ramp);
 
 	gsm_bts_trx_set_system_infos(trx);
 

-- 
To view, visit https://gerrit.osmocom.org/7784
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: Ib3291439655598fb5ddc891a3e4cc35b0bad250f
Gerrit-PatchSet: 2
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Owner: Stefan Sperling <ssperling at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list