pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/37617?usp=email )
Change subject: sgsn: Introduce test TC_attach_pdp_act_pmm_idle ......................................................................
sgsn: Introduce test TC_attach_pdp_act_pmm_idle
Change-Id: Id46ccd9db11c8b792e1c071de91ef092ed1544c7 --- M library/ranap/RANAP_Templates.ttcn M sgsn/BSSGP_ConnHdlr.ttcn M sgsn/SGSN_Tests_Iu.ttcn M sgsn/expected-results.xml 4 files changed, 149 insertions(+), 46 deletions(-)
Approvals: Jenkins Builder: Verified pespin: Looks good to me, approved
diff --git a/library/ranap/RANAP_Templates.ttcn b/library/ranap/RANAP_Templates.ttcn index 7fb374d..a433d62 100644 --- a/library/ranap/RANAP_Templates.ttcn +++ b/library/ranap/RANAP_Templates.ttcn @@ -13,6 +13,7 @@
template (value) Cause ts_RanapCause_om_intervention := { misc := 113 }; template (value) Cause ts_RanapCause_nas_normal := { nAS := 83 }; +template (value) Cause ts_RanapCause_radio_conn_release := { radioNetwork := 40 }; template (value) Cause ts_RanapCause_radio_conn_lost := { radioNetwork := 46 };
/***************************************************************************************************** diff --git a/sgsn/BSSGP_ConnHdlr.ttcn b/sgsn/BSSGP_ConnHdlr.ttcn index d62f7f8..de864b3 100644 --- a/sgsn/BSSGP_ConnHdlr.ttcn +++ b/sgsn/BSSGP_ConnHdlr.ttcn @@ -494,9 +494,7 @@
/* IuPS case: Expect Iu Release */ if (is_iu(ran_index)) { - as_iu_release_compl_disc(); - /* Next message will be an InitialUE since conn was torn down */ - g_pars.rnc_send_initial_ue := true; + as_iu_release_compl_disc_ext(); }
/* Race condition @@ -633,6 +631,7 @@ }
function f_service_request(ServiceType service_type := SERVICE_TYPE_Signalling, + template (value) OCT2 pdp_status := '0000'O, integer ran_index := 0, float Tval := 2.0) runs on BSSGP_ConnHdlr { timer T := Tval; @@ -643,7 +642,10 @@ }
- f_send_l3(ts_GMM_SERVICE_REQ(service_type, p_tmsi := g_pars.p_tmsi), ran_index); + f_send_l3(ts_GMM_SERVICE_REQ(service_type, + p_tmsi := g_pars.p_tmsi, + pdp_status := pdp_status), + ran_index);
T.start; alt { @@ -656,6 +658,38 @@ } }
+/* expect a IuReleaseCommand; Confirm that; expect SCCP-level N-DISCONNET.ind */ +altstep as_iu_release_compl_disc_ext() runs on BSSGP_ConnHdlr { + [] as_iu_release_compl_disc() { + /* Next message will be an InitialUE since conn was torn down */ + g_pars.rnc_send_initial_ue := true; + } +} + +function f_iu_release_req(template (value) Cause cause) runs on BSSGP_ConnHdlr { + timer T := 5.0; + BSSAP.send(ts_RANAP_IuReleaseRequest(cause)); + T.start; + alt { + [] as_iu_release_compl_disc_ext() { T.stop; }; + [] T.timeout { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + "Timeout completing the Iu Release procedure"); + } + } +} + +altstep as_ranap_rab_ass_req(inout PdpActPars apars) runs on BSSGP_ConnHdlr { + var RANAP_PDU ranap; + [] BSSAP.receive(tr_RANAP_RabAssReq(?)) -> value ranap { + var RAB_ID rab_id := f_ranap_rab_ass_req_extract_rab_id(ranap); + /*TODO: validate received remote IP addr + TEID = apars.ggsn_ip_u + apars.ggsn_tei_u */ + var template (value) RAB_SetupOrModifiedList l; + l := ts_RAB_SMdL_ps(rab_id, oct2bit(apars.rnc_ip_u), apars.rnc_tei_u); + BSSAP.send(ts_RANAP_RabAssResp(l)); + } +} + type record PdpActPars { BIT3 tid, /* L3 Transaction ID */ BIT4 nsapi, /* SNDCP NSAPI */ @@ -693,25 +727,72 @@ f_gtp_register_teid(apars.ggsn_tei_c, GTP_GGSN_IDX); f_gtp_register_teid(apars.ggsn_tei_u, GTP_GGSN_IDX); } +private altstep as_ggsn_gtp_ctx_act_req(inout PdpActPars apars, boolean send_recovery := false) runs on BSSGP_ConnHdlr { + var Gtp1cUnitdata g_ud; + var template Recovery_gtpc recovery := omit;
-function f_process_gtp_ctx_upd_req(inout PdpActPars apars, PDU_GTPC gtpc, integer ran_index := 0) runs on BSSGP_ConnHdlr { + [] GTP[GTP_GGSN_IDX].receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud { + f_process_gtp_ctx_act_req(apars, g_ud.gtpc); + if (send_recovery) { + recovery := ts_Recovery(apars.ggsn_restart_ctr); + } + var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber); + GTP[GTP_GGSN_IDX].send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr, + apars.sgsn_tei_c, apars.gtp_resp_cause, + apars.ggsn_tei_c, apars.ggsn_tei_u, + apars.nsapi, + apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id, + omit, recovery)); + } +} + +function f_process_gtp_ctx_upd_req(inout PdpActPars apars, + PDU_GTPC gtpc, + boolean exp_dir_tun := true, + integer ran_index := 0) runs on BSSGP_ConnHdlr { var UpdatePDPContextRequestSGSN upd := gtpc.gtpc_pdu.updatePDPContextRequest.updatePDPContextRequestSGSN; - - if (not ispresent(upd.directTunnelFlags) or upd.directTunnelFlags.dTI != '1'B) { + var boolean dti := ispresent(upd.directTunnelFlags) and upd.directTunnelFlags.dTI == '1'B; + if (dti != exp_dir_tun) { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Rx UpdatePDPCtxReq with Direct Tunnel Flags ", - upd.directTunnelFlags, " vs exp DTI=1")); + upd.directTunnelFlags, " vs exp DTI=", dti)); }
if (ispresent(upd.teidControlPlane.teidControlPlane)) { apars.sgsn_tei_c := upd.teidControlPlane.teidControlPlane; } - apars.sgsn_tei_u := upd.teidDataI.teidDataI; apars.sgsn_ip_c := upd.sgsn_addr_controlPlane.addressf; - apars.sgsn_ip_u := upd.sgsn_addr_traffic.addressf; - f_gtp_register_teid(apars.rnc_tei_u, ran2gtp_idx(ran_index)); - /* TODO: If "Direct Tunnel" flag, update apars.rnc_{tei,ip}_u instead, - * and store "direct_tunnel" in ggsn state */ + if (dti) { + if (apars.rnc_ip_u != upd.sgsn_addr_traffic.addressf or + apars.rnc_tei_u != upd.teidDataI.teidDataI) { + Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, + log2str("Rx UpdatePDPCtxReq with DTI=1 and wrong RNC IP+TEID: ", + upd.sgsn_addr_traffic.addressf, ":", upd.teidDataI.teidDataI, + " vs exp ", apars.rnc_ip_u, ":", apars.rnc_tei_u)); + } + f_gtp_register_teid(apars.rnc_tei_u, ran2gtp_idx(ran_index)); + } else { + apars.sgsn_ip_u := upd.sgsn_addr_traffic.addressf; + apars.sgsn_tei_u := upd.teidDataI.teidDataI; + } +} +altstep as_ggsn_gtp_ctx_upd_req(inout PdpActPars apars, + boolean send_recovery := false, + boolean exp_dir_tun := true, + integer ran_index := 0) runs on BSSGP_ConnHdlr { + var Gtp1cUnitdata g_ud; + + [] GTP[GTP_GGSN_IDX].receive(tr_GTPC_MsgType(?, updatePDPContextRequest, ?)) -> value g_ud { + f_process_gtp_ctx_upd_req(apars, g_ud.gtpc, + exp_dir_tun := exp_dir_tun, + ran_index := ran_index); + var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber); + GTP[GTP_GGSN_IDX].send(ts_GTPC_UpdatePdpRespGGSN(g_ud.peer, seq_nr, + apars.sgsn_tei_c, apars.gtp_resp_cause, + apars.ggsn_tei_c, apars.ggsn_tei_u, + apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id, + omit, omit)); + } }
altstep as_pdp_ctx_act_gb(inout PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr { @@ -766,46 +847,20 @@
function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0, float Tval := 5.0) runs on BSSGP_ConnHdlr { - var Gtp1cUnitdata g_ud; - var template Recovery_gtpc recovery := omit; timer T := Tval;
f_send_l3(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr, apars.apn, apars.pco), ran_index);
- if (send_recovery) { - recovery := ts_Recovery(apars.ggsn_restart_ctr); - } - GTP[GTP_GGSN_IDX].receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud { - f_process_gtp_ctx_act_req(apars, g_ud.gtpc); - var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber); - GTP[GTP_GGSN_IDX].send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr, - apars.sgsn_tei_c, apars.gtp_resp_cause, - apars.ggsn_tei_c, apars.ggsn_tei_u, - apars.nsapi, - apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id, - omit, recovery)); - } + as_ggsn_gtp_ctx_act_req(apars, send_recovery := send_recovery);
T.start; if (is_iu(ran_index)) { - var RANAP_PDU ranap; alt { - [] BSSAP.receive(tr_RANAP_RabAssReq(?)) -> value ranap { - var RAB_ID rab_id := f_ranap_rab_ass_req_extract_rab_id(ranap); - var template (value) RAB_SetupOrModifiedList l; - l := ts_RAB_SMdL_ps(rab_id, oct2bit(apars.rnc_ip_u), apars.rnc_tei_u); - BSSAP.send(ts_RANAP_RabAssResp(l)); - - GTP[GTP_GGSN_IDX].receive(tr_GTPC_MsgType(?, updatePDPContextRequest, ?)) -> value g_ud { - f_process_gtp_ctx_upd_req(apars, g_ud.gtpc, ran_index); - var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber); - GTP[GTP_GGSN_IDX].send(ts_GTPC_UpdatePdpRespGGSN(g_ud.peer, seq_nr, - apars.sgsn_tei_c, apars.gtp_resp_cause, - apars.ggsn_tei_c, apars.ggsn_tei_u, - apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id, - omit, recovery)); - } + [] as_ranap_rab_ass_req(apars) { + as_ggsn_gtp_ctx_upd_req(apars, + send_recovery := send_recovery, + ran_index := ran_index); } [] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, @@ -815,7 +870,7 @@ }
alt { - [] as_pdp_ctx_act(apars, ran_index) { setverdict(pass); } + [] as_pdp_ctx_act(apars, ran_index) { T.stop; setverdict(pass); } [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; } [is_iu(ran_index)] BSSAP.receive { repeat; } [] T.timeout { diff --git a/sgsn/SGSN_Tests_Iu.ttcn b/sgsn/SGSN_Tests_Iu.ttcn index 7ee4c51..8806791 100644 --- a/sgsn/SGSN_Tests_Iu.ttcn +++ b/sgsn/SGSN_Tests_Iu.ttcn @@ -138,7 +138,43 @@ 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, 1001); + 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(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(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(); } @@ -149,6 +185,7 @@ 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() ); }
diff --git a/sgsn/expected-results.xml b/sgsn/expected-results.xml index 1e7367d..8b17802 100644 --- a/sgsn/expected-results.xml +++ b/sgsn/expected-results.xml @@ -93,6 +93,7 @@ <testcase classname='SGSN_Tests_Iu' name='TC_iu_attach_geran_rau' time='MASKED'/> <testcase classname='SGSN_Tests_Iu' name='TC_geran_attach_iu_rau' time='MASKED'/> <testcase classname='SGSN_Tests_Iu' name='TC_attach_pdp_act_user' time='MASKED'/> + <testcase classname='SGSN_Tests_Iu' name='TC_attach_pdp_act_pmm_idle' time='MASKED'/> <!-- SGSN_Tests_NS (handle_sns == true) testcases start here --> <testcase classname='SGSN_Tests_NS' name='TC_SNS_size' time='MASKED'/> <testcase classname='SGSN_Tests_NS' name='TC_SNS_size_too_big' time='MASKED'/>