Change in osmo-bts[master]: [VAMOS] osmo-bts-trx: properly handle per-timeslot TSC values

laforge gerrit-no-reply at lists.osmocom.org
Fri Jun 4 20:04:14 UTC 2021


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

Change subject: [VAMOS] osmo-bts-trx: properly handle per-timeslot TSC values
......................................................................

[VAMOS] osmo-bts-trx: properly handle per-timeslot TSC values

Each timeslot can have its own Training Sequence Code value, which
may optionally be included in the NM_MT_SET_CHAN_ATTR message sent
over the A-bis/OML.  If it's not present, then the TSC value for a
timeslot is derived from the BCC part of BSIC, which is always
included in the NM_MT_SET_BTS_ATTR message.

On the TRXC interface, the BTS global TSC value is indicated to the
transceiver using either of the 'SETTSC' or 'SETBSIC' commands.
The transceiver then applies this value for all timeslots by default,
however it can be redefined for each timeslot individually using
additional arguments of the 'SETSLOT' command (see section 25.2.4.1
in the user manual [1] for more details).

Currently, trx_set_ts_as_pchan() sends TRX_PROV_EV_CFG_TSC to the
transceiver provisioning FSM, together with the per-timeslot TSC
value.  This event causes the FSM to modify the global TSC value,
that is going to be or has already been sent to the transceiver.
This is wrong, the global TSC value shall not be overwritten.

Remove the TRX_PROV_EV_CFG_TSC, and include per-timeslot Training
Sequence Code and Set in the data structure that gets passed together
with the TRX_PROV_EV_CFG_TS instead.  Implement handling of the
optional per-timeslot TSC in trx_if_cmd_setslot().

[1] https://downloads.osmocom.org/docs/latest/osmobts-usermanual.pdf

Change-Id: Idc5796151e3e83f42d60c2d4cb7c35890d76a7f5
Related: SYS#4895, OS#4941
---
M src/osmo-bts-trx/l1_if.c
M src/osmo-bts-trx/l1_if.h
M src/osmo-bts-trx/main.c
M src/osmo-bts-trx/trx_if.c
M src/osmo-bts-trx/trx_if.h
M src/osmo-bts-trx/trx_provision_fsm.c
M src/osmo-bts-trx/trx_provision_fsm.h
M src/osmo-bts-trx/trx_vty.c
8 files changed, 84 insertions(+), 58 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified



diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c
index 3f95a69..3be5179 100644
--- a/src/osmo-bts-trx/l1_if.c
+++ b/src/osmo-bts-trx/l1_if.c
@@ -271,15 +271,9 @@
 	struct phy_instance *pinst = trx_phy_instance(ts->trx);
 	struct trx_l1h *l1h = pinst->u.osmotrx.hdl;
 	uint8_t tn = ts->nr;
-	uint16_t tsc = ts->tsc;
 	uint8_t slottype;
 	int rc;
 
-	/* all TSC of all timeslots must be equal, because transceiver only
-	 * supports one TSC per TRX */
-
-	osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_TSC, (void*)(intptr_t)tsc);
-
 	/* ignore disabled slots */
 	if (!(l1h->config.slotmask & (1 << tn)))
 		return NM_NACK_RES_NOTAVAIL;
@@ -303,6 +297,13 @@
 
 
 	struct trx_prov_ev_cfg_ts_data data = { .tn = tn, .slottype = slottype };
+	if (ts->tsc_set != 0 || ts->tsc != BTS_TSC(ts->trx->bts)) {
+		/* On TRXC we use 3GPP compliant numbering, so +1 */
+		data.tsc_set = ts->tsc_set + 1;
+		data.tsc_val = ts->tsc;
+		data.tsc_valid = true;
+	}
+
 	osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_TS, &data);
 
 	return 0;
diff --git a/src/osmo-bts-trx/l1_if.h b/src/osmo-bts-trx/l1_if.h
index 864bb69..50369d9 100644
--- a/src/osmo-bts-trx/l1_if.h
+++ b/src/osmo-bts-trx/l1_if.h
@@ -105,9 +105,14 @@
 
 	uint8_t			slotmask;
 
-	bool			slottype_valid[TRX_NR_TS];
-	uint8_t			slottype[TRX_NR_TS];
-	bool			slottype_sent[TRX_NR_TS];
+	bool			setslot_valid[TRX_NR_TS];
+	struct {
+		uint8_t slottype;
+		uint8_t tsc_set;
+		uint8_t tsc_val;
+		bool tsc_valid;
+	}			setslot[TRX_NR_TS];
+	bool			setslot_sent[TRX_NR_TS];
 };
 
 struct trx_l1h {
diff --git a/src/osmo-bts-trx/main.c b/src/osmo-bts-trx/main.c
index e0a99a5..6ec8dfc 100644
--- a/src/osmo-bts-trx/main.c
+++ b/src/osmo-bts-trx/main.c
@@ -145,6 +145,7 @@
 	osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH);
 	osmo_bts_set_feature(bts->features, BTS_FEAT_HOPPING);
 	osmo_bts_set_feature(bts->features, BTS_FEAT_ACCH_REP);
