From 20bc3e25a7fdd38895b88d7c7919812619d47de2 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Fri, 9 Nov 2018 01:40:16 +0100 Subject: bsc: add inter-bsc ho incoming failure tests Change-Id: I849e4c0a14cc091195d948adb8df7a0b7414ecfe --- bsc/BSC_Tests.ttcn | 348 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) (limited to 'bsc/BSC_Tests.ttcn') diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn index 29961e59..9b445f5c 100644 --- a/bsc/BSC_Tests.ttcn +++ b/bsc/BSC_Tests.ttcn @@ -2578,6 +2578,348 @@ testcase TC_ho_into_this_bsc() runs on test_CT { vc_conn.done; } +private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr { + var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH)); + f_rslem_register(0, new_chan_nr); + g_chan_nr := new_chan_nr; + f_sleep(1.0); + + f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit}); + f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR); + activate(as_Media()); + + BSSAP.send(ts_BSSAP_Conn_Req(g_pars.handover.sccp_addr_bsc, g_pars.handover.sccp_addr_msc, + f_gen_handover_req())); + BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND); + + /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */ + + var PDU_BSSAP rx_bssap; + var octetstring ho_command_str; + + BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap; + + ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info; + log("Received L3 Info in HO Request Ack: ", ho_command_str); + var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str); + log("L3 Info in HO Request Ack is ", ho_command); + + var GsmArfcn arfcn; + var RslChannelNr actual_new_chan_nr; + f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2, + actual_new_chan_nr, arfcn); + + if (actual_new_chan_nr != new_chan_nr) { + log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.", + " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr); + setverdict(fail); + return; + } + log("Handover Command chan_nr is", actual_new_chan_nr); + + /* Now the MSC forwards the RR Handover Command to the other BSC, which + * tells the MS to handover to the new lchan. In this case, the MS + * reports a Handover Failure to the old BSS, which forwards a BSSMAP + * Handover Failure to the MSC. The procedure according to 3GPP TS + * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a + * BSSMAP Clear Command: */ + + var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION; + var BssmapCause cause := enum2int(cause_val); + BSSAP.send(ts_BSSMAP_ClearCommand(cause)); + + /* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */ + var MgcpCommand mgcp; + interleave { + [] BSSAP.receive(tr_BSSMAP_ClearComplete); + [] MGCP.receive(tr_DLCX()) -> value mgcp { + log("Got first DLCX: ", mgcp); + } + [] MGCP.receive(tr_DLCX()) -> value mgcp { + log("Got second DLCX: ", mgcp); + } + } + setverdict(pass); + f_sleep(1.0); + + setverdict(pass); +} +testcase TC_ho_in_fail_msc_clears() runs on test_CT { + var MSC_ConnHdlr vc_conn; + var TestHdlrParams pars := f_gen_test_hdlr_pars(); + + f_init(1, true); + f_sleep(1.0); + + pars.handover.sccp_addr_msc := g_bssap.sccp_addr_own; + pars.handover.sccp_addr_bsc := g_bssap.sccp_addr_peer; + + vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars); + vc_conn.done; +} + +private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr { + /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the + * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting + * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we + * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation + * before we get started. */ + var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH)); + f_rslem_register(0, new_chan_nr); + g_chan_nr := new_chan_nr; + f_sleep(1.0); + + f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit}); + f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR); + activate(as_Media()); + + BSSAP.send(ts_BSSAP_Conn_Req(g_pars.handover.sccp_addr_bsc, g_pars.handover.sccp_addr_msc, + f_gen_handover_req())); + BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND); + + /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */ + + var PDU_BSSAP rx_bssap; + var octetstring ho_command_str; + + BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap; + + ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info; + log("Received L3 Info in HO Request Ack: ", ho_command_str); + var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str); + log("L3 Info in HO Request Ack is ", ho_command); + + var GsmArfcn arfcn; + var RslChannelNr actual_new_chan_nr; + f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2, + actual_new_chan_nr, arfcn); + + if (actual_new_chan_nr != new_chan_nr) { + log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.", + " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr); + setverdict(fail); + return; + } + log("Handover Command chan_nr is", actual_new_chan_nr); + + /* Now the MSC forwards the RR Handover Command to the other BSC, which + * tells the MS to handover to the new lchan. Here comes the new MS on + * the new lchan with a Handover RACH: */ + + /* send handover detect */ + + RSL.send(ts_RSL_HANDO_DET(new_chan_nr)); + + BSSAP.receive(tr_BSSMAP_HandoverDetect); + + /* The MSC chooses to clear the connection now, maybe we got the + * Handover RACH on the new cell but the MS still signaled Handover + * Failure to the old BSS? */ + + var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION; + var BssmapCause cause := enum2int(cause_val); + BSSAP.send(ts_BSSMAP_ClearCommand(cause)); + + /* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */ + var MgcpCommand mgcp; + interleave { + [] BSSAP.receive(tr_BSSMAP_ClearComplete); + [] MGCP.receive(tr_DLCX()) -> value mgcp { + log("Got first DLCX: ", mgcp); + } + [] MGCP.receive(tr_DLCX()) -> value mgcp { + log("Got second DLCX: ", mgcp); + } + } + setverdict(pass); + f_sleep(1.0); +} +testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT { + var MSC_ConnHdlr vc_conn; + var TestHdlrParams pars := f_gen_test_hdlr_pars(); + + f_init(1, true); + f_sleep(1.0); + + pars.handover.sccp_addr_msc := g_bssap.sccp_addr_own; + pars.handover.sccp_addr_bsc := g_bssap.sccp_addr_peer; + + vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars); + vc_conn.done; +} + +/* The new BSS's lchan times out before the MSC decides that handover failed. */ +private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr { + var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH)); + f_rslem_register(0, new_chan_nr); + g_chan_nr := new_chan_nr; + f_sleep(1.0); + + f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit}); + f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR); + activate(as_Media()); + + BSSAP.send(ts_BSSAP_Conn_Req(g_pars.handover.sccp_addr_bsc, g_pars.handover.sccp_addr_msc, + f_gen_handover_req())); + BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND); + + /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */ + + var PDU_BSSAP rx_bssap; + var octetstring ho_command_str; + + BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap; + + ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info; + log("Received L3 Info in HO Request Ack: ", ho_command_str); + var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str); + log("L3 Info in HO Request Ack is ", ho_command); + + var GsmArfcn arfcn; + var RslChannelNr actual_new_chan_nr; + f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2, + actual_new_chan_nr, arfcn); + + if (actual_new_chan_nr != new_chan_nr) { + log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.", + " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr); + setverdict(fail); + return; + } + log("Handover Command chan_nr is", actual_new_chan_nr); + + /* Now the MSC forwards the RR Handover Command to the other BSC, which + * tells the MS to handover to the new lchan. But the MS never shows up + * on the new lchan. */ + + BSSAP.receive(tr_BSSMAP_HandoverFailure); + + /* Did osmo-bsc also send a Clear Request? */ + timer T := 0.5; + T.start; + alt { + [] BSSAP.receive(tr_BSSMAP_ClearRequest); + [] T.timeout { } + } + + /* MSC plays along with a Clear Command (no matter whether osmo-bsc + * asked for it, this is a Handover Failure after all). */ + + var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION; + var BssmapCause cause := enum2int(cause_val); + BSSAP.send(ts_BSSMAP_ClearCommand(cause)); + + /* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */ + var MgcpCommand mgcp; + interleave { + [] BSSAP.receive(tr_BSSMAP_ClearComplete); + [] MGCP.receive(tr_DLCX()) -> value mgcp { + log("Got first DLCX: ", mgcp); + } + [] MGCP.receive(tr_DLCX()) -> value mgcp { + log("Got second DLCX: ", mgcp); + } + } + setverdict(pass); + f_sleep(1.0); + + setverdict(pass); +} +testcase TC_ho_in_fail_no_detect() runs on test_CT { + var MSC_ConnHdlr vc_conn; + var TestHdlrParams pars := f_gen_test_hdlr_pars(); + + f_init(1, true); + f_sleep(1.0); + + pars.handover.sccp_addr_msc := g_bssap.sccp_addr_own; + pars.handover.sccp_addr_bsc := g_bssap.sccp_addr_peer; + + vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars); + vc_conn.done; +} + +/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */ +private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr { + var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH)); + f_rslem_register(0, new_chan_nr); + g_chan_nr := new_chan_nr; + f_sleep(1.0); + + f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit}); + f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR); + activate(as_Media()); + + BSSAP.send(ts_BSSAP_Conn_Req(g_pars.handover.sccp_addr_bsc, g_pars.handover.sccp_addr_msc, + f_gen_handover_req())); + BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND); + + /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */ + + var PDU_BSSAP rx_bssap; + var octetstring ho_command_str; + + BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap; + + ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info; + log("Received L3 Info in HO Request Ack: ", ho_command_str); + var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str); + log("L3 Info in HO Request Ack is ", ho_command); + + var GsmArfcn arfcn; + var RslChannelNr actual_new_chan_nr; + f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2, + actual_new_chan_nr, arfcn); + + if (actual_new_chan_nr != new_chan_nr) { + log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.", + " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr); + setverdict(fail); + return; + } + log("Handover Command chan_nr is", actual_new_chan_nr); + + /* Now the MSC forwards the RR Handover Command to the other BSC, which + * tells the MS to handover to the new lchan. But the MS never shows up + * on the new lchan. */ + + BSSAP.receive(tr_BSSMAP_HandoverFailure); + + /* MSC plays dumb and sends no Clear Command */ + + /* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */ + var PDU_BSSAP rx_clear_request; + var MgcpCommand mgcp; + interleave { + [] BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request { + var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue); + BSSAP.send(ts_BSSMAP_ClearCommand(cause)); + }; + [] BSSAP.receive(tr_BSSMAP_ClearComplete); + + [] MGCP.receive(tr_DLCX()) -> value mgcp { + log("Got first DLCX: ", mgcp); + } + [] MGCP.receive(tr_DLCX()) -> value mgcp { + log("Got second DLCX: ", mgcp); + } + } + setverdict(pass); + f_sleep(1.0); +} +testcase TC_ho_in_fail_no_detect2() runs on test_CT { + var MSC_ConnHdlr vc_conn; + var TestHdlrParams pars := f_gen_test_hdlr_pars(); + + f_init(1, true); + f_sleep(1.0); + + pars.handover.sccp_addr_msc := g_bssap.sccp_addr_own; + pars.handover.sccp_addr_bsc := g_bssap.sccp_addr_peer; + + vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars); + vc_conn.done; +} /* OS#3041: Open and close N connections in a normal fashion, and expect no * BSSMAP Reset just because of that. */ @@ -3079,11 +3421,17 @@ control { execute( TC_err_84_unknown_msg() ); execute( TC_ho_int() ); + execute( TC_ho_out_of_this_bsc() ); execute( TC_ho_out_fail_no_msc_response() ); execute( TC_ho_out_fail_rr_ho_failure() ); execute( TC_ho_out_fail_no_ho_detect() ); + execute( TC_ho_into_this_bsc() ); + execute( TC_ho_in_fail_msc_clears() ); + execute( TC_ho_in_fail_msc_clears_after_ho_detect() ); + execute( TC_ho_in_fail_no_detect() ); + execute( TC_ho_in_fail_no_detect2() ); execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() ); execute( TC_bssmap_clear_does_not_cause_bssmap_reset() ); -- cgit v1.2.3