module SGSN_Tests_Iu { import from Osmocom_Types all; import from Osmocom_VTY_Functions all; import from SGSN_Tests all; import from BSSGP_Emulation all; import from RAN_Adapter all; import from RAN_Emulation all; import from RANAP_Templates all; import from RANAP_PDU_Descriptions all; import from RANAP_IEs all; import from GTPv1C_Templates all; import from GTPv1U_Templates all; import from GTP_Emulation all; import from BSSGP_ConnHdlr all; private function f_init() runs on test_CT { g_iu_enable := true; SGSN_Tests.f_init(); /* default VTY configuration */ f_vty_config(SGSNVTY, "sgsn", "encryption uea 0"); } private function f_TC_iu_attach(charstring id) runs on BSSGP_ConnHdlr { var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip, mp_ranap_cfg[0].sctp_addr.local_ip_addr)); /* first perform regular attach */ f_gmm_attach(umts_aka_challenge := true, force_gsm_sres := false, ran_index := 3); setverdict(pass); } testcase TC_iu_attach() runs on test_CT { /* MS -> SGSN: Attach Request IMSI * MS <- SGSN: Identity Request IMEI * MS -> SGSN: Identity Response IMEI * MS <- SGSN: Auth Request * MS -> SGSN: Auth Response * MS <- SGSN: Attach Accept * MS -> SGSN: Attach Complete */ var BSSGP_ConnHdlr vc_conn; f_init(); f_sleep(1.0); f_vty_config(SGSNVTY, "sgsn", "encryption uea 0"); vc_conn := f_start_handler(refers(f_TC_iu_attach), testcasename(), g_gb, 1001); vc_conn.done; f_cleanup(); } testcase TC_iu_attach_encr() runs on test_CT { /* MS -> SGSN: Attach Request IMSI * MS <- SGSN: Identity Request IMEI * MS -> SGSN: Identity Response IMEI * MS <- SGSN: Auth Request * MS -> SGSN: Auth Response * MS <- SGSN: Security Mode Command * MS -> SGSN: Security Mode Complete * hNodeB <- SGSN: Common Id * MS <- SGSN: Attach Accept * MS -> SGSN: Attach Complete */ var BSSGP_ConnHdlr vc_conn; f_init(); f_vty_config(SGSNVTY, "sgsn", "encryption uea 1 2"); f_sleep(1.0); vc_conn := f_start_handler(refers(f_TC_iu_attach), testcasename(), g_gb, 1001, expect_ciph := true); vc_conn.done; f_cleanup(); } private function f_TC_iu_attach_geran_rau(charstring id) runs on BSSGP_ConnHdlr { var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip, mp_ranap_cfg[0].sctp_addr.local_ip_addr)); /* first perform regular attach */ f_gmm_attach(umts_aka_challenge := true, force_gsm_sres := false, ran_index := 3); /* we got a new TLLI, register it */ f_bssgp_client_unregister(g_pars.imsi); f_bssgp_client_register(g_pars.imsi, g_pars.tlli); /* do a routing area update */ f_routing_area_update(g_pars.ra); } testcase TC_iu_attach_geran_rau() runs on test_CT { /* MS <-> SGSN: Successful Attach over Iu * MS <-> SGSN: Routing Area Update over Geran */ var BSSGP_ConnHdlr vc_conn; f_init(); f_sleep(1.0); vc_conn := f_start_handler(refers(f_TC_iu_attach_geran_rau), testcasename(), g_gb, 1002); vc_conn.done; f_cleanup(); } private function f_TC_geran_attach_iu_rau(charstring id) runs on BSSGP_ConnHdlr { var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip, mp_ranap_cfg[0].sctp_addr.local_ip_addr)); /* first perform regular attach */ f_gmm_attach(umts_aka_challenge := true, force_gsm_sres := false, ran_index := 0); /* do a routing area update */ f_routing_area_update(g_pars.ra, ran_index := 3); setverdict(pass); } testcase TC_geran_attach_iu_rau() runs on test_CT { /* MS <-> SGSN: Successful Attach over Geran * MS <-> SGSN: Routing Area Update over Iu */ var BSSGP_ConnHdlr vc_conn; f_init(); f_sleep(1.0); vc_conn := f_start_handler(refers(f_TC_geran_attach_iu_rau), testcasename(), g_gb, 1003); vc_conn.done; f_cleanup(); } private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr { var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip, mp_ranap_cfg[0].sctp_addr.local_ip_addr)); /* first perform regular attach */ f_gmm_attach(umts_aka_challenge := true, force_gsm_sres := false, ran_index := 3); f_service_request(apars, ran_index := 3); f_pdp_ctx_act(apars, ran_index := 3); /* then transceive a downlink PDU */ f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 3); f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 3); f_pdp_ctx_deact_mo(apars, '00'O, ran_index := 3); setverdict(pass); } testcase TC_attach_pdp_act_user() runs on test_CT { var BSSGP_ConnHdlr vc_conn; f_init(); f_sleep(1.0); vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 1004); vc_conn.done; f_cleanup(); } /* Test UE going to PMM IDLE state after having activated the PDP context. * SGSN is expected to update the GGSN cancelling the Direct Tunnel feature. */ private function f_TC_attach_pdp_act_pmm_idle(charstring id) runs on BSSGP_ConnHdlr { var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip, mp_ranap_cfg[0].sctp_addr.local_ip_addr)); /* first perform regular attach */ f_gmm_attach(umts_aka_challenge := true, force_gsm_sres := false, ran_index := 3); f_service_request(apars, ran_index := 3); f_pdp_ctx_act(apars, ran_index := 3); f_iu_release_req(ts_RanapCause_radio_conn_release); /* Now UE is in PMM IDLE state at the SGSN. * Expect SGSN to point GTPU at GGSN back to itself: */ as_ggsn_gtp_ctx_upd_req(apars, exp_dir_tun := false, ran_index := 3); /* Now UE tries to send new data after a while of being IDLE. * SGSN recreates the Iu ctx and recovers the Direct Tunnel RNC<->GGSN: */ f_service_request(apars, pdp_status := '2000'O /*NSAPI=5*/, ran_index := 3); as_ranap_rab_ass_req(apars); as_ggsn_gtp_ctx_upd_req(apars, exp_dir_tun := true, ran_index := 3); /* Now UE is in PMM ENABLED state, tear it down to clean up: */ f_pdp_ctx_deact_mo(apars, '00'O, ran_index := 3); setverdict(pass); } testcase TC_attach_pdp_act_pmm_idle() runs on test_CT { var BSSGP_ConnHdlr vc_conn; f_init(); f_sleep(1.0); vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_pmm_idle), testcasename(), g_gb, 1005); vc_conn.done; f_cleanup(); } /* TODO: same as TC_attach_pdp_act_pmm_idle, but with pdp_status=0000, meaning UE lost status about previous PDP Ctx. * We should see SGSN doing DeletePDPCtxReq towards GGSN instead of UdatePDPCtxReq, then probably re-create it. */ private function f_TC_attach_pdp_act_pmm_idle_lost_pdp_status(charstring id) runs on BSSGP_ConnHdlr { var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip, mp_ranap_cfg[0].sctp_addr.local_ip_addr)); /* first perform regular attach */ f_gmm_attach(umts_aka_challenge := true, force_gsm_sres := false, ran_index := 3); f_service_request(apars, ran_index := 3); f_pdp_ctx_act(apars, ran_index := 3); f_iu_release_req(ts_RanapCause_radio_conn_release); /* Now UE is in PMM IDLE state at the SGSN. * Expect SGSN to point GTPU at GGSN back to itself: */ as_ggsn_gtp_ctx_upd_req(apars, exp_dir_tun := false, ran_index := 3); /* Now UE tries to send new data after a while of being IDLE. * It forgot its previous pdp status, hence := 0000. * SGSN will delete previous PDP ctx at the GGSN. */ f_service_request(apars, pdp_status := '0000'O /*NSAPI=5*/, exp_ggsn_pdp_del := true, ran_index := 3); f_pdp_ctx_act(apars, ran_index := 3); /* Now UE is in PMM ENABLED state, tear it down to clean up: */ f_pdp_ctx_deact_mo(apars, '00'O, ran_index := 3); setverdict(pass); } testcase TC_attach_pdp_act_pmm_idle_lost_pdp_status() runs on test_CT { var BSSGP_ConnHdlr vc_conn; f_init(); f_sleep(1.0); vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_pmm_idle_lost_pdp_status), testcasename(), g_gb, 1006); vc_conn.done; f_cleanup(); } /* Test UE going to PMM IDLE state after having activated the PDP context. * SGSN is expected to update the GGSN cancelling the Direct Tunnel feature. */ private function f_TC_pmm_idle_rx_mt_data(charstring id) runs on BSSGP_ConnHdlr { var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip, mp_ranap_cfg[0].sctp_addr.local_ip_addr)); /* first perform regular attach */ f_gmm_attach(umts_aka_challenge := true, force_gsm_sres := false, ran_index := 3); f_service_request(apars, ran_index := 3); f_pdp_ctx_act(apars, ran_index := 3); f_iu_release_req(ts_RanapCause_radio_conn_release); /* Now UE is in PMM IDLE state at the SGSN. * Expect SGSN to point GTPU at GGSN back to itself: */ as_ggsn_gtp_ctx_upd_req(apars, exp_dir_tun := false, ran_index := 3); /* Now GGSN receives new MT data and forwards it to SGSN: */ f_gtp_register_teid('00000000'O, GTP_GGSN_IDX); /* Ease debugging in case SGSN sends ErrorInd */ f_ran_register_imsi(g_pars.imsi, g_pars.p_tmsi); /* Forward Paging below to this component */ var octetstring payload := f_rnd_octstring(100); f_ggsn_gtpu_send(apars, payload); BSSAP.receive(tr_RANAP_Paging(ps_domain, imsi_hex2oct(g_pars.imsi))); /* Ue comes back, answering the paging: * SGSN recreates the Iu ctx and recovers the Direct Tunnel RNC<->GGSN: */ f_service_request(apars, pdp_status := '2000'O /*NSAPI=5*/, ran_index := 3); as_ranap_rab_ass_req(apars); as_ggsn_gtp_ctx_upd_req(apars, exp_dir_tun := true, ran_index := 3); /* Now UE is in PMM ENABLED state, tear it down to clean up: */ f_pdp_ctx_deact_mo(apars, '00'O, ran_index := 3); setverdict(pass); } testcase TC_pmm_idle_rx_mt_data() runs on test_CT { var BSSGP_ConnHdlr vc_conn; f_init(); f_sleep(1.0); vc_conn := f_start_handler(refers(f_TC_pmm_idle_rx_mt_data), testcasename(), g_gb, 1007); vc_conn.done; f_cleanup(); } /* TS 29.060 7.3.3, 3GPP TS 23.007 15.2: Emulate GGSN sending UpdatePDPCtx[NSAPI, Direct Tunnel Flags(EI=1)] due to having receiving an Error Indication from RNC while in Direct Tunnel mode. SGSN should attempt recreation of the RAB to make sure PDP context is established, since it may be that RNC got restarted. */ private function f_TC_update_ctx_err_ind_from_ggsn(charstring id) runs on BSSGP_ConnHdlr { var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip, mp_ranap_cfg[0].sctp_addr.local_ip_addr)); var integer ran_index := 3; /* first perform regular attach */ f_gmm_attach(umts_aka_challenge := true, force_gsm_sres := false, ran_index := ran_index); f_service_request(apars, ran_index := ran_index); f_pdp_ctx_act(apars, ran_index := ran_index); /* then transceive a downlink PDU */ f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := ran_index); /* RNC answers with Error Indication, it probably crashed and lost state: */ f_gtp_register_teid('00000000'O, GTP_GGSN_IDX); /* Ease debugging in case SGSN sends ErrorInd */ f_ran_register_imsi(g_pars.imsi, g_pars.p_tmsi); /* Forward Paging below to this component */ GTP[ran2gtp_idx(ran_index)].send(ts_GTPU_ErrorIndication(ts_GtpPeerU(apars.ggsn_ip_u), 0, apars.rnc_tei_u, apars.rnc_ip_u)); GTP[GTP_GGSN_IDX].receive(tr_GTPU_ErrorIndication(ts_GtpPeerU(apars.rnc_ip_u), apars.rnc_tei_u, apars.rnc_ip_u)); GTP[GTP_GGSN_IDX].send(ts_GTPC_UpdatePDP_GGSN(ts_GtpPeerC(apars.sgsn_ip_c), apars.sgsn_tei_c, 2, apars.nsapi, g_pars.imsi, dtf := ts_DirectTunnelFlags(eI := '1'B))); GTP[GTP_GGSN_IDX].receive(tr_GTPC_UpdatePdpRespSGSN(ts_GtpPeerC(apars.sgsn_ip_c), 2, apars.ggsn_tei_c, GTP_CAUSE_REQUEST_ACCEPTED)); BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND); g_pars.rnc_send_initial_ue := true; BSSAP.receive(tr_RANAP_Paging(ps_domain, imsi_hex2oct(g_pars.imsi))); /* Ue comes back, answering the paging: * SGSN recreates the Iu ctx and recovers the Direct Tunnel RNC<->GGSN: */ f_service_request(apars, pdp_status := '2000'O /*NSAPI=5*/, ran_index := ran_index); as_ranap_rab_ass_req(apars); as_ggsn_gtp_ctx_upd_req(apars, exp_dir_tun := true, ran_index := ran_index); /* Now UE is in PMM ENABLED state, tear it down to clean up: */ f_pdp_ctx_deact_mo(apars, '00'O, ran_index := ran_index); setverdict(pass); } testcase TC_update_ctx_err_ind_from_ggsn() runs on test_CT { var BSSGP_ConnHdlr vc_conn; f_init(); f_sleep(1.0); vc_conn := f_start_handler(refers(f_TC_update_ctx_err_ind_from_ggsn), testcasename(), g_gb, 1004); vc_conn.done; f_cleanup(); } control { execute( TC_iu_attach() ); execute( TC_iu_attach_encr() ); execute( TC_iu_attach_geran_rau() ); execute( TC_geran_attach_iu_rau() ); execute( TC_attach_pdp_act_user() ); execute( TC_attach_pdp_act_pmm_idle() ); execute( TC_pmm_idle_rx_mt_data() ); execute( TC_update_ctx_err_ind_from_ggsn() ); } }