Change in osmo-bsc[master]: add VAMOS secondary lchans to timeslot struct

neels gerrit-no-reply at lists.osmocom.org
Thu Jun 10 15:21:24 UTC 2021


neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bsc/+/24377 )

Change subject: add VAMOS secondary lchans to timeslot struct
......................................................................

add VAMOS secondary lchans to timeslot struct

So far there is a bunch of code setting a primary lchan in VAMOS mode.
This patch now adds the actual secondary "shadow" lchans that may be
combined with a primary lchan in VAMOS mode to form a multiplex.

VAMOS lchans are put in the same ts->lchan[] array that keeps the
primary lchans. They are at most two additional usable lchans (for a
TCH/H shadow) added to either TCH/F or TCH/H.

Keeping these in the same array allows looping over all lchans easily.
The ts->max_primary_lchans indicates the index of the first VAMOS shadow
lchan.

Related: SYS#5315 OS#4940
Change-Id: I928af99498bba488d317693f3144d4fccbbe9af3
---
M include/osmocom/bsc/gsm_data.h
M src/osmo-bsc/abis_rsl.c
M src/osmo-bsc/assignment_fsm.c
M src/osmo-bsc/gsm_data.c
M src/osmo-bsc/timeslot_fsm.c
5 files changed, 105 insertions(+), 12 deletions(-)

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



diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index fc6ce30..88adb9f 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -1041,8 +1041,11 @@
 
 enum gsm_phys_chan_config ts_pchan(struct gsm_bts_trx_ts *ts);
 uint8_t pchan_subslots(enum gsm_phys_chan_config pchan);
+uint8_t pchan_subslots_vamos(enum gsm_phys_chan_config pchan);
 bool ts_is_tch(struct gsm_bts_trx_ts *ts);
 
+struct gsm_lchan *gsm_lchan_vamos_to_primary(const struct gsm_lchan *lchan_vamos);
+struct gsm_lchan *gsm_lchan_primary_to_vamos(const struct gsm_lchan *lchan_primary);
 
 struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn);
 
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index c206937..1f7b639 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -1708,10 +1708,11 @@
 	 * This will take a short amount of time. We need to come back and check regulary to see if we managed to
 	 * free up another lchan. */
 	if (!rqd->release_lchan) {
+		struct gsm_lchan *release_lchan;
 		/* Pick any busy TCH/F or TCH/H lchan and inititate a channel
 		 * release to make room for the incoming emergency call */
-		rqd->release_lchan = get_any_lchan(rqd->bts);
-		if (!rqd->release_lchan) {
+		rqd->release_lchan = release_lchan = get_any_lchan(rqd->bts);
+		if (!release_lchan) {
 			/* It can not happen that we first find out that there
 			 * is no TCH/H or TCH/F available and at the same time
 			 * we ware unable to find any busy TCH/H or TCH/F. In
@@ -1724,10 +1725,16 @@
 
 		LOG_BTS(rqd->bts, DRSL, LOGL_NOTICE,
 			"CHAN RQD/EMERGENCY-PRIORITY: inducing termination of lchan %s (state:%s) in favor of incoming EMERGENCY CALL!\n",
-			gsm_lchan_name(rqd->release_lchan), osmo_fsm_inst_state_name(rqd->release_lchan->fi));
+			gsm_lchan_name(release_lchan), osmo_fsm_inst_state_name(release_lchan->fi));
 
-		lchan_release(rqd->release_lchan, !!(rqd->release_lchan->conn), true, 0,
-			      gscon_last_eutran_plmn(rqd->release_lchan->conn));
+		lchan_release(release_lchan, !!(release_lchan->conn), true, 0,
+			      gscon_last_eutran_plmn(release_lchan->conn));
+
+		/* Also release any overlapping VAMOS multiplexes on this lchan */
+		release_lchan = gsm_lchan_primary_to_vamos(release_lchan);
+		if (release_lchan)
+			lchan_release(release_lchan, !!(release_lchan->conn), true, 0,
+				      gscon_last_eutran_plmn(release_lchan->conn));
 	} else {
 		/* BTS is shutting down, give up... */
 		if (rqd->release_lchan->ts->fi->state == TS_ST_NOT_INITIALIZED)
diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c
index 65cd8a8..b6de293 100644
--- a/src/osmo-bsc/assignment_fsm.c
+++ b/src/osmo-bsc/assignment_fsm.c
@@ -640,6 +640,7 @@
 		.ta_known = true,
 		.tsc_set = req->tsc_set,
 		.tsc = req->tsc,
+		.vamos = conn->assignment.new_lchan->vamos.is_secondary,
 	};
 	lchan_activate(conn->assignment.new_lchan, &activ_info);
 }
diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c
index b33b1c3..4d2d811 100644
--- a/src/osmo-bsc/gsm_data.c
+++ b/src/osmo-bsc/gsm_data.c
@@ -337,8 +337,9 @@
 char *gsm_lchan_name_compute(void *ctx, const struct gsm_lchan *lchan)
 {
 	struct gsm_bts_trx_ts *ts = lchan->ts;
-	return talloc_asprintf(ctx, "(bts=%d,trx=%d,ts=%d,ss=%d)",
-			       ts->trx->bts->nr, ts->trx->nr, ts->nr, lchan->nr);
+	return talloc_asprintf(ctx, "(bts=%d,trx=%d,ts=%d,ss=%d%s)",
+			       ts->trx->bts->nr, ts->trx->nr, ts->nr, lchan->nr,
+			       lchan->vamos.is_secondary ? "-VAMOS" : "");
 }
 
 /* obtain the MO structure for a given object instance */
@@ -545,9 +546,13 @@
 
 uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan)
 {
-	/* Note: non-standard Osmocom style dyn TS PDCH mode chan_nr is only used within
-	 * rsl_tx_dyn_ts_pdch_act_deact(). */
-	return gsm_pchan2chan_nr(lchan->ts->pchan_is, lchan->ts->nr, lchan->nr);
+	uint8_t lchan_nr = lchan->nr;
+	/* The VAMOS lchans are behind the primary ones in the ts->lchan[] array. They keep their lchan->nr as in the
+	 * array, but on the wire they are the "shadow" lchans for the primary lchans. For example, for TCH/F, there is
+	 * a primary ts->lchan[0] and a VAMOS ts->lchan[1]. Still, the VAMOS lchan should send chan_nr = 0. */
+	if (lchan->vamos.is_secondary)
+		lchan_nr -= lchan->ts->max_primary_lchans;
+	return gsm_pchan2chan_nr(lchan->ts->pchan_is, lchan->ts->nr, lchan_nr);
 }
 
 static const uint8_t subslots_per_pchan[] = {
@@ -574,6 +579,30 @@
 	return subslots_per_pchan[pchan];
 }
 
