mme: Add code to derive NAS token from NAS ul_count

NAS Token is derived from kasme and NAS ul_count as specified in 3GPP TS
33.401 A.9, and its LSB 16 bits passed to the network when mapping the GUTI to
RAI+PTMSI+PTIMSI_SIG.

Take the chance to move guti2rai_ptmsi() up to before the place it is
used.
Change-Id: I5e6003a2fe3e74cc93cfe4a288e6c114aa288d0b
diff --git a/mme/MME_Tests.ttcn b/mme/MME_Tests.ttcn
index f4f41e2..50b89b3 100644
--- a/mme/MME_Tests.ttcn
+++ b/mme/MME_Tests.ttcn
@@ -83,6 +83,7 @@
 	hexstring imsi,
 	charstring ue_ip,
 	NAS_EPS_Types.GUTI guti optional,
+	octetstring kasme optional,
 
 	/* TEI (Control) local side, S11 (SGW) */
 	OCT4 	s11_teic_local,
@@ -289,6 +290,7 @@
 		imsi := f_gen_imsi(imsi_suffix),
 		ue_ip := "192.168.123.50",
 		guti := omit,
+		kasme := omit,
 		s11_teic_local := '00000000'O,
 		s11_teic_remote := omit,
 		s5c_teic_local := '00000000'O,
@@ -585,11 +587,11 @@
 		const OCT3 plmn_id := '00F110'O;
 		const OCT6 sqn := '000000000020'O;
 		const OCT6 ak := substr(autn, 0, 6) xor4b sqn;
-		var octetstring kasme := f_kdf_kasme(ck, ik, plmn_id, sqn, ak);
+		g_pars.ue_pars.kasme := f_kdf_kasme(ck, ik, plmn_id, sqn, ak);
 		var S1APEM_Config cfg := {
 			set_nas_keys := {
-				k_nas_int := f_kdf_nas_int(1, kasme),
-				k_nas_enc := f_kdf_nas_enc(1, kasme)
+				k_nas_int := f_kdf_nas_int(1, g_pars.ue_pars.kasme),
+				k_nas_enc := f_kdf_nas_enc(1, g_pars.ue_pars.kasme)
 			}
 		};
 		S1AP.send(cfg);
@@ -856,6 +858,31 @@
 	}
 }
 
+
+/* 3GPP TS 23.401 D.3.5, TS 23.003 2.8.2.1 */
+private function guti2rai_ptmsi(in NAS_EPS_Types.GUTI guti, in OCT2 truncated_nas_token, out RoutingAreaIdentity rai, out OCT4 ptmsi, out OCT3 ptmsi_sig) runs on ConnHdlr {
+	var bitstring mtmsi_bits := oct2bit(guti.mTMSI);
+	var bitstring ptmsi_bits;
+	var bitstring ptmsi_sig_bits;
+
+	rai := valueof(ts_RoutingAreaIdentity(guti.mccDigit1 & guti.mccDigit2 & guti.mccDigit3,
+					      guti.mncDigit3 & guti.mncDigit1 & guti.mncDigit2,
+					      guti.mMEGI, 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.*/
+}
+
+/* Test UE attached to EUTRAN reselecting a GERAN cell. In this scenario, the
+ * new SGSN will attempt to obtain information of the UE from the old SGSN (MME)
+ * through Gn interface using SGSN Context Request/Response procedure (OS#6294). */
 private function f_gtp_sgsn_context_4g_to_2g(OCT4 new_sgsn_local_teid := '12345678'O) runs on ConnHdlr {
 	var template (value) GTPC_PDUs SGSNContextReqPDU;
 	var RoutingAreaIdentity rai;
@@ -864,7 +891,11 @@
 	var Gtp1cUnitdata gtpc_pdu;
 	var OCT4 old_mme_local_teid;
 
-	guti2rai_ptmsi(g_pars.ue_pars.guti, rai, ptmsi, ptmsi_sig);
+	/* Derive NAS Token (and post-increment ul_count): */
+	var OCT32 nas_token := f_s1apem_derive_nas_token(g_pars.ue_pars.kasme);
+	var OCT2 truncated_nas_token := substr(nas_token, 30, 2);
+
+	guti2rai_ptmsi(g_pars.ue_pars.guti, truncated_nas_token, rai, ptmsi, ptmsi_sig);
 
 	SGSNContextReqPDU := ts_SGSNContextReqPDU(rai, new_sgsn_local_teid, f_inet_addr(mp_gn_local_ip),
 						  ptmsi := ts_PTMSI(ptmsi), ptmsi_sig := ts_PTMSI_sig(ptmsi_sig));
@@ -880,10 +911,10 @@
 		setverdict(pass);
 		}
 	[] GTP.receive {
-		setverdict(fail, "unexpected GTPC message from MME");
+		 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("unexpected GTPC message from MME"));
 		}
 	[] T.timeout {
-		setverdict(fail, "no SGSN Context Response from MME");
+		 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("no SGSN Context Response from MME"));
 		}
 	}
 
@@ -1312,36 +1343,6 @@
 	vc_conn.done;
 }
 
-/* Test UE attached to EUTRAN reselecting a GERAN cell. In this scenario, the
- * new SGSN will attempt to obtain information of the UE from the old SGSN (MME)
- * through Gn interface using SGSN Context Request/Response procedure (OS#6294). */
-/* TS 23.003 2.8.2.1 */
-private function guti2rai_ptmsi(in NAS_EPS_Types.GUTI guti, out RoutingAreaIdentity rai, out OCT4 ptmsi, out OCT3 ptmsi_sig) runs on ConnHdlr {
-	var bitstring mtmsi_bits := oct2bit(guti.mTMSI);
-	var bitstring ptmsi_bits;
-	var bitstring ptmsi_sig_bits;
-
-	rai := valueof(ts_RoutingAreaIdentity(guti.mccDigit1 & guti.mccDigit2 & guti.mccDigit3,
-					      guti.mncDigit3 & guti.mncDigit1 & guti.mncDigit2,
-					      guti.mMEGI, 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('0000'O);
-	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.*/
-	/* TODO: 3GPP TS 33.401 9.1.1 The 16 least significant bits available in
-	 * the P-TMSI signature field shall be filled with the truncated NAS-token
-	 * according to 3GPP TS 23.003 [3].The truncated NAS-token is defined as the 16
-	 * least significant bits of the NAS-token.
-	 * The NAS-token is derived as specified in Annex A.9. The UE shall use the uplink NAS COUNT value that it would use
-	 * in the next NAS message to calculate the NAS-token and increase the stored uplink NAS COUNT value by 1.*/
-	/* TODO: mMEC "also copied into the 8 Most Significant Bits of the NRI field within the P-TMSI" */
-}
 private function f_TC_ue_cell_reselect_eutran_to_geran(ConnHdlrPars pars) runs on ConnHdlr {
 	f_init_handler(pars);
 	f_gtp_register_imsi(g_pars.ue_pars.imsi);