bsc: add inter-bsc ho incoming failure tests
Change-Id: I849e4c0a14cc091195d948adb8df7a0b7414ecfe
diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn
index 29961e5..9b445f5 100644
--- a/bsc/BSC_Tests.ttcn
+++ b/bsc/BSC_Tests.ttcn
@@ -2578,6 +2578,348 @@
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 @@
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() );