laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/39017?usp=email )
Change subject: SGSN_Tests: fix TC_sgsn_context_req_out ......................................................................
SGSN_Tests: fix TC_sgsn_context_req_out
The TC_sgsn_context_req_out wasn't complete when merged and didn't work as expected.
Change-Id: I0666a518aed57c2594653ab6b0f801c4193fd2f3 --- M sgsn/SGSN_Tests.ttcn M sgsn/gen_links.sh 2 files changed, 151 insertions(+), 17 deletions(-)
Approvals: pespin: Looks good to me, approved Jenkins Builder: Verified
diff --git a/sgsn/SGSN_Tests.ttcn b/sgsn/SGSN_Tests.ttcn index 51eabd4..1d58b46 100644 --- a/sgsn/SGSN_Tests.ttcn +++ b/sgsn/SGSN_Tests.ttcn @@ -69,6 +69,10 @@
import from BSSGP_ConnHdlr all;
+import from NAS_EPS_Templates all; +import from NAS_EPS_Types all; + + modulepar { /* IP/port on which we run our internal GSUP/HLR emulation */ charstring mp_hlr_ip := "127.0.0.1"; @@ -1730,7 +1734,7 @@ /* Attempt an attach, but loose the Identification Request (IMEI) */ private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr { var integer count_req := 0; - var MobileIdentityLV mi; + var MobileL3_CommonIE_Types.MobileIdentityLV mi;
f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
@@ -1776,7 +1780,7 @@ /* Attempt an attach, but loose the Identification Request (IMSI) */ private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr { var integer count_req := 0; - var MobileIdentityLV mi; + var MobileL3_CommonIE_Types.MobileIdentityLV mi;
/* set p_tmsi to use it in Attach Req via f_mi_get_lv() */ g_pars.p_tmsi := 'c0000035'O; @@ -2060,7 +2064,7 @@
private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr { var integer count_req := 0; - var MobileIdentityLV mi; + var MobileL3_CommonIE_Types.MobileIdentityLV mi; var RoutingAreaIdentificationV rand_rai := f_random_RAI(); var PDU_L3_SGSN_MS l3_mt;
@@ -3147,24 +3151,112 @@ f_cleanup(); }
+/* 3GPP TS 23.401 D.3.5, TS 23.003 2.8.2.1 */ +function guti2rai_ptmsi(in NAS_EPS_Types.GUTI guti, in OCT2 truncated_nas_token, out RoutingAreaIdentificationV rai, out OCT4 ptmsi, out OCT3 ptmsi_sig) { + var bitstring mtmsi_bits := oct2bit(guti.mTMSI); + var bitstring ptmsi_bits; + var bitstring ptmsi_sig_bits; + + rai := { + mccDigit1 := guti.mccDigit1, + mccDigit2 := guti.mccDigit2, + mccDigit3 := guti.mccDigit3, + mncDigit3 := guti.mncDigit3, + mncDigit1 := guti.mncDigit1, + mncDigit2 := guti.mncDigit2, + lac := guti.mMEGI, + rac := guti.mMEC + }; + /* 3GPP TS 23.003 2.8.2.0: "P-TMSI shall be of 32 bits length where the two topmost bits are + * reserved and always set to '11'. Hence, for a UE which may handover to GERAN/UTRAN (based on + * subscription and UE capabilities), the corresponding bits in the M-TMSI are set to '11'" + */ + ptmsi_bits := '11'B & substr(mtmsi_bits, 2, 6) & oct2bit(guti.mMEC) & substr(mtmsi_bits, 16, 16); + ptmsi_sig_bits := substr(mtmsi_bits, 8, 8) & oct2bit(truncated_nas_token); + ptmsi := bit2oct(ptmsi_bits); + ptmsi_sig := bit2oct(ptmsi_sig_bits); + /* TODO: The UE shall fill the remaining 2 octets of the <P-TMSI signature> according to clauses 9.1.1, 9.4.1, 10.2.1, or + * 10.5.1 of 3GPP TS.33.401 [89] , as appropriate, for RAU/Attach procedures.*/ +} + +function rai_to_oct(in RoutingAreaIdentity rai) return OCT6 { + var OCT6 ret; + ret := hex2oct(rai.mcc_digits[1] & rai.mcc_digits[0]) & + hex2oct(rai.mnc_digits[2] & rai.mcc_digits[2]) & + hex2oct(rai.mnc_digits[1] & rai.mnc_digits[0]) & + rai.lac & rai.rac; + return ret; +} + +function raiv_to_gtp_rai(in RoutingAreaIdentificationV rai) return template (value) RoutingAreaIdentity { + return ts_RoutingAreaIdentity( + mcc_digits := rai.mccDigit1 & rai.mccDigit2 & rai.mccDigit3, + mnc_digits := rai.mccDigit3 & rai.mccDigit1 & rai.mccDigit2, + lac := rai.lac, + rac := rai.rac) +} + /* 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; - var OCT4 teidc := f_gtp_teic_random(); + /* Used by SGSN Ctx Req/Resp/Ack */ + var OCT4 ctx_teidc := f_gtp_teic_random(); + /* Used for the UE which is transmited via Ctx Response */ + var OCT4 pdp_teidc := f_gtp_teic_random(); timer T; + var RoutingAreaIdentificationV rai; + var P_TMSI_TypeTV p_tmsi_type; + var OCT3 p_tmsi_sig; + var OCT4 add_p_tmsi; + var RoutingAreaIdentificationV add_rai; + var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip)); + + var Gtp1cPeer peer := { + connId := 1, + remName := mp_sgsn_gtp_ip, + remPort := GTP1C_PORT + } + g_pars.vec := f_gen_auth_vec_3g(); + + /* SGSN Context Req doesn't necessarily contain IMSI, hence expect it through TEID=0 */ + f_gtp1u_register_teid('00000000'O); + f_gtp1u_register_teid(ctx_teidc); + f_gtp1u_register_teid(pdp_teidc); + + g_pars.ra := f_random_RAI(); + var NAS_EPS_Types.GUTI guti := valueof(ts_NAS_GUTI( + mcc_mnc := g_pars.ra.mccDigit1 & g_pars.ra.mccDigit2 & g_pars.ra.mccDigit3 & + g_pars.ra.mncDigit3 & g_pars.ra.mncDigit1 & g_pars.ra.mncDigit2, + mmegi := '000c'O, + mmec := '06'O, + tmsi := '12345678'O)); + + guti2rai_ptmsi(guti, '8888'O, add_rai, add_p_tmsi, p_tmsi_sig);
/* 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)), + f_send_l3(ts_GMM_RAU_REQ(mi_lv := valueof(ts_MI_TMSI_LV(add_p_tmsi)), upd_type := GPRS_UPD_T_RA, - old_ra := f_random_RAI()), 0); + old_ra := add_rai, + p_tmsi_sig := ts_PtmsiSigTV(p_tmsi_sig), + p_tmsi_type := ts_PtmsiTypeTV(c_GMM_PMTSI_TYPE_MAPPED), + ms_network_cap := ts_GMM_MsNetCapV + ), + 0);
- + var GTPv1C_Templates.GTP_RATType rat_type := GTP_RAT_TYPE_EUTRAN; /* The SGSN has no idea about the MS and inquires the MME about it */ T.start(2.0); alt { - [] GTP[GTP_GGSN_IDX].receive(tr_GTPC_SGSNContextReq(?, ?)) -> value gtpc_ud { + [] GTP[GTP_GGSN_IDX].receive( + tr_GTPC_SGSNContextReq( + peer, + tr_SGSNContextReqPDU( + rai := raiv_to_gtp_rai(rai), + ptmsi := ts_PTMSI(add_p_tmsi), + ptmsi_sig := ts_PTMSI_sig(p_tmsi_sig), + rat_type := int2oct(enum2int(rat_type), 1)))) -> value gtpc_ud { log("Rx SGSN Context Req from SGSN"); setverdict(pass); T.stop; @@ -3189,24 +3281,39 @@ }
/* The MME responds */ - var OCT8 kc := f_rnd_octstring(8); + var OCT16 ck := f_rnd_octstring(16); + var OCT16 ik := f_rnd_octstring(16);
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); + apn := '08696E7465726E6574'O, + ggsn_teic := pdp_teidc);
var template (value) GTPC_PDUs ctx_rsp; + var OCT4 old_sgsn_remote_teid := gtpc_ud.gtpc.gtpc_pdu.sgsn_ContextRequest.teidControlPlane.teidControlPlane; ctx_rsp := ts_SGSNContextRespPDU(cause := GTP_CAUSE_REQUEST_ACCEPTED, imsi := g_pars.imsi, - teic := teidc, - mm_context := ts_MM_ContextGSM(kc), + teic := ctx_teidc, + mm_context := ts_MM_ContextUMTS(ck, ik), pdp_ctx_list := { pdp_ctx }); - GTP[GTP_GGSN_IDX].send(ts_GTPC_SGSNContextResp(gtpc_ud.peer, '12345678'O, seq_nr, ctx_rsp)); + GTP[GTP_GGSN_IDX].send(ts_GTPC_SGSNContextResp(gtpc_ud.peer, + old_sgsn_remote_teid, + oct2int(gtpc_ud.gtpc.opt_part.sequenceNumber), + ctx_rsp));
- /* TODO: Security Functions (auth/ciphering?) */ + /* TODO: Create a test case which fails at auth! */ + /* We expect a Send Auth Information and ignoring all keys received by the MME */ + T.start(2.0); + alt { + [] as_gmm_auth(umts_aka_challenge := true, expect_sai := true) {}; + [] T.timeout { + setverdict(fail, "Timeout waiting for SGSN SAI"); + mtc.stop; + } + }
- /* The SGSN ACKs */ + /* Step 4: The SGSN ACKs */ T.start(2.0); alt { [] GTP[GTP_GGSN_IDX].receive(tr_GTPC_SGSNContextAck) -> value gtpc_ud { @@ -3220,8 +3327,30 @@ } }
- /* TODO: Update PDP Context Req/Resp */ - /* TODO: 7..10 Update Location, ISD */ + /* 7..10 Update Location, ISD */ + T.start(2.0); + alt { + [] as_gmm_gsup_lu_isd(); + [] T.timeout { + setverdict(fail, "Timeout waiting for Update Location, ISD"); + mtc.stop; + } + } + + /* Step 5: There is no such step */ + /* Step 6: Update PDP Context Req/Resp */ + T.start(2.0); + alt { + [] as_ggsn_gtp_ctx_upd_req(apars, exp_dir_tun := false) { + log("Rx GTP PDP Context Update Request"); + setverdict(pass); + T.stop; + } + [] T.timeout { + setverdict(fail, "Timeout waiting for Update PDP Context Req"); + mtc.stop; + } + }
/* RAU procedure completion */ T.start(2.0); diff --git a/sgsn/gen_links.sh b/sgsn/gen_links.sh index 338b9f5..2b565c4 100755 --- a/sgsn/gen_links.sh +++ b/sgsn/gen_links.sh @@ -82,6 +82,10 @@ FILES+="RANAP_Types.ttcn RANAP_Templates.ttcn RANAP_CodecPort.ttcn RANAP_EncDec.cc " gen_links $DIR $FILES
+DIR=$BASEDIR/titan.ProtocolModules.NAS_EPS_15.2.0.1/src +FILES="NAS_EPS_Types.ttcn" +gen_links $DIR $FILES + DIR=../library FILES="Misc_Helpers.ttcn General_Types.ttcn GSM_Types.ttcn Osmocom_Types.ttcn " FILES+="RAW_NS.ttcnpp NS_Provider_IPL4.ttcn NS_Emulation.ttcnpp " @@ -91,6 +95,7 @@ FILES+="StatsD_Types.ttcn StatsD_CodecPort.ttcn StatsD_CodecPort_CtrlFunct.ttcn StatsD_CodecPort_CtrlFunctdef.cc StatsD_Checker.ttcnpp " FILES+="LLC_Templates.ttcn L3_Templates.ttcn L3_Common.ttcn " FILES+="ITU_X213_Types.ttcn " +FILES+="NAS_EPS_Templates.ttcn " FILES+="RAN_Emulation.ttcnpp SCCP_Adapter.ttcnpp RAN_Adapter.ttcnpp SCCP_Templates.ttcn " # IPA_Emulation + dependencies FILES+="IPA_Types.ttcn IPA_Emulation.ttcnpp IPA_CodecPort.ttcn IPA_CodecPort_CtrlFunct.ttcn IPA_CodecPort_CtrlFunctDef.cc Native_Functions.ttcn Native_FunctionDefs.cc "