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>