From 2d5d61073a2f6a9efb6622a8b603c6698f883e2c Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Wed, 4 Dec 2013 14:29:38 +0000
Subject: [PATCH] - Work in progress

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4589 818b1a75-f10b-46b9-bf7c-635c3b92a50f
---
 openair-cn/COMMON/nas_messages_def.h          |   7 +-
 openair-cn/COMMON/nas_messages_types.h        |  26 +-
 .../NAS/EURECOM-NAS/src/api/mme/mme_api.c     | 460 +++++++++---------
 .../NAS/EURECOM-NAS/src/api/mme/mme_api.h     |  82 ++--
 openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c   |   7 +
 .../NAS/EURECOM-NAS/src/emm/Authentication.c  |   8 +-
 openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h  |   8 +-
 openair-cn/NAS/nas_defs.h                     |  30 ++
 openair-cn/NAS/nas_itti_messaging.c           |   2 +
 openair-cn/NAS/nas_itti_messaging.h           |  18 +
 openair-cn/NAS/nas_main.c                     |  30 ++
 openair-cn/S1AP/s1ap_mme_itti_messaging.h     |  23 +-
 openair-cn/S1AP/s1ap_mme_nas_procedures.c     |  64 +--
 13 files changed, 431 insertions(+), 334 deletions(-)

diff --git a/openair-cn/COMMON/nas_messages_def.h b/openair-cn/COMMON/nas_messages_def.h
index dd2c6b95b8..a7a1e3154e 100644
--- a/openair-cn/COMMON/nas_messages_def.h
+++ b/openair-cn/COMMON/nas_messages_def.h
@@ -11,11 +11,14 @@ MESSAGE_DEF(NAS_NON_DELIVERY_IND,             MESSAGE_PRIORITY_MED, nas_non_del_
 MESSAGE_DEF(NAS_RAB_ESTABLISHMENT_REQ,        MESSAGE_PRIORITY_MED, nas_rab_est_req_t,   nas_rab_est_req)
 MESSAGE_DEF(NAS_RAB_ESTABLISHMENT_RESP,       MESSAGE_PRIORITY_MED, nas_rab_est_rsp_t,   nas_rab_est_rsp)
 MESSAGE_DEF(NAS_RAB_RELEASE_REQ,              MESSAGE_PRIORITY_MED, nas_rab_rel_req_t,   nas_rab_rel_req)
-MESSAGE_DEF(NAS_AUTHENTICATION_REQ,           MESSAGE_PRIORITY_MED, nas_auth_req_t,      nas_auth_req)
-MESSAGE_DEF(NAS_AUTHENTICATION_RESP,          MESSAGE_PRIORITY_MED, nas_auth_resp_t,     nas_auth_resp)
+
+/* NAS layer -> MME app messages */
+MESSAGE_DEF(NAS_AUTHENTICATION_REQ,           MESSAGE_PRIORITY_MED, nas_auth_req_t,       nas_auth_req)
+MESSAGE_DEF(NAS_AUTHENTICATION_PARAM_REQ,     MESSAGE_PRIORITY_MED, nas_auth_param_req_t, nas_auth_param_req)
 
 /* MME app -> NAS layer messages */
 MESSAGE_DEF(NAS_BEARER_PARAM,                 MESSAGE_PRIORITY_MED, nas_bearer_param_t,  nas_bearer_param)
+MESSAGE_DEF(NAS_AUTHENTICATION_RESP,          MESSAGE_PRIORITY_MED, nas_auth_resp_t,     nas_auth_resp)
 
 #if defined(DISABLE_USE_NAS)
 MESSAGE_DEF(NAS_ATTACH_REQ,                   MESSAGE_PRIORITY_MED, nas_attach_req_t,    nas_attach_req)
diff --git a/openair-cn/COMMON/nas_messages_types.h b/openair-cn/COMMON/nas_messages_types.h
index 910e8b3591..7031eec40c 100644
--- a/openair-cn/COMMON/nas_messages_types.h
+++ b/openair-cn/COMMON/nas_messages_types.h
@@ -3,11 +3,14 @@
 #ifndef NAS_MESSAGES_TYPES_H_
 #define NAS_MESSAGES_TYPES_H_
 
-#define NAS_UL_DATA_IND(mSGpTR)  (mSGpTR)->ittiMsg.nas_ul_data_ind
-#define NAS_DL_DATA_REQ(mSGpTR)  (mSGpTR)->ittiMsg.nas_dl_data_req
-#define NAS_DL_DATA_CNF(mSGpTR)  (mSGpTR)->ittiMsg.nas_dl_data_cnf
-#define NAS_CONN_EST_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_est_cnf
-#define NAS_BEARER_PARAM(mSGpTR) (mSGpTR)->ittiMsg.nas_bearer_param
+#define NAS_UL_DATA_IND(mSGpTR)                 (mSGpTR)->ittiMsg.nas_ul_data_ind
+#define NAS_DL_DATA_REQ(mSGpTR)                 (mSGpTR)->ittiMsg.nas_dl_data_req
+#define NAS_DL_DATA_CNF(mSGpTR)                 (mSGpTR)->ittiMsg.nas_dl_data_cnf
+#define NAS_CONN_EST_IND(mSGpTR)                (mSGpTR)->ittiMsg.nas_conn_est_ind
+#define NAS_CONN_EST_CNF(mSGpTR)                (mSGpTR)->ittiMsg.nas_conn_est_cnf
+#define NAS_BEARER_PARAM(mSGpTR)                (mSGpTR)->ittiMsg.nas_bearer_param
+#define NAS_AUTHENTICATION_REQ(mSGpTR)          (mSGpTR)->ittiMsg.nas_auth_req
+#define NAS_AUTHENTICATION_PARAM_REQ(mSGpTR)    (mSGpTR)->ittiMsg.nas_auth_param_req
 
 typedef struct {
     
@@ -90,17 +93,28 @@ typedef struct {
 } nas_attach_req_t;
 
 typedef struct {
+    /* UE imsi */
     char imsi[16];
 
 #define NAS_FAILURE_OK  0x0
 #define NAS_FAILURE_IND 0x1
     unsigned failure:1;
     int cause;
-    
 } nas_auth_req_t;
 
 typedef struct {
     char imsi[16];
 } nas_auth_resp_t;
 
+typedef struct nas_auth_param_req_s {
+    uint8_t imsi_length;
+    char    imsi[15];
+
+    uint8_t initial_req:1;
+} nas_auth_param_req_t;
+
+typedef struct nas_attach_accept_s {
+    
+} nas_attach_accept_t;
+
 #endif /* NAS_MESSAGES_TYPES_H_ */
diff --git a/openair-cn/NAS/EURECOM-NAS/src/api/mme/mme_api.c b/openair-cn/NAS/EURECOM-NAS/src/api/mme/mme_api.c
index 3615378462..d1b4966cef 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/api/mme/mme_api.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/api/mme/mme_api.c
@@ -1,21 +1,21 @@
 /*****************************************************************************
-			Eurecom OpenAirInterface 3
-			Copyright(c) 2012 Eurecom
+            Eurecom OpenAirInterface 3
+            Copyright(c) 2012 Eurecom
 
-Source		mme_api.c
+Source      mme_api.c
 
-Version		0.1
+Version     0.1
 
-Date		2013/02/28
+Date        2013/02/28
 
-Product		NAS stack
+Product     NAS stack
 
-Subsystem	Application Programming Interface
+Subsystem   Application Programming Interface
 
-Author		Frederic Maurel
+Author      Frederic Maurel
 
-Description	Implements the API used by the NAS layer running in the MME
-		to interact with a Mobility Management Entity
+Description Implements the API used by the NAS layer running in the MME
+        to interact with a Mobility Management Entity
 
 *****************************************************************************/
 
@@ -24,7 +24,7 @@ Description	Implements the API used by the NAS layer running in the MME
 #include "mme_api.h"
 #include "nas_log.h"
 
-#include <string.h>	// memcpy
+#include <string.h> // memcpy
 
 /****************************************************************************/
 /****************  E X T E R N A L    D E F I N I T I O N S  ****************/
@@ -35,32 +35,34 @@ Description	Implements the API used by the NAS layer running in the MME
 /****************************************************************************/
 
 /* Maximum number of PDN connections the MME may simultaneously support */
-#define MME_API_PDN_MAX			10
+#define MME_API_PDN_MAX         10
 
 /* MME group identifier */
-#define MME_API_MME_GID			0x0102
+#define MME_API_MME_GID         0x0102
 
 /* MME code */
-#define MME_API_MME_CODE		0x12
+#define MME_API_MME_CODE        0x12
 
 /* Default APN */
 static const OctetString mme_api_default_apn = {
-    14, (uint8_t*)("www.eurecom.fr")};
+    14, (uint8_t *)("www.eurecom.fr")
+};
 
 /* APN configured for emergency bearer services */
 static const OctetString mme_api_emergency_apn = {
-    18, (uint8_t*)("www.eurecom_sos.fr")};
+    18, (uint8_t *)("www.eurecom_sos.fr")
+};
 
 /* Public Land Mobile Network identifier */
