[MERGED] osmo-bts[master]: sysmo: add L3 handle to l1prim messages

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

Harald Welte gerrit-no-reply at lists.osmocom.org
Wed Jun 15 09:30:24 UTC 2016


Harald Welte has submitted this change and it was merged.

Change subject: sysmo: add L3 handle to l1prim messages
......................................................................


sysmo: add L3 handle to l1prim messages

Place a layer 3 handle into GSM L1 messages to better match up confirmations to
respective requests. This handle is a uint32_t transparently returned in the
confirmation messages, so a match-up is easy to add.

So far, a GSM L1 confirmation message received for a preceding L1 Request was
matched only by the prim_id. That meant that only one instance of the same
primitive could be waiting for a confirmation at any given time, or the
responses would get mixed up: the struct wait_l1_conf instances entered into
the fl1h->wlc_list queue would be returned to a possibly mismatching
confirmation handler. (Seen during testing of dyn pdch switching.)

Send the hLayer3 handle out via prim_init(), using new static functions to
produce handles on different scopes:

* l1p_handle_for_trx()
* l1p_handle_for_ts()
* l1p_handle_for_lchan()

(These could possibly move to a more general .h/.c file later.)

Remember the hLayer3 handle in

* struct wait_l1_conf.

Match the incoming confirmations' and stored hLayer3 handles up in, and remove
a now obsolete comment from:

* is_prim_compat()

Since the hLayer3 members are at different byte offsets in
GsmL1_Prim_t.u.*, use large switch statements to set/get the value:

* In prim_init(), extend existing switch statement to set in GsmL1_Prim_t.
* Add l1p_get_hLayer3() to retrieve from GsmL1_Prim_t (could possibly move to a
  more general .h/.c file later).

Change-Id: Ie4533c6cbc160318917e7a672ab6f9a848f01d1b
---
M src/osmo-bts-sysmo/l1_if.c
M src/osmo-bts-sysmo/oml.c
2 files changed, 128 insertions(+), 13 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 84fad99..14de251 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -67,6 +67,7 @@
 	struct llist_head list;		/* internal linked list */
 	struct osmo_timer_list timer;	/* timer for L1 timeout */
 	unsigned int conf_prim_id;	/* primitive we expect in response */
+	HANDLE conf_hLayer3;		/* layer 3 handle we expect in response */
 	unsigned int is_sys_prim;	/* is this a system (1) or L1 (0) primitive */
 	l1if_compl_cb *cb;
 	void *cb_data;
@@ -90,6 +91,58 @@
 			get_value_string(femtobts_l1prim_names, wlc->conf_prim_id));
 	exit(23);
 }
