aboutsummaryrefslogtreecommitdiffstats
path: root/sgsn/SGSN_Tests.ttcn
diff options
context:
space:
mode:
Diffstat (limited to 'sgsn/SGSN_Tests.ttcn')
-rw-r--r--sgsn/SGSN_Tests.ttcn1055
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() );
}