|
|
|
@ -2630,46 +2630,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 (omit) 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2706,14 +2727,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(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), ran_index := 1);
|
|
|
|
|
|
|
|
|
|
f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
|
|
|
|
|
}
|
|
|
|
@ -3706,6 +3727,139 @@ testcase TC_cell_change_different_ci_data() runs on test_CT {
|
|
|
|
|
f_cleanup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* SGSN terminated SGSN Context Request procedure (we request, SGSN responds) */
|
|
|
|
|
private function f_TC_sgsn_context_req(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);
|
|
|
|
|
/* TODO: match MM/PDP Context, GSN Address */
|
|
|
|
|
|
|
|
|
|
T.start(2.0);
|
|
|
|
|
alt {
|
|
|
|
|
[] GTP.receive(tr_GTPC_SGSNContextResp(?, ?, ctx_rsp)) -> value gtpc_ud {
|
|
|
|
|
GTP.send(ts_GTPC_SGSNContextAck(gtpc_ud.peer, '12345678'O, seq_nr));
|
|
|
|
|
setverdict(pass);
|
|
|
|
|
}
|
|
|
|
|
[] GTP.receive(tr_GTPC_SGSNContextResp) {
|
|
|
|
|
setverdict(fail, "Rx unexpected SGSN Context Resp");
|
|
|
|
|
}
|
|
|
|
|
[] T.timeout {
|
|
|
|
|
setverdict(fail, "Timeout waiting for SGSN Contect Resp");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
testcase TC_sgsn_context_req() 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), testcasename(), g_gb, 72);
|
|
|
|
|
vc_conn.done;
|
|
|
|
|
f_cleanup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* SGSN originated SGSN Context Request procedure (SGSN requests, we respond) */
|
|
|
|
|
private function f_TC_sgsn_context_req2(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 Request from SGSN: ", gtpc_ud.gtpc);
|
|
|
|
|
setverdict(pass);
|
|
|
|
|
T.stop;
|
|
|
|
|
}
|
|
|
|
|
[] GTP.receive(tr_GTPC_SGSNContextResp) {
|
|
|
|
|
setverdict(fail, "Rx unexpected SGSN Context Req");
|
|
|
|
|
mtc.stop;
|
|
|
|
|
}
|
|
|
|
|
[] T.timeout {
|
|
|
|
|
setverdict(fail, "Timeout waiting for SGSN Contect 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));
|
|
|
|
|
|
|
|
|
|
/* The SGSN ACKs */
|
|
|
|
|
T.start(2.0);
|
|
|
|
|
alt {
|
|
|
|
|
[] GTP.receive(tr_GTPC_SGSNContextAck) -> value gtpc_ud {
|
|
|
|
|
log("Rx SGSN Context ACK from SGSN: ", gtpc_ud.gtpc);
|
|
|
|
|
setverdict(pass);
|
|
|
|
|
T.stop;
|
|
|
|
|
}
|
|
|
|
|
[] T.timeout {
|
|
|
|
|
setverdict(fail, "Timeout waiting for SGSN Contect ACK");
|
|
|
|
|
mtc.stop;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO: the RAU procedure continues, see f_routing_area_update() */
|
|
|
|
|
T.start(2.0);
|
|
|
|
|
alt {
|
|
|
|
|
[] as_routing_area_update_gb(0) { setverdict(pass); }
|
|
|
|
|
[] BSSGP[0].receive { repeat; }
|
|
|
|
|
[] T.timeout {
|
|
|
|
|
setverdict(fail, "Timeout completing the RAU procedure");
|
|
|
|
|
mtc.stop;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
testcase TC_sgsn_context_req2() 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_req2), testcasename(), g_gb, 73);
|
|
|
|
|
vc_conn.done;
|
|
|
|
|
f_cleanup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
control {
|
|
|
|
|
execute( TC_attach() );
|
|
|
|
|
execute( TC_attach_mnc3() );
|
|
|
|
|