+
+static HANDLE l1p_get_hLayer3(GsmL1_Prim_t *prim)
+{
+	switch (prim->id) {
+	case GsmL1_PrimId_MphInitReq:
+		return prim->u.mphInitReq.hLayer3;
+	case GsmL1_PrimId_MphCloseReq:
+		return prim->u.mphCloseReq.hLayer3;
+	case GsmL1_PrimId_MphConnectReq:
+		return prim->u.mphConnectReq.hLayer3;
+	case GsmL1_PrimId_MphDisconnectReq:
+		return prim->u.mphDisconnectReq.hLayer3;
+	case GsmL1_PrimId_MphActivateReq:
+		return prim->u.mphActivateReq.hLayer3;
+	case GsmL1_PrimId_MphDeactivateReq:
+		return prim->u.mphDeactivateReq.hLayer3;
+	case GsmL1_PrimId_MphConfigReq:
+		return prim->u.mphConfigReq.hLayer3;
+	case GsmL1_PrimId_MphMeasureReq:
+		return prim->u.mphMeasureReq.hLayer3;
+	case GsmL1_PrimId_MphInitCnf:
+		return prim->u.mphInitCnf.hLayer3;
+	case GsmL1_PrimId_MphCloseCnf:
+		return prim->u.mphCloseCnf.hLayer3;
+	case GsmL1_PrimId_MphConnectCnf:
+		return prim->u.mphConnectCnf.hLayer3;
+	case GsmL1_PrimId_MphDisconnectCnf:
+		return prim->u.mphDisconnectCnf.hLayer3;
+	case GsmL1_PrimId_MphActivateCnf:
+		return prim->u.mphActivateCnf.hLayer3;
+	case GsmL1_PrimId_MphDeactivateCnf:
+		return prim->u.mphDeactivateCnf.hLayer3;
+	case GsmL1_PrimId_MphConfigCnf:
+		return prim->u.mphConfigCnf.hLayer3;
+	case GsmL1_PrimId_MphMeasureCnf:
+		return prim->u.mphMeasureCnf.hLayer3;
+	case GsmL1_PrimId_MphTimeInd:
+	case GsmL1_PrimId_MphSyncInd:
+	case GsmL1_PrimId_PhEmptyFrameReq:
+	case GsmL1_PrimId_PhDataReq:
+	case GsmL1_PrimId_PhConnectInd:
+	case GsmL1_PrimId_PhReadyToSendInd:
+	case GsmL1_PrimId_PhDataInd:
+	case GsmL1_PrimId_PhRaInd:
+		break;
+	default:
+		LOGP(DL1C, LOGL_ERROR, "unknown L1 primitive %u\n", prim->id);
+		break;
+	}
+	return 0;
+}
+
 
 static int _l1if_req_compl(struct femtol1_hdl *fl1h, struct msgb *msg,
 		   int is_system_prim, l1if_compl_cb *cb, void *data)
@@ -118,6 +171,7 @@
 		}
 		wlc->is_sys_prim = 0;
 		wlc->conf_prim_id = femtobts_l1prim_req2conf[l1p->id];
