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-ttcn3-hacks/+/20373 ) Change subject: bsc: implement initial LCS tests for OsmoBSC ...................................................................... bsc: implement initial LCS tests for OsmoBSC Change-Id: Id3df9439752c088cff5618d21254af42365690ca --- M bsc/BSC_Tests.ttcn M bsc/MSC_ConnectionHandler.ttcn 2 files changed, 573 insertions(+), 31 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/73/20373/1 diff --git a/bsc/BSC_Tests.ttcn b/bsc/BSC_Tests.ttcn index a42b33d..3d96df1 100644 --- a/bsc/BSC_Tests.ttcn +++ b/bsc/BSC_Tests.ttcn @@ -30,6 +30,8 @@ import from RAN_Adapter all; import from BSSAP_LE_Adapter all; import from BSSAP_LE_CodecPort all; +import from BSSAP_LE_Types all; +import from BSSLAP_Types all; import from BSSAP_CodecPort all; import from BSSMAP_Templates all; import from IPA_Emulation all; @@ -63,6 +65,7 @@ import from SCCP_Templates all; import from BSSMAP_Templates all; +import from BSSMAP_LE_Templates all; import from SCCPasp_Types all; @@ -4490,12 +4493,12 @@ f_shutdown_helper(); } -private function f_verify_active_layer3() runs on MSC_ConnHdlr +private function f_verify_active_layer3(RSL_DCHAN_PT rsl := RSL) runs on MSC_ConnHdlr { /* The old lchan and conn should still be active. See that arbitrary L3 * is still going through. */ var octetstring l3 := '0123456789'O; - RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3)); + rsl.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3)); var template PDU_BSSAP exp_data := { discriminator := '1'B, spare := '0000000'B, @@ -6108,6 +6111,22 @@ template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) := ts_MI_TMSI_LV(tmsi := f_tmsi_nri(nri_v, nri_bitlen := nri_bitlen)); +private function f_expect_lchan_rel(RSL_DCHAN_PT rsl) runs on MSC_ConnHdlr { + interleave { + [] rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) { + f_logp(BSCVTY, "Got RSL RR Release"); + } + [] rsl.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) { + f_logp(BSCVTY, "Got RSL Deact SACCH"); + } + [] rsl.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) { + f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack"); + rsl.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr)); + break; + } + } +} + private function f_perform_clear(RSL_DCHAN_PT rsl) runs on MSC_ConnHdlr { f_logp(BSCVTY, "MSC instructs BSC to clear channel"); BSSAP.send(ts_BSSMAP_ClearCommand(0)); @@ -6130,7 +6149,7 @@ } } -private function f_perform_compl_l3(RSL_DCHAN_PT rsl, template PDU_ML3_MS_NW l3_info, boolean do_clear := true) +private function f_perform_compl_l3(RSL_DCHAN_PT rsl, template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true) runs on MSC_ConnHdlr { timer T := 10.0; var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info)); @@ -6173,34 +6192,36 @@ rsl.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc)); - f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC"); - var template PDU_BSSAP exp_l3_compl; - exp_l3_compl := tr_BSSMAP_ComplL3() - if (g_pars.aoip == false) { - exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit; - } else { - exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?; - } + if (expect_bssmap_l3) { + f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC"); + var template PDU_BSSAP exp_l3_compl; + exp_l3_compl := tr_BSSMAP_ComplL3() + if (g_pars.aoip == false) { + exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit; + } else { + exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?; + } - var PDU_BSSAP bssap; - T.start; - alt { - [] BSSAP.receive(exp_l3_compl) -> value bssap { - f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC"); - log("rx exp_l3_compl = ", bssap); + var PDU_BSSAP bssap; + T.start; + alt { + [] BSSAP.receive(exp_l3_compl) -> value bssap { + f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC"); + log("rx exp_l3_compl = ", bssap); + } + [] BSSAP.receive(tr_BSSMAP_ComplL3) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION"); + } + [] T.timeout { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION"); + } } - [] BSSAP.receive(tr_BSSMAP_ComplL3) { - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION"); - } - [] T.timeout { - Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION"); - } - } - /* start ciphering, if requested */ - if (ispresent(g_pars.encr)) { - f_logp(BSCVTY, "start ciphering"); - f_cipher_mode(g_pars.encr.enc_alg, g_pars.encr.enc_key); + /* start ciphering, if requested */ + if (ispresent(g_pars.encr)) { + f_logp(BSCVTY, "start ciphering"); + f_cipher_mode(g_pars.encr.enc_alg, g_pars.encr.enc_key); + } } if (do_clear) { @@ -7510,6 +7531,514 @@ f_shutdown_helper(); } +template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap) + := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap))); + +private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg, + template (present) BSSLAP_PDU expect_bsslap) +{ + var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data); + if (not match(bsslap, expect_bsslap)) { + log("EXPECTING BSSLAP: ", expect_bsslap); + log("GOT BSSLAP: ", bsslap); + setverdict(fail, "BSSLAP is not as expected"); + mtc.stop; + } + setverdict(pass); +} + +/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */ +const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O; + +private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr { + var PDU_BSSAP_LE rx_bsslap; + BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap); + f_match_bsslap(rx_bsslap, expect_rx_bsslap); +} + +private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr { + f_sleep(1.0); + + f_establish_fully(omit, omit); + f_bssap_le_register_imsi(g_pars.imsi, omit); + + f_logp(BSCVTY, "f_tc_lcs_loc_req_for_active_ms start"); + + BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi), + ts_CellId_CGI('262'H, '42'H, 23, 42)))); + + var PDU_BSSAP_LE plr; + BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr); + + if (not do_ta_request) { + /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */ + var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?); + if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) { + log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu); + log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu); + setverdict(fail, "BSSMAP-LE APDU IE is not as expected"); + mtc.stop; + } + var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0)); + var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data); + if (not match(bsslap, expect_ta_layer3)) { + log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3); + log("GOT BSSLAP: ", bsslap); + setverdict(fail, "BSSLAP is not as expected"); + mtc.stop; + } + /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC + * has no need to request the TA from the BSC and directly responds. */ + } else { + /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */ + BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req)); + f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?)); + } + + /* SMLC got the TA from the BSC, now responds with geo information data. */ + BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit)); + BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND); + BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle))); + + /* The LCS was using an active A-interface conn. It should still remain active after this. */ + f_verify_active_layer3(); + + f_perform_clear(RSL); + + f_sleep(2.0); + f_logp(BSCVTY, "f_tc_lcs_loc_req_for_active_ms done"); + setverdict(pass); +} + +private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr { + f_lcs_loc_req_for_active_ms(false); +} +testcase TC_lcs_loc_req_for_active_ms() 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); + vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars); + vc_conn.done; +} + +private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr { + f_lcs_loc_req_for_active_ms(true); +} +testcase TC_lcs_loc_req_for_active_ms_ta_req() 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); + vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars); + vc_conn.done; +} + +private function f_clear_A_conn() runs on MSC_ConnHdlr +{ + var BssmapCause cause := 0; + BSSAP.send(ts_BSSMAP_ClearCommand(cause)); + BSSAP.receive(tr_BSSMAP_ClearComplete); + BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ); + + timer no_more_bssap := 5.0; + no_more_bssap.start; + alt { + [] no_more_bssap.timeout { break; } + [] BSSAP.receive(tr_BSSAP_BSSMAP) { + setverdict(fail, "Expected no more BSSAP after Clear Complete"); + mtc.stop; + } + } + setverdict(pass); +} + +private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr +{ + f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear"); + + /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other + * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface + * connection is still up, we need something that echos back on the A-interface. Another LCS request! */ + BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi), + ts_CellId_CGI('262'H, '42'H, 23, 42)))); + BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)); + + /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */ + f_clear_A_conn(); + BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED)); + BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND); + f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: done"); +} + +private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr { + f_sleep(1.0); + + f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR); + f_bssap_le_register_imsi(g_pars.imsi, omit); + + /* Register to receive the Paging Command */ + var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH)); + g_chan_nr := new_chan_nr; + f_rslem_register(0, g_chan_nr); + + f_logp(BSCVTY, "f_tc_lcs_loc_req_for_idle_ms start"); + BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, + valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi), + ts_CellId_CGI('001'H, '01'H, 1, 0))))); + BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND); + + var PDU_BSSAP_LE plr; + BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr); + + /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */ + BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req)); + + /* OsmoBSC needs to Page */ + RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))); + f_logp(BSCVTY, "got Paging Command"); + + /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to + * the MSC, and releases the lchan directly. */ + f_perform_compl_l3(RSL, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(g_pars.imsi))), do_clear := false, expect_bssmap_l3 := false); + f_expect_lchan_rel(RSL); + + /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */ + + f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?)); + + /* SMLC got the TA from the BSC, now responds with geo information data. */ + BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit)); + BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND); + + BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle))); + + /* The lchan is gone, the A-interface conn was created for the LCS only. + * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */ + f_verify_active_A_conn_and_clear(); + + f_sleep(2.0); + f_logp(BSCVTY, "f_tc_lcs_loc_req_for_idle_ms done"); + setverdict(pass); +} +testcase TC_lcs_loc_req_for_idle_ms() 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.sccp_addr_msc := g_bssap[0].sccp_addr_own; + pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer; + + vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars); + vc_conn.done; +} + +private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr { + f_sleep(1.0); + + f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR); + f_bssap_le_register_imsi(g_pars.imsi, omit); + + f_logp(BSCVTY, "f_tc_lcs_loc_req_no_subscriber start"); + + /* provoke an abort by omitting both IMSI and IMEI */ + BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, + valueof(ts_BSSMAP_Perform_Location_Request(omit, + ts_CellId_CGI('262'H, '42'H, 23, 42))))); + BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND); + + /* BSC tells MSC about failure */ + BSSAP.receive(tr_BSSMAP_Perform_Location_Response( + locationEstimate := omit, positioningData := omit, + lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LE_LCS_CAUSE_DATA_MISSING_IN_REQ))); + + /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */ + f_verify_active_A_conn_and_clear(); + + f_sleep(2.0); + f_logp(BSCVTY, "f_tc_lcs_loc_req_no_subscriber done"); + setverdict(pass); +} +testcase TC_lcs_loc_req_no_subscriber() 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.sccp_addr_msc := g_bssap[0].sccp_addr_own; + pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer; + + vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars); + vc_conn.done; +} + +private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr { + f_sleep(1.0); + + f_establish_fully(omit, omit); + f_bssap_le_register_imsi(g_pars.imsi, omit); + + f_logp(BSCVTY, "f_tc_lcs_loc_req_for_active_ms_le_timeout start"); + + BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi), + ts_CellId_CGI('262'H, '42'H, 23, 42)))); + + var PDU_BSSAP_LE plr; + BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr); + + if (do_ta) { + /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */ + BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req)); + f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?)); + } + + /* SMLC fails to respond, BSC runs into timeout */ + BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE)); + BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND); + + BSSAP.receive(tr_BSSMAP_Perform_Location_Response( + locationEstimate := omit, positioningData := omit, + lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE))); + + /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */ + f_verify_active_A_conn_and_clear(); + + f_sleep(2.0); + f_logp(BSCVTY, "f_tc_lcs_loc_req_for_active_ms_le_timeout done"); + setverdict(pass); +} + +private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr { + f_lcs_loc_req_for_active_ms_le_timeout(false); +} + +testcase TC_lcs_loc_req_for_active_ms_le_timeout() 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); + vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars); + vc_conn.done; +} + +private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr { + f_lcs_loc_req_for_active_ms_le_timeout(true); +} + +testcase TC_lcs_loc_req_for_active_ms_le_timeout2() 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); + vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars); + vc_conn.done; +} + +private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr { + f_sleep(1.0); + + f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR); + f_bssap_le_register_imsi(g_pars.imsi, omit); + + /* Register to receive the Paging Command */ + var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH)); + g_chan_nr := new_chan_nr; + f_rslem_register(0, g_chan_nr); + + f_logp(BSCVTY, "f_tc_lcs_loc_req_for_idle_ms_no_pag_resp start"); + BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, + valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi), + ts_CellId_CGI('001'H, '01'H, 1, 0))))); + BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND); + + var PDU_BSSAP_LE plr; + BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr); + + /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */ + BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req)); + + /* OsmoBSC needs to Page */ + var PDU_BSSAP_LE rx_bsslap; + alt { + [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) { + f_logp(BSCVTY, "got Paging Command"); + repeat; + } + [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) { + /* MS does not respond to Paging, TA Req runs into timeout. */ + f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?)); + } + } + + /* SMLC responds with failure */ + BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED)); + BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND); + + /* BSC tells MSC about failure */ + BSSAP.receive(tr_BSSMAP_Perform_Location_Response( + locationEstimate := omit, positioningData := omit, + lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED))); + + /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */ + f_verify_active_A_conn_and_clear(); + + f_sleep(2.0); + f_logp(BSCVTY, "f_tc_lcs_loc_req_for_idle_ms_no_pag_resp done"); + setverdict(pass); +} +testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() 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.sccp_addr_msc := g_bssap[0].sccp_addr_own; + pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer; + + vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars); + vc_conn.done; +} + +private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr { + f_sleep(1.0); + + f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR); + f_bssap_le_register_imsi(g_pars.imsi, omit); + + /* Register to receive the Paging Command */ + var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH)); + g_chan_nr := new_chan_nr; + f_rslem_register(0, g_chan_nr); + + f_logp(BSCVTY, "f_tc_cm_service_during_lcs_loc_req start"); + BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, + valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi), + ts_CellId_CGI('001'H, '01'H, 1, 0))))); + BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND); + + var PDU_BSSAP_LE plr; + BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr); + + /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request + * and establish Layer 3. It should use the existing A-interface conn. */ + f_perform_compl_l3(RSL, valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV(g_pars.imsi)))), + do_clear := false, expect_bssmap_l3 := true); + + /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */ + BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req)); + + /* OsmoBSC already has an lchan, no need to Page, just returns the TA */ + f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?)); + + /* SMLC got the TA from the BSC, now responds with geo information data. */ + BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit)); + BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND); + BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle))); + + /* The lchan should still exist, it was from a CM Service Request. */ + f_verify_active_layer3(); + + f_perform_clear(RSL); + + f_sleep(2.0); + f_logp(BSCVTY, "f_tc_cm_service_during_lcs_loc_req done"); + setverdict(pass); +} +testcase TC_cm_service_during_lcs_loc_req() 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.sccp_addr_msc := g_bssap[0].sccp_addr_own; + pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer; + + vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars); + vc_conn.done; +} + +private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr { + f_sleep(1.0); + + f_establish_fully(omit, omit); + f_bssap_le_register_imsi(g_pars.imsi, omit); + + f_logp(BSCVTY, "f_tc_ho_during_lcs_loc_req start"); + + BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi), + ts_CellId_CGI('262'H, '42'H, 23, 42)))); + + var PDU_BSSAP_LE plr; + BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr); + + /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */ + f_bts_0_cfg(BSCVTY, {"neighbor bts 1"}); + + var HandoverState hs := { + rr_ho_cmpl_seen := false, + handover_done := false, + old_chan_nr := - + }; + /* issue hand-over command on VTY */ + f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1); + /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */ + f_rslem_suspend(RSL1_PROC); + + /* From the MGW perspective, a handover is is characterized by + * performing one MDCX operation with the MGW. So we expect to see + * one more MDCX during handover. */ + g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1; + + alt { + [] as_handover(hs); + } + + var PDU_BSSAP_LE rx_bsslap; + + interleave { + /* Expect the BSC to inform the MSC about the handover */ + [] BSSAP.receive(tr_BSSMAP_HandoverPerformed); + + /* Expect the BSC to inform the SMLC about the handover */ + [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) { + f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO)); + } + } + + /* SMLC now responds with geo information data. */ + BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit)); + BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND); + BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle))); + + /* lchan still active */ + f_verify_active_layer3(RSL1); + + /* MSC decides it is done now. */ + f_perform_clear(RSL1); + + f_sleep(2.0); + f_logp(BSCVTY, "f_tc_ho_during_lcs_loc_req done"); + setverdict(pass); +} +testcase TC_ho_during_lcs_loc_req() runs on test_CT { + var MSC_ConnHdlr vc_conn; + var TestHdlrParams pars := f_gen_test_hdlr_pars(); + + f_init(2, true); + f_sleep(1.0); + vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars); + vc_conn.done; +} + /* Dyn PDCH todo: * activate OSMO as TCH/F * activate OSMO as TCH/H @@ -7750,6 +8279,17 @@ execute( TC_fh_params_assignment_cmd() ); execute( TC_fh_params_handover_cmd() ); execute( TC_fh_params_si4_cbch() ); + + execute( TC_lcs_loc_req_for_active_ms() ); + execute( TC_lcs_loc_req_for_active_ms_ta_req() ); + execute( TC_lcs_loc_req_for_idle_ms() ); + execute( TC_lcs_loc_req_no_subscriber() ); + execute( TC_lcs_loc_req_for_active_ms_le_timeout() ); + execute( TC_lcs_loc_req_for_active_ms_le_timeout2() ); + execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() ); + execute( TC_cm_service_during_lcs_loc_req() ); + execute( TC_ho_during_lcs_loc_req() ); + } } diff --git a/bsc/MSC_ConnectionHandler.ttcn b/bsc/MSC_ConnectionHandler.ttcn index 3e58f5a..5460e2c 100644 --- a/bsc/MSC_ConnectionHandler.ttcn +++ b/bsc/MSC_ConnectionHandler.ttcn @@ -1323,9 +1323,11 @@ * time. When we receive the RSL_RF_CHAN_REL command the media negotiation on * IPACC or MGCP level may be still in progress. In order to make sure that * we do only stop when we have seen an MDCX on MGCP level and another a CRCX - * as well as an MDCX on IPACC level. */ - if (g_media.mgcp_conn[0].mdcx_seen <= st.mdcx_seen_before_ho or - g_media.bts1.ipa_mdcx_seen == false or g_media.bts1.ipa_crcx_seen == false) { + * as well as an MDCX on IPACC level. + * If ipa_crcx_seen is false, this is not a voice channel and we need not check MGCP at all.. */ + if (g_media.bts.ipa_crcx_seen + and (g_media.mgcp_conn[0].mdcx_seen <= st.mdcx_seen_before_ho or + g_media.bts1.ipa_mdcx_seen == false or g_media.bts1.ipa_crcx_seen == false)) { repeat; } else { st.handover_done := true; -- To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/20373 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-ttcn3-hacks Gerrit-Branch: master Gerrit-Change-Id: Id3df9439752c088cff5618d21254af42365690ca Gerrit-Change-Number: 20373 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/20201001/15dcbe04/attachment.htm>