[MERGED] osmo-bts[master]: octphy: implement support for dynamic timeslots

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
Tue Aug 15 18:29:21 UTC 2017


Harald Welte has submitted this change and it was merged.

Change subject: octphy: implement support for dynamic timeslots
......................................................................


octphy: implement support for dynamic timeslots

Implement API functions bts_model_ts_connect() and
bts_model_ts_disconnect() in order to support dynamic timeslot
allocation.

Change-Id: Ia109d4bfade7bc28442127581f4bb0289146ea71
---
M src/osmo-bts-octphy/l1_if.c
M src/osmo-bts-octphy/l1_oml.c
2 files changed, 126 insertions(+), 13 deletions(-)

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



diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c
index cb792d7..e4ab538 100644
--- a/src/osmo-bts-octphy/l1_if.c
+++ b/src/osmo-bts-octphy/l1_if.c
@@ -329,11 +329,30 @@
 	return 0;
 }
 
-static uint8_t chan_nr_by_sapi(enum gsm_phys_chan_config pchan,
+static enum gsm_phys_chan_config pick_pchan(struct gsm_bts_trx_ts *ts)
+{
+	switch (ts->pchan) {
+	case GSM_PCHAN_TCH_F_PDCH:
+		if (ts->flags & TS_F_PDCH_ACTIVE)
+			return GSM_PCHAN_PDCH;
+		return GSM_PCHAN_TCH_F;
+	case GSM_PCHAN_TCH_F_TCH_H_PDCH:
+		return ts->dyn.pchan_is;
+	default:
+		return ts->pchan;
+	}
+}
+
+static uint8_t chan_nr_by_sapi(struct gsm_bts_trx_ts *ts,
 		      tOCTVC1_GSM_SAPI_ENUM sapi, uint8_t subCh,
 		      uint8_t u8Tn, uint32_t u32Fn)
 {
 	uint8_t cbits = 0;
+	enum gsm_phys_chan_config pchan = pick_pchan(ts);
+
+	OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_PDCH);
+	OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH);
+
 	switch (sapi) {
 	case cOCTVC1_GSM_SAPI_ENUM_BCCH:
 		cbits = 0x10;
@@ -476,7 +495,7 @@
 		if (!L1SAP_IS_CHAN_TCHF(chan_nr) && !L1SAP_IS_CHAN_PDCH(chan_nr))
 			subCh = l1sap_chan2ss(chan_nr);
 	} else if (L1SAP_IS_CHAN_TCHF(chan_nr) || L1SAP_IS_CHAN_PDCH(chan_nr)) {
-		if (trx->ts[u8Tn].pchan == GSM_PCHAN_PDCH) {
+		if (ts_is_pdch(&trx->ts[u8Tn])) {
 			if (L1SAP_IS_PTCCH(u32Fn)) {
 				sapi = cOCTVC1_GSM_SAPI_ENUM_PTCCH;
 			} else {
@@ -932,7 +951,7 @@
 	       get_value_string(octphy_l1sapi_names, sapi));
 
 	/* in case we need to forward primitive to common part */
-	chan_nr = chan_nr_by_sapi(trx->ts[ts_num].pchan, sapi, sc, ts_num, fn);
+	chan_nr = chan_nr_by_sapi(&trx->ts[ts_num], sapi, sc, ts_num, fn);
 	if (chan_nr) {
 		if (sapi == cOCTVC1_GSM_SAPI_ENUM_SACCH)
 			link_id = LID_SACCH;
@@ -1053,7 +1072,7 @@
 	fn = data_ind->Data.ulFrameNumber;
 
 	/* chan_nr and link_id */
-	chan_nr = chan_nr_by_sapi(trx->ts[ts_num].pchan, sapi, sc, ts_num, fn);
+	chan_nr = chan_nr_by_sapi(&trx->ts[ts_num], sapi, sc, ts_num, fn);
 	if (!chan_nr) {
 		LOGP(DL1C, LOGL_ERROR,
 		     "Rx PH-DATA.ind for unknown L1 SAPI %s\n",
diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c
index 03ff547..d1d5bf6 100644
--- a/src/osmo-bts-octphy/l1_oml.c
+++ b/src/osmo-bts-octphy/l1_oml.c
@@ -1406,21 +1406,24 @@
 	return opstart_compl(mo);
 }
 
-static int ts_connect(struct gsm_bts_trx_ts *ts)
+static int ts_connect_as(struct gsm_bts_trx_ts *ts,
+			 enum gsm_phys_chan_config pchan,
+			 l1if_compl_cb * cb, void *data)
 {
 	struct phy_instance *pinst = trx_phy_instance(ts->trx);
 	struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl;
 	struct msgb *msg = l1p_msgb_alloc();
 	tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *oc =
-		(tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *) oc;
+	    (tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *) oc;
 
-	oc = (tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *) msgb_put(msg, sizeof(*oc));
+	oc = (tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD*)
+		msgb_put(msg, sizeof(*oc));
 	l1if_fill_msg_hdr(&oc->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND,
 			  cOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CID);
 
 	oc->TrxId.byTrxId = pinst->u.octphy.trx_id;
 	oc->PchId.byTimeslotNb = ts->nr;
-	oc->ulChannelType = pchan_to_logChComb[ts->pchan];
+	oc->ulChannelType = pchan_to_logChComb[pchan];
 
 	/* TODO: how should we know the payload type here?  Also, why
 	 * would the payload type have to be the same for both halves of
@@ -1436,11 +1439,71 @@
 	}
 
 	LOGP(DL1C, LOGL_INFO, "PCHAN-ACT.req(trx=%u, ts=%u, chcomb=%u)\n",
-		ts->trx->nr, ts->nr, ts->pchan);
+	     ts->trx->nr, ts->nr, pchan);
 
 	mOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD_SWAP(oc);
 
-	return l1if_req_compl(fl1h, msg, pchan_act_compl_cb, NULL);
+	return l1if_req_compl(fl1h, msg, cb, data);
+}
+
+/* Dynamic timeslots: Disconnect callback, reports completed disconnection
+ * to higher layers */
+static int ts_disconnect_cb(struct octphy_hdl *fl1, struct msgb *resp,
+			    void *data)
+{
+	tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_RSP *ar =
+	    (tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_RSP *) resp->l2h;
+	uint8_t ts_nr;
+	struct gsm_bts_trx *trx;
+	struct gsm_bts_trx_ts *ts;
+
+	trx = trx_by_l1h(fl1, ar->TrxId.byTrxId);
+	ts_nr = ar->PchId.byTimeslotNb;
+	ts = &trx->ts[ts_nr];
+
+	cb_ts_disconnected(ts);
+
+	return 0;
+}
+
+/* Dynamic timeslots: Connect  callback, reports completed disconnection to
+ * higher layers */
+static int ts_connect_cb(struct octphy_hdl *fl1, struct msgb *resp, void *data)
+{
+	tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_RSP *ar =
+	    (tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_RSP *) resp->l2h;
+	uint8_t ts_nr;
+	struct gsm_bts_trx *trx;
+	struct gsm_bts_trx_ts *ts;
+
+	/* in a completion call-back, we take msgb ownership and must
+	 * release it before returning */
+
+	mOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_RSP_SWAP(ar);
+	trx = trx_by_l1h(fl1, ar->TrxId.byTrxId);
+	ts_nr = ar->PchId.byTimeslotNb;
+	OSMO_ASSERT(ts_nr <= ARRAY_SIZE(trx->ts));
+
+	ts = &trx->ts[ts_nr];
+
+	LOGP(DL1C, LOGL_INFO, "PCHAN-ACT.conf(trx=%u, ts=%u, chcomb=%u) = %s\n",
+	     ts->trx->nr, ts->nr, ts->pchan,
+	     octvc1_rc2string(ar->Header.ulReturnCode));
+
+	if (ar->Header.ulReturnCode != cOCTVC1_RC_OK) {
+		LOGP(DL1C, LOGL_ERROR,
+		     "PCHAN-ACT failed: %s\n\n",
+		     octvc1_rc2string(ar->Header.ulReturnCode));
+		LOGP(DL1C, LOGL_ERROR, "Exiting... \n\n");
+		msgb_free(resp);
+		exit(-1);
+	}
+
+	msgb_free(resp);
+
+	cb_ts_connected(ts);
+
+	return 0;
 }
 
 /***********************************************************************
@@ -1583,13 +1646,15 @@
 int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
 {
 	int rc = -1;
+	struct gsm_bts_trx_ts *ts;
 
 	switch (mo->obj_class) {
 	case NM_OC_RADIO_CARRIER:
 		rc = trx_init(obj);
 		break;
 	case NM_OC_CHANNEL:
-		rc = ts_connect(obj);
+		ts = (struct gsm_bts_trx_ts*) obj;
+		rc = ts_connect_as(ts, ts->pchan, pchan_act_compl_cb, NULL);
 		break;
 	case NM_OC_BTS:
 	case NM_OC_SITE_MANAGER:
@@ -1614,11 +1679,40 @@
 
 int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts)
 {
-	return -ENOTSUP;
+	struct phy_instance *pinst = trx_phy_instance(ts->trx);
+	struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl;
+	struct msgb *msg = l1p_msgb_alloc();
+	tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *oc =
+	    (tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *) oc;
+
+	oc = (tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *)
+	    msgb_put(msg, sizeof(*oc));
+	l1if_fill_msg_hdr(&oc->Header, msg, fl1h, cOCTVC1_MSG_TYPE_COMMAND,
+			  cOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CID);
+
+	oc->TrxId.byTrxId = pinst->u.octphy.trx_id;
+	oc->PchId.byTimeslotNb = ts->nr;
+
+	LOGP(DL1C, LOGL_INFO, "PCHAN-DEACT.req(trx=%u, ts=%u, chcomb=%u)\n",
+	     ts->trx->nr, ts->nr, ts->pchan);
+
+	mOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD_SWAP(oc);
+
+	return l1if_req_compl(fl1h, msg, ts_disconnect_cb, NULL);
 }
 
 int bts_model_ts_connect(struct gsm_bts_trx_ts *ts,
 			 enum gsm_phys_chan_config as_pchan)
 {
-	return -ENOTSUP;
+	if (as_pchan == GSM_PCHAN_TCH_F_PDCH
+	    || as_pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
+		LOGP(DL1C, LOGL_ERROR,
+		     "%s Requested TS connect as %s,"
+		     " expected a specific pchan instead\n",
+		     gsm_ts_and_pchan_name(ts), gsm_pchan_name(as_pchan));
+		exit(1);
+		return -EINVAL;
+	}
+
+	return ts_connect_as(ts, as_pchan, ts_connect_cb, NULL);
 }

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

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



More information about the gerrit-log mailing list