+	osmo_bts_set_feature(bts->features, BTS_FEAT_MULTI_TSC);
 
 	bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB);
 
diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c
index af1deef..c10a15f 100644
--- a/src/osmo-bts-trx/trx_if.c
+++ b/src/osmo-bts-trx/trx_if.c
@@ -8,6 +8,7 @@
  * Copyright (C) 2013  Andreas Eversberg <jolly at eversberg.eu>
  * Copyright (C) 2016-2017  Harald Welte <laforge at gnumonks.org>
  * Copyright (C) 2019  Vadim Yanitskiy <axilirator at gmail.com>
+ * Copyright (C) 2021  sysmocom - s.m.f.c. GmbH <info at sysmocom.de>
  *
  * All Rights Reserved
  *
@@ -326,10 +327,21 @@
 	return trx_ctrl_cmd(l1h, 0, "SETMAXDLYNB", "%d", dly);
 }
 
-/*! Send "SETSLOT" command to TRX: Configure Channel Combination for TS */
-int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, uint8_t type, trx_if_cmd_setslot_cb *cb)
+/*! Send "SETSLOT" command to TRX: Configure Channel Combination and TSC for TS */
+int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn,
+		       trx_if_cmd_setslot_cb *cb)
 {
-	return trx_ctrl_cmd_cb(l1h, 1, cb, "SETSLOT", "%d %d", tn, type);
+	const struct trx_config *cfg = &l1h->config;
+
+	if (cfg->setslot[tn].tsc_valid) { /* PHY is instructed to use a custom TSC */
+		return trx_ctrl_cmd_cb(l1h, 1, cb, "SETSLOT", "%u %u C%u/S%u",
+				       tn, cfg->setslot[tn].slottype,
+				       cfg->setslot[tn].tsc_val,
+				       cfg->setslot[tn].tsc_set);
+       } else { /* PHY is instructed to use the default TSC from 'SETTSC' */
+		return trx_ctrl_cmd_cb(l1h, 1, cb, "SETSLOT", "%u %u",
+				       tn, cfg->setslot[tn].slottype);
+	}
 }
 
 /*! Send "RXTUNE" command to TRX: Tune Receiver to given ARFCN */
diff --git a/src/osmo-bts-trx/trx_if.h b/src/osmo-bts-trx/trx_if.h
index e131d56..b838b76 100644
--- a/src/osmo-bts-trx/trx_if.h
+++ b/src/osmo-bts-trx/trx_if.h
@@ -34,7 +34,7 @@
 int trx_if_cmd_setpower_att(struct trx_l1h *l1h, int power_att_db, trx_if_cmd_setpower_att_cb *cb);
 int trx_if_cmd_setmaxdly(struct trx_l1h *l1h, int dly);
 int trx_if_cmd_setmaxdlynb(struct trx_l1h *l1h, int dly);
-int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, uint8_t type, trx_if_cmd_setslot_cb *cb);
+int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, trx_if_cmd_setslot_cb *cb);
 int trx_if_cmd_rxtune(struct trx_l1h *l1h, uint16_t arfcn, trx_if_cmd_generic_cb *cb);
 int trx_if_cmd_txtune(struct trx_l1h *l1h, uint16_t arfcn, trx_if_cmd_generic_cb *cb);
 int trx_if_cmd_handover(struct trx_l1h *l1h, uint8_t tn, uint8_t ss);
diff --git a/src/osmo-bts-trx/trx_provision_fsm.c b/src/osmo-bts-trx/trx_provision_fsm.c
index 070037d..5beca2a 100644
--- a/src/osmo-bts-trx/trx_provision_fsm.c
+++ b/src/osmo-bts-trx/trx_provision_fsm.c
@@ -191,17 +191,15 @@
 	cb_ts_connected(ts, rc);
 }
 