-static const plmn_t mme_api_plmn = {0, 2, 0xf, 8, 0, 1};	// 20810
+static const plmn_t mme_api_plmn = {0, 2, 0xf, 8, 0, 1};    // 20810
 
 /* Number of concecutive tracking areas */
-#define MME_API_NB_TACS		4
+#define MME_API_NB_TACS     4
 /* Code of the first tracking area belonging to the PLMN */
-#define MME_API_FIRST_TAC	0x0001
+#define MME_API_FIRST_TAC   0x0001
 
 /* NAS security key */
-#define MME_API_KASME	"CAFECAFECAFECAFECAFECAFECAFECAFE"
+#define MME_API_KASME   "CAFECAFECAFECAFECAFECAFECAFECAFE"
 
 /* Authentication parameter RAND */
 static const UInt8_t _mme_api_rand[AUTH_RAND_SIZE] = {
@@ -90,111 +92,110 @@ enum {
 
 /* Pool of IPv4 addresses */
 static uint8_t _mme_api_ipv4_addr[MME_API_PDN_MAX][4] = {
-    {0xC0, 0xA8, 0x02, 0x3C},	/* 192.168.02.60	*/
-    {0xC0, 0xA8, 0x0C, 0xBB},	/* 192.168.12.187	*/
-    {0xC0, 0xA8, 0x0C, 0xBC},	/* 192.168.12.188	*/
-    {0xC0, 0xA8, 0x0C, 0xBD},	/* 192.168.12.189	*/
-    {0xC0, 0xA8, 0x0C, 0xBE},	/* 192.168.12.190	*/
-    {0xC0, 0xA8, 0x0C, 0xBF},	/* 192.168.12.191	*/
-    {0xC0, 0xA8, 0x0C, 0xC0},	/* 192.168.12.192	*/
-    {0xC0, 0xA8, 0x0C, 0xC1},	/* 192.168.12.193	*/
-    {0xC0, 0xA8, 0x0C, 0xC2},	/* 192.168.12.194	*/
-    {0xC0, 0xA8, 0x0C, 0xC3},	/* 192.168.12.195	*/
+    {0xC0, 0xA8, 0x02, 0x3C},   /* 192.168.02.60    */
+    {0xC0, 0xA8, 0x0C, 0xBB},   /* 192.168.12.187   */
+    {0xC0, 0xA8, 0x0C, 0xBC},   /* 192.168.12.188   */
+    {0xC0, 0xA8, 0x0C, 0xBD},   /* 192.168.12.189   */
+    {0xC0, 0xA8, 0x0C, 0xBE},   /* 192.168.12.190   */
+    {0xC0, 0xA8, 0x0C, 0xBF},   /* 192.168.12.191   */
+    {0xC0, 0xA8, 0x0C, 0xC0},   /* 192.168.12.192   */
+    {0xC0, 0xA8, 0x0C, 0xC1},   /* 192.168.12.193   */
+    {0xC0, 0xA8, 0x0C, 0xC2},   /* 192.168.12.194   */
+    {0xC0, 0xA8, 0x0C, 0xC3},   /* 192.168.12.195   */
 };
 /* Pool of IPv6 addresses */
 static uint8_t _mme_api_ipv6_addr[MME_API_PDN_MAX][8] = {
-				/* FE80::221:70FF:C0A8:023C/64	*/
+    /* FE80::221:70FF:C0A8:023C/64  */
     {0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x02, 0x3C},
-				/* FE80::221:70FF:C0A8:0CBB/64	*/
+    /* FE80::221:70FF:C0A8:0CBB/64  */
     {0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBB},
-				/* FE80::221:70FF:C0A8:0CBC/64	*/
+    /* FE80::221:70FF:C0A8:0CBC/64  */
     {0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBC},
-				/* FE80::221:70FF:C0A8:0CBD/64	*/
+    /* FE80::221:70FF:C0A8:0CBD/64  */
     {0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBD},
-				/* FE80::221:70FF:C0A8:0CBE/64	*/
+    /* FE80::221:70FF:C0A8:0CBE/64  */
     {0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBE},
-				/* FE80::221:70FF:C0A8:0CBF/64	*/
+    /* FE80::221:70FF:C0A8:0CBF/64  */
     {0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBF},
-				/* FE80::221:70FF:C0A8:0CC0/64	*/
+    /* FE80::221:70FF:C0A8:0CC0/64  */
     {0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC0},
-				/* FE80::221:70FF:C0A8:0CC1/64	*/
+    /* FE80::221:70FF:C0A8:0CC1/64  */
     {0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC1},
-				/* FE80::221:70FF:C0A8:0CC2/64	*/
+    /* FE80::221:70FF:C0A8:0CC2/64  */
     {0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC2},
-				/* FE80::221:70FF:C0A8:0CC3/64	*/
+    /* FE80::221:70FF:C0A8:0CC3/64  */
     {0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC3},
 };
 /* Pool of IPv4v6 addresses */
 static uint8_t _mme_api_ipv4v6_addr[MME_API_PDN_MAX][12] = {
-			/* 192.168.02.60, FE80::221:70FF:C0A8:023C/64	*/
-  {0xC0, 0xA8, 0x02, 0x3C, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x02, 0x3C},
-			/* 192.168.12.187, FE80::221:70FF:C0A8:0CBB/64	*/
-  {0xC0, 0xA8, 0x0C, 0xBB, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBB},
-			/* 192.168.12.188, FE80::221:70FF:C0A8:0CBC/64	*/
-  {0xC0, 0xA8, 0x0C, 0xBC, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBC},
-			/* 192.168.12.189, FE80::221:70FF:C0A8:0CBD/64	*/
-  {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBD},
-			/* 192.168.12.189, FE80::221:70FF:C0A8:0CBE/64	*/
-  {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBE},
-			/* 192.168.12.189, FE80::221:70FF:C0A8:0CBF/64	*/
-  {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBF},
-			/* 192.168.12.189, FE80::221:70FF:C0A8:0CC0/64	*/
-  {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC0},
-			/* 192.168.12.189, FE80::221:70FF:C0A8:0CC1/64	*/
-  {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC1},
-			/* 192.168.12.189, FE80::221:70FF:C0A8:0CC2/64	*/
-  {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC2},
-			/* 192.168.12.189, FE80::221:70FF:C0A8:0CC3/64	*/
-  {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC3},
+    /* 192.168.02.60, FE80::221:70FF:C0A8:023C/64   */
+    {0xC0, 0xA8, 0x02, 0x3C, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x02, 0x3C},
+    /* 192.168.12.187, FE80::221:70FF:C0A8:0CBB/64  */
+    {0xC0, 0xA8, 0x0C, 0xBB, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBB},
+    /* 192.168.12.188, FE80::221:70FF:C0A8:0CBC/64  */
+    {0xC0, 0xA8, 0x0C, 0xBC, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBC},
+    /* 192.168.12.189, FE80::221:70FF:C0A8:0CBD/64  */
+    {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBD},
+    /* 192.168.12.189, FE80::221:70FF:C0A8:0CBE/64  */
+    {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBE},
+    /* 192.168.12.189, FE80::221:70FF:C0A8:0CBF/64  */
+    {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xBF},
+    /* 192.168.12.189, FE80::221:70FF:C0A8:0CC0/64  */
+    {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC0},
+    /* 192.168.12.189, FE80::221:70FF:C0A8:0CC1/64  */
+    {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC1},
+    /* 192.168.12.189, FE80::221:70FF:C0A8:0CC2/64  */
+    {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC2},
+    /* 192.168.12.189, FE80::221:70FF:C0A8:0CC3/64  */
+    {0xC0, 0xA8, 0x0C, 0xBD, 0x02, 0x21, 0x70, 0xFF, 0xC0, 0xA8, 0x0C, 0xC3},
 };
-static const OctetString _mme_api_pdn_addr[MME_API_ADDR_MAX][MME_API_PDN_MAX] =
-{
+static const OctetString _mme_api_pdn_addr[MME_API_ADDR_MAX][MME_API_PDN_MAX] = {
     { /* IPv4 network capability */
-	{4, _mme_api_ipv4_addr[0]},
-	{4, _mme_api_ipv4_addr[1]},
-	{4, _mme_api_ipv4_addr[2]},
-	{4, _mme_api_ipv4_addr[3]},
-	{4, _mme_api_ipv4_addr[4]},
-	{4, _mme_api_ipv4_addr[5]},
-	{4, _mme_api_ipv4_addr[6]},
-	{4, _mme_api_ipv4_addr[7]},
-	{4, _mme_api_ipv4_addr[8]},
-	{4, _mme_api_ipv4_addr[9]},
+        {4, _mme_api_ipv4_addr[0]},
+        {4, _mme_api_ipv4_addr[1]},
+        {4, _mme_api_ipv4_addr[2]},
+        {4, _mme_api_ipv4_addr[3]},
+        {4, _mme_api_ipv4_addr[4]},
+        {4, _mme_api_ipv4_addr[5]},
+        {4, _mme_api_ipv4_addr[6]},
+        {4, _mme_api_ipv4_addr[7]},
+        {4, _mme_api_ipv4_addr[8]},
+        {4, _mme_api_ipv4_addr[9]},
     },
     { /* IPv6 network capability */
-	{8, _mme_api_ipv6_addr[0]},
-	{8, _mme_api_ipv6_addr[1]},
-	{8, _mme_api_ipv6_addr[2]},
-	{8, _mme_api_ipv6_addr[3]},
-	{8, _mme_api_ipv6_addr[4]},
-	{8, _mme_api_ipv6_addr[5]},
-	{8, _mme_api_ipv6_addr[6]},
-	{8, _mme_api_ipv6_addr[7]},
-	{8, _mme_api_ipv6_addr[8]},
-	{8, _mme_api_ipv6_addr[9]},
+        {8, _mme_api_ipv6_addr[0]},
+        {8, _mme_api_ipv6_addr[1]},
+        {8, _mme_api_ipv6_addr[2]},
+        {8, _mme_api_ipv6_addr[3]},
+        {8, _mme_api_ipv6_addr[4]},
+        {8, _mme_api_ipv6_addr[5]},
+        {8, _mme_api_ipv6_addr[6]},
+        {8, _mme_api_ipv6_addr[7]},
+        {8, _mme_api_ipv6_addr[8]},
+        {8, _mme_api_ipv6_addr[9]},
     },
     { /* IPv4v6 network capability */
-	{12, _mme_api_ipv4v6_addr[0]},
-	{12, _mme_api_ipv4v6_addr[1]},
-	{12, _mme_api_ipv4v6_addr[2]},
-	{12, _mme_api_ipv4v6_addr[3]},
-	{12, _mme_api_ipv4v6_addr[4]},
-	{12, _mme_api_ipv4v6_addr[5]},
-	{12, _mme_api_ipv4v6_addr[6]},
-	{12, _mme_api_ipv4v6_addr[7]},
-	{12, _mme_api_ipv4v6_addr[8]},
-	{12, _mme_api_ipv4v6_addr[9]},
+        {12, _mme_api_ipv4v6_addr[0]},
+        {12, _mme_api_ipv4v6_addr[1]},
+        {12, _mme_api_ipv4v6_addr[2]},
+        {12, _mme_api_ipv4v6_addr[3]},
+        {12, _mme_api_ipv4v6_addr[4]},
+        {12, _mme_api_ipv4v6_addr[5]},
+        {12, _mme_api_ipv4v6_addr[6]},
+        {12, _mme_api_ipv4v6_addr[7]},
+        {12, _mme_api_ipv4v6_addr[8]},
+        {12, _mme_api_ipv4v6_addr[9]},
     },
 };
 
 /* Subscribed QCI */
-#define MME_API_QCI		3
+#define MME_API_QCI     3
 
 /* Data bit rates */
-#define MME_API_BIT_RATE_64K	0x40
-#define MME_API_BIT_RATE_128K	0x48
-#define MME_API_BIT_RATE_512K	0x78
-#define MME_API_BIT_RATE_1024K	0x87
+#define MME_API_BIT_RATE_64K    0x40
+#define MME_API_BIT_RATE_128K   0x48
+#define MME_API_BIT_RATE_512K   0x78
+#define MME_API_BIT_RATE_1024K  0x87
 
 /* Total number of PDN connections (should not exceed MME_API_PDN_MAX) */
 static int _mme_api_pdn_id = 0;
@@ -209,23 +210,24 @@ static int _mme_api_pdn_id = 0;
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 mme_api_get_emm_config()                                  **
+ ** Name:    mme_api_get_emm_config()                                  **
  **                                                                        **
  ** Description: Retreives MME configuration data related to EPS mobility  **
- **		 management                                                **
+ **      management                                                **
  **                                                                        **
- ** Inputs:	 None                                                      **
- **		 Others:	None                                       **
+ ** Inputs:  None                                                      **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      ** 
- **		 Return:	RETURNok, RETURNerror                      **
- **		 Others:	None                                       **
+ ** Outputs:     None                                                      **
+ **      Return:    RETURNok, RETURNerror                      **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
 #if defined(EPC_BUILD)
-int mme_api_get_emm_config(mme_api_emm_config_t* config, mme_config_t *mme_config_p)
+int mme_api_get_emm_config(mme_api_emm_config_t *config,
+                           mme_config_t *mme_config_p)
 #else
-int mme_api_get_emm_config(mme_api_emm_config_t* config)
+int mme_api_get_emm_config(mme_api_emm_config_t *config)
 #endif
 {
     LOG_FUNC_IN;
@@ -255,31 +257,31 @@ int mme_api_get_emm_config(mme_api_emm_config_t* config)
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 mme_api_get_config()                                      **
+ ** Name:    mme_api_get_config()                                      **
  **                                                                        **
  ** Description: Retreives MME configuration data related to EPS session   **
- **		 management                                                **
+ **      management                                                **
  **                                                                        **
- ** Inputs:	 None                                                      **
- **		 Others:	None                                       **
+ ** Inputs:  None                                                      **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      ** 
- **		 Return:	RETURNok, RETURNerror                      **
- **		 Others:	None                                       **
+ ** Outputs:     None                                                      **
+ **      Return:    RETURNok, RETURNerror                      **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int mme_api_get_esm_config(mme_api_esm_config_t* config)
+int mme_api_get_esm_config(mme_api_esm_config_t *config)
 {
     LOG_FUNC_IN;
 
     if (_mme_api_ip_capability == MME_API_IPV4_ADDR) {
-	config->features = MME_API_IPV4;
+        config->features = MME_API_IPV4;
     } else if (_mme_api_ip_capability == MME_API_IPV6_ADDR) {
-	config->features = MME_API_IPV6;
+        config->features = MME_API_IPV6;
     } else if (_mme_api_ip_capability == MME_API_IPV4V6_ADDR) {
-	config->features = MME_API_IPV4 | MME_API_IPV6;
+        config->features = MME_API_IPV4 | MME_API_IPV6;
     } else {
-	config->features = 0;
+        config->features = 0;
     }
 
     LOG_FUNC_RETURN (RETURNok);
@@ -287,55 +289,55 @@ int mme_api_get_esm_config(mme_api_esm_config_t* config)
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 mme_api_identify_guti()                                   **
+ ** Name:    mme_api_identify_guti()                                   **
  **                                                                        **
  ** Description: Requests the MME to identify the UE using the specified   **
- **		 GUTI. If the UE is known by the MME (a Mobility Manage-   **
- **		 ment context exists for this  UE  in  the  MME), its se-  **
- **		 curity context is returned.                               **
+ **      GUTI. If the UE is known by the MME (a Mobility Manage-   **
+ **      ment context exists for this  UE  in  the  MME), its se-  **
+ **      curity context is returned.                               **
  **                                                                        **
- ** Inputs:	 guti:		EPS Globally Unique Temporary UE Identity  **
- **		 Others:	None                                       **
+ ** Inputs:  guti:      EPS Globally Unique Temporary UE Identity  **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 vector:	The EPS authentication vector of the UE if **
- **				known by the network; NULL otherwise.      **
- **		 Return:	RETURNok, RETURNerror                      **
- **		 Others:	None                                       **
+ ** Outputs:     vector:    The EPS authentication vector of the UE if **
+ **             known by the network; NULL otherwise.      **
+ **      Return:    RETURNok, RETURNerror                      **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int mme_api_identify_guti(const GUTI_t* guti, auth_vector_t* vector)
+int mme_api_identify_guti(const GUTI_t *guti, auth_vector_t *vector)
 {
-    LOG_FUNC_IN;
-
     int rc = RETURNerror;
 
+    LOG_FUNC_IN;
+
     LOG_FUNC_RETURN(rc);
 }
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 mme_api_identify_imsi()                                   **
+ ** Name:    mme_api_identify_imsi()                                   **
  **                                                                        **
  ** Description: Requests the MME to identify the UE using the specified   **
- **		 IMSI. If the UE is known by the MME (a Mobility Manage-   **
- **		 ment context exists for this  UE  in  the  MME), its se-  **
- **		 curity context is returned.                               **
+ **      IMSI. If the UE is known by the MME (a Mobility Manage-   **
+ **      ment context exists for this  UE  in  the  MME), its se-  **
+ **      curity context is returned.                               **
  **                                                                        **
- ** Inputs:	 imsi:		International Mobile Subscriber Identity   **
- **		 Others:	None                                       **
+ ** Inputs:  imsi:      International Mobile Subscriber Identity   **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 vector:	The EPS authentication vector of the UE if **
- **				known by the network; NULL otherwise.      **
- **		 Return:	RETURNok, RETURNerror                      **
- **		 Others:	None                                       **
+ ** Outputs:     vector:    The EPS authentication vector of the UE if **
+ **             known by the network; NULL otherwise.      **
+ **      Return:    RETURNok, RETURNerror                      **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int mme_api_identify_imsi(const imsi_t* imsi, auth_vector_t* vector)
+int mme_api_identify_imsi(const imsi_t *imsi, auth_vector_t *vector)
 {
-    LOG_FUNC_IN;
-
     int rc = RETURNok;
 
+    LOG_FUNC_IN;
+
     memcpy(vector->rand, _mme_api_rand, AUTH_RAND_SIZE);
     memcpy(vector->autn, _mme_api_autn, AUTH_AUTN_SIZE);
     memcpy(vector->xres, _mme_api_xres, AUTH_XRES_SIZE);
@@ -345,61 +347,61 @@ int mme_api_identify_imsi(const imsi_t* imsi, auth_vector_t* vector)
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 mme_api_identify_imei()                                   **
+ ** Name:    mme_api_identify_imei()                                   **
  **                                                                        **
  ** Description: Requests the MME to identify the UE using the specified   **
- **		 IMEI. If the UE is known by the MME (a Mobility Manage-   **
- **		 ment context exists for this  UE  in  the  MME), its se-  **
- **		 curity context is returned.                               **
+ **      IMEI. If the UE is known by the MME (a Mobility Manage-   **
+ **      ment context exists for this  UE  in  the  MME), its se-  **
+ **      curity context is returned.                               **
  **                                                                        **
- ** Inputs:	 imei:		International Mobile Equipment Identity    **
- **		 Others:	None                                       **
+ ** Inputs:  imei:      International Mobile Equipment Identity    **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 vector:	The EPS authentication vector of the UE if **
- **				known by the network; NULL otherwise.      **
- **		 Return:	RETURNok, RETURNerror                      **
- **		 Others:	None                                       **
+ ** Outputs:     vector:    The EPS authentication vector of the UE if **
+ **             known by the network; NULL otherwise.      **
+ **      Return:    RETURNok, RETURNerror                      **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int mme_api_identify_imei(const imei_t* imei, auth_vector_t* vector)
+int mme_api_identify_imei(const imei_t *imei, auth_vector_t *vector)
 {
-    LOG_FUNC_IN;
-
     int rc = RETURNerror;
 
+    LOG_FUNC_IN;
+
     LOG_FUNC_RETURN(rc);
 }
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 mme_api_new_guti()                                        **
+ ** Name:    mme_api_new_guti()                                        **
  **                                                                        **
  ** Description: Requests the MME to assign a new GUTI to the UE identi-   **
- **		 fied by the given IMSI.                                   **
+ **      fied by the given IMSI.                                   **
  **                                                                        **
  ** Description: Requests the MME to assign a new GUTI to the UE identi-   **
- **		 fied by the given IMSI and returns the list of consecu-   **
- **		 tive tracking areas the UE is registered to.              **
+ **      fied by the given IMSI and returns the list of consecu-   **
+ **      tive tracking areas the UE is registered to.              **
  **                                                                        **
- ** Inputs:	 imsi:		International Mobile Subscriber Identity   **
- **		 Others:	None                                       **
+ ** Inputs:  imsi:      International Mobile Subscriber Identity   **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 guti:		The new assigned GUTI                      **
- **		 tac:		Code of the first tracking area belonging  **
- **				to the PLMN                                **
- **		 n_tacs:	Number of concecutive tracking areas       **
- **		 Return:	RETURNok, RETURNerror                      **
- **		 Others:	None                                       **
+ ** Outputs:     guti:      The new assigned GUTI                      **
+ **      tac:       Code of the first tracking area belonging  **
+ **             to the PLMN                                **
+ **      n_tacs:    Number of concecutive tracking areas       **
+ **      Return:    RETURNok, RETURNerror                      **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int mme_api_new_guti(const imsi_t* imsi, GUTI_t* guti, tac_t* tac, int* n_tacs)
+int mme_api_new_guti(const imsi_t *imsi, GUTI_t *guti, tac_t *tac, int *n_tacs)
 {
-    LOG_FUNC_IN;
-
     int rc = RETURNok;
 
     static unsigned int tmsi = 1;
 
+    LOG_FUNC_IN;
+
     guti->gummei.plmn = mme_api_plmn;
     guti->gummei.MMEgid = MME_API_MME_GID;
     guti->gummei.MMEcode = MME_API_MME_CODE;
@@ -413,72 +415,72 @@ int mme_api_new_guti(const imsi_t* imsi, GUTI_t* guti, tac_t* tac, int* n_tacs)
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 mme_api_subscribe()                                       **
+ ** Name:        mme_api_subscribe()                                       **
  **                                                                        **
  ** Description: Requests the MME to check whether connectivity with the   **
- **		 requested PDN can be established using the specified APN. **
- **		 If accepted the MME returns PDN subscription context con- **
- **		 taining EPS subscribed QoS profile, the default APN if    **
- **		 required and UE's IPv4 address and/or the IPv6 prefix.    **
- **                                                                        **
- ** Inputs:	 apn:		If not NULL, Access Point Name of the PDN  **
- **				to connect to                              **
- **		 is_emergency:	TRUE if the PDN connectivity is requested  **
- **				for emergency bearer services              **
- **		 Others:	None                                       **
- **                                                                        **
- ** Outputs:	 apn:		If NULL, default APN or APN configured for **
- **				emergency bearer services                  **
- **		 pdn_addr:	PDN connection IPv4 address or IPv6 inter- **
- **				face identifier to be used to build the    **
- **				IPv6 link local address                    **
- **		 qos:		EPS subscribed QoS profile                 **
- **		 Return:	RETURNok, RETURNerror                      **
- **		 Others:	None                                       **
+ **              requested PDN can be established using the specified APN. **
+ **              If accepted the MME returns PDN subscription context con- **
+ **              taining EPS subscribed QoS profile, the default APN if    **
+ **              required and UE's IPv4 address and/or the IPv6 prefix.    **
+ **                                                                        **
+ ** Inputs:  apn:               If not NULL, Access Point Name of the PDN  **
+ **                             to connect to                              **
+ **              is_emergency:  TRUE if the PDN connectivity is requested  **
+ **                             for emergency bearer services              **
+ **                  Others:    None                                       **
+ **                                                                        **
+ ** Outputs:         apn:       If NULL, default APN or APN configured for **
+ **                             emergency bearer services                  **
+ **                  pdn_addr:  PDN connection IPv4 address or IPv6 inter- **
+ **                             face identifier to be used to build the    **
+ **                             IPv6 link local address                    **
+ **                  qos:       EPS subscribed QoS profile                 **
+ **                  Return:    RETURNok, RETURNerror                      **
+ **                  Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int mme_api_subscribe(OctetString* apn, OctetString* pdn_addr,
-		      int is_emergency, mme_api_qos_t* qos)
+int mme_api_subscribe(OctetString *apn, OctetString *pdn_addr,
+                      int is_emergency, mme_api_qos_t *qos)
 {
-    LOG_FUNC_IN;
-
     int rc = RETURNok;
 
+    LOG_FUNC_IN;
+
     if ( apn && (apn->length == 0) ) {
-	/* PDN connectivity to default APN */
-	if (is_emergency) {
-	    apn->length = mme_api_emergency_apn.length;
-	    apn->value = mme_api_emergency_apn.value;
-	} else {
-	    apn->length = mme_api_default_apn.length;
-	    apn->value = mme_api_default_apn.value;
-	}
+        /* PDN connectivity to default APN */
+        if (is_emergency) {
+            apn->length = mme_api_emergency_apn.length;
+            apn->value = mme_api_emergency_apn.value;
+        } else {
+            apn->length = mme_api_default_apn.length;
+            apn->value = mme_api_default_apn.value;
+        }
     }
 
     /* Assign PDN address */
     if ( pdn_addr && (_mme_api_pdn_id < MME_API_PDN_MAX) ) {
-	pdn_addr->length =
-	    _mme_api_pdn_addr[_mme_api_ip_capability][_mme_api_pdn_id].length;
-	pdn_addr->value =
-	    _mme_api_pdn_addr[_mme_api_ip_capability][_mme_api_pdn_id].value;
-	/* Increment the total number of PDN connections */
-	_mme_api_pdn_id += 1;
+        pdn_addr->length =
+            _mme_api_pdn_addr[_mme_api_ip_capability][_mme_api_pdn_id].length;
+        pdn_addr->value =
+            _mme_api_pdn_addr[_mme_api_ip_capability][_mme_api_pdn_id].value;
+        /* Increment the total number of PDN connections */
+        _mme_api_pdn_id += 1;
     } else {
-	/* Maximum number of PDN connections exceeded */
-	rc = RETURNerror;
+        /* Maximum number of PDN connections exceeded */
+        rc = RETURNerror;
     }
 
     /* Setup EPS subscribed QoS profile */
     if (qos) {
-	qos->qci = MME_API_QCI;
-	/* Uplink bit rate */
-	qos->gbr[MME_API_UPLINK] = MME_API_BIT_RATE_64K;
-	qos->mbr[MME_API_UPLINK] = MME_API_BIT_RATE_128K;
-	/* Downlink bit rate */
-	qos->gbr[MME_API_DOWNLINK] = MME_API_BIT_RATE_512K;
-	qos->mbr[MME_API_DOWNLINK] = MME_API_BIT_RATE_1024K;
+        qos->qci = MME_API_QCI;
+        /* Uplink bit rate */
+        qos->gbr[MME_API_UPLINK] = MME_API_BIT_RATE_64K;
+        qos->mbr[MME_API_UPLINK] = MME_API_BIT_RATE_128K;
+        /* Downlink bit rate */
+        qos->gbr[MME_API_DOWNLINK] = MME_API_BIT_RATE_512K;
+        qos->mbr[MME_API_DOWNLINK] = MME_API_BIT_RATE_1024K;
     } else {
-	rc = RETURNerror;
+        rc = RETURNerror;
     }
 
     LOG_FUNC_RETURN(rc);
@@ -486,21 +488,21 @@ int mme_api_subscribe(OctetString* apn, OctetString* pdn_addr,
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 mme_api_unsubscribe()                                     **
+ ** Name:        mme_api_unsubscribe()                                     **
  **                                                                        **
  ** Description: Requests the MME to release connectivity with the reques- **
- **		 ted PDN using the specified APN.                          **
+ **              ted PDN using the specified APN.                          **
  **                                                                        **
- ** Inputs:	 apn:		Access Point Name of the PDN to disconnect **
- **				from                                       **
- **		 Others:	None                                       **
+ ** Inputs:  apn:               Access Point Name of the PDN to disconnect **
+ **                             from                                       **
+ **                  Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      ** 
- **		 Return:	RETURNok, RETURNerror                      **
- **		 Others:	None                                       **
+ ** Outputs:     None                                                      **
+ **                  Return:    RETURNok, RETURNerror                      **
+ **                  Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int mme_api_unsubscribe(OctetString* apn)
+int mme_api_unsubscribe(OctetString *apn)
 {
     LOG_FUNC_IN;
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/api/mme/mme_api.h b/openair-cn/NAS/EURECOM-NAS/src/api/mme/mme_api.h
index 4f87228f8f..644b4155f6 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/api/mme/mme_api.h
+++ b/openair-cn/NAS/EURECOM-NAS/src/api/mme/mme_api.h
@@ -1,21 +1,21 @@
 /*****************************************************************************
-			Eurecom OpenAirInterface 3
-			Copyright(c) 2012 Eurecom
+            Eurecom OpenAirInterface 3
+            Copyright(c) 2012 Eurecom
 
-Source		mme_api.h
+Source      mme_api.h
 
-Version		0.1
+Version     0.1
 
-Date		2013/02/28
+Date        2013/02/28
 
-Product		NAS stack
+Product     NAS stack
 
-Subsystem	Application Programming Interface
+Subsystem   Application Programming Interface
 
-Author		Frederic Maurel
+Author      Frederic Maurel
 
-Description	Implements the API used by the NAS layer running in the MME
-		to interact with a Mobility Management Entity
+Description Implements the API used by the NAS layer running in the MME
+        to interact with a Mobility Management Entity
 
 *****************************************************************************/
 #ifndef __MME_API_H__
@@ -35,35 +35,35 @@ Description	Implements the API used by the NAS layer running in the MME
 /****************************************************************************/
 
 /* Maximum number of UEs the MME may simultaneously support */
-#define MME_API_NB_UE_MAX		1
+#define MME_API_NB_UE_MAX       1
 
 #ifdef NAS_MME
 
 /* Features supported by the MME */
-typedef enum {
-    MME_API_NO_FEATURE_SUPPORTED	= 0,
-    MME_API_EMERGENCY_ATTACH		= (1<<0),
-    MME_API_UNAUTHENTICATED_IMSI	= (1<<1),
-    MME_API_IPV4			= (1<<2),
-    MME_API_IPV6			= (1<<3),
-    MME_API_SINGLE_ADDR_BEARERS		= (1<<4),
+typedef enum mme_api_feature_s {
+    MME_API_NO_FEATURE_SUPPORTED    = 0,
+    MME_API_EMERGENCY_ATTACH        = (1<<0),
+    MME_API_UNAUTHENTICATED_IMSI    = (1<<1),
+    MME_API_IPV4                    = (1<<2),
+    MME_API_IPV6                    = (1<<3),
+    MME_API_SINGLE_ADDR_BEARERS     = (1<<4),
 } mme_api_feature_t;
 
 /*
  * EPS Mobility Management configuration data
  * ------------------------------------------
  */
-typedef struct {
-    mme_api_feature_t features;	/* Supported features			*/
-    gummei_t          gummei;	/* EPS Globally Unique MME Identity	*/
+typedef struct mme_api_emm_config_s {
+    mme_api_feature_t features; /* Supported features           */
+    gummei_t          gummei;   /* EPS Globally Unique MME Identity */
 } mme_api_emm_config_t;
 
 /*
  * EPS Session Management configuration data
  * -----------------------------------------
  */
-typedef struct {
-    mme_api_feature_t features;	/* Supported features			*/
+typedef struct mme_api_esm_config_s {
+    mme_api_feature_t features; /* Supported features           */
 } mme_api_esm_config_t;
 
 /****************************************************************************/
@@ -71,17 +71,17 @@ typedef struct {
 /****************************************************************************/
 
 /* EPS subscribed QoS profile  */
-typedef struct {
-#define MME_API_UPLINK		0
-#define MME_API_DOWNLINK	1
-#define MME_API_DIRECTION	2
-    int gbr[MME_API_DIRECTION];	/* Guaranteed Bit Rate			*/
-    int mbr[MME_API_DIRECTION];	/* Maximum Bit Rate			*/
-    int qci;			/* QoS Class Identifier			*/
+typedef struct mme_api_qos_s {
+#define MME_API_UPLINK      0
+#define MME_API_DOWNLINK    1
+#define MME_API_DIRECTION   2
+    int gbr[MME_API_DIRECTION]; /* Guaranteed Bit Rate          */
+    int mbr[MME_API_DIRECTION]; /* Maximum Bit Rate         */
+    int qci;            /* QoS Class Identifier         */
 } mme_api_qos_t;
 
 /* Traffic Flow Template */
-typedef struct {
+typedef struct mme_api_tft_s {
 } mme_api_tft_t;
 
 /****************************************************************************/
@@ -93,19 +93,21 @@ typedef struct {
 /****************************************************************************/
 
 #if defined(EPC_BUILD)
-int mme_api_get_emm_config(mme_api_emm_config_t* config, mme_config_t *mme_config_p);
+int mme_api_get_emm_config(mme_api_emm_config_t *config,
+                           mme_config_t *mme_config_p);
 #else
-int mme_api_get_emm_config(mme_api_emm_config_t* config);
+int mme_api_get_emm_config(mme_api_emm_config_t *config);
 #endif
-int mme_api_get_esm_config(mme_api_esm_config_t* config);
+int mme_api_get_esm_config(mme_api_esm_config_t *config);
 
-int mme_api_identify_guti(const GUTI_t* guti, auth_vector_t* vector);
-int mme_api_identify_imsi(const imsi_t* imsi, auth_vector_t* vector);
-int mme_api_identify_imei(const imei_t* imei, auth_vector_t* vector);
-int mme_api_new_guti(const imsi_t* imsi, GUTI_t* guti, tac_t* tac, int* n_tacs);
+int mme_api_identify_guti(const GUTI_t *guti, auth_vector_t *vector);
+int mme_api_identify_imsi(const imsi_t *imsi, auth_vector_t *vector);
+int mme_api_identify_imei(const imei_t *imei, auth_vector_t *vector);
+int mme_api_new_guti(const imsi_t *imsi, GUTI_t *guti, tac_t *tac, int *n_tacs);
 
-int mme_api_subscribe(OctetString* apn, OctetString* pdn_addr, int is_emergency, mme_api_qos_t* qos);
-int mme_api_unsubscribe(OctetString* apn);
+int mme_api_subscribe(OctetString *apn, OctetString *pdn_addr,
+                      int is_emergency, mme_api_qos_t *qos);
+int mme_api_unsubscribe(OctetString *apn);
 
 #endif // NAS_MME
 
diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c b/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c
index d78308b91f..681a954472 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c
@@ -47,6 +47,9 @@ Description Defines the attach related EMM procedure executed by the
 
 #ifdef NAS_MME
 #include "mme_api.h"
+# if defined(EPC_BUILD)
+#   include "nas_itti_messaging.h"
+# endif
 #endif
 
 #include <string.h> // memcmp, memcpy
@@ -1835,6 +1838,10 @@ static int _emm_attach_identify(void *args)
               emm_ctx->ueid, (emm_ctx->imsi)? "IMSI" : (emm_ctx->guti)? "GUTI" :
               (emm_ctx->imei)? "IMEI" : "none");
 
+#if defined(EPC_BUILD)
+    nas_itti_auth_info_req(emm_ctx->imsi, 1);
+#endif
+
     /*
      * UE's identification
      * -------------------
diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c b/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c
index 56c28cb231..90b985529c 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c
@@ -529,15 +529,15 @@ int emm_proc_authentication(unsigned int ueid, int ksi,
                             emm_common_failure_callback_t failure)
 
 {
-    LOG_FUNC_IN;
-
     int rc = RETURNerror;
+    authentication_data_t *data;
+
+    LOG_FUNC_IN;
 
     LOG_TRACE(INFO, "EMM-PROC  - Initiate authentication KSI = %d", ksi);
 
     /* Allocate parameters of the retransmission timer callback */
-    authentication_data_t *data =
-        (authentication_data_t *)malloc(sizeof(authentication_data_t));
+    data = (authentication_data_t *)malloc(sizeof(authentication_data_t));
 
     if (data != NULL) {
         /* Setup ongoing EMM procedure callback functions */
diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h b/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h
index d98656aaad..238e31c516 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h
+++ b/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h
@@ -320,6 +320,10 @@ typedef struct {
  * ---------------------------------------------------------------------------
  */
 typedef struct emm_data_context_s {
+#if defined(EPC_BUILD)
+    RB_ENTRY(emm_data_context_s) entries;
+#endif
+
     unsigned int ueid;   /* UE identifier                    */
     int is_dynamic;  /* Dynamically allocated context indicator      */
     int is_attached;     /* Attachment indicator                 */
@@ -344,10 +348,6 @@ typedef struct emm_data_context_s {
     int emm_cause;   /* EMM failure cause code               */
 
     emm_fsm_state_t _emm_fsm_status;
-
-#if defined(EPC_BUILD)
-    RB_ENTRY(emm_data_context_s) entries;
-#endif
 } emm_data_context_t;
 
 /*
diff --git a/openair-cn/NAS/nas_defs.h b/openair-cn/NAS/nas_defs.h
index 99a15998b5..bdb1bf47b4 100644
--- a/openair-cn/NAS/nas_defs.h
+++ b/openair-cn/NAS/nas_defs.h
@@ -1,3 +1,33 @@
+/*******************************************************************************
+
+  Eurecom OpenAirInterface
+  Copyright(c) 1999 - 2013 Eurecom
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information
+  Openair Admin: openair_admin@eurecom.fr
+  Openair Tech : openair_tech@eurecom.fr
+  Forums       : http://forums.eurecom.fr/openairinterface
+  Address      : EURECOM, Campus SophiaTech, 450 Route des Chappes
+                 06410 Biot FRANCE
+
+*******************************************************************************/
+
 #ifndef NAS_DEFS_H_
 #define NAS_DEFS_H_
 
diff --git a/openair-cn/NAS/nas_itti_messaging.c b/openair-cn/NAS/nas_itti_messaging.c
index 0f7140a6f2..64ce5074ec 100644
--- a/openair-cn/NAS/nas_itti_messaging.c
+++ b/openair-cn/NAS/nas_itti_messaging.c
@@ -28,6 +28,8 @@
 
 *******************************************************************************/
 
+#include <string.h>
+
 #include "intertask_interface.h"
 #include "nas_itti_messaging.h"
 
diff --git a/openair-cn/NAS/nas_itti_messaging.h b/openair-cn/NAS/nas_itti_messaging.h
index 7eab09ef27..5f60d505dc 100644
--- a/openair-cn/NAS/nas_itti_messaging.h
+++ b/openair-cn/NAS/nas_itti_messaging.h
@@ -28,6 +28,9 @@
 
 *******************************************************************************/
 
+#include "intertask_interface.h"
+#include "conversions.h"
+
 #ifndef NAS_ITTI_MESSAGING_H_
 #define NAS_ITTI_MESSAGING_H_
 
@@ -37,4 +40,19 @@ int nas_itti_dl_data_req(const uint32_t ue_id, void * const data,
 void nas_itti_establish_cnf(const nas_error_code_t error_code, void * const data,
                             const uint32_t length);
 
+static inline void nas_itti_auth_info_req(const imsi_t * const imsi,
+                                          uint8_t initial_req)
+{
+    MessageDef *message_p;
+
+    message_p = itti_alloc_new_message(TASK_NAS, NAS_AUTHENTICATION_PARAM_REQ);
+
+    hexa_to_ascii((uint8_t *)imsi->u.value, NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi,
+                  imsi->length);
+    NAS_AUTHENTICATION_PARAM_REQ(message_p).initial_req = initial_req;
+    NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi_length = imsi->length - imsi->u.num.parity;
+
+    itti_send_msg_to_task(TASK_MME_APP, INSTANCE_DEFAULT, message_p);
+}
+
 #endif /* NAS_ITTI_MESSAGING_H_ */
diff --git a/openair-cn/NAS/nas_main.c b/openair-cn/NAS/nas_main.c
index 7612c31561..a32a494e05 100644
--- a/openair-cn/NAS/nas_main.c
+++ b/openair-cn/NAS/nas_main.c
@@ -1,3 +1,33 @@
+/*******************************************************************************
+
+  Eurecom OpenAirInterface
+  Copyright(c) 1999 - 2013 Eurecom
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information
+  Openair Admin: openair_admin@eurecom.fr
+  Openair Tech : openair_tech@eurecom.fr
+  Forums       : http://forums.eurecom.fr/openairinterface
+  Address      : EURECOM, Campus SophiaTech, 450 Route des Chappes
+                 06410 Biot FRANCE
+
+*******************************************************************************/
+
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/openair-cn/S1AP/s1ap_mme_itti_messaging.h b/openair-cn/S1AP/s1ap_mme_itti_messaging.h
index 38e30f6a90..07f8265635 100644
--- a/openair-cn/S1AP/s1ap_mme_itti_messaging.h
+++ b/openair-cn/S1AP/s1ap_mme_itti_messaging.h
@@ -29,6 +29,7 @@
 *******************************************************************************/
 
 #include <stdint.h>
+#include <string.h>
 
 #include "intertask_interface.h"
 
@@ -38,10 +39,30 @@
 int s1ap_mme_itti_send_sctp_request(uint8_t *buffer, uint32_t length,
                                     uint32_t assoc_id, uint16_t stream);
 
-int s1ap_mme_itti_nas_uplink_ind(const uint32_t ue_id, uint8_t * const buffer,
+int s1ap_mme_itti_nas_uplink_ind(const uint32_t ue_id, uint8_t *const buffer,
                                  const uint32_t length);
 
 int s1ap_mme_itti_nas_downlink_cnf(const uint32_t ue_id,
                                    nas_error_code_t error_code);
 
+static inline void s1ap_mme_itti_nas_establish_ind(
+    const uint32_t ue_id, uint8_t * const nas_msg, const uint32_t nas_msg_length,
+    const long cause, const uint16_t tac)
+{
+    MessageDef     *message_p;
+
+    message_p = itti_alloc_new_message(TASK_S1AP, NAS_CONNECTION_ESTABLISHMENT_IND);
+
+    NAS_CONN_EST_IND(message_p).nas.UEid                 = ue_id;
+    /* Mapping between asn1 definition and NAS definition */
+    NAS_CONN_EST_IND(message_p).nas.asCause              = cause + 1;
+    NAS_CONN_EST_IND(message_p).nas.tac                  = tac;
+    NAS_CONN_EST_IND(message_p).nas.initialNasMsg.length = nas_msg_length;
+
+    NAS_CONN_EST_IND(message_p).nas.initialNasMsg.data = malloc(sizeof(uint8_t) * nas_msg_length);
+    memcpy(NAS_CONN_EST_IND(message_p).nas.initialNasMsg.data, nas_msg, nas_msg_length);
+
+    itti_send_msg_to_task(TASK_NAS, INSTANCE_DEFAULT, message_p);
+}
+
 #endif /* S1AP_MME_ITTI_MESSAGING_H_ */
diff --git a/openair-cn/S1AP/s1ap_mme_nas_procedures.c b/openair-cn/S1AP/s1ap_mme_nas_procedures.c
index b849e98f11..037a0571c2 100644
--- a/openair-cn/S1AP/s1ap_mme_nas_procedures.c
+++ b/openair-cn/S1AP/s1ap_mme_nas_procedures.c
@@ -75,7 +75,11 @@ int s1ap_mme_handle_initial_ue_message(uint32_t assoc_id, uint32_t stream,
     S1AP_DEBUG("New Initial UE message received with eNB UE S1AP ID: 0x%06x\n",
                eNB_ue_s1ap_id);
 
-    if ((ue_ref = s1ap_is_ue_eNB_id_in_list(eNB_ref, eNB_ue_s1ap_id)) == NULL) {
+    ue_ref = s1ap_is_ue_eNB_id_in_list(eNB_ref, eNB_ue_s1ap_id);
+    if (ue_ref == NULL)
+    {
+        uint16_t tac = 0;
+
         /* This UE eNB Id has currently no known s1 association.
          * Create new UE context by associating new mme_ue_s1ap_id.
          * Update eNB UE list.
@@ -115,57 +119,21 @@ int s1ap_mme_handle_initial_ue_message(uint32_t assoc_id, uint32_t stream,
             /* TODO: should take the first available mme_ue_s1ap_id instead of
              * the mme_ue_s1ap_id variable.
              */
-            assert(0);
+            DevMessage("mme ue s1ap id has wrapped -> case not handled\n");
         }
-        s1ap_dump_eNB(ue_ref->eNB);
-        {
-            /* We received the first NAS transport message: initial UE message.
-            * The containt of the NAS pdu should be forwarded to NAS for processing
-            */
-            MessageDef          *message_p;
-            nas_establish_ind_t *con_ind_p;
-
-            s1ap_initial_ue_message_t *s1ap_p;
-
-            message_p = itti_alloc_new_message(TASK_S1AP, NAS_CONNECTION_ESTABLISHMENT_IND);
-            /* We failed to allocate a new message... */
-            if (message_p == NULL) {
-                return -1;
-            }
-            con_ind_p = &message_p->ittiMsg.nas_conn_est_ind.nas;
-
-            s1ap_p = &message_p->ittiMsg.nas_conn_est_ind.transparent;
-
-            s1ap_p->eNB_ue_s1ap_id = eNB_ue_s1ap_id;
-            s1ap_p->mme_ue_s1ap_id = ue_ref->mme_ue_s1ap_id;
 
-#if !defined(DISABLE_USE_NAS)
-            con_ind_p->UEid = ue_ref->mme_ue_s1ap_id;
-#endif
+        s1ap_dump_eNB(ue_ref->eNB);
 
-            BIT_STRING_TO_CELL_IDENTITY(&initialUEMessage_p->eutran_cgi.cell_ID,
-                                        s1ap_p->e_utran_cgi.cell_identity);
-            TBCD_TO_PLMN_T(&initialUEMessage_p->eutran_cgi.pLMNidentity,
-                           &s1ap_p->e_utran_cgi.plmn);
+        OCTET_STRING_TO_TAC(&initialUEMessage_p->tai.tAC, tac);
 
-#if !defined(DISABLE_USE_NAS)
-            /* Copy the TAI */
-//             TBCD_TO_PLMN_T(&initialUEMessage_p->tai.pLMNidentity, &con_ind_p->tai.plmn);
-            OCTET_STRING_TO_INT16(&initialUEMessage_p->tai.tAC, con_ind_p->tac);
-#else
-            /* TODO: copy the TAC */
-//             TBCD_TO_PLMN_T(&initialUEMessage_p->tai.pLMNidentity, &con_ind_p->tai.plmn);
-            OCTET_STRING_TO_INT16(&initialUEMessage_p->tai.tAC, con_ind_p->tac);
-#endif
-            /* Copy the NAS payload */
-            con_ind_p->initialNasMsg.length = initialUEMessage_p->nas_pdu.size;
-            con_ind_p->initialNasMsg.data = malloc(sizeof(con_ind_p->initialNasMsg.data) *
-                                                   initialUEMessage_p->nas_pdu.size);
-            memcpy(con_ind_p->initialNasMsg.data, initialUEMessage_p->nas_pdu.buf,
-                   initialUEMessage_p->nas_pdu.size);
-
-            return itti_send_msg_to_task(TASK_NAS, INSTANCE_DEFAULT, message_p);
-        }
+        /* We received the first NAS transport message: initial UE message.
+         * Send a NAS ESTABLISH IND to NAS layer
+         */
+        s1ap_mme_itti_nas_establish_ind(ue_ref->mme_ue_s1ap_id,
+                                        initialUEMessage_p->nas_pdu.buf,
+                                        initialUEMessage_p->nas_pdu.size,
+                                        initialUEMessage_p->rrC_Establishment_Cause,
+                                        tac);
     }
     return 0;
 }
-- 
GitLab