diff options
Diffstat (limited to 'sgsn/SGSN_Tests.ttcn')
-rw-r--r-- | sgsn/SGSN_Tests.ttcn | 1055 |
1 files changed, 930 insertions, 125 deletions
diff --git a/sgsn/SGSN_Tests.ttcn b/sgsn/SGSN_Tests.ttcn index 53ecdff3..9c738342 100644 --- a/sgsn/SGSN_Tests.ttcn +++ b/sgsn/SGSN_Tests.ttcn @@ -31,8 +31,9 @@ import from MobileL3_Types all; import from L3_Templates all; import from L3_Common all; -import from GSUP_Emulation all; import from GSUP_Types all; +import from GSUP_Templates all; +import from GSUP_Emulation all; import from IPA_Emulation all; import from RAN_Adapter all; @@ -41,11 +42,13 @@ import from RANAP_Templates all; import from RANAP_PDU_Descriptions all; import from RANAP_IEs all; -import from GTP_Emulation all; -import from GTP_Templates all; -import from GTP_CodecPort all; +import from GTPv1C_CodecPort all; +import from GTPv1U_CodecPort all; import from GTPC_Types all; import from GTPU_Types all; +import from GTPv1C_Templates all; +import from GTPv1U_Templates all; +import from GTP_Emulation all; import from LLC_Types all; import from LLC_Templates all; @@ -55,8 +58,6 @@ import from SNDCP_Types all; import from TELNETasp_PortType all; import from Osmocom_VTY_Functions all; -import from GSM_RR_Types all; - import from MobileL3_MM_Types all; @@ -64,54 +65,73 @@ modulepar { /* IP/port on which we run our internal GSUP/HLR emulation */ charstring mp_hlr_ip := "127.0.0.1"; integer mp_hlr_port := 4222; - charstring mp_ggsn_ip := "127.0.0.2"; + charstring mp_ggsn_ip := "127.0.0.103"; integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */ + charstring mp_sgsn_gtp_ip := "127.0.0.10"; NSConfigurations mp_nsconfig := { { - provider := { - ip := { - address_family := AF_INET, - local_udp_port := 21010, - local_ip := "127.0.0.1", - remote_udp_port := 23000, - remote_ip := "127.0.0.1" - } - }, - nsvci := 97, nsei := 96, role_sgsn := false, - handle_sns := false + handle_sns := false, + nsvc := { + { + provider := { + ip := { + address_family := AF_INET, + local_udp_port := 21010, + local_ip := "127.0.0.1", + remote_udp_port := 23000, + remote_ip := "127.0.0.1", + data_weight := 1, + signalling_weight := 1 + } + }, + nsvci := 97 + } + } }, { - provider := { - ip := { - address_family := AF_INET, - local_udp_port := 21011, - local_ip := "127.0.0.1", - remote_udp_port := 23000, - remote_ip := "127.0.0.1" - } - }, - nsvci := 98, nsei := 97, role_sgsn := false, - handle_sns := false + handle_sns := false, + nsvc := { + { + provider := { + ip := { + address_family := AF_INET, + local_udp_port := 21011, + local_ip := "127.0.0.1", + remote_udp_port := 23000, + remote_ip := "127.0.0.1", + data_weight := 1, + signalling_weight := 1 + } + }, + nsvci := 98 + } + } }, { - provider := { - ip := { - address_family := AF_INET, - local_udp_port := 21012, - local_ip := "127.0.0.1", - remote_udp_port := 23000, - remote_ip := "127.0.0.1" - } - }, - nsvci := 99, nsei := 98, role_sgsn := false, - handle_sns := false + handle_sns := false, + nsvc := { + { + provider := { + ip := { + address_family := AF_INET, + local_udp_port := 21012, + local_ip := "127.0.0.1", + remote_udp_port := 23000, + remote_ip := "127.0.0.1", + data_weight := 1, + signalling_weight := 1 + } + }, + nsvci := 99 + } + } } }; @@ -159,6 +179,10 @@ type component test_CT { /* only needed at start to get the per-BVC references */ port BSSGP_CT_PROC_PT PROC; + /* used by RIM related test */ + port BSSGP_PT RIM[NUM_GB]; + port GTPEM_PT GTPC; + var GTP_Emulation_CT vc_GTP; port TELNETasp_PT SGSNVTY; @@ -204,6 +228,12 @@ type record BSSGP_ConnHdlrPars { SCCP_PAR_Address sccp_addr_peer optional }; +/* Passed in RAN-INFO message from emulated neighbor using RIM */ +const octetstring si1_default := '198fb100000000000000000000000000007900002b'O; +const octetstring si3_default := '1b753000f110236ec9033c2747407900003c0b2b2b'O; +const octetstring si13_default := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O; +const octetstring si_default := si1_default & si3_default & si13_default; + private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV { /* mcc_mnc is encoded as of 24.008 10.5.5.15 */ var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc; @@ -215,15 +245,21 @@ private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdent mncDigit3 := mcc_mnc[3], mncDigit1 := mcc_mnc[4], mncDigit2 := mcc_mnc[5], - lac := int2oct(cell_id.ra_id.lai.lac, 16), - rac := int2oct(cell_id.ra_id.rac, 8) + lac := int2oct(cell_id.ra_id.lai.lac, 2), + rac := int2oct(cell_id.ra_id.rac, 1) } return ret; }; +private function f_BssgpCellId_to_GTP_CellId(in BssgpCellId cell_id) return GTP_CellId +{ + template (value) GTP_CellId ret := ts_GTP_CellId(cell_id.ra_id, cell_id.cell_id); + return valueof(ret); +} + private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT { - gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset)); - gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset)); + gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset)) alive; + gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset)) alive; /* connect lower end of BSSGP emulation with NS upper port */ connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP); @@ -235,6 +271,8 @@ private function f_init_gb(inout GbInstance gb, charstring id, integer offset) r gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC); disconnect(self:PROC, gb.vc_BSSGP:PROC); } + /* connect RIM related port */ + connect(gb.vc_BSSGP:RIM, self:RIM[offset]); } private function f_init_gsup(charstring id) runs on test_CT { @@ -322,7 +360,8 @@ function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT { }, cell_id := 20960 }, - depth := BSSGP_DECODE_DEPTH_L3 + depth := BSSGP_DECODE_DEPTH_L3, + create_cb := refers(BSSGP_Emulation.DefaultCreateCallback) } } }; @@ -342,11 +381,12 @@ function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT { }, cell_id := 20961 }, - depth := BSSGP_DECODE_DEPTH_L3 + depth := BSSGP_DECODE_DEPTH_L3, + create_cb := refers(BSSGP_Emulation.DefaultCreateCallback) } } }; - g_gb[2].cfg := { + g_gb[2].cfg := { /* [2] configured to have same RAC as [1] */ nsei := 98, sgsn_role := false, bvc := { @@ -356,13 +396,14 @@ function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT { ra_id := { lai := { mcc_mnc := mcc_mnc, - lac := 13300 + lac := 13200 }, rac := 0 }, cell_id := 20962 }, - depth := BSSGP_DECODE_DEPTH_L3 + depth := BSSGP_DECODE_DEPTH_L3, + create_cb := refers(BSSGP_Emulation.DefaultCreateCallback) } } }; @@ -417,6 +458,7 @@ const RanOps RNC_RanOps := { protocol := RAN_PROTOCOL_RANAP, transport := RANAP_TRANSPORT_IuCS, use_osmux := false, + bssap_reset_retries := 1, sccp_addr_local := omit, sccp_addr_peer := omit }; @@ -425,13 +467,13 @@ type function void_fn(charstring id) runs on BSSGP_ConnHdlr; /* helper function to create, connect and start a BSSGP_ConnHdlr component */ function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix, - float t_guard := 30.0) + float t_guard := 30.0, boolean expect_ciph := false) runs on test_CT return BSSGP_ConnHdlr { var BSSGP_ConnHdlr vc_conn; var SGSN_ConnHdlrNetworkPars net_pars := { expect_ptmsi := true, expect_auth := true, - expect_ciph := false + expect_ciph := expect_ciph }; var BSSGP_ConnHdlrPars pars := { imei := f_gen_imei(imsi_suffix), @@ -465,14 +507,17 @@ runs on test_CT return BSSGP_ConnHdlr { connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP); connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG); connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC); + connect(vc_conn:BSSGP_GLOBAL[0], gb[0].vc_BSSGP:GLOBAL); connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP); connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG); connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC); + connect(vc_conn:BSSGP_GLOBAL[1], gb[1].vc_BSSGP:GLOBAL); connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP); connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG); connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC); + connect(vc_conn:BSSGP_GLOBAL[2], gb[2].vc_BSSGP:GLOBAL); /* FIXME: support multiple RNCs */ if (g_ranap_enable) { @@ -569,6 +614,7 @@ function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSS lAC := '1234'O, iE_Extensions := omit }; + var RANAP_IEs.RAC rac := '00'O; var SAI sai := { pLMNidentity := lai.pLMNidentity, lAC := lai.lAC, @@ -581,7 +627,7 @@ function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSS rNC_ID := 2342 /* FIXME */ }; - ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id)); + ranap := valueof(ts_RANAP_initialUE_PS(lai, rac, sai, l3_enc, sigc_id, grnc_id)); BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap)); alt { [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {} @@ -644,6 +690,34 @@ runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS { return l3_mt; } +/* (copied from msc/BSC_ConnectionHandler.ttcn) */ +private altstep as_ciph_utran() runs on BSSGP_ConnHdlr +{ + [g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(uia_algs := ?, + uia_key := oct2bit(g_pars.vec.ik), + key_sts := ?, + uea_algs := ?, + uea_key := oct2bit(g_pars.vec.ck))) { + var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1*/ + var EncryptionAlgorithm uea_chosen := 1; /*standard_UMTS_encryption_algorith_UEA1*/ + BSSAP.send(ts_RANAP_SecurityModeCompleteEnc(uia_chosen, uea_chosen)); + } + [g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(?,?,?,?,?)) { + setverdict(fail, "Invalid SecurityModeCommand (ciphering case)"); + mtc.stop; + } + [not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, + uia_key := oct2bit(g_pars.vec.ik), + key_sts := ?)) { + var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1;*/ + BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen)); + } + [not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(?,?,?)) { + setverdict(fail, "Invalid SecurityModeCommand (non-ciphering case)"); + mtc.stop; + } +} + /* perform GMM authentication (if expected). * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */ @@ -687,7 +761,7 @@ function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn; l3_mt := f_receive_l3(auth_ciph_req, ran_index); var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField; - var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres); + var template (value) PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres); if (umts_aka_challenge and not force_gsm_sres) { /* set UMTS response instead */ @@ -711,12 +785,8 @@ function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres /* Security Mode Command + Complete on Iu case */ if (is_iu(ran_index)) { - BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik), - key_sts := ?)) { - var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */ - BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen)); - BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi))) - } + as_ciph_utran(); + BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi))); } } else { /* wait for identity procedure */ @@ -736,12 +806,14 @@ function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP } } -function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr { +function f_process_attach_accept(PDU_GMM_AttachAccept aa, integer ran_index := 0) runs on BSSGP_ConnHdlr { /* mandatory IE */ var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification); + /* we cannot use ran_index here, as it would overflow the cell_id object, since ran_idx > NUM_GB + * indicates an Iu RAN connection. All cells are expected to run the same MCC/MNC anyway... */ if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) { setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn) - & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc)); + & "; expected " & hex2str(g_pars.bssgp_cell_id[ran_index].ra_id.lai.mcc_mnc)); mtc.stop; } g_pars.ra := aa.routingAreaIdentification; @@ -750,7 +822,8 @@ function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr setverdict(fail, "unexpected P-TMSI allocation"); mtc.stop; } - f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets); + f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, + ran_index); } if (ispresent(aa.msIdentity)) { setverdict(fail, "unexpected TMSI allocation in non-combined attach"); @@ -773,7 +846,8 @@ function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_in setverdict(fail, "unexpected P-TMSI allocation"); mtc.stop; } - f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index); + f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, + ran_index); } if (ispresent(ra.msIdentity)) { setverdict(fail, "unexpected TMSI allocation in non-combined attach"); @@ -802,22 +876,29 @@ private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV { } } -private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr { - var GSUP_PDU gsup; - /* Expect MSC to perform LU with HLR */ - GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)); - gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn)); - gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) }; - GSUP.send(gsup); - GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi)); - GSUP.send(ts_GSUP_UL_RES(g_pars.imsi)); +private altstep as_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr { + [] GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) { + var GSUP_PDU gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn)); + gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo('00'O, char2oct("*"), ts_EuaIPv4Dyn, ''O)) }; + GSUP.send(gsup); + GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi)); + GSUP.send(ts_GSUP_UL_RES(g_pars.imsi)); + } } -friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0) runs on BSSGP_ConnHdlr { - var RoutingAreaIdentificationV old_ra := f_random_RAI(); - var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit); +friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0, + template (omit) RoutingAreaIdentificationV old_ra := omit) runs on BSSGP_ConnHdlr { + var RoutingAreaIdentificationV old_ra_val; + var template (value) PDU_L3_MS_SGSN attach_req; var PDU_L3_SGSN_MS l3_mt; + if (istemplatekind(old_ra, "omit")) { + old_ra_val := f_random_RAI(); + } else { + old_ra_val := valueof(old_ra); + } + + attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra_val, false, false, omit, omit); /* indicate R99 capability of the MS to enable UMTS AKA in presence of * 3G auth vectors */ attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B; @@ -828,10 +909,10 @@ friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, f_send_l3(attach_req, ran_index); f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index); /* Expect SGSN to perform LU with HLR */ - f_gmm_gsup_lu_isd(); + as_gmm_gsup_lu_isd(); l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index); - f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept); + f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept, ran_index); /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */ f_send_l3(ts_GMM_ATTACH_COMPL, ran_index); @@ -853,13 +934,13 @@ friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 { timer T := 5.0; var PDU_BSSGP rx_pdu; - BSSGP_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id)); + BSSGP_GLOBAL[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id)); T.start; alt { - [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu { + [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu { return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value; } - [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu { + [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu { setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli); mtc.stop; } @@ -873,11 +954,11 @@ friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr ret friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr { timer T := 5.0; - BSSGP_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref)); + BSSGP_GLOBAL[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref)); T.start; alt { - [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id)); - [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, + [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id)); + [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) { setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli); mtc.stop; @@ -939,6 +1020,78 @@ testcase TC_attach_umts_aka_gsm_sres() runs on test_CT { f_cleanup(); } +/* Let T3350 expire while the MS holds an active PDP context (OS#4221). Do this by + * Establishing a PDP context and then resending an ATTACH REQUEST, + * making sure that exactly five ATTACH ACCEPTS are sent */ +private function f_TC_attach_timeout_after_pdp_act(charstring id) runs on BSSGP_ConnHdlr { + var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip)); + /* Vars needed for triggering T3350 timeouts */ + const integer ran_index := 0; + /* See TS 24.008 Rel. 16 Sect. 4.7.3.1.6 c) */ + const integer gmm_attach_repeats := 5; + /* See TS 24.008 Rel. 16 Table 11.4 */ + const float T3350 := 6.0; + var template (value) PDU_L3_MS_SGSN attach_req; + timer t_receive_GMM_ATTACH_ACCEPT; + var RoutingAreaIdentificationV rai := f_random_RAI(); + timer T; + + /* First establish PDP context */ + f_TC_attach(id); + f_pdp_ctx_act(apars); + + /* Now, try another GPRS attach procedure. Note that osmo-sgsn does not require + * authentication for the second GMM ATTACH REQUEST, so we expect GSUP UPDATE + * LOCATION REQUEST and optionally a GMM IDENTITY REQUEST (IMEI). */ + attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), rai, false, false, omit, omit); + f_send_l3(attach_req, ran_index); + + T.start(1.0); + alt { + [] as_gmm_gsup_lu_isd(); + [] as_mm_identity(ran_index); + [] as_xid(apars, ran_index); + [] T.timeout { + setverdict(fail, "Timeout waiting for GSUP UPDATE LOCATION REQUEST"); + return; + } + } + + BSSGP[ran_index].clear; + log("Trying to receive ", gmm_attach_repeats, " ATTACH ACCEPTs"); + for (var integer i := 1; i <= gmm_attach_repeats; i := i+1) { + t_receive_GMM_ATTACH_ACCEPT.start(T3350 + 0.5); + alt { + [] BSSGP[ran_index].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) { + t_receive_GMM_ATTACH_ACCEPT.stop; + } + [] t_receive_GMM_ATTACH_ACCEPT.timeout { + setverdict(fail, "Timeout on receiving ", i, "th ATTACH ACCEPT") + } + } + } + log("Have received ", gmm_attach_repeats, " ATTACH ACCEPT messages"); + log("Make sure not more than ", gmm_attach_repeats, " ATTACH ACCEPT messages are sent"); + t_receive_GMM_ATTACH_ACCEPT.start(T3350 + 0.5); + alt { + [] BSSGP[ran_index].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) { + setverdict(fail, "Received ", gmm_attach_repeats + 1, "th ATTACH ACCEPT") + } + [] t_receive_GMM_ATTACH_ACCEPT.timeout { } + } + + setverdict(pass); +} + +testcase TC_attach_timeout_after_pdp_act() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + vc_conn := f_start_handler(refers(f_TC_attach_timeout_after_pdp_act), + testcasename(), g_gb, 21, t_guard := 45.0); + vc_conn.done; + f_cleanup(); +} + /* MS never responds to ID REQ, expect ATTACH REJECT */ private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr { var RoutingAreaIdentificationV old_ra := f_random_RAI(); @@ -1079,7 +1232,7 @@ private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr { f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit)); f_gmm_auth(); /* Expect MSC to perform LU with HLR */ - f_gmm_gsup_lu_isd(); + as_gmm_gsup_lu_isd(); BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt { f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept); @@ -1400,12 +1553,13 @@ function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, runs on BSSGP_ConnHdlr { var Gtp1cUnitdata g_ud; var integer seq_nr := 23; - var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c)); BSSGP[ran_index].clear; if (error_ind) { + var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_c)); GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u)); } else { + var Gtp1cPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c)); GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B)); } @@ -1500,20 +1654,20 @@ template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := { sgsn_ip_u := omit } -template (value) GtpPeer ts_GtpPeerU(octetstring ip) := { +template (value) Gtp1uPeer ts_GtpPeerU(octetstring ip) := { connId := 1, remName := f_inet_ntoa(ip), remPort := GTP1U_PORT } -template (value) GtpPeer ts_GtpPeerC(octetstring ip) := { +template (value) Gtp1cPeer ts_GtpPeerC(octetstring ip) := { connId := 1, remName := f_inet_ntoa(ip), remPort := GTP1C_PORT } private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr { - var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u)); + var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u)); GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload)); } @@ -1581,12 +1735,12 @@ runs on BSSGP_ConnHdlr { } /* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */ -private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0) +private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0, uint9_t n_u := 0) runs on BSSGP_ConnHdlr { /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */ - var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u)); + var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u)); var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload)); - BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0)); + BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, n_u)); /* Expect PDU via GTP from SGSN on simulated GGSN */ alt { [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload)); @@ -1899,7 +2053,6 @@ private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_Con var Gtp1cUnitdata g_ud; var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip)); var integer seq_nr := 23; - var GtpPeer peer; /* first perform regular attach */ f_TC_attach(id); @@ -1939,7 +2092,7 @@ testcase TC_attach_restart_ctr_create() runs on test_CT { private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr { var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip)); var integer seq_nr := 23; - var GtpPeer peer; + var Gtp1cPeer peer; var integer i; /* first perform regular attach */ @@ -2043,7 +2196,7 @@ private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */ BSSGP[0].clear; - var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c)); + var Gtp1cPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c)); g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B); GTP.send(g_delete_req); alt { @@ -2442,7 +2595,7 @@ private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit)); f_gmm_auth(); /* Expect SGSN to perform LU with HLR */ - f_gmm_gsup_lu_isd(); + as_gmm_gsup_lu_isd(); timer T := 10.0; T.start; @@ -2478,46 +2631,67 @@ testcase TC_attach_check_complete_resend() runs on test_CT { f_cleanup(); } -friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr { +friend altstep as_routing_area_update_gb(integer ran_index := 0) runs on BSSGP_ConnHdlr { var PDU_L3_SGSN_MS l3_mt; - var PDU_DTAP_PS_MT mt; - var template OCT4 p_tmsi := omit; - if (is_iu(ran_index)) { - p_tmsi := g_pars.p_tmsi; - } - /* then send RAU */ - f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit, p_tmsi), ran_index); - alt { - [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt { + [] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt { f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index); f_send_l3(ts_GMM_RAU_COMPL, ran_index); setverdict(pass); } - [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt { + [] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) { + setverdict(fail, "Unexpected RAU Reject"); + mtc.stop; + } +} +friend altstep as_routing_area_update_iu(integer ran_index := 0) runs on BSSGP_ConnHdlr { + var PDU_DTAP_PS_MT mt; + + [] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt { f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index); f_send_l3(ts_GMM_RAU_COMPL, ran_index); setverdict(pass); } - - [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) { - setverdict(fail, "Unexpected RAU Reject"); - mtc.stop; - } - [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) { + [] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) { setverdict(fail, "Unexpected RAU Reject"); mtc.stop; } + [] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, + uia_key := oct2bit(g_pars.vec.ik), + key_sts := ?)) { + var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */ + BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen)); + BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi))) + repeat; + } +} +friend altstep as_routing_area_update(integer ran_index := 0) runs on BSSGP_ConnHdlr { + [is_gb(ran_index)] as_routing_area_update_gb(ran_index); + [is_iu(ran_index)] as_routing_area_update_iu(ran_index); +} - [is_iu(ran_index)] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik), - key_sts := ?)) { - var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */ - BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen)); - BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi))) - repeat; - } +friend function f_routing_area_update(RoutingAreaIdentificationV old_ra, + GprsUpdateType upd_type := GPRS_UPD_T_RA, + integer ran_index := 0, + float Tval := 2.0) runs on BSSGP_ConnHdlr { + var template (omit) OCT4 p_tmsi := omit; + timer T := Tval; + + if (is_iu(ran_index)) { + p_tmsi := g_pars.p_tmsi; + } + + f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), upd_type, old_ra, p_tmsi := p_tmsi), ran_index); + + T.start; + alt { + [] as_routing_area_update(ran_index) { setverdict(pass); } [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; } [is_iu(ran_index)] BSSAP.receive { repeat; } + [] T.timeout { + setverdict(fail, "Timeout completing the RAU procedure"); + mtc.stop; + } } } @@ -2554,14 +2728,14 @@ private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr { f_TC_attach(id); log("attach complete sending rau"); - f_routing_area_update(g_pars.ra, 0); + f_routing_area_update(g_pars.ra); log("rau complete unregistering"); f_bssgp_client_unregister(g_pars.imsi); f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]); log("sending second RAU via different RA"); - f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1); + f_routing_area_update(old_ra := g_pars.ra, ran_index := 1); f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1); } @@ -2658,7 +2832,7 @@ testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT { private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr { var RoutingAreaIdentificationV old_ra := f_random_RAI(); - var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit); + var template (value) PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit); /* send Attach Request */ /* indicate R99 capability of the MS to enable UMTS AKA in presence of @@ -2730,7 +2904,7 @@ private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr { auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn; BSSGP[0].receive(auth_ciph_req) -> value l3_mt; var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField; - var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres); + var template (value) PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres); auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres); auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := { valueField := substr(g_pars.vec.res, 0, 4) @@ -2750,7 +2924,7 @@ private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr { deactivate(di); /* Expect SGSN to perform LU with HLR */ - f_gmm_gsup_lu_isd(); + as_gmm_gsup_lu_isd(); BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt { f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept); @@ -2784,6 +2958,123 @@ testcase TC_attach_usim_resync() runs on test_CT { f_cleanup(); } +private function f_TC_attach_usim_crypt(OCT1 netcap_a2345, BIT3 auth_req_ciph) runs on BSSGP_ConnHdlr { + var RoutingAreaIdentificationV old_ra := f_random_RAI(); + + var template (value) PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit); + attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.spare_octets := netcap_a2345; /* GEA2345... */ + + /* send Attach Request */ + /* indicate R99 capability of the MS to enable UMTS AKA in presence of + * 3G auth vectors */ + attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B; + /* The thing is, if the solSACapability is 'omit', then the + * revisionLevelIndicatior is at the wrong place! */ + attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B; + f_send_l3(attach_req); + + /* do the auth */ + var PDU_L3_MS_SGSN l3_mo; + var PDU_L3_SGSN_MS l3_mt; + var default di := activate(as_mm_identity()); + + var GSUP_IE auth_tuple; + var template AuthenticationParameterAUTNTLV autn; + + g_pars.vec := f_gen_auth_vec_3g(); + autn := { + elementIdentifier := '28'O, + lengthIndicator := lengthof(g_pars.vec.autn), + autnValue := g_pars.vec.autn + }; + auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand, + g_pars.vec.sres, + g_pars.vec.kc, + g_pars.vec.ik, + g_pars.vec.ck, + g_pars.vec.autn, + g_pars.vec.res)); + log("GSUP sends 2G and 3G auth tuples", auth_tuple); + GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); + GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple)); + + var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand, auth_req_ciph); + auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn; + BSSGP[0].receive(auth_ciph_req) -> value l3_mt; + + setverdict(pass); + deactivate(di); +} + +private function f_TC_attach_usim_a54_a54(charstring id) runs on BSSGP_ConnHdlr { + f_TC_attach_usim_crypt('10'O, '100'B); +} + +private function f_TC_attach_usim_a54_a53(charstring id) runs on BSSGP_ConnHdlr { + f_TC_attach_usim_crypt('20'O, '011'B); +} + +private function f_TC_attach_usim_a53_a54(charstring id) runs on BSSGP_ConnHdlr { + f_TC_attach_usim_crypt('30'O, '011'B); +} + +private function f_TC_attach_usim_a50_a54(charstring id) runs on BSSGP_ConnHdlr { + f_TC_attach_usim_crypt('30'O, '000'B); +} + +private function f_TC_attach_usim_a54_a50(charstring id) runs on BSSGP_ConnHdlr { + f_TC_attach_usim_crypt('00'O, '000'B); +} + +testcase TC_attach_usim_a54_a54() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + f_sleep(1.0); + f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4"); + vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a54), testcasename(), g_gb, 40); + vc_conn.done; + f_cleanup(); +} + +testcase TC_attach_usim_a54_a53() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + f_sleep(1.0); + f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4"); + vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a53), testcasename(), g_gb, 40); + vc_conn.done; + f_cleanup(); +} + +testcase TC_attach_usim_a53_a54() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + f_sleep(1.0); + f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3"); + vc_conn := f_start_handler(refers(f_TC_attach_usim_a53_a54), testcasename(), g_gb, 40); + vc_conn.done; + f_cleanup(); +} + +testcase TC_attach_usim_a50_a54() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + f_sleep(1.0); + f_vty_config(SGSNVTY, "sgsn", "encryption gea 0"); + vc_conn := f_start_handler(refers(f_TC_attach_usim_a50_a54), testcasename(), g_gb, 40); + vc_conn.done; + f_cleanup(); +} + +testcase TC_attach_usim_a54_a50() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + f_sleep(1.0); + f_vty_config(SGSNVTY, "sgsn", "encryption gea 0 3 4"); + vc_conn := f_start_handler(refers(f_TC_attach_usim_a54_a50), testcasename(), g_gb, 40); + vc_conn.done; + f_cleanup(); +} /* Send LLC NULL to see if the SGSN survives it (OS#3952) */ private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr { @@ -2926,7 +3217,7 @@ private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_C var RoutingAreaIdentificationV old_ra := f_random_RAI(); var RoutingAreaIdentificationV new_ra := f_random_RAI(); while (old_ra == new_ra) { new_ra := f_random_RAI(); }; - var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit); + var template (value) PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit); var PDU_L3_SGSN_MS l3_mt; f_send_l3(attach_req, 0); @@ -3064,6 +3355,9 @@ private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr { /* perform RAU (implicit RESUME) */ f_routing_area_update(g_pars.ra); + /* give SGSN some time to actually receve + process the RAU Complete we sent */ + f_sleep(0.5); + /* now data should be flowing again */ f_gtpu_xceive_mt(apars, f_rnd_octstring(100)); @@ -3112,15 +3406,510 @@ testcase TC_paging_ps() runs on test_CT { f_cleanup(); } +/* Run a RIM single report procedure over the sgsn. Since the SGSN will only do a transparent routing of the + * RIM messages this basically tests if the message is correctly transfered from one GB interface to the + * other and vice versa. */ +testcase TC_bssgp_rim_single_report() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + + timer T := 2.0; + + var template RIM_Routing_Address dst_addr; + var template RIM_Routing_Address src_addr; + var template (value) RAN_Information_Request_RIM_Container req_cont; + var template (value) RAN_Information_RIM_Container res_cont; + var template (value) PDU_BSSGP bssgp_rim_pdu; + var template PDU_BSSGP bssgp_rim_pdu_expect; + + dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id); + src_addr := t_RIM_Routing_Address_cid(g_gb[0].cfg.bvc[0].cell_id); + + + /* Send NACC Ran information request to SGSN at GB interface #0. We epect the SGSN to forward this request + * based on the cell id in dst_addr to GB interface #1. */ + req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC), + ts_RIM_Sequence_Number(1), + ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP), + ts_RIM_Protocol_Version_Number(1), + tsu_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id), + omit); + bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr), + ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr), + req_cont); + bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr), + tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr), + tr_RAN_Information_Request_RIM_Container); + RIM[0].send(bssgp_rim_pdu); + T.start; + alt { + [] RIM[1].receive(bssgp_rim_pdu_expect) { + setverdict(pass); + } + [] RIM[1].receive { + setverdict(fail, "Unexpected BSSGP RIM PDU received"); + } + [] T.timeout { + setverdict(fail, "No BSSGP RIM PDU received"); + mtc.stop; + } + } + + /* Now also emulate also the response as well and send it back on GB interface #1. Expect the result on + * GB interface #0 */ + res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC), + ts_RIM_Sequence_Number(2), + ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP), + ts_RIM_Protocol_Version_Number(1), + tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[0].cfg.bvc[0].cell_id, false, 3, si_default)), + omit); + bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr), + ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr), + res_cont); + bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr), + tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr), + ?); + RIM[1].send(bssgp_rim_pdu); + T.start; + alt { + [] RIM[0].receive(bssgp_rim_pdu_expect) { + setverdict(pass); + } + [] RIM[0].receive { + setverdict(fail, "Unexpected BSSGP RIM PDU received"); + } + [] T.timeout { + setverdict(fail, "No BSSGP RIM PDU received"); + mtc.stop; + } + } + + f_cleanup(); +} + +testcase TC_rim_eutran_to_geran() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + /* connect RIM related port */ + connect(vc_GTP:CLIENT_DEFAULT, self:GTPC); + + var Gtp1cPeer peer := { + connId := 1, + remName := mp_sgsn_gtp_ip, + remPort := GTP1C_PORT + } + var GTP_CellId gtp_ci := f_BssgpCellId_to_GTP_CellId(g_gb[1].cfg.bvc[0].cell_id); + + var template (value) RIM_Routing_Address_GTPC gtpc_dst_addr, gtpc_src_addr; + var template (value) RAN_Information_Request_RIM_Container_GTPC gtpc_rim_req_cont; + var template (value) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_bssgp_cont; + var template (value) RIM_RoutingAddress gtpc_rim_ra; + var template (value) RIM_RoutingAddress_Discriminator gtpc_rim_ra_discr; + var template (value) Gtp1cUnitdata gtpc_pdu; + + gtpc_dst_addr := t_GTPC_RIM_Routing_Address_cid(gtp_ci); + gtpc_src_addr := t_GTPC_RIM_Routing_Address_enbid(gtp_ci, tac := 3, gnbid := '12345678123456'O); + + gtpc_rim_req_cont := ts_GTPC_RAN_Information_Request_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC), + ts_GTPC_RIM_Sequence_Number(1), + ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP), + ts_GTPC_RIM_Protocol_Version_Number(1), + tsu_GTPC_RAN_Information_Request_Application_Container_NACC(gtp_ci), + omit); + gtpc_bssgp_cont := ts_GTPC_RAN_Information_Request(ts_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr), + ts_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr), + gtpc_rim_req_cont); + + /* Assemble RIM Routing Address (essentially a copy of the destination cell identifier)*/ + gtpc_rim_ra := ts_RIM_RoutingAddress(enc_RIM_Routing_Address_GTPC(valueof(gtpc_dst_addr))); + gtpc_rim_ra_discr := ts_RIM_RoutingAddress_Discriminator(hex2bit(RIM_ADDR_GERAN_CELL_ID)); + gtpc_pdu := ts_GTPC_RANInfoRelay(peer, ts_RANTransparentContainer_RAN_INFO_REQ(gtpc_bssgp_cont), + gtpc_rim_ra, gtpc_rim_ra_discr); + GTPC.send(gtpc_pdu); + + var template RIM_Routing_Address bssgp_dst_addr, bssgp_src_addr; + var template PDU_BSSGP bssgp_rim_pdu_expect; + bssgp_dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id); + bssgp_src_addr := t_RIM_Routing_Address_enbid(g_gb[1].cfg.bvc[0].cell_id, tac := 3, gnbid := '12345678123456'O); + bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr), + tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr), + tr_RAN_Information_Request_RIM_Container); + timer T := 2.0; + T.start; + alt { + [] RIM[1].receive(bssgp_rim_pdu_expect) { + setverdict(pass); + T.stop; + } + [] RIM[1].receive { + setverdict(fail, "Unexpected BSSGP RIM PDU received"); + } + [] T.timeout { + setverdict(fail, "No BSSGP RIM PDU received"); + mtc.stop; + } + } + + /* Now also emulate also the response as well and send it back on GB + interface #1. Expect the result on * GTPC */ + var template (value) RAN_Information_RIM_Container res_cont; + var template (value) PDU_BSSGP bssgp_rim_pdu; + res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC), + ts_RIM_Sequence_Number(2), + ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP), + ts_RIM_Protocol_Version_Number(1), + tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[1].cfg.bvc[0].cell_id, false, 3, si_default)), + omit); + bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr), + ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr), + res_cont); + RIM[1].send(bssgp_rim_pdu); + + var template RAN_Information_RIM_Container_GTPC rim_cont; + var template PDU_BSSGP_RAN_INFORMATION_GTPC gtpc_bssgp_cont_ack; + var template Gtp1cUnitdata gtpc_pdu_exp; + rim_cont := tr_GTPC_RAN_Information_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC), + ts_GTPC_RIM_Sequence_Number(2), + ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP), + ts_GTPC_RIM_Protocol_Version_Number(1), + tru_GTPC_ApplContainer_or_ApplErrContainer_NACC(tru_GTPC_ApplContainer_NACC(gtp_ci, false, 3, si_default)), + omit); + gtpc_bssgp_cont_ack := tr_GTPC_RAN_Information(tr_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr), + tr_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr), + rim_cont); + gtpc_pdu_exp := tr_GTPC_RANInfoRelay(peer, tr_RANTransparentContainer_RAN_INFO(gtpc_bssgp_cont_ack)); + + T.start; + alt { + [] GTPC.receive(gtpc_pdu_exp) { + setverdict(pass); + T.stop; + } + [] GTPC.receive { + setverdict(fail, "Unexpected GTPC RIM PDU received"); + } + [] T.timeout { + setverdict(fail, "No GTPC RIM PDU received"); + mtc.stop; + } + } + + f_cleanup(); +} + +/* Test if the SGSN routes traffic to new cell after the MS attached to it */ +private function f_TC_cell_change_different_rai_ci_attach(charstring id) runs on BSSGP_ConnHdlr { + var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip)); + + /* first perform regular attach */ + f_gmm_attach(false, false, ran_index := 0); + /* then activate PDP context */ + f_pdp_ctx_act(apars, ran_index := 0); + /* then transceive a downlink PDU */ + f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0); + f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0); + + /* Now attach on different cell: */ + f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]); + f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]); + g_pars.net.expect_auth := false; + f_gmm_attach(false, false, ran_index := 1, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[0])); + f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1); + f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1, n_u := 1); +} +testcase TC_cell_change_different_rai_ci_attach() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_attach), testcasename(), g_gb, 68); + vc_conn.done; + f_cleanup(); +} + +/* Test if the SGSN routes traffic to new cell after the MS attached to it */ +/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */ +private function f_TC_cell_change_different_ci_attach(charstring id) runs on BSSGP_ConnHdlr { + var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip)); + + f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]); + f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]); + + /* first perform regular attach */ + f_gmm_attach(false, false, ran_index := 1); + /* then activate PDP context */ + f_pdp_ctx_act(apars, ran_index := 1); + /* then transceive a downlink PDU */ + f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1); + f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1); + + /* Now attach on different cell: */ + f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]); + f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]); + g_pars.net.expect_auth := false; + f_gmm_attach(false, false, ran_index := 2, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[1])); + f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2); + f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1); +} +testcase TC_cell_change_different_ci_attach() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_attach), testcasename(), g_gb, 69); + vc_conn.done; + f_cleanup(); +} + +/* Test if the SGSN silently drops MO data message coming from new BVCI if RAC changed (eg. cell change) */ +private function f_TC_cell_change_different_rai_ci_data(charstring id) runs on BSSGP_ConnHdlr { + var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip)); + + /* first perform regular attach */ + f_gmm_attach(false, false, ran_index := 0); + /* then activate PDP context */ + f_pdp_ctx_act(apars, ran_index := 0); + /* then transceive a downlink PDU */ + f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0); + f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0); + + /* Send some data over new bvci, it should be silently discarded since + * RAC changed and SGSN expects a RAU to occur in that case */ + f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]); + var octetstring payload := f_rnd_octstring(200); + var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload)); + BSSGP[1].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 1)); + var Gtp1uPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u)); + timer T := 2.0; + T.start; + alt { + [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload)) { + setverdict(fail, "Unexpected GTP message"); + } + [] T.timeout { setverdict(pass); } + } + + /* Expect SGSN to continue routing DL data to last known NSEI+BVCI */ + f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]); + f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0); +} +testcase TC_cell_change_different_rai_ci_data() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_data), testcasename(), g_gb, 70); + vc_conn.done; + f_cleanup(); +} + +/* Test if the SGSN routes traffic to new cell after the MS switched cell without re-attaching */ +/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */ +private function f_TC_cell_change_different_ci_data(charstring id) runs on BSSGP_ConnHdlr { + var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip)); + + f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]); + f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]); + + /* first perform regular attach */ + f_gmm_attach(false, false, ran_index := 1); + /* then activate PDP context */ + f_pdp_ctx_act(apars, ran_index := 1); + /* then transceive a downlink PDU */ + f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1); + f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1); + + /* Now attach on different cell: */ + f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]); + f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]); + + f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1); + f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2); +} +testcase TC_cell_change_different_ci_data() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_data), testcasename(), g_gb, 71); + vc_conn.done; + f_cleanup(); +} + +/* SGSN terminated SGSN Context Request procedure (we request, SGSN responds) + * 3GPP TS 23.401, Figure D.3.6-1: "Gn/Gp SGSN to MME Tracking Area Update procedure" */ +private function f_TC_sgsn_context_req_in(charstring id) runs on BSSGP_ConnHdlr { + var integer seq_nr := f_rnd_int(65535); + var Gtp1cUnitdata gtpc_ud; + timer T; + + var Gtp1cPeer peer := { + connId := 1, + remName := mp_sgsn_gtp_ip, + remPort := GTP1C_PORT + } + + /* The MS attaches to GERAN/UTRAN and enjoys the service */ + f_gmm_attach(false, false); + + /* The MS switches to an LTE cell and performs Tracking Area Update Request there. + * The MME requests information about the MS by sending SGSN Context Request. */ + var template (value) GTPC_PDUs ctx_req; + ctx_req := ts_SGSNContextReqPDU(rai := ts_RoutingAreaIdentity('250'H, 'F99'H, '4242'O, 'DE'O), + teic := '12345678'O, + sgsn_addr_control := f_inet_addr(mp_ggsn_ip), + ptmsi := ts_PTMSI(g_pars.p_tmsi), + ptmsi_sig := ts_PTMSI_sig('010203'O)); + GTP.send(ts_GTPC_SGSNContextReq(peer, seq_nr, ctx_req)); + + /* The SGSN responds with subscriber's IMSI */ + var template (present) GTPC_PDUs ctx_rsp; + ctx_rsp := tr_SGSNContextRespPDU(cause := GTP_CAUSE_REQUEST_ACCEPTED, + imsi := g_pars.imsi); + + /* SGSN Address for Control Plane */ + var octetstring sgsn_addr := f_inet_addr(mp_sgsn_gtp_ip); + ctx_rsp.sgsn_ContextResponse.sgsn_addr_controlPlane := tr_GsnAddr(sgsn_addr); + + /* Match MM Context */ + if (ispresent(g_pars.vec)) { + /* XXX: this is only valid for GERAN */ + var octetstring triplet := g_pars.vec.rand & g_pars.vec.sres & g_pars.vec.kc; + ctx_rsp.sgsn_ContextResponse.mm_Context := tr_MM_ContextGSM(kc := g_pars.vec.kc, + triplet := triplet); + /* TODO: 7.5.4 "The IMEISV shall, if available, be included in the MM Context". + * See also 3GPP TS 29.060, section 7.7.28 and Table 47A */ + } + + /* TODO: match PDP Context */ + + T.start(2.0); + alt { + [] GTP.receive(tr_GTPC_SGSNContextResp(?, ?, ctx_rsp)) -> value gtpc_ud { + log("Rx SGSN Context Resp from SGSN, sending Ack"); + GTP.send(ts_GTPC_SGSNContextAck(gtpc_ud.peer, '12345678'O, seq_nr)); + setverdict(pass); + } + [] GTP.receive(tr_GTPC_SGSNContextResp) -> value gtpc_ud { + GTP.send(ts_GTPC_SGSNContextAck(gtpc_ud.peer, '12345678'O, seq_nr, + ts_SGSNContextAckPDU(GTP_CAUSE_INVALID_MSG_FORMAT))); + setverdict(fail, "Rx unexpected SGSN Context Resp"); + } + [] T.timeout { + setverdict(fail, "Timeout waiting for SGSN Context Resp"); + } + } + /* HLR/HSS tells SGSN to forget this MS/UE */ + GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE)); + GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi)); +} +testcase TC_sgsn_context_req_in() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + f_sleep(1.0); + vc_conn := f_start_handler(refers(f_TC_sgsn_context_req_in), testcasename(), g_gb, 72); + vc_conn.done; + f_cleanup(); +} +/* SGSN originated SGSN Context Request procedure (SGSN requests, we respond) + * 3GPP TS 23.401, Figure D.3.5-1 "Routing Area Update procedure" */ +private function f_TC_sgsn_context_req_out(charstring id) runs on BSSGP_ConnHdlr { + var integer seq_nr := f_rnd_int(65535); + var Gtp1cUnitdata gtpc_ud; + timer T; + /* The MS goes to GERAN/UTRAN from an LTE cell */ + f_send_l3(ts_GMM_RAU_REQ(mi_lv := valueof(ts_MI_TMSI_LV('DE42DE42'O)), + upd_type := GPRS_UPD_T_RA, + old_ra := f_random_RAI()), 0); + + + /* The SGSN has no idea about the MS and inquires the MME about it */ + T.start(2.0); + alt { + [] GTP.receive(tr_GTPC_SGSNContextReq(?, ?)) -> value gtpc_ud { + log("Rx SGSN Context Req from SGSN"); + setverdict(pass); + T.stop; + } + [] GTP.receive(tr_GTPC_SGSNContextResp) { + setverdict(fail, "Rx unexpected SGSN Context Req"); + mtc.stop; + } + [] BSSGP[0].receive(tr_LLC_XID_MT_CMD(?, ?)) { + /* Ignore XID Reset */ + repeat; + } + [] BSSGP[0].receive(tr_GMM_RAU_REJECT) { + /* osmo-sgsn -latest would send RAU Reject (Implicitly detached) */ + setverdict(fail, "Rx unexpected RAU Reject"); + mtc.stop; + } + [] T.timeout { + setverdict(fail, "Timeout waiting for SGSN Context Req"); + mtc.stop; + } + } + + /* The MME responds */ + var OCT8 kc := f_rnd_octstring(8); + + var template (value) PDP_Context_GTPC pdp_ctx; + pdp_ctx := ts_PDP_Context_GTPC(pdp_addr := f_inet_addr("10.10.10.10"), + ggsn_gsn_addr := f_inet_addr(mp_ggsn_ip), + apn := '08696E7465726E6574'O); + + var template (value) GTPC_PDUs ctx_rsp; + ctx_rsp := ts_SGSNContextRespPDU(cause := GTP_CAUSE_REQUEST_ACCEPTED, + imsi := g_pars.imsi, + teic := '12345678'O, + mm_context := ts_MM_ContextGSM(kc), + pdp_ctx_list := { pdp_ctx }); + GTP.send(ts_GTPC_SGSNContextResp(gtpc_ud.peer, '12345678'O, seq_nr, ctx_rsp)); + + /* TODO: Security Functions (auth/ciphering?) */ + + /* The SGSN ACKs */ + T.start(2.0); + alt { + [] GTP.receive(tr_GTPC_SGSNContextAck) -> value gtpc_ud { + log("Rx SGSN Context ACK from SGSN"); + setverdict(pass); + T.stop; + } + [] T.timeout { + setverdict(fail, "Timeout waiting for SGSN Contect ACK"); + mtc.stop; + } + } + + /* TODO: Update PDP Context Req/Resp */ + /* TODO: 7..10 Update Location, ISD */ + + /* RAU procedure completion */ + T.start(2.0); + alt { + [] as_routing_area_update_gb(0) { + log("RAU procedure completed"); + setverdict(pass); + T.stop; + } + [] BSSGP[0].receive { repeat; } + [] T.timeout { + setverdict(fail, "Timeout completing the RAU procedure"); + mtc.stop; + } + } +} +testcase TC_sgsn_context_req_out() runs on test_CT { + var BSSGP_ConnHdlr vc_conn; + f_init(); + f_sleep(1.0); + vc_conn := f_start_handler(refers(f_TC_sgsn_context_req_out), testcasename(), g_gb, 73); + vc_conn.done; + f_cleanup(); +} control { execute( TC_attach() ); execute( TC_attach_mnc3() ); execute( TC_attach_umts_aka_umts_res() ); execute( TC_attach_umts_aka_gsm_sres() ); + execute( TC_attach_timeout_after_pdp_act() ); execute( TC_attach_auth_id_timeout() ); execute( TC_attach_auth_sai_timeout() ); execute( TC_attach_auth_sai_reject() ); @@ -3144,6 +3933,11 @@ control { execute( TC_attach_rau_a_a() ); execute( TC_attach_rau_a_b() ); execute( TC_attach_usim_resync() ); + execute( TC_attach_usim_a54_a54() ); + execute( TC_attach_usim_a54_a53() ); + execute( TC_attach_usim_a53_a54() ); + execute( TC_attach_usim_a50_a54() ); + execute( TC_attach_usim_a54_a50() ); execute( TC_detach_unknown_nopoweroff() ); execute( TC_detach_unknown_poweroff() ); execute( TC_detach_nopoweroff() ); @@ -3178,6 +3972,17 @@ control { execute( TC_suspend_rau() ); execute( TC_paging_ps() ); + execute( TC_bssgp_rim_single_report() ); + execute( TC_rim_eutran_to_geran() ); + + execute( TC_cell_change_different_rai_ci_attach() ); + execute( TC_cell_change_different_rai_ci_data() ); + execute( TC_cell_change_different_ci_attach() ); + execute( TC_cell_change_different_ci_data() ); + + execute( TC_sgsn_context_req_in() ); + execute( TC_sgsn_context_req_out() ); + /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */ execute( TC_attach_req_id_req_ra_update() ); } |