[PATCH 4/4] sysmobts: Do a RF mute when Radio Carrier is locked

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/OpenBSC@lists.osmocom.org/.

Jacob Erlbeck jerlbeck at sysmocom.de
Mon Nov 4 13:56:12 UTC 2013


Currently a Change Administrative State Request is just applied
unconditionally to the object's state object and then acknowledged.

This patch implements the special handling of setting the Radio
Carriers state to LOCK or UNLOCK. This is done by passing the
appropriate mute command to the L1 layer. Always all radio channels
are affected, it is not possible to lock single radio channels.
On success, an ACK is sent back to the bsc with the new state (based
on the state passed in the callback by the L1 layer). If something
went wrong or the firmware doesn't support RF mute, a NACK
(REQ_NOT_GRANTED) is sent instead.

Note that a NACK for such a request hasn't been sent by the BTS to
the BSC yet, so (albeit it's spec conformant to do so) the BSC must
be prepared to handle this correctly.

Ticket: OW#976
Sponsored-by: On-Waves ehf
---
 include/osmo-bts/oml.h   |    1 +
 src/common/oml.c         |    5 ++++
 src/osmo-bts-sysmo/oml.c |   70 +++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/include/osmo-bts/oml.h b/include/osmo-bts/oml.h
index 92695ca..4281fd3 100644
--- a/include/osmo-bts/oml.h
+++ b/include/osmo-bts/oml.h
@@ -10,6 +10,7 @@ int oml_mo_send_msg(struct gsm_abis_mo *mo, struct msgb *msg, uint8_t msg_type);
 int oml_mo_opstart_ack(struct gsm_abis_mo *mo);
 int oml_mo_opstart_nack(struct gsm_abis_mo *mo, uint8_t nack_cause);
 int oml_mo_statechg_ack(struct gsm_abis_mo *mo);
+int oml_mo_statechg_nack(struct gsm_abis_mo *mo, uint8_t nack_cause);
 
 /* Change the state and send STATE CHG REP */
 int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state);
diff --git a/src/common/oml.c b/src/common/oml.c
index 1c38c66..bf174b5 100644
--- a/src/common/oml.c
+++ b/src/common/oml.c
@@ -299,6 +299,11 @@ int oml_mo_statechg_ack(struct gsm_abis_mo *mo)
 	return oml_mo_send_msg(mo, msg, NM_MT_CHG_ADM_STATE_ACK);
 }
 
+int oml_mo_statechg_nack(struct gsm_abis_mo *mo, uint8_t nack_cause)
+{
+	return oml_mo_fom_ack_nack(mo, NM_MT_CHG_ADM_STATE, nack_cause);
+}
+
 int oml_mo_opstart_ack(struct gsm_abis_mo *mo)
 {
 	return oml_mo_fom_ack_nack(mo, NM_MT_OPSTART, 0);
diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c
index 822453f..8e76093 100644
--- a/src/osmo-bts-sysmo/oml.c
+++ b/src/osmo-bts-sysmo/oml.c
@@ -326,10 +326,31 @@ int bts_model_trx_close(struct gsm_bts_trx *trx)
 	return l1if_gsm_req_compl(fl1h, msg, trx_close_compl_cb);
 }
 
+static int trx_rf_lock(struct gsm_bts_trx *trx, int locked)
+{
+	struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx);
+	uint8_t mute[8];
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mute); ++i)
+		mute[i] = locked ? 1 : 0;
+
+	return l1if_mute_rf(fl1h, mute);
+}
+
 int oml_mo_rf_lock_chg(struct gsm_abis_mo *mo, uint8_t mute_state[8],
 		       int success)
 {
-	return 0;
+	if (success) {
+		/* assume mute_state[i] == mute_state[k] */
+		mo->nm_state.administrative =
+			mute_state[0] ? NM_STATE_LOCKED : NM_STATE_UNLOCKED;
+		mo->procedure_pending = 0;
+		return oml_mo_statechg_ack(mo);
+	} else {
+		mo->procedure_pending = 0;
+		return oml_mo_statechg_nack(mo, NM_NACK_REQ_NOT_GRANT);
+	}
 }
 
 static int ts_connect(struct gsm_bts_trx_ts *ts)
@@ -1461,9 +1482,50 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
 int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo,
 			    void *obj, uint8_t adm_state)
 {
-	/* blindly accept all state changes */
-	mo->nm_state.administrative = adm_state;
-	return oml_mo_statechg_ack(mo);
+	int rc;
+	int granted = 0;
+
+	switch (mo->obj_class) {
+	case NM_OC_RADIO_CARRIER:
+
+		if (mo->procedure_pending) {
+			LOGP(DL1C, LOGL_ERROR, "Discarding adm change command: "
+			     "pending procedure on RC %d\n",
+			     ((struct gsm_bts_trx *)obj)->nr);
+			return 0;
+		}
+		mo->procedure_pending = 1;
+		switch (adm_state) {
+		case NM_STATE_LOCKED:
+			rc = trx_rf_lock(obj, 1);
+			break;
+		case NM_STATE_UNLOCKED:
+			rc = trx_rf_lock(obj, 0);
+			break;
+		default:
+			granted = 1;
+			break;
+		}
+
+		if (!granted && rc == 0)
+			/* in progress, will send ack/nack after completion */
+			return 0;
+
+		mo->procedure_pending = 0;
+
+		break;
+	default:
+		/* blindly accept all state changes */
+		granted = 1;
+		break;
+	}
+
+	if (granted) {
+		mo->nm_state.administrative = adm_state;
+		return oml_mo_statechg_ack(mo);
+	} else
+		return oml_mo_statechg_nack(mo, NM_NACK_REQ_NOT_GRANT);
+
 }
 int bts_model_rsl_chan_act(struct gsm_lchan *lchan, struct tlv_parsed *tp)
 {
-- 
1.7.9.5





More information about the OpenBSC mailing list