pespin submitted this change.
sgsn: Introduce test TC_update_ctx_err_ind_from_ggsn
Related: OS#6512
Related: SYS#5435
Change-Id: Ic417b23cae798361f73150f6a72f91e2f8528e7a
---
M library/GTPv1C_Templates.ttcn
M library/GTPv1U_Templates.ttcn
M sgsn/BSSGP_ConnHdlr.ttcn
M sgsn/SGSN_Tests_Iu.ttcn
M sgsn/expected-results.xml
5 files changed, 201 insertions(+), 2 deletions(-)
diff --git a/library/GTPv1C_Templates.ttcn b/library/GTPv1C_Templates.ttcn
index 893ab01..b1059fe 100644
--- a/library/GTPv1C_Templates.ttcn
+++ b/library/GTPv1C_Templates.ttcn
@@ -404,6 +404,18 @@
}
}
+ /* 7.7.81 Direct Tunnel Flags */
+ template (value) DirectTunnelFlags ts_DirectTunnelFlags(BIT1 dTI := '0'B,
+ BIT1 gCSI := '0'B,
+ BIT1 eI := '0'B) := {
+ type_gtpc := 'B6'O,
+ lengthf := 0, /* overwritten */
+ dTI := dTI,
+ gCSI := gCSI,
+ eI := eI,
+ spare := '00000'B
+ }
+
/* 7.7.29 PDP Context */
template (value) PDP_Context_GTPC ts_PDP_Context_GTPC(template (value) octetstring pdp_addr,
template (value) octetstring ggsn_gsn_addr,
@@ -902,6 +914,53 @@
sgsn_ip_data, pco, ratType, uli)), seq)
}
+ /* Update PPD Context Sent GGSN -> SGSN: */
+ template (value) GTPC_PDUs ts_UpdatePdpPDU_GGSN(template (value) BIT4 nsapi,
+ template (omit) hexstring imsi := omit,
+ template (omit) Recovery_gtpc recovery := omit,
+ template (omit) EndUserAddress eua := omit,
+ template (omit) ProtConfigOptions pco := omit,
+ template (omit) QualityOfServiceProfile qos := omit,
+ template (omit) DirectTunnelFlags dtf := omit) := {
+ updatePDPContextRequest := {
+ updatePDPContextRequestGGSN := {
+ imsi := f_ts_Imsi(imsi),
+ recovery := recovery,
+ nsapi := ts_NSAPI(nsapi),
+ endUserAddress := eua,
+ protConfigOptions := pco,
+ qualityOfServiceProfile := qos,
+ tft := omit,
+ commonFlags := omit,
+ aPN_Restriction := omit,
+ mS_InfoChangeReportingAction := omit,
+ directTunnelFlags := dtf,
+ bearerControlMode := omit,
+ evolvedAllocationRetentionPriorityI := omit,
+ extendedCommonFlags := omit,
+ cSGInfoReportingAction := omit,
+ aPN_AMBR := omit,
+ private_extension_gtpc := omit
+ }
+ }
+ }
+ template (value) Gtp1cUnitdata ts_GTPC_UpdatePDP_GGSN(template (value) Gtp1cPeer peer,
+ template (value) OCT4 teid,
+ template (value) uint16_t seq,
+ template (value) BIT4 nsapi,
+ template (omit) hexstring imsi := omit,
+ template (omit) Recovery_gtpc recovery := omit,
+ template (omit) EndUserAddress eua := omit,
+ template (omit) ProtConfigOptions pco := omit,
+ template (omit) QualityOfServiceProfile qos := omit,
+ template (omit) DirectTunnelFlags dtf := omit) := {
+ peer := peer,
+ gtpc := ts_GTP1C_PDU(updatePDPContextRequest, teid,
+ ts_UpdatePdpPDU_GGSN(nsapi, imsi, recovery,
+ eua, pco, qos, dtf),
+ seq)
+ }
+
template (value) NSAPI_GTPC ts_NSAPI(template (value) BIT4 nsapi) := {
type_gtpc := '14'O,
@@ -1029,6 +1088,48 @@
eua, recovery, pco)), seq)
}
+ /* Update PDP Context Resp sent SGSN -> GGSN: */
+ template (present) GTPC_PDUs tr_UpdatePdpRespSGSNPDU(template (present) GTP_Cause cause := ?,
+ template Recovery_gtpc recovery := *,
+ template TeidDataI teidDataI := *,
+ template ProtConfigOptions pco := *,
+ template GSN_Address_GTPC sgsn_addr_traffic := *,
+ template QualityOfServiceProfile qos := *,
+ template DirectTunnelFlags dtf := *) := {
+ updatePDPContextResponse := {
+ updatePDPContextResponseSGSN := {
+
+ cause := tr_Cause_gtpc(cause),
+
+ recovery := recovery,
+ teidDataI := teidDataI,
+ protConfigOptions := pco,
+ sgsn_addr_traffic := sgsn_addr_traffic,
+ qualityOfServiceProfile := qos,
+ userLocationInformation := *,
+ mS_TimeZone := *,
+ directTunnelFlags := dtf,
+ evolvedAllocationRetentionPriorityI := *,
+ aPN_AMBR := *,
+ private_extension_gtpc := *
+ }
+ }
+ }
+
+ template (present) Gtp1cUnitdata tr_GTPC_UpdatePdpRespSGSN(template (present) Gtp1cPeer peer, uint16_t seq, OCT4 teid,
+ template (present) GTP_Cause cause := ?,
+ template Recovery_gtpc recovery := *,
+ template TeidDataI teidDataI := *,
+ template ProtConfigOptions pco := *,
+ template GSN_Address_GTPC sgsn_addr_traffic := *,
+ template QualityOfServiceProfile qos := *,
+ template DirectTunnelFlags dtf := *) := {
+ peer := peer,
+ gtpc := tr_GTP1C_PDU(updatePDPContextResponse, teid,
+ tr_UpdatePdpRespSGSNPDU(cause, recovery, teidDataI, pco,
+ sgsn_addr_traffic, qos, dtf))
+ }
+
/* PCO send base template */
template (value) ProtConfigOptions ts_PCO := {
type_gtpc := '84'O,
diff --git a/library/GTPv1U_Templates.ttcn b/library/GTPv1U_Templates.ttcn
index 86d2401..c242115 100644
--- a/library/GTPv1U_Templates.ttcn
+++ b/library/GTPv1U_Templates.ttcn
@@ -140,17 +140,41 @@
gtpu := ts_GTP1U_PDU('02'O, seq, '00000000'O, ts_UEchoRespPDU(rest_ctr))
}
+ template (present) GSNAddress_gtpu tr_UGsnAddr(template (present) octetstring ip_addr := ?) := {
+ type_gtpu := '85'O,
+ lengthf := ?,
+ gSNAddressValue := ip_addr
+ }
template (value) GSNAddress_gtpu ts_UGsnAddr(template (value) octetstring ip_addr) := {
type_gtpu := '85'O,
lengthf := lengthof(valueof(ip_addr)),
gSNAddressValue := ip_addr
}
+ template (present) TeidDataI_gtpu tr_UteidDataI(template (present) OCT4 teid := ?) := {
+ type_gtpu := '10'O,
+ teidDataI := teid
+ }
template (value) TeidDataI_gtpu ts_UteidDataI(template (value) OCT4 teid) := {
type_gtpu := '10'O,
teidDataI := teid
}
+ template (present) GTPU_IEs tr_UErrorIndication(template (present) OCT4 teid := ?,
+ template (present) octetstring gsn_addr := ?) := {
+ errorIndication_IEs := {
+ teidDataI_gtpu := tr_UteidDataI(teid),
+ gSNAddress_gtpu := tr_UGsnAddr(gsn_addr),
+ private_extension_gtpu := *
+ }
+ }
+ template (present) Gtp1uUnitdata tr_GTPU_ErrorIndication(template (present) Gtp1uPeer peer := ?,
+ template (present) OCT4 teid := ?,
+ template (present) octetstring gsn_addr := ?) := {
+ peer := peer,
+ gtpu := tr_GTP1U_PDU('1A'O, '00000000'O, tr_UErrorIndication(teid, gsn_addr))
+ }
+
template (value) GTPU_IEs ts_UErrorIndication(template (value) OCT4 teid,
template (value) octetstring gsn_addr) := {
errorIndication_IEs := {
@@ -159,7 +183,6 @@
private_extension_gtpu := omit
}
}
-
/* master template for sending a GTP-U Error indication */
template (value) Gtp1uUnitdata ts_GTPU_ErrorIndication(template (value) Gtp1uPeer peer,
template (value) uint16_t seq,
diff --git a/sgsn/BSSGP_ConnHdlr.ttcn b/sgsn/BSSGP_ConnHdlr.ttcn
index 140fa99..055902a 100644
--- a/sgsn/BSSGP_ConnHdlr.ttcn
+++ b/sgsn/BSSGP_ConnHdlr.ttcn
@@ -54,7 +54,7 @@
/* Emulated GGSN is at GTP_ConnHdlr.GTP[0] */
const integer GTP_GGSN_IDX := 0;
-private function ran2gtp_idx(integer ran_index) return integer {
+function ran2gtp_idx(integer ran_index) return integer {
return ran_index + 1 - NUM_GB;
}
diff --git a/sgsn/SGSN_Tests_Iu.ttcn b/sgsn/SGSN_Tests_Iu.ttcn
index 5010443..f5339d4 100644
--- a/sgsn/SGSN_Tests_Iu.ttcn
+++ b/sgsn/SGSN_Tests_Iu.ttcn
@@ -12,6 +12,7 @@
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;
@@ -262,6 +263,67 @@
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() );
@@ -270,6 +332,7 @@
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() );
}
diff --git a/sgsn/expected-results.xml b/sgsn/expected-results.xml
index 3461721..a29467d 100644
--- a/sgsn/expected-results.xml
+++ b/sgsn/expected-results.xml
@@ -96,6 +96,7 @@
<testcase classname='SGSN_Tests_Iu' name='TC_attach_pdp_act_pmm_idle' time='MASKED'/>
<testcase classname='SGSN_Tests_Iu' name='TC_attach_pdp_act_pmm_idle_lost_pdp_status' time='MASKED'/>
<testcase classname='SGSN_Tests_Iu' name='TC_pmm_idle_rx_mt_data' time='MASKED'/>
+ <testcase classname='SGSN_Tests_Iu' name='TC_update_ctx_err_ind_from_ggsn' 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'/>
To view, visit change 37665. To unsubscribe, or for help writing mail filters, visit settings.