-/* Returns true if any TS changed, false otherwise */
-static bool update_ts_data(struct trx_l1h *l1h, struct trx_prov_ev_cfg_ts_data* ts_data) {
+static void update_ts_data(struct trx_l1h *l1h, struct trx_prov_ev_cfg_ts_data *data)
+{
+	l1h->config.setslot[data->tn].slottype = data->slottype;
+	l1h->config.setslot[data->tn].tsc_set = data->tsc_set;
+	l1h->config.setslot[data->tn].tsc_val = data->tsc_val;
+	l1h->config.setslot[data->tn].tsc_valid = data->tsc_valid;
 
-	if (l1h->config.slottype[ts_data->tn] != ts_data->slottype ||
-	    !l1h->config.slottype_valid[ts_data->tn]) {
-		l1h->config.slottype[ts_data->tn] = ts_data->slottype;
-		l1h->config.slottype_valid[ts_data->tn] = true;
-		l1h->config.slottype_sent[ts_data->tn] = false;
-		return true;
-	}
-	return false;
+	l1h->config.setslot_valid[data->tn] = true;
+	l1h->config.setslot_sent[data->tn] = false;
 }
 
 /* Whether a given TRX is fully configured and can be powered on */
@@ -290,9 +288,7 @@
 	struct trx_l1h *l1h = (struct trx_l1h *)fi->priv;
 	struct phy_instance *pinst = l1h->phy_inst;
 	struct gsm_bts_trx *trx = pinst->trx;
-	uint8_t bsic;
 	uint16_t arfcn;
-	uint16_t tsc;
 	int nominal_power;
 	int status;
 	bool others_ready;
@@ -302,11 +298,21 @@
 		l1h->config.enabled =(bool)data;
 		break;
 	case TRX_PROV_EV_CFG_BSIC:
-		bsic = (uint8_t)(intptr_t)data;
-		if (l1h->config.bsic != bsic || !l1h->config.bsic_valid) {
-			l1h->config.bsic = bsic;
-			l1h->config.bsic_valid = true;
-			l1h->config.bsic_sent = false;
+		/* We always get BSIC from the BSC, TSC can be derived from the BCC */
+		if (!pinst->phy_link->u.osmotrx.use_legacy_setbsic) {
+			const uint8_t tsc = BSIC2BCC((uint8_t)(intptr_t)data);
+			if (l1h->config.tsc != tsc || !l1h->config.tsc_valid) {
+				l1h->config.tsc = tsc;
+				l1h->config.tsc_valid = true;
+				l1h->config.tsc_sent = false;
+			}
+		} else {
+			const uint8_t bsic = (uint8_t)(intptr_t)data;
+			if (l1h->config.bsic != bsic || !l1h->config.bsic_valid) {
+				l1h->config.bsic = bsic;
+				l1h->config.bsic_valid = true;
+				l1h->config.bsic_sent = false;
+			}
 		}
 		break;
 	case TRX_PROV_EV_CFG_ARFCN:
@@ -319,14 +325,6 @@
 			l1h->config.nomtxpower_sent = false;
 		}
 		break;
-	case TRX_PROV_EV_CFG_TSC:
-		tsc = (uint16_t)(intptr_t)data;
-		if (l1h->config.tsc != tsc || !l1h->config.tsc_valid) {
-			l1h->config.tsc = tsc;
-			l1h->config.tsc_valid = true;
-			l1h->config.tsc_sent = false;
-		}
-		break;
 	case TRX_PROV_EV_CFG_TS:
 		update_ts_data(l1h, (struct trx_prov_ev_cfg_ts_data*)data);
 		break;
@@ -478,11 +476,10 @@
 	}
 
 	for (tn = 0; tn < TRX_NR_TS; tn++) {
-		if (l1h->config.slottype_valid[tn]
-		 && !l1h->config.slottype_sent[tn]) {
-			trx_if_cmd_setslot(l1h, tn,
-				l1h->config.slottype[tn], l1if_setslot_cb);
-			l1h->config.slottype_sent[tn] = true;
+		if (l1h->config.setslot_valid[tn]
+		 && !l1h->config.setslot_sent[tn]) {
+			trx_if_cmd_setslot(l1h, tn, l1if_setslot_cb);
+			l1h->config.setslot_sent[tn] = true;
 		}
 	}
 }
@@ -507,7 +504,7 @@
 			l1h->config.maxdly_sent = false;
 			l1h->config.maxdlynb_sent = false;
 			for (tn = 0; tn < TRX_NR_TS; tn++)
-				l1h->config.slottype_sent[tn] = false;
+				l1h->config.setslot_sent[tn] = false;
 		} else if (!pinst->phy_link->u.osmotrx.poweronoff_sent) {
 			bts_model_trx_close_cb(pinst->trx, 0);
 		} /* else: poweroff in progress, cb will be called upon TRXC RSP */
@@ -519,12 +516,10 @@
 		break;
 	case TRX_PROV_EV_CFG_TS:
 		ts_data = (struct trx_prov_ev_cfg_ts_data*)data;