+static const uint8_t subslots_per_pchan_vamos[] = {
+	[GSM_PCHAN_NONE] = 0,
+	[GSM_PCHAN_CCCH] = 0,
+	[GSM_PCHAN_PDCH] = 0,
+	[GSM_PCHAN_CCCH_SDCCH4] = 0,
+	/* VAMOS: on a TCH/F, there may be a TCH/H shadow */
+	[GSM_PCHAN_TCH_F] = 2,
+	[GSM_PCHAN_TCH_H] = 2,
+	[GSM_PCHAN_SDCCH8_SACCH8C] = 0,
+	[GSM_PCHAN_CCCH_SDCCH4_CBCH] = 0,
+	[GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = 0,
+	[GSM_PCHAN_TCH_F_TCH_H_PDCH] = 2,
+	[GSM_PCHAN_TCH_F_PDCH] = 2,
+};
+
+/* Return the maximum number of VAMOS secondary lchans that may be used in a timeslot of the given physical channel
+ * configuration. */
+uint8_t pchan_subslots_vamos(enum gsm_phys_chan_config pchan)
+{
+	if (pchan < 0 || pchan >= ARRAY_SIZE(subslots_per_pchan_vamos))
+		return 0;
+	return subslots_per_pchan_vamos[pchan];
+}
+
 static bool pchan_is_tch(enum gsm_phys_chan_config pchan)
 {
 	switch (pchan) {
@@ -590,6 +619,36 @@
 	return pchan_is_tch(ts->pchan_is);
 }
 
+/* For a VAMOS secondary shadow lchan, return its primary lchan. If the lchan is not a secondary lchan, return NULL. */
+struct gsm_lchan *gsm_lchan_vamos_to_primary(const struct gsm_lchan *lchan_vamos)
+{
+	struct gsm_lchan *lchan_primary;
+	if (!lchan_vamos || !lchan_vamos->vamos.is_secondary)
+		return NULL;
+	/* OsmoBSC currently does not support mixed TCH/F + TCH/H VAMOS multiplexes. Hence the primary <-> secondary
+	 * relation is a simple index shift in the lchan array. If mixed multiplexes were allowed, a TCH/F primary might
+	 * have two TCH/H VAMOS secondary lchans, etc. Fortunately, we don't need to care about that. */
+	lchan_primary = (struct gsm_lchan*)lchan_vamos - lchan_vamos->ts->max_primary_lchans;
+	if (!lchan_primary->fi)
+		return NULL;
+	return lchan_primary;
+}
+
+/* For a primary lchan, return its VAMOS secondary shadow lchan. If the lchan is not a primary lchan, return NULL. */
+struct gsm_lchan *gsm_lchan_primary_to_vamos(const struct gsm_lchan *lchan_primary)
+{
+	struct gsm_lchan *lchan_vamos;
+	if (!lchan_primary || lchan_primary->vamos.is_secondary)
+		return NULL;
+	/* OsmoBSC currently does not support mixed TCH/F + TCH/H VAMOS multiplexes. Hence the primary <-> secondary
+	 * relation is a simple index shift in the lchan array. If mixed multiplexes were allowed, a TCH/F primary might
+	 * have two TCH/H VAMOS secondary lchans, etc. Fortunately, we don't need to care about that. */
+	lchan_vamos = (struct gsm_lchan*)lchan_primary + lchan_primary->ts->max_primary_lchans;
+	if (!lchan_vamos->fi)
+		return NULL;
+	return lchan_vamos;
+}
+
 struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn) {
 	if (!conn || !conn->lchan)
 		return NULL;
diff --git a/src/osmo-bsc/timeslot_fsm.c b/src/osmo-bsc/timeslot_fsm.c
index 0470972..64b98a6 100644
--- a/src/osmo-bsc/timeslot_fsm.c
+++ b/src/osmo-bsc/timeslot_fsm.c
@@ -189,22 +189,45 @@
 
 void ts_set_pchan_is(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pchan_is)
 {
+	int i;
+	struct gsm_lchan *lchan;
 	ts->pchan_is = pchan_is;
 	ts->max_primary_lchans = pchan_subslots(ts->pchan_is);
 	LOG_TS(ts, LOGL_DEBUG, "pchan_is=%s max_primary_lchans=%d max_lchans_possible=%d\n",
 	       gsm_pchan_name(ts->pchan_is), ts->max_primary_lchans, ts->max_lchans_possible);
+	switch (ts->pchan_is) {
+	case GSM_PCHAN_TCH_F:
+	case GSM_PCHAN_TCH_H:
+		for (i = 0; i < ts->max_lchans_possible; i++) {
+			lchan = &ts->lchan[i];
+			if (i < ts->max_primary_lchans)
+				lchan->vamos.is_secondary = false;
+			else
+				lchan->vamos.is_secondary = true;
+		}
+		break;
+	default:
+		ts_for_n_lchans(lchan, ts, ts->max_lchans_possible)
+			lchan->vamos.is_secondary = false;
+		break;
+	}
 }
 
 static void ts_setup_lchans(struct gsm_bts_trx_ts *ts)
 {
 	int i, max_lchans;
+	int max_lchans_vamos;
 
 	ts->pchan_on_init = ts->pchan_from_config;
 	ts_fsm_update_id(ts);
 
 	max_lchans = pchan_subslots(ts->pchan_on_init);
-	LOG_TS(ts, LOGL_DEBUG, "max lchans: %d\n", max_lchans);
-	ts->max_lchans_possible = max_lchans;
+	if (osmo_bts_has_feature(&ts->trx->bts->features, BTS_FEAT_VAMOS))
+		max_lchans_vamos = pchan_subslots_vamos(ts->pchan_on_init);
+	else
+		max_lchans_vamos = 0;
+	LOG_TS(ts, LOGL_DEBUG, "max lchans: %d + %d VAMOS secondaries\n", max_lchans, max_lchans_vamos);
+	ts->max_lchans_possible = max_lchans + max_lchans_vamos;
 	ts->max_primary_lchans = 0;
 
 	for (i = 0; i < ts->max_lchans_possible; i++) {

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

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I928af99498bba488d317693f3144d4fccbbe9af3
Gerrit-Change-Number: 24377
Gerrit-PatchSet: 22
Gerrit-Owner: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr at sysmocom.de>
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/20210610/74f447be/attachment.htm>


More information about the gerrit-log mailing list