+		wlc->conf_hLayer3 = l1p_get_hLayer3(l1p);
 		wqueue = &fl1h->write_q[MQ_L1_WRITE];
 		timeout_secs = 30;
 	} else {
@@ -943,12 +997,12 @@
 
 static inline int is_prim_compat(GsmL1_Prim_t *l1p, struct wait_l1_conf *wlc)
 {
-	/* the limitation here is that we cannot have multiple callers
-	 * sending the same primitive */
 	if (wlc->is_sys_prim != 0)
 		return 0;
 	if (l1p->id != wlc->conf_prim_id)
 		return 0;
+	if (l1p_get_hLayer3(l1p) != wlc->conf_hLayer3)
+		return 0;
 	return 1;
 }
 
diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c
index cd03b22..6951f84 100644
--- a/src/osmo-bts-sysmo/oml.c
+++ b/src/osmo-bts-sysmo/oml.c
@@ -92,45 +92,70 @@
 
 static int trx_rf_lock(struct gsm_bts_trx *trx, int locked, l1if_compl_cb *cb);
 
-static void *prim_init(GsmL1_Prim_t *prim, GsmL1_PrimId_t id, struct femtol1_hdl *gl1)
+static void *prim_init(GsmL1_Prim_t *prim, GsmL1_PrimId_t id, struct femtol1_hdl *gl1,
+		       HANDLE hLayer3)
 {
 	prim->id = id;
 
-	/* for some reason the hLayer1 field is not always at the same position
-	 * in the GsmL1_Prim_t, so we have to have this ugly case statement here... */
+	/* for some reason the hLayer1 and hlayer3 fields are not always at the
+	 * same position in the GsmL1_Prim_t, so we have to have this ugly case
+	 * statement here... */
 	switch (id) {
 	case GsmL1_PrimId_MphInitReq:
 		//prim->u.mphInitReq.hLayer1 = gl1->hLayer1;
+		prim->u.mphInitReq.hLayer3 = hLayer3;
 		break;
 	case GsmL1_PrimId_MphCloseReq:
 		prim->u.mphCloseReq.hLayer1 = gl1->hLayer1;
+		prim->u.mphCloseReq.hLayer3 = hLayer3;
 		break;
 	case GsmL1_PrimId_MphConnectReq:
 		prim->u.mphConnectReq.hLayer1 = gl1->hLayer1;
+		prim->u.mphConnectReq.hLayer3 = hLayer3;
 		break;
 	case GsmL1_PrimId_MphDisconnectReq:
 		prim->u.mphDisconnectReq.hLayer1 = gl1->hLayer1;
+		prim->u.mphDisconnectReq.hLayer3 = hLayer3;
 		break;
 	case GsmL1_PrimId_MphActivateReq:
 		prim->u.mphActivateReq.hLayer1 = gl1->hLayer1;
+		prim->u.mphActivateReq.hLayer3 = hLayer3;
 		break;
 	case GsmL1_PrimId_MphDeactivateReq:
 		prim->u.mphDeactivateReq.hLayer1 = gl1->hLayer1;
+		prim->u.mphDeactivateReq.hLayer3 = hLayer3;
 		break;
 	case GsmL1_PrimId_MphConfigReq:
 		prim->u.mphConfigReq.hLayer1 = gl1->hLayer1;
+		prim->u.mphConfigReq.hLayer3 = hLayer3;
 		break;
 	case GsmL1_PrimId_MphMeasureReq:
 		prim->u.mphMeasureReq.hLayer1 = gl1->hLayer1;
+		prim->u.mphMeasureReq.hLayer3 = hLayer3;
 		break;
 	case GsmL1_PrimId_MphInitCnf:
+		prim->u.mphInitCnf.hLayer3 = hLayer3;
+		break;
 	case GsmL1_PrimId_MphCloseCnf:
+		prim->u.mphCloseCnf.hLayer3 = hLayer3;
+		break;
 	case GsmL1_PrimId_MphConnectCnf:
+		prim->u.mphConnectCnf.hLayer3 = hLayer3;
+		break;
 	case GsmL1_PrimId_MphDisconnectCnf:
+		prim->u.mphDisconnectCnf.hLayer3 = hLayer3;
+		break;
 	case GsmL1_PrimId_MphActivateCnf:
+		prim->u.mphActivateCnf.hLayer3 = hLayer3;
+		break;
 	case GsmL1_PrimId_MphDeactivateCnf:
+		prim->u.mphDeactivateCnf.hLayer3 = hLayer3;
+		break;
 	case GsmL1_PrimId_MphConfigCnf:
+		prim->u.mphConfigCnf.hLayer3 = hLayer3;
+		break;
 	case GsmL1_PrimId_MphMeasureCnf:
+		prim->u.mphMeasureCnf.hLayer3 = hLayer3;
 		break;
 	case GsmL1_PrimId_MphTimeInd:
 		break;
@@ -155,6 +180,35 @@
 		break;
 	}
 	return &prim->u;
+}
+
+static HANDLE l1p_handle_for_trx(struct gsm_bts_trx *trx)
+{
+	struct gsm_bts *bts = trx->bts;
+
+	osmo_static_assert(sizeof(HANDLE) >= 4, l1p_handle_is_at_least_32bit);
+	osmo_static_assert(sizeof(trx->nr) == 1, trx_nr_is_8bit);
+	osmo_static_assert(sizeof(bts->nr) == 1, bts_nr_is_8bit);
+
+	return   bts->nr << 24
+	       | trx->nr << 16;
+}
+
+static HANDLE l1p_handle_for_ts(struct gsm_bts_trx_ts *ts)
+{
+	osmo_static_assert(sizeof(ts->nr) == 1, ts_nr_is_8bit);
+
+	return   l1p_handle_for_trx(ts->trx)
+	       | ts->nr << 8;
+}
+
+
+static HANDLE l1p_handle_for_lchan(struct gsm_lchan *lchan)
+{
+	osmo_static_assert(sizeof(lchan->nr) == 1, lchan_nr_is_8bit);
+
+	return   l1p_handle_for_ts(lchan->ts)
+	       | lchan->nr;
 }
 
 GsmL1_Status_t prim_status(GsmL1_Prim_t *prim)
@@ -346,7 +400,8 @@
 	}
 
 	msg = l1p_msgb_alloc();