-		if (update_ts_data(l1h, ts_data)) {
-			trx_if_cmd_setslot(l1h, ts_data->tn,
-				l1h->config.slottype[ ts_data->tn], l1if_setslot_cb);
-			l1h->config.slottype_sent[ts_data->tn] = true;
-		}
-
+		update_ts_data(l1h, ts_data);
+		/* While in this state we can send SETSLOT immediately */
+		trx_if_cmd_setslot(l1h, ts_data->tn, l1if_setslot_cb);
+		l1h->config.setslot_sent[ts_data->tn] = true;
 		break;
 	default:
 		OSMO_ASSERT(0);
@@ -571,7 +566,6 @@
 			X(TRX_PROV_EV_CFG_ENABLE) |
 			X(TRX_PROV_EV_CFG_BSIC) |
 			X(TRX_PROV_EV_CFG_ARFCN) |
-			X(TRX_PROV_EV_CFG_TSC) |
 			X(TRX_PROV_EV_CFG_TS) |
 			X(TRX_PROV_EV_RXTUNE_CNF) |
 			X(TRX_PROV_EV_TXTUNE_CNF) |
@@ -623,7 +617,6 @@
 	OSMO_VALUE_STRING(TRX_PROV_EV_CFG_ENABLE),
 	OSMO_VALUE_STRING(TRX_PROV_EV_CFG_BSIC),
 	OSMO_VALUE_STRING(TRX_PROV_EV_CFG_ARFCN),
-	OSMO_VALUE_STRING(TRX_PROV_EV_CFG_TSC),
 	OSMO_VALUE_STRING(TRX_PROV_EV_CFG_TS),
 	OSMO_VALUE_STRING(TRX_PROV_EV_CFG_RXGAIN),
 	OSMO_VALUE_STRING(TRX_PROV_EV_CFG_SETMAXDLY),
diff --git a/src/osmo-bts-trx/trx_provision_fsm.h b/src/osmo-bts-trx/trx_provision_fsm.h
index 0f80088..8e6b97b 100644
--- a/src/osmo-bts-trx/trx_provision_fsm.h
+++ b/src/osmo-bts-trx/trx_provision_fsm.h
@@ -22,6 +22,8 @@
 
 #pragma once
 
+#include <stdbool.h>
+
 #include <osmocom/core/fsm.h>
 
 enum trx_provision_fsm_states {
@@ -35,6 +37,11 @@
 struct trx_prov_ev_cfg_ts_data {
 	uint8_t tn;
 	uint8_t slottype;
+
+	/* Training Sequence Code and Set */
+	uint8_t tsc_set;
+	uint8_t tsc_val;
+	bool tsc_valid;
 };
 
 enum trx_provision_fsm_events {
diff --git a/src/osmo-bts-trx/trx_vty.c b/src/osmo-bts-trx/trx_vty.c
index 2b0913f..d9d17d0 100644
--- a/src/osmo-bts-trx/trx_vty.c
+++ b/src/osmo-bts-trx/trx_vty.c
@@ -127,16 +127,23 @@
 	else
 		vty_out(vty, " maxdlynb : undefined%s", VTY_NEWLINE);
 	for (tn = 0; tn < TRX_NR_TS; tn++) {
-		if (!((1 << tn) & l1h->config.slotmask))
+		if (!((1 << tn) & l1h->config.slotmask)) {
 			vty_out(vty, " slot #%d: unsupported%s", tn,
 				VTY_NEWLINE);
-		else if (l1h->config.slottype_valid[tn])
-			vty_out(vty, " slot #%d: type %d%s", tn,
-				l1h->config.slottype[tn],
-				VTY_NEWLINE);
-		else
+			continue;
+		} else if (!l1h->config.setslot_valid[tn]) {
 			vty_out(vty, " slot #%d: undefined%s", tn,
 				VTY_NEWLINE);
+			continue;
+		}
+
+		vty_out(vty, " slot #%d: type %d", tn,
+			l1h->config.setslot[tn].slottype);
+		if (l1h->config.setslot[tn].tsc_valid)
+			vty_out(vty, " TSC-s%dc%d",
+				l1h->config.setslot[tn].tsc_set,
+				l1h->config.setslot[tn].tsc_val);
+		vty_out(vty, "%s", VTY_NEWLINE);
 	}
 }
 

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

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: Idc5796151e3e83f42d60c2d4cb7c35890d76a7f5
Gerrit-Change-Number: 24388
Gerrit-PatchSet: 7
Gerrit-Owner: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
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/20210604/745f4fc5/attachment.htm>


More information about the gerrit-log mailing list