Change in osmo-bsc[master]: implement Channel Mode Modify to VAMOS mode

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

neels gerrit-no-reply at lists.osmocom.org
Sun May 23 23:02:36 UTC 2021


neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/24374 )


Change subject: implement Channel Mode Modify to VAMOS mode
......................................................................

implement Channel Mode Modify to VAMOS mode

Related: SYS#5315 OS#4940
Change-Id: Ibf53f4797d7491b17a33946fd7d920f038362b4c
---
M include/osmocom/bsc/gsm_data.h
M src/osmo-bsc/abis_rsl.c
M src/osmo-bsc/bsc_vty.c
M src/osmo-bsc/gsm_04_08_rr.c
M src/osmo-bsc/lchan_fsm.c
5 files changed, 149 insertions(+), 42 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/74/24374/1

diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index e250a5d..5e2196c 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -626,6 +626,8 @@
 	/* TSC to use, or -1 for automatically determining the TSC to use. Valid range is 0 to 7, as described in 3GPP
 	 * TS 45.002. */
 	int tsc;
+
+	bool vamos;
 };
 
 struct gsm_lchan {
@@ -739,6 +741,9 @@
 		/* Whether this lchan represents a secondary "shadow" lchan to multiplex a second MS onto a primary
 		 * "normal" lchan */
 		bool is_secondary;
+
+		/* Whether this lchan is activated/modified into a mode that allows VAMOS multiplexing at this moment */
+		bool enabled;
 	} vamos;
 
 	/* Circuit-Switched TSC Set in use, or -1 if no specific TSC Set was requested. The valid range is 1-4 as
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 4a80364..1b08e03 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -352,7 +352,8 @@
 
 static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
 				   struct gsm_lchan *lchan,
-				   const struct channel_mode_and_rate *ch_mode_rate)
+				   const struct channel_mode_and_rate *ch_mode_rate,
+				   bool vamos)
 {
 	int spd_ind;
 	memset(cm, 0, sizeof(*cm));
@@ -377,10 +378,10 @@
 		cm->chan_rt = RSL_CMOD_CRT_SDCCH;
 		break;
 	case GSM_LCHAN_TCH_F:
-		cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
+		cm->chan_rt = vamos ? RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm : RSL_CMOD_CRT_TCH_Bm;
 		break;
 	case GSM_LCHAN_TCH_H:
-		cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
+		cm->chan_rt = vamos ? RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm : RSL_CMOD_CRT_TCH_Lm;
 		break;
 	case GSM_LCHAN_NONE:
 	case GSM_LCHAN_UNKNOWN:
@@ -396,12 +397,15 @@
 		cm->chan_rate = 0;
 		break;
 	case GSM48_CMODE_SPEECH_V1:
+	case GSM48_CMODE_SPEECH_V1_VAMOS:
 		cm->chan_rate = RSL_CMOD_SP_GSM1;
 		break;
 	case GSM48_CMODE_SPEECH_EFR:
+	case GSM48_CMODE_SPEECH_V2_VAMOS:
 		cm->chan_rate = RSL_CMOD_SP_GSM2;
 		break;
 	case GSM48_CMODE_SPEECH_AMR:
+	case GSM48_CMODE_SPEECH_V3_VAMOS:
 		cm->chan_rate = RSL_CMOD_SP_GSM3;
 		break;
 	case GSM48_CMODE_DATA_14k5:
@@ -501,6 +505,11 @@
 	}
 }
 
+struct rsl_osmo_training_sequence_ie {
+	uint8_t tsc_set;
+	uint8_t tsc;
+} __attribute__ ((packed));
+
 /* Chapter 8.4.1 */
 int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref)
 {
@@ -521,7 +530,7 @@
 	/* PDCH activation is a job for rsl_tx_dyn_ts_pdch_act_deact(); */
 	OSMO_ASSERT(act_type != RSL_ACT_OSMO_PDCH);
 
-	rc = channel_mode_from_lchan(&cm, lchan, &lchan->activate.info.ch_mode_rate);
+	rc = channel_mode_from_lchan(&cm, lchan, &lchan->activate.info.ch_mode_rate, false);
 	if (rc < 0) {
 		LOGP(DRSL, LOGL_ERROR,
 		     "%s Cannot find channel mode from lchan type\n",
@@ -636,7 +645,7 @@
 	struct rsl_ie_chan_mode cm;
 	struct gsm_bts *bts = lchan->ts->trx->bts;
 
-	rc = channel_mode_from_lchan(&cm, lchan, &lchan->modify.info.ch_mode_rate);
+	rc = channel_mode_from_lchan(&cm, lchan, &lchan->modify.info.ch_mode_rate, lchan->modify.info.vamos);
 	if (rc < 0)
 		return rc;
 
@@ -667,6 +676,16 @@
 
         rep_acch_cap_for_bts(lchan, msg);
 
+	/* Selecting a specific TSC Set is only applicable to VAMOS mode */
+	if (lchan->modify.info.vamos && lchan->modify.tsc_set >= 1) {
+		struct rsl_osmo_training_sequence_ie tsie = {
+			/* Convert from spec conforming "human readable" TSC Set 1-4 to 0-3 on the wire */
+			.tsc_set = lchan->modify.tsc_set - 1,
+			.tsc = lchan->modify.tsc,
+		};
+		msgb_tlv_put(msg, RSL_IE_OSMO_TRAINING_SEQUENCE, sizeof(tsie), (uint8_t*)&tsie);
+	}
+
 	msg->dst = rsl_chan_link(lchan);
 
 	return abis_rsl_sendmsg(msg);
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index caa72e4..8e64cd5 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -192,6 +192,34 @@
 	return CMD_SUCCESS;
 }
 
+/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
+static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
+					 const char *ts_str)
+{
+	int bts_nr = atoi(bts_str);
+	int trx_nr = atoi(trx_str);
+	int ts_nr = atoi(ts_str);
+	struct gsm_bts *bts;
+	struct gsm_bts_trx *trx;
+	struct gsm_bts_trx_ts *ts;
+
+	bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
+	if (!bts) {
+		vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
+		return NULL;
+	}
+
+	trx = gsm_bts_trx_num(bts, trx_nr);
+	if (!trx) {
+		vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
+		return NULL;
+	}
+
+	ts = &trx->ts[ts_nr];
+
+	return ts;
+}
+
 static void net_dump_nmstate(struct vty *vty, struct gsm_nm_state *nms)
 {
 	vty_out(vty,"Oper '%s', Admin '%s', Avail '%s'%s",
@@ -1958,9 +1986,27 @@
 	return CMD_WARNING;
 }
 
+static int trigger_vamos_mode_modify(struct vty *vty, struct gsm_lchan *lchan, int tsc_set, int tsc)
+{
+	struct lchan_modify_info info = {
+		.modify_for = MODIFY_FOR_VTY,
+		.ch_mode_rate = lchan->current_ch_mode_rate,
+		.requires_voice_stream = (lchan->fi_rtp != NULL),
+		.vamos = true,
+		.tsc_set = tsc_set,
+		.tsc = tsc,
+	};
+
+	lchan_mode_modify(lchan, &info);
+	return CMD_SUCCESS;
+}
+
 #define MANUAL_HANDOVER_STR "Manually trigger handover (for debugging)\n"
 #define MANUAL_ASSIGNMENT_STR "Manually trigger assignment (for debugging)\n"
 
+#define MANUAL_VAMOS_STR "Manually initiate VAMOS lchan multiplexing (for debugging)\n"
+#define MANUAL_VAMOS_MODIFY_STR "Send Channel Mode Modify to change an lchan to prepare it for serving a second MS via VAMOS\n"
+
 DEFUN(handover_subscr_conn,
       handover_subscr_conn_cmd,
       "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> handover <0-255>",
@@ -2120,6 +2166,46 @@
 	return CMD_SUCCESS;
 }
 
+#define TSC_ARGS_OPT "[tsc] [<1-4>] [<0-7>]"
+#define TSC_ARGS_DOC \
+      "Provide specific TSC Set and Training Sequence Code\n" \
+      "TSC Set\n" \
+      "Training Sequence Code\n"
+
+DEFUN(vamos_modify_lchan, vamos_modify_lchan_cmd,
+      "vamos modify lchan <0-255> <0-255> <0-7> <0-1> " TSC_ARGS_OPT,
+      /* Note above, only subslots 0-1 because only TCH/F and TCH/H make sense to be modified to VAMOS mode. */
+      MANUAL_VAMOS_STR
+      MANUAL_VAMOS_MODIFY_STR
+      "Pick a specific lchan to modify to VAMOS mode\n"
+      BTS_TRX_TS_LCHAN_STR
+      TSC_ARGS_DOC)
+{
+	struct gsm_bts_trx_ts *ts;
+	struct gsm_lchan *lchan;
+	int ss_nr = atoi(argv[3]);
+	int tsc_set = (argc > 5) ? atoi(argv[5]) : -1;
+	int tsc = (argc > 6) ? atoi(argv[6]) : -1;
+
+	ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
+	if (!ts)
+		return CMD_WARNING;
+
+	if (ss_nr >= ts->max_primary_lchans) {
+		vty_out(vty, "Invalid sub-slot number for this timeslot type%s", VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	if (!osmo_bts_has_feature(&ts->trx->bts->features, BTS_FEAT_VAMOS)) {
+		vty_out(vty, "BTS does not support VAMOS%s", VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	lchan = &ts->lchan[ss_nr];
+
+	return trigger_vamos_mode_modify(vty, lchan, tsc_set, tsc);
+}
+
 static void paging_dump_vty(struct vty *vty, struct gsm_paging_request *pag)
 {
 	vty_out(vty, "Paging on BTS %u%s", pag->bts->nr, VTY_NEWLINE);
@@ -5967,34 +6053,6 @@
 	return CMD_SUCCESS;
 }
 
-/* resolve a gsm_bts_trx_ts basd on the given numeric identifiers */
-static struct gsm_bts_trx_ts *vty_get_ts(struct vty *vty, const char *bts_str, const char *trx_str,
-					 const char *ts_str)
-{
-	int bts_nr = atoi(bts_str);
-	int trx_nr = atoi(trx_str);
-	int ts_nr = atoi(ts_str);
-	struct gsm_bts *bts;
-	struct gsm_bts_trx *trx;
-	struct gsm_bts_trx_ts *ts;
-
-	bts = gsm_bts_num(gsmnet_from_vty(vty), bts_nr);
-	if (!bts) {
-		vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
-		return NULL;
-	}
-
-	trx = gsm_bts_trx_num(bts, trx_nr);
-	if (!trx) {
-		vty_out(vty, "%% No such TRX (%d)%s", trx_nr, VTY_NEWLINE);
-		return NULL;
-	}
-
-	ts = &trx->ts[ts_nr];
-
-	return ts;
-}
-
 DEFUN(pdch_act, pdch_act_cmd,
 	"bts <0-255> trx <0-255> timeslot <0-7> pdch (activate|deactivate)",
 	BTS_NR_TRX_TS_STR2
@@ -7727,6 +7785,8 @@
 	install_element(ENABLE_NODE, &handover_any_to_arfcn_bsic_cmd);
 	/* See also handover commands added on net level from handover_vty.c */
 
+	install_element(ENABLE_NODE, &vamos_modify_lchan_cmd);
+
 	logging_vty_add_cmds();
 	osmo_talloc_vty_add_cmds();
 
diff --git a/src/osmo-bsc/gsm_04_08_rr.c b/src/osmo-bsc/gsm_04_08_rr.c
index 8febd54..bb654b4 100644
--- a/src/osmo-bsc/gsm_04_08_rr.c
+++ b/src/osmo-bsc/gsm_04_08_rr.c
@@ -694,6 +694,8 @@
 	tsc = (lchan->modify.info.tsc >= 0) ? lchan->modify.info.tsc : gsm_ts_tsc(lchan->ts); /* FIXME */
 	gsm48_lchan2chan_desc(&cmm->chan_desc, lchan, tsc);
 	cmm->mode = mode;
+	if (lchan->modify.info.vamos)
+		cmm->mode = gsm48_chan_mode_to_vamos(cmm->mode);
 
 	/* in case of multi rate we need to attach a config */
 	if (lchan->modify.info.ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR) {
@@ -706,6 +708,12 @@
 		}
 	}
 
+	if (lchan->modify.info.vamos && lchan->modify.tsc_set > 0) {
+		/* Add the Extended TSC Set IE. So far we only need a TSC Set sent for VAMOS.
+		 * Convert from spec conforming "human readable" TSC Set 1-4 to 0-3 on the wire */
+		msgb_tv_put(msg, 0x6d, (lchan->modify.tsc_set - 1) & 0x3);
+	}
+
 	return gsm48_sendmsg(msg);
 }
 
@@ -714,14 +722,20 @@
 	struct gsm48_hdr *gh = msgb_l3(msg);
 	struct gsm48_chan_mode_modify *mod =
 				(struct gsm48_chan_mode_modify *) gh->data;
+	enum gsm48_chan_mode expect_chan_mode;
 
 	LOG_LCHAN(msg->lchan, LOGL_DEBUG, "CHANNEL MODE MODIFY ACK for %s\n",
 		  gsm48_chan_mode_name(mod->mode));
 
-	if (mod->mode != msg->lchan->modify.info.ch_mode_rate.chan_mode) {
+	/* The modify.info may indicate a non-VAMOS chan_mode, and indicate VAMOS-ness by info.vamos == true. Internally
+	 * we convert the chan_mode to a VAMOS chan_mode then, leaving the info unchanged. Also do this change here. */
+	expect_chan_mode = msg->lchan->modify.info.ch_mode_rate.chan_mode;
+	if (msg->lchan->modify.info.vamos)
+		expect_chan_mode = gsm48_chan_mode_to_vamos(expect_chan_mode);
+	if (mod->mode != expect_chan_mode) {
 		LOG_LCHAN(msg->lchan, LOGL_ERROR,
 			  "CHANNEL MODE MODIFY ACK has wrong mode: Wanted: %s Got: %s\n",
-			  gsm48_chan_mode_name(msg->lchan->modify.info.ch_mode_rate.chan_mode),
+			  gsm48_chan_mode_name(expect_chan_mode),
 			  gsm48_chan_mode_name(mod->mode));
 		return -1;
 	}
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index e25a6de..7344ddf 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -382,6 +382,17 @@
 {
 	OSMO_ASSERT(lchan && info);
 
+	if ((info->vamos || lchan->vamos.is_secondary)
+	    && !osmo_bts_has_feature(&lchan->ts->trx->bts->features, BTS_FEAT_VAMOS)) {
+		lchan->last_error = talloc_strdup(lchan->ts->trx, "VAMOS related Channel Mode Modify requested,"
+						  " but BTS does not support VAMOS");
+		LOG_LCHAN(lchan, LOGL_ERROR,
+			  "VAMOS related Channel Mode Modify requested, but BTS %u does not support VAMOS\n",
+			  lchan->ts->trx->bts->nr);
+		lchan_on_mode_modify_failure(lchan, info->modify_for, lchan->conn);
+		return;
+	}
+
 	/* To make sure that the lchan is actually allowed to initiate Mode Modify, feed through an FSM event. */
 	if (osmo_fsm_inst_dispatch(lchan->fi, LCHAN_EV_REQUEST_MODE_MODIFY, info)) {
 		LOG_LCHAN(lchan, LOGL_ERROR,
@@ -973,6 +984,7 @@
 		lchan->current_mr_conf = lchan->modify.mr_conf_filtered;
 		lchan->tsc_set = lchan->modify.tsc_set;
 		lchan->tsc = lchan->modify.tsc;
+		lchan->vamos.enabled = lchan->modify.info.vamos;
 
 		if (lchan->modify.info.requires_voice_stream
 		    && !lchan->fi_rtp) {
@@ -1113,18 +1125,13 @@
 		/* FIXME: Add missing implementation to handle an already existing RTP voice stream on MODE MODIFY.
 		 * there may be transitions from VOICE to SIGNALLING and also from VOICE to VOICE with a different
 		 * codec. */
-		if (lchan->fi_rtp) {
-			lchan_fail("MODE MODIFY not implemented when RTP voice stream is already active (VOICE => SIGNALLING, VOICE/CODEC_A => VOICE/CODEC_B)\n");
-			return;
-		}
-
 		modif_info = data;
 		lchan->modify.info = *modif_info;
 		lchan->modify.concluded = false;
 
 		use_mgwep_ci = lchan_use_mgw_endpoint_ci_bts(lchan);
 
-		if (modif_info->ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR) {
+		if (gsm48_chan_mode_to_non_vamos(modif_info->ch_mode_rate.chan_mode) == GSM48_CMODE_SPEECH_AMR) {
 			if (lchan_mr_config(&lchan->modify.mr_conf_filtered, lchan, modif_info->ch_mode_rate.s15_s0)
 			    < 0) {
 				lchan_fail("Can not generate multirate configuration IE\n");
@@ -1132,10 +1139,12 @@
 			}
 		}
 
+		/* If enabling VAMOS mode and no specific TSC Set was selected, make sure to select a sane TSC Set by
+		 * default: Set 1 for the primary and Set 2 for the shadow lchan. For non-VAMOS lchans, TSC Set 1. */
 		if (lchan->modify.info.tsc_set > 0)
 			lchan->modify.tsc_set = lchan->modify.info.tsc_set;
 		else
-			lchan->modify.tsc_set = 1;
+			lchan->modify.tsc_set = lchan->vamos.is_secondary ? 2 : 1;
 
 		/* Use the TSC provided in the modification request, if any. Otherwise use the timeslot's configured
 		 * TSC. */

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

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: Ibf53f4797d7491b17a33946fd7d920f038362b4c
Gerrit-Change-Number: 24374
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210523/379b515c/attachment.htm>


More information about the gerrit-log mailing list