-	mi_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphInitReq, fl1h);
+	mi_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphInitReq, fl1h,
+			   l1p_handle_for_trx(trx));
 	dev_par = &mi_req->deviceParam;
 	dev_par->devType = GsmL1_DevType_TxdRxu;
 	dev_par->freqBand = femto_band;
@@ -385,7 +440,8 @@
 	struct msgb *msg;
 
 	msg = l1p_msgb_alloc();
-	prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphCloseReq, fl1h);
+	prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphCloseReq, fl1h,
+		  l1p_handle_for_trx(trx));
 	LOGP(DL1C, LOGL_NOTICE, "Close TRX %u\n", trx->nr);
 
 	return l1if_gsm_req_compl(fl1h, msg, trx_close_compl_cb, NULL);
@@ -430,7 +486,8 @@
 	struct femtol1_hdl *fl1h = trx_femtol1_hdl(ts->trx);
 	GsmL1_MphConnectReq_t *cr;
 
-	cr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConnectReq, fl1h);
+	cr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConnectReq, fl1h,
+		       l1p_handle_for_ts(ts));
 	cr->u8Tn = ts->nr;
 	cr->logChComb = pchan_to_logChComb[ts->pchan];
 	
@@ -917,7 +974,8 @@
 	GsmL1_MphActivateReq_t *act_req;
 	GsmL1_LogChParam_t *lch_par;
 
-	act_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphActivateReq, fl1h);
+	act_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphActivateReq,
+			    fl1h, l1p_handle_for_lchan(lchan));
 	lch_par = &act_req->logChPrm;
 	act_req->u8Tn = lchan->ts->nr;
 	act_req->subCh = lchan_to_GsmL1_SubCh_t(lchan);
@@ -1210,7 +1268,8 @@
 	/* channel mode, encryption and/or multirate have changed */
 
 	/* update multi-rate config */
-	conf_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConfigReq, fl1h);
+	conf_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConfigReq, fl1h,
+			     l1p_handle_for_lchan(lchan));
 	conf_req->cfgParamId = GsmL1_ConfigParamId_SetLogChParams;
 	conf_req->cfgParams.setLogChParams.sapi = cmd->sapi;
 	conf_req->cfgParams.setLogChParams.u8Tn = lchan->ts->nr;
@@ -1263,7 +1322,7 @@
 	struct msgb *msg = l1p_msgb_alloc();
 	GsmL1_MphConfigReq_t *conf_req;
 
-	conf_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConfigReq, fl1h);
+	conf_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConfigReq, fl1h, 0);
 	conf_req->cfgParamId = GsmL1_ConfigParamId_SetTxPowerLevel;
 	conf_req->cfgParams.setTxPowerLevel.fTxPowerLevel = tx_power;
 
@@ -1284,7 +1343,8 @@
 	struct msgb *msg = l1p_msgb_alloc();
 	struct GsmL1_MphConfigReq_t *cfgr;
 
-	cfgr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConfigReq, fl1h);
+	cfgr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphConfigReq, fl1h,
+			 l1p_handle_for_lchan(lchan));
 
 	cfgr->cfgParamId = GsmL1_ConfigParamId_SetCipheringParams;
 	cfgr->cfgParams.setCipheringParams.u8Tn = lchan->ts->nr;
@@ -1431,7 +1491,8 @@
 	struct msgb *msg = l1p_msgb_alloc();
 	GsmL1_MphDeactivateReq_t *deact_req;
 
-	deact_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphDeactivateReq, fl1h);
+	deact_req = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphDeactivateReq,
+			      fl1h, l1p_handle_for_lchan(lchan));
 	deact_req->u8Tn = lchan->ts->nr;
 	deact_req->subCh = lchan_to_GsmL1_SubCh_t(lchan);
 	deact_req->dir = cmd->dir;

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ie4533c6cbc160318917e7a672ab6f9a848f01d1b
Gerrit-PatchSet: 2
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list