| module MSC_Tests_ASCI { |
| |
| /* Osmocom MSC test suite for ASCI support in TTCN-3 |
| * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> |
| * All Rights Reserved |
| * |
| * Author: Andreas Eversberg |
| * |
| * Released under the terms of GNU General Public License, Version 2 or |
| * (at your option) any later version. |
| * |
| * SPDX-License-Identifier: GPL-2.0-or-later |
| */ |
| |
| import from General_Types all; |
| import from Osmocom_Types all; |
| |
| import from BSC_ConnectionHandler all; |
| import from MSC_Tests all; |
| |
| import from Osmocom_VTY_Functions all; |
| |
| import from GSUP_Emulation all; |
| import from RAN_Emulation all; |
| import from MGCP_Emulation all; |
| |
| import from RANAP_Templates all; |
| |
| import from BSSAP_Types all; |
| import from BSSMAP_Templates all; |
| |
| import from L3_Templates all; |
| |
| import from MobileL3_CommonIE_Types all; |
| |
| |
| /* Call control for VGCS and VBS |
| * |
| * There are 3 connection: |
| * - "call" = voice group/broadcast call initiated by the calling subscriber |
| * - "control" = VGCS/VBS call control connection |
| * - "channel" = VGCS/VBS channel resource connection |
| * |
| * All 3 connections have their own handlers. They send their test results via |
| * COORD messages to the main test function. There the result is collected and |
| * the outcome of the test is checked. |
| */ |
| |
| /* Test functions */ |
| const charstring COORD_TEST_NO_CALLREF := "TEST_NO_CALLREF"; |
| const charstring COORD_TEST_SETUP_REFUSE := "TEST_SETUP_REFUSE"; |
| const charstring COORD_TEST_ASSIGN_FAIL := "TEST_ASSIGN_FAIL"; |
| const charstring COORD_TEST_COMPLETE_VGCS := "TEST_COMPLETE_VGCS"; |
| const charstring COORD_TEST_COMPLETE_VBS := "TEST_COMPLETE_VBS"; |
| |
| /* COORD pipes for each connection */ |
| type component asci_CT extends MTC_CT { |
| port BSC_ConnHdlr_Coord_PT COORD_call; |
| port BSC_ConnHdlr_Coord_PT COORD_control; |
| port BSC_ConnHdlr_Coord_PT COORD_channel; |
| } |
| |
| /* COORD messages for test events */ |
| const charstring COORD_SETUP := "SETUP"; |
| const charstring COORD_VGCS_SETUP := "VGCS_SETUP"; |
| const charstring COORD_VGCS_ASSIGN := "VGCS_ASSIGN"; |
| const charstring COORD_UPLINK_SEIZED := "UPLINK_SEIZED"; |
| const charstring COORD_GCC_CONNECT := "GCC_CONNECT"; |
| const charstring COORD_BCC_CONNECT := "BCC_CONNECT"; |
| const charstring COORD_GCC_SET_PARAM := "GCC_SET_PARAM"; |
| const charstring COORD_BCC_SET_PARAM := "BCC_SET_PARAM"; |
| const charstring COORD_UPLINK_REQ_ACK := "UPLINK_REQ_ACK"; |
| const charstring COORD_GCC_TERMINATION := "GCC_TERMINATION"; |
| const charstring COORD_BCC_TERMINATION := "BCC_TERMINATION"; |
| const charstring COORD_GCC_TERMINATION_FAIL := "GCC_TERMINATION_FAIL"; |
| const charstring COORD_BCC_TERMINATION_FAIL := "BCC_TERMINATION_FAIL"; |
| const charstring COORD_ASSIGNMENT := "ASSIGNMENT"; |
| const charstring COORD_CLEAR := "CLEAR"; |
| |
| template (value) DescriptiveGroupOrBroadcastCallReference_V |
| ts_BSSMAP_IE_GroupCallRef(integer cr, |
| BIT1 sf, |
| BIT1 af, |
| BIT3 prio, |
| BIT4 ci) := { |
| binaryCodingOfGroupOrBroadcastCallReference := int2bit(cr, 27), |
| sF := sf, |
| aF := af, |
| callPriority := prio, |
| cipheringInformation := ci, |
| spare := '0000'B |
| } |
| |
| function f_gen_asci_ass_res(integer bssap_idx := 0, |
| template (value) BSSMAP_IE_ChannelType ch_type := ts_BSSMAP_IE_ChannelType, |
| template (value) BSSMAP_IE_CellIdentifier cell_id := ts_CellId_CI(0), |
| template (omit) BSSMAP_IE_AoIP_TransportLayerAddress aoip_tla := omit, |
| template (omit) BSSMAP_IE_SpeechCodec codec := omit, |
| template (omit) OCT4 call_id := omit) |
| runs on BSC_ConnHdlr return template (value) PDU_BSSAP { |
| if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) { |
| return ts_BSSMAP_VGCS_VBS_AssignmentRes(ch_type, cell_id, omit, omit, aoip_tla, codec, call_id); |
| } else { |
| var template (value) BSSMAP_IE_CircuitIdentityCode cic := ts_BSSMAP_IE_CIC(0,1); |
| return ts_BSSMAP_VGCS_VBS_AssignmentRes(ch_type, cell_id, omit, cic, omit, omit, omit); |
| } |
| } |
| |
| /* "call" connection handling */ |
| private function f_tc_vgcs_call(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr |
| { |
| /* Receive test case from main function. */ |
| var charstring test; |
| COORD.receive(charstring:?) -> value test; |
| |
| /* Initialize variables and templates. */ |
| var CallParameters cpars := valueof(t_CallParams('12345'H, 0)); |
| var template (value) DescriptiveGroupOrBroadcastCallReference_V callref := |
| ts_BSSMAP_IE_GroupCallRef(oct2int('190000'O), '1'B, '0'B, '000'B, '0000'B); |
| if (test == COORD_TEST_COMPLETE_VBS) { |
| callref := ts_BSSMAP_IE_GroupCallRef(oct2int('1a0000'O), '0'B, '0'B, '000'B, '0000'B); |
| } |
| var template BSSMAP_IE_ChannelType tr_ch_type := tr_BSSMAP_IE_ChannelType('0001'B, ChRate_TCHF, Spdi_TCHF_FR); |
| var template PDU_BSSAP tr_assignment_req := tr_BSSMAP_AssignmentReq(); |
| tr_assignment_req.pdu.bssmap.assignmentRequest.channelType := tr_ch_type; |
| tr_assignment_req.pdu.bssmap.assignmentRequest.groupCallReference := |
| tr_BSSMAP_IE_GroupCallRef(bit2oct(encvalue(callref))); |
| /* Due to a bug in dec_PDU_BSSAP(), we do not get the callref IE, so we need to match it with omit. */ |
| tr_assignment_req.pdu.bssmap.assignmentRequest.groupCallReference := omit; |
| var template (value) PDU_BSSAP ts_assignment_cpl := ts_BSSMAP_AssignmentComplete(omit, omit, omit, omit); |
| var octetstring xcc_termination_21 := '340121'O; |
| var octetstring xcc_termination_11 := '340111'O; |
| var PDU_BSSAP rx_bssap; |
| |
| f_init_handler(pars); |
| |
| /* Location Update to make subscriber known. */ |
| f_perform_lu(); |
| |
| /* MGW */ |
| f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit}); |
| var default crcx := activate(as_optional_mgcp_crcx(cpars)); |
| var default mdcx := activate(as_optional_mgcp_mdcx(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_port)); |
| var default dlcx := activate(as_optional_mgcp_dlcx(cpars)); |
| |
| /* Establish connection using the service type, defined by the test. */ |
| if (test == COORD_TEST_COMPLETE_VBS) { |
| f_establish_fully(EST_TYPE_VBS); |
| } else { |
| f_establish_fully(EST_TYPE_VGCS); |
| } |
| |
| /* Send incorrect call reference, if selected by test. */ |
| log("Sending SETUP."); |
| select (test) { |
| case (COORD_TEST_NO_CALLREF) { |
| BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_GCC(cpars.transaction_id, '3200002900'O))); |
| } |
| case (COORD_TEST_COMPLETE_VBS) { |
| BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_BCC(cpars.transaction_id, '3200001a00'O))); |
| } |
| case else { |
| BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_GCC(cpars.transaction_id, '3200001900'O))); |
| } |
| } |
| COORD.send(COORD_SETUP); |
| |
| timer T := 10.0; |
| T.start; |
| alt { |
| [] BSSAP.receive(tr_assignment_req) -> value rx_bssap { |
| /* The MSC sends and Assignment Request to assign the calling subscriber to the VGCS/VBS channel. */ |
| log("Got Assignment Request: ", rx_bssap); |
| COORD.send(COORD_ASSIGNMENT); |
| log("Sending Assignment Complete: ", ts_assignment_cpl); |
| BSSAP.send(ts_assignment_cpl); |
| repeat; |
| } |
| [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_GCC(cpars.transaction_id, xcc_termination_21))) { |
| /* The MSC terminates the group call with cause 21 = requested service not subscribed. */ |
| log("Got GCC Termination with failure."); |
| COORD.send(COORD_GCC_TERMINATION_FAIL); |
| repeat; |
| } |
| [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_BCC(cpars.transaction_id, xcc_termination_21))) { |
| /* The MSC terminates the broadcast call with cause 21 = requested service not subscribed. */ |
| log("Got BCC Termination with failure."); |
| COORD.send(COORD_BCC_TERMINATION_FAIL); |
| repeat; |
| } |
| [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_GCC(cpars.transaction_id, xcc_termination_11))) { |
| /* The MSC terminates the group call with cause 11 = network failure. */ |
| log("Got GCC Termination with failure."); |
| COORD.send(COORD_GCC_TERMINATION_FAIL); |
| repeat; |
| } |
| [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_BCC(cpars.transaction_id, xcc_termination_11))) { |
| /* The MSC terminates the broadcast call with cause 11 = network failure. */ |
| log("Got BCC Termination with failure."); |
| COORD.send(COORD_BCC_TERMINATION_FAIL); |
| repeat; |
| } |
| [] BSSAP.receive(tr_BSSMAP_ClearCommand) { |
| /* The SCCP connection is released. */ |
| log("Got Clear Command on initial connection."); |
| COORD.send(COORD_CLEAR); |
| repeat; |
| } |
| [] BSSAP.receive { |
| setverdict(fail, "Got unexpected message on initial connection."); |
| } |
| [] COORD.receive(COORD_CLEAR) { } |
| [] T.timeout { |
| setverdict(fail, "Timeout waiting for Message"); |
| } |
| } |
| |
| deactivate(crcx); |
| deactivate(mdcx); |
| deactivate(dlcx); |
| } |
| |
| /* "control" connection handling */ |
| private function f_tc_vgcs_control(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr |
| { |
| /* Receive test case from main function. */ |
| var charstring test; |
| COORD.receive(charstring:?) -> value test; |
| |
| /* Initialize variables and templates. */ |
| var CallParameters cpars := valueof(t_CallParams('12345'H, 0)); |
| var template (value) DescriptiveGroupOrBroadcastCallReference_V callref := |
| ts_BSSMAP_IE_GroupCallRef(oct2int('190000'O), '1'B, '0'B, '000'B, '0000'B); |
| if (test == COORD_TEST_COMPLETE_VBS) { |
| callref := ts_BSSMAP_IE_GroupCallRef(oct2int('1a0000'O), '0'B, '0'B, '000'B, '0000'B); |
| } |
| var template PDU_BSSAP tr_vgcs_vbs_setup := tr_BSSMAP_VGCS_VBS_Setup(bit2oct(encvalue(callref))); |
| var template (value) PDU_BSSAP ts_vgcs_vbs_setup_ack := ts_BSSMAP_VGCS_VBS_SetupAck(omit); |
| var myBSSMAP_Cause cause_fail := GSM0808_CAUSE_EQUIPMENT_FAILURE; |
| var template (value) PDU_BSSAP ts_vgcs_vbs_setup_refuse := ts_BSSMAP_VGCS_VBS_SetupRefuse(enum2int(cause_fail)); |
| var octetstring gcc_connect := '330000190001'O; |
| var octetstring bcc_connect := '3300001a0001'O; |
| var octetstring xcc_set_param := '3A07'O; |
| var octetstring gcc_term_req := '3500001900'O; |
| var octetstring bcc_term_req := '3500001a00'O; |
| var octetstring xcc_termination := '340110'O; |
| /* L3 info carries the mobile identity of the talker requesting the uplink. */ |
| var octetstring uplink_req_conf := '061103505902082926240000000033'O; |
| var myBSSMAP_Cause cause_success := GSM0808_CAUSE_CALL_CONTROL; |
| var template (value) PDU_BSSAP ts_uplink_rel_ind := ts_BSSMAP_UplinkRelInd(enum2int(cause_success), omit); |
| var template (value) PDU_BSSAP ts_uplink_req := ts_BSSMAP_UplinkReq; |
| var template (value) PDU_BSSAP ts_uplink_req_conf := ts_BSSMAP_UplinkReqConf(ts_CellId_CI(42), omit, uplink_req_conf); |
| var PDU_BSSAP rx_bssap; |
| |
| f_init_handler(pars); |
| |
| f_create_bssmap_exp_n_connect(193); |
| |
| timer T := 7.0; |
| T.start; |
| alt { |
| [] BSSAP.receive(tr_vgcs_vbs_setup) -> value rx_bssap { |
| /* The MSC sets up call control on the BSC. The test case will send an ack or a refuse. */ |
| log("Got VGCS/VBS Setup: ", rx_bssap); |
| COORD.send(COORD_VGCS_SETUP); |
| if (test == COORD_TEST_SETUP_REFUSE) { |
| log("Sending VGCS/VBS Setup Refuse: ", ts_vgcs_vbs_setup_refuse); |
| BSSAP.send(ts_vgcs_vbs_setup_refuse); |
| } else { |
| log("Sending VGCS/VBS Setup Ack: ", ts_vgcs_vbs_setup_ack); |
| BSSAP.send(ts_vgcs_vbs_setup_ack); |
| } |
| repeat; |
| } |
| [] BSSAP.receive(tr_BSSMAP_UplinkSeizedCmd(GSM0808_CAUSE_CALL_CONTROL)) -> value rx_bssap { |
| /* After setting up the call, the MSC marks the call as busy. */ |
| log("Got Uplink Seized Cmd: ", rx_bssap); |
| COORD.send(COORD_UPLINK_SEIZED); |
| repeat; |
| } |
| [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_GCC(cpars.transaction_id, gcc_connect))) { |
| /* The GCC CONNECT message is sent to the calling MS. */ |
| log("Got GCC Connect."); |
| COORD.send(COORD_GCC_CONNECT); |
| repeat; |
| } |
| [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_BCC(cpars.transaction_id, bcc_connect))) { |
| /* The BCC CONNECT message is sent to the calling MS. */ |
| log("Got BCC Connect."); |
| COORD.send(COORD_BCC_CONNECT); |
| repeat; |
| } |
| [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_GCC(cpars.transaction_id, xcc_set_param))) { |
| /* The GCC SET PARAMETER message is sent to the calling MS. */ |
| log("Got GCC Set Parameter."); |
| COORD.send(COORD_GCC_SET_PARAM); |
| f_sleep(0.2); |
| /* The MS releases the uplink. */ |
| log("Sending Uplink Release Ind: ", ts_uplink_rel_ind); |
| BSSAP.send(ts_uplink_rel_ind); |
| f_sleep(0.2); |
| /* The MS requests the uplink again. */ |
| log("Sending Uplink Req: ", ts_uplink_req); |
| BSSAP.send(ts_uplink_req); |
| repeat; |
| } |
| [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_BCC(cpars.transaction_id, xcc_set_param))) { |
| /* The BCC SET PARAMETER message is sent to the calling MS. */ |
| log("Got BCC Set Parameter"); |
| COORD.send(COORD_BCC_SET_PARAM); |
| f_sleep(0.2); |
| /* The MS requests termination of the call. */ |
| log("Sending BCC Termination Request: ", bcc_term_req); |
| BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_BCC(cpars.transaction_id, bcc_term_req))); |
| repeat; |
| } |
| [] BSSAP.receive(tr_BSSMAP_UplinkReqAck(*)) -> value rx_bssap { |
| /* The uplink was granted by the MSC. */ |
| log("Got Uplink Request Acknowledge: ", rx_bssap); |
| COORD.send(COORD_UPLINK_REQ_ACK); |
| f_sleep(0.2); |
| /* The BSC confirms the uplink and provides mobile identity to identify originator. */ |
| log("Sending Uplink Req Confirm: ", ts_uplink_req_conf); |
| BSSAP.send(ts_uplink_req_conf); |
| /* The MS requests termination of the call. */ |
| log("Sending GCC Termination Request: ", gcc_term_req); |
| BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_GCC(cpars.transaction_id, gcc_term_req))); |
| repeat; |
| } |
| [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_GCC(cpars.transaction_id, xcc_termination))) { |
| /* The MSC terminates the call towards the MS. */ |
| log("Got GCC Termination."); |
| COORD.send(COORD_GCC_TERMINATION); |
| repeat; |
| } |
| [] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_BCC(cpars.transaction_id, xcc_termination))) { |
| /* The MSC terminates the call towards the MS. */ |
| log("Got BCC Termination."); |
| COORD.send(COORD_BCC_TERMINATION); |
| repeat; |
| } |
| [] BSSAP.receive(tr_BSSMAP_ClearCommand) { |
| /* The SCCP connection is released. */ |
| log("Got Clear Command on control connection."); |
| COORD.send(COORD_CLEAR); |
| repeat; |
| } |
| [] BSSAP.receive(PDU_BSSAP:?) -> value rx_bssap { |
| setverdict(fail, "Got unexpected BSSAP message on control connection: ", rx_bssap); |
| } |
| [] BSSAP.receive { |
| setverdict(fail, "Got unexpected message on control connection."); |
| } |
| [] COORD.receive(COORD_CLEAR) { } |
| [] T.timeout { |
| setverdict(fail, "Timeout on control connection."); |
| } |
| } |
| } |
| |
| /* "channel" connection handling */ |
| private function f_tc_vgcs_channel(charstring id, BSC_ConnHdlrPars pars) runs on BSC_ConnHdlr |
| { |
| /* Receive test case from main function. */ |
| var charstring test; |
| COORD.receive(charstring:?) -> value test; |
| |
| /* Initialize variables and templates. */ |
| var template (value) DescriptiveGroupOrBroadcastCallReference_V callref := |
| ts_BSSMAP_IE_GroupCallRef(oct2int('190000'O), '1'B, '0'B, '000'B, '0000'B); |
| if (test == COORD_TEST_COMPLETE_VBS) { |
| callref := ts_BSSMAP_IE_GroupCallRef(oct2int('1a0000'O), '0'B, '0'B, '000'B, '0000'B); |
| } |
| var template (present) BSSMAP_IE_ChannelType tr_ch_type := |
| tr_BSSMAP_IE_ChannelType('0001'B, ChRate_TCHF, Spdi_TCHF_FR); |
| var template (value) BSSMAP_IE_ChannelType ts_ch_type := valueof(ts_BSSMAP_IE_ChannelTypeCTM); |
| var template (present) BSSMAP_IE_CellIdentifier tr_cell_id := tr_CellId_CI(42); |
| var template (value) BSSMAP_IE_CellIdentifier ts_cell_id := ts_CellId_CI(42); |
| var template (value) BSSMAP_IE_AoIP_TransportLayerAddress ts_tla := f_ts_BSSMAP_IE_AoIP_TLA("1.2.3.4", 2342); |
| var template (value) BSSMAP_IE_SpeechCodec ts_codec := ts_BSSMAP_IE_SpeechCodec({ts_CodecFR}); |
| var template PDU_BSSAP tr_vgcs_vbs_ass_req := |
| tr_BSSMAP_VGCS_VBS_AssignmentReq(tr_ch_type, '01'O, tr_cell_id, bit2oct(encvalue(callref)), *, *, *); |
| var template (value) PDU_BSSAP ts_vgcs_vbs_ass_res := |
| f_gen_asci_ass_res(0, ts_ch_type, ts_cell_id, ts_tla, ts_codec, '01000000'O); |
| var myBSSMAP_Cause cause_fail := GSM0808_CAUSE_EQUIPMENT_FAILURE; |
| var template (value) PDU_BSSAP ts_vgcs_vbs_ass_fail := ts_BSSMAP_VGCS_VBS_AssignmentFail(enum2int(cause_fail)); |
| var PDU_BSSAP rx_bssap; |
| |
| f_init_handler(pars); |
| |
| /* Wait some time before registering, because this has to be the second connection to be registered. */ |
| f_sleep(0.5); |
| f_create_bssmap_exp_n_connect(193); |
| |
| timer T := 7.0; |
| T.start; |
| alt { |
| [] BSSAP.receive(tr_vgcs_vbs_ass_req) -> value rx_bssap { |
| /* The MSC allocates channel on the given BTS. The test case will send a result or a failure. */ |
| log("Got VGCS/VBS Assignment Request: ", rx_bssap); |
| COORD.send(COORD_VGCS_ASSIGN); |
| if (test == COORD_TEST_ASSIGN_FAIL) { |
| log("Sending VGCS/VBS Assignment Failure: ", ts_vgcs_vbs_ass_fail); |
| BSSAP.send(ts_vgcs_vbs_ass_fail); |
| } else { |
| log("Sending VGCS/VBS Assignment Result: ", ts_vgcs_vbs_ass_res); |
| BSSAP.send(ts_vgcs_vbs_ass_res); |
| } |
| repeat; |
| } |
| [] BSSAP.receive(tr_BSSMAP_ClearCommand) { |
| /* The SCCP connection is released. */ |
| log("Got Clear Command on channel connection."); |
| COORD.send(COORD_CLEAR); |
| repeat; |
| } |
| [] BSSAP.receive(PDU_BSSAP:?) -> value rx_bssap { |
| setverdict(fail, "Got unexpected BSSAP message on channel connection: ", rx_bssap); |
| } |
| [] BSSAP.receive { |
| setverdict(fail, "Got unexpected message on channel connection."); |
| } |
| [] COORD.receive(COORD_CLEAR) { } |
| [] T.timeout { |
| setverdict(fail, "Timeout on channel connection."); |
| } |
| } |
| } |
| |
| /* Main function for call test */ |
| private function f_TC_asci_call(charstring test) runs on asci_CT |
| { |
| var BSC_ConnHdlr vc_conn_call, vc_conn_control, vc_conn_channel; |
| var boolean got_vgcs_setup := false; |
| var boolean got_vgcs_assign := false; |
| var boolean got_uplink_seized := false; |
| var boolean got_gcc_connect := false; |
| var boolean got_bcc_connect := false; |
| var boolean got_gcc_set_param := false; |
| var boolean got_bcc_set_param := false; |
| var boolean got_uplink_req_ack := false; |
| var boolean got_gcc_termination := false; |
| var boolean got_bcc_termination := false; |
| var boolean got_gcc_termination_fail := false; |
| var boolean got_bcc_termination_fail := false; |
| var boolean got_assignment := false; |
| var boolean connection_call := false; |
| var boolean connection_control := false; |
| var boolean connection_channel := false; |
| var charstring event; |
| |
| f_init(); |
| |
| /* Enable ASCI in VTY and setup a VGC and a VBS. */ |
| f_vty_config(MSCVTY, "asci", "enable"); |
| f_vty_config2(MSCVTY, { "asci", "gcr", "vgc 200"}, "cell 0.24.1 42"); |
| f_vty_config2(MSCVTY, { "asci", "gcr", "vbc 208"}, "cell 0.24.1 42"); |
| |
| vc_conn_call := f_start_handler(refers(f_tc_vgcs_call), 33); |
| vc_conn_control := f_start_handler(refers(f_tc_vgcs_control), 34); |
| vc_conn_channel := f_start_handler(refers(f_tc_vgcs_channel), 35); |
| |
| connect(self:COORD_call, vc_conn_call:COORD); |
| connect(self:COORD_control, vc_conn_control:COORD); |
| connect(self:COORD_channel, vc_conn_channel:COORD); |
| |
| COORD_call.send(test); |
| COORD_control.send(test); |
| COORD_channel.send(test); |
| |
| /* Receive the test events until all three connections are released or not established. */ |
| timer T := 7.0, Texit := 0.5; |
| T.start; |
| alt { |
| [] COORD_call.receive(COORD_SETUP) -> value event { |
| log("Got test event: ", event); |
| connection_call := true; |
| repeat; |
| } |
| [] COORD_control.receive(COORD_VGCS_SETUP) -> value event { |
| log("Got test event: ", event); |
| got_vgcs_setup := true; |
| connection_control := true; |
| repeat; |
| } |
| [] COORD_channel.receive(COORD_VGCS_ASSIGN) -> value event { |
| log("Got test event: ", event); |
| got_vgcs_assign := true; |
| connection_channel := true; |
| repeat; |
| } |
| [] COORD_control.receive(COORD_UPLINK_REQ_ACK) -> value event { |
| log("Got test event: ", event); |
| got_uplink_req_ack := true; |
| repeat; |
| } |
| [] COORD_control.receive(COORD_GCC_CONNECT) -> value event { |
| log("Got test event: ", event); |
| got_gcc_connect := true; |
| repeat; |
| } |
| [] COORD_control.receive(COORD_BCC_CONNECT) -> value event { |
| log("Got test event: ", event); |
| got_bcc_connect := true; |
| repeat; |
| } |
| [] COORD_control.receive(COORD_GCC_SET_PARAM) -> value event { |
| log("Got test event: ", event); |
| got_gcc_set_param := true; |
| repeat; |
| } |
| [] COORD_control.receive(COORD_BCC_SET_PARAM) -> value event { |
| log("Got test event: ", event); |
| got_bcc_set_param := true; |
| repeat; |
| } |
| [] COORD_control.receive(COORD_UPLINK_SEIZED) -> value event { |
| log("Got test event: ", event); |
| got_uplink_seized := true; |
| repeat; |
| } |
| [] COORD_call.receive(COORD_GCC_TERMINATION_FAIL) -> value event { |
| log("Got test event: ", event); |
| got_gcc_termination_fail := true; |
| repeat; |
| } |
| [] COORD_call.receive(COORD_BCC_TERMINATION_FAIL) -> value event { |
| log("Got test event: ", event); |
| got_bcc_termination_fail := true; |
| repeat; |
| } |
| [] COORD_control.receive(COORD_GCC_TERMINATION) -> value event { |
| log("Got test event: ", event); |
| got_gcc_termination := true; |
| repeat; |
| } |
| [] COORD_control.receive(COORD_BCC_TERMINATION) -> value event { |
| log("Got test event: ", event); |
| got_bcc_termination := true; |
| repeat; |
| } |
| [] COORD_call.receive(COORD_ASSIGNMENT) -> value event { |
| log("Got test event: ", event); |
| got_assignment := true; |
| repeat; |
| } |
| [not connection_call] COORD_call.receive(COORD_CLEAR) -> value event { |
| setverdict(fail, "Received CLEAR COMMAND of initial call twice."); |
| } |
| [] COORD_call.receive(COORD_CLEAR) -> value event { |
| log("Got test event: ", event); |
| connection_call := false; |
| if (connection_call or connection_control or connection_channel) { |
| repeat; |
| } |
| Texit.start; |
| repeat; |
| } |
| [not connection_control] COORD_control.receive(COORD_CLEAR) -> value event { |
| setverdict(fail, "Received CLEAR COMMAND control connection twice."); |
| } |
| [] COORD_control.receive(COORD_CLEAR) -> value event { |
| log("Got test event: ", event); |
| connection_control := false; |
| if (connection_call or connection_control or connection_channel) { |
| repeat; |
| } |
| Texit.start; |
| repeat; |
| } |
| [not connection_channel] COORD_channel.receive(COORD_CLEAR) -> value event { |
| setverdict(fail, "Received CLEAR COMMAND of channel connection twice."); |
| } |
| [] COORD_channel.receive(COORD_CLEAR) -> value event { |
| log("Got test event: ", event); |
| connection_channel := false; |
| if (connection_call or connection_control or connection_channel) { |
| repeat; |
| } |
| Texit.start; |
| repeat; |
| } |
| [] COORD_call.receive { |
| setverdict(fail, "Unhandled COORD_call, please fix!"); |
| } |
| [] COORD_control.receive { |
| setverdict(fail, "Unhandled COORD_control, please fix!"); |
| } |
| [] COORD_channel.receive { |
| setverdict(fail, "Unhandled COORD_channel, please fix!"); |
| } |
| [] T.timeout { |
| setverdict(fail, "Timeout waiting for Test result"); |
| } |
| [] Texit.timeout { |
| log("All connection are cleared now."); |
| } |
| } |
| |
| /* Tell the connection handlers to exit. */ |
| COORD_call.send(COORD_CLEAR); |
| COORD_control.send(COORD_CLEAR); |
| COORD_channel.send(COORD_CLEAR); |
| |
| vc_conn_call.done; |
| vc_conn_control.done; |
| vc_conn_channel.done; |
| |
| if (getverdict == fail) { |
| return; |
| } |
| |
| /* Check if the outcome of each test is as expected. */ |
| select (test) { |
| case (COORD_TEST_NO_CALLREF) { |
| if (not got_vgcs_setup and |
| not got_vgcs_assign and |
| got_gcc_termination_fail) { |
| setverdict(pass); |
| } |
| } |
| case (COORD_TEST_SETUP_REFUSE) { |
| if (got_vgcs_setup and |
| not got_vgcs_assign and |
| got_gcc_termination_fail) { |
| setverdict(pass); |
| } |
| } |
| case (COORD_TEST_ASSIGN_FAIL) { |
| if (got_vgcs_setup and |
| got_vgcs_assign and |
| got_gcc_termination_fail) { |
| setverdict(pass); |
| } |
| } |
| case (COORD_TEST_COMPLETE_VGCS) { |
| if (got_vgcs_setup and |
| got_vgcs_assign and |
| got_uplink_req_ack and |
| got_gcc_connect and |
| got_gcc_set_param and |
| got_uplink_seized and |
| got_gcc_termination and |
| got_assignment) { |
| setverdict(pass); |
| } |
| } |
| case (COORD_TEST_COMPLETE_VBS) { |
| if (got_vgcs_setup and |
| got_vgcs_assign and |
| not got_uplink_req_ack and |
| got_bcc_connect and |
| got_bcc_set_param and |
| got_uplink_seized and |
| got_bcc_termination and |
| got_assignment) { |
| setverdict(pass); |
| } |
| } |
| case else { |
| setverdict(fail, "Test case has no check for the outcome, please fix! Test was: ", test); |
| } |
| } |
| |
| if (getverdict == pass) { |
| log("All expected events have been received. The test passed."); |
| } else { |
| setverdict(fail, "Not all expected event received."); |
| } |
| } |
| |
| /* A call is tried, but the given call reference does not exit. */ |
| testcase TC_no_callref() runs on asci_CT |
| { |
| f_TC_asci_call(COORD_TEST_NO_CALLREF); |
| } |
| |
| /* The VGCS/VBS is refused by the BSC. */ |
| testcase TC_setup_refuse() runs on asci_CT |
| { |
| f_TC_asci_call(COORD_TEST_SETUP_REFUSE); |
| } |
| |
| /* The VGCS/VBS channel is refused by the BSC. */ |
| testcase TC_assign_fail() runs on asci_CT |
| { |
| f_TC_asci_call(COORD_TEST_ASSIGN_FAIL); |
| } |
| |
| /* The VGCS call is completed and the MS releases and requests the uplink again. Then it terminates the call. */ |
| testcase TC_complete_vgcs() runs on asci_CT |
| { |
| f_TC_asci_call(COORD_TEST_COMPLETE_VGCS); |
| } |
| |
| /* The VBS call is completed and the MS terminates the call. */ |
| testcase TC_complete_vbs() runs on asci_CT |
| { |
| f_TC_asci_call(COORD_TEST_COMPLETE_VBS); |
| } |
| |
| control { |
| execute( TC_no_callref() ); |
| execute( TC_setup_refuse() ); |
| execute( TC_assign_fail() ); |
| execute( TC_complete_vgcs() ); |
| execute( TC_complete_vbs() ); |
| } |
| |
| } |