pespin has submitted this change. ( 
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/35513?usp=email )

Change subject: mme: Introduce test TC_ue_cell_reselect_geran_to_eutran
......................................................................

mme: Introduce test TC_ue_cell_reselect_geran_to_eutran

This test allows reproducing an idle mobility GERAN->EUTRAN.

Related: OS#6294
Change-Id: I6f8f077b99e83e6467d2b0c05148b81dbcf2ede4
---
M library/NAS_Templates.ttcn
M library/S1AP_Emulation.ttcn
M mme/MME_Tests.ttcn
3 files changed, 241 insertions(+), 6 deletions(-)

Approvals:
  daniel: Looks good to me, approved
  Jenkins Builder: Verified




diff --git a/library/NAS_Templates.ttcn b/library/NAS_Templates.ttcn
index 944d857..d45dc7d 100644
--- a/library/NAS_Templates.ttcn
+++ b/library/NAS_Templates.ttcn
@@ -44,6 +44,9 @@
 }

 const BIT4 c_EPS_SEC_NONE := '0000'B;
+const BIT4 c_EPS_SEC_IP := '0001'B;
+const BIT4 c_EPS_SEC_IP_CIPH := '0010'B;
+
 const BIT4 c_EPS_NAS_PD_EMM := '0111'B;
 const BIT4 c_EPS_NAS_PD_ESM := '0010'B;

@@ -58,6 +61,16 @@
        content := inp
 }

+/* 9.9.3.4A - 10.5.1.2/24.008 */
+template (value) CipheringKeySequenceNumberTV
+ts_CipheringKeySequenceNumberTV(template (value) BIT3 key_seq) := {
+        keySequence := {
+               keySequence := key_seq,
+               spare := '0'B
+        },
+        elementIdentifier := '1000'B
+}
+
 private template (value) MobileIdentityLV
 ts_NAS_MobileIdLV(template (value) MobileIdentityV mid) := {
        lengthIndicator := 0,
@@ -178,6 +191,19 @@
         ePS_MobileIdentity := ts_NAS_MobileId_GUTI(guti)
 }

+/* 9.9.3.25 Nonce */
+template (value) NonceTV
+ts_NonceTV(template (value) OCT4 nonce) := {
+        elementIdentifier := '55'O,
+        noncevalue := nonce
+}
+function f_ts_NonceTV(template (omit) OCT4 nonce) return template (omit) 
NonceTV {
+       if (istemplatekind(nonce, "omit")) {
+               return omit;
+       }
+       return ts_NonceTV(nonce);
+}
+
 /* 9.9.3.26 P-TMSI signature */
 template (value) P_TMSISignatureTV
 ts_PTMSI_SignatureTV(template (value) OCT3 ptmsi_sig) := {
@@ -408,6 +434,20 @@
        }
 }

