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