From 559d5d0f8637b77291d7196102517f64995269b4 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Fri, 16 Apr 2021 16:50:49 +0200 Subject: [PATCH] bsc: add TC_assignment_codec_fr_by_mode_modify Test the lchan mode modification code path of OsmoBSC, in preparation of adding VAMOS bits to the mode modification procedure. Related: SYS#4895 Change-Id: Idf4efaed986de0bbd2b663313e837352cc139f0f --- bsc/BSC_Tests.ttcn | 92 +++++++++++++++++++++++++--------- bsc/MSC_ConnectionHandler.ttcn | 46 ++++++++++++++++- 2 files changed, 111 insertions(+), 27 deletions(-) diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn index bc243b1fd..b07e69347 100644 --- a/bsc/BSC_Tests.ttcn +++ b/bsc/BSC_Tests.ttcn @@ -3612,36 +3612,39 @@ private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr { f_establish_fully(ass_cmd, exp_compl); - /* Verify that the RSL-side activation actually matches our expectations */ - var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr); + if (not g_pars.expect_channel_mode_modify) { + /* Verify that the RSL-side activation actually matches our expectations */ + var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr); - var RSL_IE_Body mode_ie; - if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) { - setverdict(fail, "Couldn't find CHAN_MODE IE"); - mtc.stop; - } - var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]); - if (not match(mode_ie, t_mode_ie)) { - setverdict(fail, "RSL Channel Mode IE doesn't match expectation"); - } - - var RSL_IE_Body mr_conf; - if (g_pars.expect_mr_conf_ie != omit) { - if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) { - setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ"); + var RSL_IE_Body mode_ie; + if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) { + setverdict(fail, "Couldn't find CHAN_MODE IE"); mtc.stop; } - log("found RSL MR CONFIG IE: ", mr_conf); - - if (not match(mr_conf, g_pars.expect_mr_conf_ie)) { - setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ", - g_pars.expect_mr_conf_ie); + var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]); + if (not match(mode_ie, t_mode_ie)) { + log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie); + setverdict(fail, "RSL Channel Mode IE doesn't match expectation"); } - } else { - if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) { + + var RSL_IE_Body mr_conf; + if (g_pars.expect_mr_conf_ie != omit) { + if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) { + setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ"); + mtc.stop; + } log("found RSL MR CONFIG IE: ", mr_conf); - setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit"); - mtc.stop; + + if (not match(mr_conf, g_pars.expect_mr_conf_ie)) { + setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ", + g_pars.expect_mr_conf_ie); + } + } else { + if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) { + log("found RSL MR CONFIG IE: ", mr_conf); + setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit"); + mtc.stop; + } } } } @@ -3803,6 +3806,30 @@ testcase TC_assignment_codec_amr_h() runs on test_CT { f_shutdown_helper(); } +/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */ +testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT { + var TestHdlrParams pars := f_gen_test_hdlr_pars(); + var MSC_ConnHdlr vc_conn; + + f_init(1, true); + f_sleep(1.0); + + /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should + * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for + * expecting a Channel Mode Modify if the channel type is compatible. */ + f_disable_all_sdcch(); + f_disable_all_tch_h(); + + pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR})); + pars.expect_channel_mode_modify := true; + vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars); + vc_conn.done; + + f_enable_all_sdcch(); + f_enable_all_tch(); + f_shutdown_helper(); +} + /* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */ testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT { var TestHdlrParams pars := f_gen_test_hdlr_pars(); @@ -4062,6 +4089,20 @@ private function f_enable_all_tch() runs on test_CT { f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused"); } +private function f_disable_all_sdcch() runs on test_CT { + f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken"); + f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken"); + f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken"); + f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken"); +} + +private function f_enable_all_sdcch() runs on test_CT { + f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused"); + f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused"); + f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused"); + f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused"); +} + /* Allow HR only */ private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr { g_pars := f_gen_test_hdlr_pars(); @@ -8608,6 +8649,7 @@ control { execute( TC_ciph_mode_a5_3() ); execute( TC_assignment_codec_fr() ); + execute( TC_assignment_codec_fr_by_mode_modify() ); execute( TC_assignment_codec_hr() ); execute( TC_assignment_codec_efr() ); execute( TC_assignment_codec_amr_f() ); diff --git a/bsc/MSC_ConnectionHandler.ttcn b/bsc/MSC_ConnectionHandler.ttcn index aa9f3956e..6b93ca5f1 100644 --- a/bsc/MSC_ConnectionHandler.ttcn +++ b/bsc/MSC_ConnectionHandler.ttcn @@ -589,7 +589,8 @@ type record TestHdlrParams { charstring host_aoip_tla, TestHdlrParamsMSCPool mscpool, boolean media_mgw_offer_ipv6, - OCT3 last_used_eutran_plmn optional + OCT3 last_used_eutran_plmn optional, + boolean expect_channel_mode_modify }; /* Note: Do not use valueof() to get a value of this template, use @@ -625,7 +626,8 @@ template (value) TestHdlrParams t_def_TestHdlrPars := { l3_info := omit }, media_mgw_offer_ipv6 := true, - last_used_eutran_plmn := omit + last_used_eutran_plmn := omit, + expect_channel_mode_modify := false } function f_create_chan_and_exp() runs on MSC_ConnHdlr { @@ -784,7 +786,9 @@ type record AssignmentState { boolean assignment_done, RslChannelNr old_chan_nr, /* Modify related bits */ + PDU_ML3_NW_MS rr_channel_mode_modify_msg optional, boolean rr_modify_seen, + RSL_Message rsl_mode_modify_msg optional, boolean modify_done } @@ -796,7 +800,9 @@ template (value) AssignmentState ts_AssignmentStateInit := { old_lchan_rll_rel_req_seen := false, assignment_done := false, old_chan_nr := -, + rr_channel_mode_modify_msg := omit, rr_modify_seen := false, + rsl_mode_modify_msg := omit, modify_done := false } @@ -908,6 +914,7 @@ altstep as_modify(inout AssignmentState st) runs on MSC_ConnHdlr { var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload); log("Rx L3 from net: ", l3); if (ischosen(l3.msgs.rrm.channelModeModify)) { + st.rr_channel_mode_modify_msg := l3; f_rsl_reply(ts_RRM_ModeModifyAck(l3.msgs.rrm.channelModeModify.channelDescription, l3.msgs.rrm.channelModeModify.channelMode), rsl); st.rr_modify_seen := true; @@ -915,6 +922,7 @@ altstep as_modify(inout AssignmentState st) runs on MSC_ConnHdlr { repeat; } [st.voice_call and st.rr_modify_seen] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_MODE_MODIFY_REQ)) -> value rsl { + st.rsl_mode_modify_msg := rsl; RSL.send(ts_RSL_MODE_MODIFY_ACK(g_chan_nr)); st.modify_done := true; repeat; @@ -1144,6 +1152,7 @@ runs on MSC_ConnHdlr { * channel, we must now check if the mode of the current * channel is compatible. If not we expect the BSC to modify * the mode */ + st.is_assignment := false; exp_modify := f_channel_needs_modify(BSCVTY, ass_cmd.pdu.bssmap.assignmentRequest.channelType, g_chan_nr); } @@ -1218,6 +1227,39 @@ runs on MSC_ConnHdlr { mtc.stop; } + if (exp_modify) { + /* Verify that the RR Channel Mode Modify and RSL MODE MODIFY message asked for the expected channel + * mode. */ + /* TODO: more precisely expect the different types of speech? */ + var OCT1 rr_channel_mode := st.rr_channel_mode_modify_msg.msgs.rrm.channelModeModify.channelMode.mode; + + if (st.voice_call and rr_channel_mode == '00'O) { + setverdict(fail, "f_establish_fully(): Expected RR Channel Mode Modify", + " to a speech mode, but got channelMode == ", rr_channel_mode); + mtc.stop; + } else if (not st.voice_call and rr_channel_mode != '00'O) { + setverdict(fail, "f_establish_fully(): Expected RR Channel Mode Modify", + " to signalling mode, but got channelMode == ", rr_channel_mode); + mtc.stop; + } + + var RSL_IE_Body chan_mode_ie; + if (not f_rsl_find_ie(st.rsl_mode_modify_msg, RSL_IE_CHAN_MODE, chan_mode_ie)) { + setverdict(fail, "RSL MODE MODIFY message lacks a Channel Mode IE"); + mtc.stop; + } + var RSL_SpeechDataInd rsl_spd_ind := chan_mode_ie.chan_mode.spd_ind; + if (st.voice_call and rsl_spd_ind != RSL_SPDI_SPEECH) { + setverdict(fail, "f_establish_fully(): Expected RSL MODE MODIFY", + " to a speech mode, but got spd_ind == ", rsl_spd_ind); + mtc.stop; + } else if (not st.voice_call and rsl_spd_ind != RSL_SPDI_SIGN) { + setverdict(fail, "f_establish_fully(): Expected RSL MODE MODIFY", + " to signalling mode, but got spd_ind == ", rsl_spd_ind); + mtc.stop; + } + } + /* When the BSC detects that LCLS is possible it will cross the * connetions that point to the PBX side of the MGW. In our case this * is mgcp_conn[1]. The BSC performs this operation already before the