+/* 8.2.27 Tracking Area Update Complete */
+template (value) PDU_NAS_EPS
+ts_PDU_NAS_EPS_TrackingAreaUpdateComplete(template (value) BIT4 
securityHeaderType := c_EPS_SEC_NONE) := {
+       protocolDiscriminator := c_EPS_NAS_PD_EMM,
+       ePS_messages := {
+               ePS_MobilityManagement := {
+                       pDU_NAS_EPS_TrackingAreaUpdateComplete := {
+                               securityHeaderType := securityHeaderType,
+                               messageType := '01001010'B
+                       }
+               }
+       }
+}
+
 /* 8.2.28 Tracking Area Update Reject */
 template (present) PDU_NAS_EPS
 tr_PDU_NAS_EPS_TrackingAreaUpdateReject(template (present) EMM_CauseV cause := 
?) := {
@@ -429,7 +469,9 @@
 template (value) PDU_NAS_EPS
 ts_PDU_NAS_EPS_TrackingAreaUpdateRequest(template (value) EPS_MobileIdentityLV 
old_guti,
                                         template (omit) P_TMSISignatureTV 
old_ptmsi_sig := omit,
-                                        template (omit) GUTI_TypeTV 
old_guti_type := omit) := {
+                                        template (omit) GUTI_TypeTV 
old_guti_type := omit,
+                                        template (omit) NonceTV nonce_ue := 
omit,
+                                        template (omit) 
CipheringKeySequenceNumberTV gprs_cksn := omit) := {
        protocolDiscriminator := c_EPS_NAS_PD_EMM,
        ePS_messages := {
                ePS_MobilityManagement := {
@@ -440,10 +482,10 @@
                                nasKeySetId := ts_NAS_KeySetIdentifierV,
                                oldGUTI := old_guti,
                                nonCurrentNative_nasKeySetId := omit,
-                               gprsCipheringKeySequenceNumber := omit,
+                               gprsCipheringKeySequenceNumber := gprs_cksn,
                                old_P_TMSISignature := old_ptmsi_sig,
                                additionalGUTI := omit,
-                               nonce := omit,
+                               nonce := nonce_ue,
                                uENetworkCapability := omit,
                                lastVisitedRegisteredTAI := omit,
                                dRXParameter := omit,
diff --git a/library/S1AP_Emulation.ttcn b/library/S1AP_Emulation.ttcn
index e3e3216..955c690 100644
--- a/library/S1AP_Emulation.ttcn
+++ b/library/S1AP_Emulation.ttcn
@@ -72,7 +72,8 @@
 };
 type union S1APEM_Config {
        NAS_Keys set_nas_keys,
-       ResetNAScounts reset_nas_counts
+       ResetNAScounts reset_nas_counts,
+       NAS_ALG_INT set_nas_alg_int
 };

 type enumerated S1APEM_EventUpDown {
@@ -453,6 +454,11 @@
                        S1apAssociationTable[assoc_id].nus.rx_count := 0;
                        S1apAssociationTable[assoc_id].nus.tx_count := 0;
                        }
+               /* Configuration primitive from client */
+               [] S1AP_CLIENT.receive(S1APEM_Config:{set_nas_alg_int:=?}) -> 
value s1cfg sender vc_conn {
+                       var integer assoc_id := f_assoc_id_by_comp(vc_conn);
+                       S1apAssociationTable[assoc_id].nus.alg_int := 
s1cfg.set_nas_alg_int;
+                       }
                /* S1AP from client: InitialUE */
                [] S1AP_CLIENT.receive(tr_S1AP_InitialUE) -> value msg sender 
vc_conn {
                        /* create a table entry about this connection */
diff --git a/mme/MME_Tests.ttcn b/mme/MME_Tests.ttcn
index 2194e8a..aa23a84 100644
--- a/mme/MME_Tests.ttcn
+++ b/mme/MME_Tests.ttcn
@@ -617,7 +617,7 @@
 }


-private altstep as_s1ap_handle_IntialCtxSetupReq() runs on ConnHdlr {
+private altstep as_s1ap_handle_IntialCtxSetupReq_Attach_Accept() runs on 
ConnHdlr {
        var S1AP_PDU rx_msg;
        var PDU_NAS_EPS rx_nas;
        [] S1AP.receive(tr_S1AP_IntialCtxSetupReq) -> value rx_msg {
@@ -654,6 +654,40 @@
        }
 }

+private altstep as_s1ap_handle_IntialCtxSetupReq_TAU_Accept() runs on ConnHdlr 
{
+       var S1AP_PDU rx_msg;
+       var PDU_NAS_EPS rx_nas;
+       [] S1AP.receive(tr_S1AP_IntialCtxSetupReq) -> value rx_msg {
+               /* 3GPP TS 23.401 D.3.6 step 22: */
+               var template (omit) MME_UE_S1AP_ID mme_ue_id := 
f_S1AP_get_MME_UE_S1AP_ID(rx_msg);
+               var template (omit) ENB_UE_S1AP_ID enb_ue_id := 
f_S1AP_get_ENB_UE_S1AP_ID(rx_msg);
+               var template (value) E_RABSetupItemCtxtSURes rab_setup_it;
+               var template (value) E_RABSetupListCtxtSURes rab_setup_items;
+               var S1APEM_Config cfg;
+
+               S1AP.receive(tr_PDU_NAS_EPS_TrackingAreaUpdateAccept)-> value 
rx_nas;
+
+               /* Configure integrity protection: */
+               cfg := {
+                       set_nas_alg_int := NAS_ALG_IP_EIA1
+               };
+               S1AP.send(cfg);
+
+               rab_setup_it := ts_S1AP_RABSetupItemCtxtSURes(rab_id := 5,
+                                                       tla := 
oct2bit(f_inet_addr(mp_mme_ip)),
+                                                       gtp_teid := 
'00000002'O);
+               rab_setup_items := ts_S1AP_RABSetupListCtxtSURes(rab_setup_it);
+               S1AP.send(ts_S1AP_InitialCtxSetupResp(valueof(mme_ue_id), 
valueof(enb_ue_id), rab_setup_items));
+
+               /* 3GPP TS 23.401 D.3.6 step 23: */
+               /* Integrity Protection: TS 24.301 Section 4.4.4.3*/
+               
S1AP.send(ts_PDU_NAS_EPS_TrackingAreaUpdateComplete(c_EPS_SEC_IP));
+               }
+       [] S1AP.receive(PDU_NAS_EPS:?) -> value rx_nas {
+               Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Rx 
Unexpected NAS PDU msg: ", rx_nas));
+       }
+}
+
 private altstep as_s1ap_handle_UeContextReleaseCmd(template S1AP_IEs.Cause 
cause := ?) runs on ConnHdlr {
        var S1AP_PDU rx_msg;
        var PDU_NAS_EPS rx_nas;
@@ -925,6 +959,43 @@

 }

+private altstep as_gtp_sgsn_context_2g_to_4g(OCT4 new_sgsn_teid := 
'ABABABAB'O, GTP_Templates.GTP_RATType rat_type := GTP_RAT_TYPE_EUTRAN) runs on 
ConnHdlr {
+       var Gtp1cUnitdata gtpc_pdu;
+
+       [] GTP.receive(tr_GTPC_SGSNContextReq(g_gn_iface_peer, 
tr_SGSNContextReqPDU(rat_type := int2oct(enum2int(rat_type), 1)))) -> value 
gtpc_pdu {
+               var template (value) PDP_Context_GTPC pdp_ctx;
+               var template (value) GTPC_PDUs SGSNContextRespPDU;
+               var Gtp1cUnitdata gtpc_pdu_ack;
+               var OCT4 old_mme_remote_teid := 
gtpc_pdu.gtpc.gtpc_pdu.sgsn_ContextRequest.teidControlPlane.teidControlPlane;
+
+               const OCT16 ck := '740d62df9803eebde5120acf358433d0'O;
+               const OCT16 ik := '11329aae8e8d2941bb226b2061137c58'O;
+
+               pdp_ctx := 
ts_PDP_Context_GTPC(f_inet_addr(g_pars.ue_pars.ue_ip),
+                                              f_inet_addr(mp_gn_local_ip),
+                                              c_NAS_defaultAPN,
+                                              ggsn_teic := '12345678'O,
+                                              ggsn_teid := '87654321'O);
+               SGSNContextRespPDU := 
ts_SGSNContextRespPDU(GTP_CAUSE_REQUEST_ACCEPTED,
+                                                          g_pars.ue_pars.imsi,
+                                                          new_sgsn_teid,
+                                                          
f_inet_addr(mp_gn_local_ip),
+                                                          
ts_MM_ContextUMTS(ck, ik),
+                                                          { pdp_ctx });
+               GTP.send(ts_GTPC_SGSNContextResp(g_gn_iface_peer,
+                                                old_mme_remote_teid,
+                                                
oct2int(gtpc_pdu.gtpc.opt_part.sequenceNumber),
+                                                SGSNContextRespPDU));
+
+               GTP.receive(tr_GTPC_SGSNContextAck(g_gn_iface_peer, 
new_sgsn_teid,
+                                                  
tr_SGSNContextAckPDU(GTP_CAUSE_REQUEST_ACCEPTED))) -> value gtpc_pdu;
+               setverdict(pass);
+       }
+       [] GTP.receive {
+               setverdict(fail, "unexpected GTPC message from MME");
+       }
+}
+
 private function f_attach() runs on ConnHdlr {
        var template (value) EPS_MobileIdentityV mi := 
ts_NAS_MobileId_IMSI(g_pars.ue_pars.imsi);
        var template (value) PDU_NAS_EPS nas_esm, nas_emm;
@@ -963,7 +1034,7 @@

        T.start;
        alt {
-       [] as_s1ap_handle_IntialCtxSetupReq();
+       [] as_s1ap_handle_IntialCtxSetupReq_Attach_Accept();
        [] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, 
log2str("No message from MME")); }
        }

@@ -1383,6 +1454,109 @@
        vc_conn.done;
 }

+/* 3GPP TS 23.401 D.3.6, TS 23.003 2.8.2.2 */
+private function rai_ptmsi2_guti(in RoutingAreaIdentity rai, in OCT4 ptmsi, in 
OCT3 ptmsi_sig, out NAS_EPS_Types.GUTI guti) runs on ConnHdlr {
+
+
+       var bitstring ptmsi_bits := oct2bit(ptmsi);
+       var bitstring ptmsi_sig_bits := oct2bit(ptmsi_sig);
+       var bitstring mtmsi_bits := '11'B &
+                                   substr(ptmsi_bits, 2, 6) &
+                                   substr(ptmsi_sig_bits, 0, 8) &
+                                   substr(ptmsi_bits, 16, 16);
+       guti := valueof(ts_NAS_GUTI(mcc_mnc := rai.mcc_digits & rai.mnc_digits,
+                           mmegi := rai.lac,
+                           mmec := rai.rac,
+                           tmsi := bit2oct(mtmsi_bits)));
+}
+/* Test UE attached to GERAN reselecting a EUTRAN cell. In this scenario, the
+ * new MME will attempt to obtain information of the UE from the old SGSN
+ * through Gn interface using SGSN Context Request/Response procedure 
(OS#6294). */
+/* 3GPP TS 23.401 D.3.6, TS 23.003 2.8.2.1 */
+private function f_TC_ue_cell_reselect_geran_to_eutran(ConnHdlrPars pars) runs 
on ConnHdlr {
+       f_init_handler(pars);
+       f_gtp_register_imsi(g_pars.ue_pars.imsi);
+       f_gtp2_register_imsi(g_pars.ue_pars.imsi);
+       /* SGSN Context Req doesn't necessarily contain IMSI, hence expect it 
through TEID=0 */
+       f_gtp_register_teid('00000000'O);
+       /* passed in SGSN Context Resp to MME, will be used by MME when 
answering with SGSN Context Ack: */
+       const OCT4 new_sgsn_teid := 'ABABABAB'O;
+       f_gtp_register_teid(new_sgsn_teid);
+
+       var template (value) EPS_MobileIdentityV mi := 
ts_NAS_MobileId_IMSI(pars.ue_pars.imsi);
+       var template (value) S1AP_PDU tx;
+       var template (value) PDU_NAS_EPS nas_tau;
+       var RoutingAreaIdentity rai;
+       var OCT4 ptmsi := f_gen_tmsi(suffix := 0, nri_v := 0, nri_bitlen := 8);
+       var OCT3 ptmsi_sig := f_rnd_octstring(3);
+       var NAS_EPS_Types.GUTI guti_val;
+       var template (value) EPS_MobileIdentityLV old_guti;
+       var S1APEM_Config cfg;
+       timer T := 5.0;
+
+       rai := valueof(ts_RoutingAreaIdentity(mp_gn_local_mcc, mp_gn_local_mnc,
+                                     int2oct(mp_gn_local_lac, 2), 
int2oct(mp_gn_local_rac, 1)));
+       rai_ptmsi2_guti(rai, ptmsi, ptmsi_sig, guti_val);
+       old_guti := ts_EPS_MobileId_GUTI_(guti_val);
+
+       nas_tau := ts_PDU_NAS_EPS_TrackingAreaUpdateRequest(old_guti,
+                                                           
ts_PTMSI_SignatureTV(ptmsi_sig),
+                                                           
ts_GUTI_TypeTV(GUTI_TYPE_MAPPED),
+                                                           
ts_NonceTV('12345678'O),
+                                                           
ts_CipheringKeySequenceNumberTV('000'B));
+       tx := ts_S1AP_InitialUE(p_eNB_value := 0, p_nasPdu := 
enc_PDU_NAS_EPS(valueof(nas_tau)),
+                               p_tAI := 
ts_enb_S1AP_TAI(g_pars.enb_pars[g_pars.mme_idx]),
+                               p_eUTRAN_CGI := 
ts_enb_S1AP_CGI(g_pars.enb_pars[g_pars.mme_idx]),
+                               p_rrcCause := mo_Signalling);
+
+       S1AP.send(tx);
+
+       /* NAS counts are reset to zero when a mapped security context is 
created. */
+       cfg := {
+               reset_nas_counts := {}
+       };
+       S1AP.send(cfg);
+
+       as_gtp_sgsn_context_2g_to_4g(new_sgsn_teid);
+
+       /* We now expect the MME to send a Create Session Request to the SGW-C 
*/
+       T.start;
+       alt {
+       [] as_GTP2C_CreateSession_success();
+       [] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, 
log2str("No message from MME")); }
+       }
+
+       /* 3GPP TS 23.401 D.3.6 steps 14-21: */
+       as_DIA_UpdLoc();
+
+       /* 3GPP TS 23.401 D.3.6 step 22, 23: */
+       as_s1ap_handle_IntialCtxSetupReq_TAU_Accept();
+
+       /* We now expect the MME to send a Modify Bearer Request to the SGW-C */
+       T.start;
+       alt {
+       [] as_GTP2C_ModifyBearer_success();
+       [] T.timeout { Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, 
log2str("No message from MME")); }
+       }
+
+       /* Leave some time for MME to handle Modify Bearer Response: */
+       f_sleep(1.0);
+}
+testcase TC_ue_cell_reselect_geran_to_eutran() runs on MTC_CT {
+       var charstring id := testcasename();
+
+       f_init_diameter(id);
+       f_init_s1ap(id, 7);
+       f_init_gtpv2_s11(id);
+       f_s1ap_setup(0);
+       f_init_gtp(id);
+
+       var ConnHdlrPars pars := f_init_pars(ue_idx := 0);
+       var ConnHdlr vc_conn;
+       vc_conn := 
f_start_handler_with_pars(refers(f_TC_ue_cell_reselect_geran_to_eutran), pars);
+       vc_conn.done;
+}
+
 control {
        execute( TC_s1ap_setup_wrong_plmn() );
        execute( TC_s1ap_setup_wrong_tac() );
@@ -1393,6 +1567,7 @@
        execute( TC_RIM_RAN_INF() );
        execute( TC_s1ap_reset() );
        execute( TC_ue_cell_reselect_eutran_to_geran() );
+       execute( TC_ue_cell_reselect_geran_to_eutran() );
 }



--
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/35513?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: I6f8f077b99e83e6467d2b0c05148b81dbcf2ede4
Gerrit-Change-Number: 35513
Gerrit-PatchSet: 4
Gerrit-Owner: pespin <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <[email protected]>
Gerrit-Reviewer: pespin <[email protected]>
Gerrit-MessageType: merged

Reply via email to