From 117dc25a97a0785e881c44a17ac74a999489f456 Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Thu, 5 Dec 2013 16:57:37 +0000
Subject: [PATCH] - Use itti timer API for NAS within MME

standalone NAS build OK

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4619 818b1a75-f10b-46b9-bf7c-635c3b92a50f
---
 openair-cn/NAS/EURECOM-NAS/src/nas_network.c  |   2 +
 .../NAS/EURECOM-NAS/src/util/nas_timer.c      | 685 ++++++++++--------
 .../NAS/EURECOM-NAS/src/util/nas_timer.h      |  37 +-
 openair-cn/NAS/Makefile.inc                   |   2 +
 openair-cn/NAS/nas_main.c                     |   9 +
 5 files changed, 411 insertions(+), 324 deletions(-)

diff --git a/openair-cn/NAS/EURECOM-NAS/src/nas_network.c b/openair-cn/NAS/EURECOM-NAS/src/nas_network.c
index 6898bc1f24..ea48bd305d 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/nas_network.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/nas_network.c
@@ -21,6 +21,7 @@ Description NAS procedure functions triggered by the network
 #include "nas_network.h"
 #include "commonDef.h"
 #include "nas_log.h"
+#include "nas_timer.h"
 
 #include "as_message.h"
 #include "nas_proc.h"
@@ -62,6 +63,7 @@ void nas_network_initialize(void)
 #ifdef NAS_MME
     /* Initialize the internal NAS processing data */
 # if defined(EPC_BUILD)
+    nas_timer_init();
     nas_proc_initialize(mme_config_p);
 # else
     nas_proc_initialize();
diff --git a/openair-cn/NAS/EURECOM-NAS/src/util/nas_timer.c b/openair-cn/NAS/EURECOM-NAS/src/util/nas_timer.c
index 5b18e3d3b9..1d7b963132 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/util/nas_timer.c
+++ b/openair-cn/NAS/EURECOM-NAS/src/util/nas_timer.c
@@ -1,38 +1,40 @@
 /*****************************************************************************
-			Eurecom OpenAirInterface 3
-			Copyright(c) 2012 Eurecom
+            Eurecom OpenAirInterface 3
+            Copyright(c) 2012 Eurecom
 
-Source		timer.c
+Source      timer.c
 
-Version		0.1
+Version     0.1
 
-Date		2012/10/09
+Date        2012/10/09
 
-Product		NAS stack
+Product     NAS stack
 
-Subsystem	Utilities
+Subsystem   Utilities
 
-Author		Frederic Maurel
+Author      Frederic Maurel
 
-Description	Timer utilities
+Description Timer utilities
 
 *****************************************************************************/
 
+#include <pthread.h>
+#include <assert.h>
+#include <signal.h>
+#include <stdint.h>
+
+#include <string.h> // memset
+#include <time.h>   // clock_gettime
+#include <sys/time.h>   // setitimer
+#include <stdlib.h> // malloc, free
+
 #if defined(NAS_MME) && defined(EPC_BUILD)
-# include "TIMER/timer.h"
+# include "intertask_interface.h"
+# include "timer.h"
 #endif
 #include "nas_timer.h"
 #include "commonDef.h"
 
-#include <assert.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include <string.h>	// memset
-#include <time.h>	// clock_gettime
-#include <sys/time.h>	// setitimer
-#include <stdlib.h>	// malloc, free
-
 /****************************************************************************/
 /****************  E X T E R N A L    D E F I N I T I O N S  ****************/
 /****************************************************************************/
@@ -48,11 +50,15 @@ Description	Timer utilities
  * value when the timer entry was allocated.
  */
 typedef struct {
-    struct timeval itv;		/* Initial interval timer value		 */
-    struct timeval tv;		/* Interval timer value			 */
-    nas_timer_callback_t cb;	/* Callback executed at timer expiration */
-    void* args;			/* Callback argument parameters		 */
-    pthread_t pid;		/* Thread identifier of the callback	 */
+#if !defined(EPC_BUILD)
+    pthread_t pid;          /* Thread identifier of the callback    */
+#endif
+
+    struct timeval itv;     /* Initial interval timer value         */
+    struct timeval tv;      /* Interval timer value                 */
+
+    nas_timer_callback_t cb;    /* Callback executed at timer expiration */
+    void *args;                 /* Callback argument parameters          */
 } nas_timer_entry_t;
 
 /* Structure of a timer queue - list of active interval timer entries
@@ -62,10 +68,10 @@ typedef struct {
  * entry is removed from the queue and freed.
  */
 typedef struct _nas_timer_queue_t {
-    int id;			/* Identifier of the current timer entry */
-    nas_timer_entry_t* entry;	/* The current timer entry		 */
-    struct _nas_timer_queue_t* prev;/* The previous timer entry in the queue */
-    struct _nas_timer_queue_t* next;/* The next timer entry in the queue	 */
+    int id;         /* Identifier of the current timer entry */
+    nas_timer_entry_t *entry;   /* The current timer entry       */
+    struct _nas_timer_queue_t *prev;/* The previous timer entry in the queue */
+    struct _nas_timer_queue_t *next;/* The next timer entry in the queue     */
 } timer_queue_t;
 
 /* Structure of a timer database
@@ -74,49 +80,72 @@ typedef struct _nas_timer_queue_t {
  * startup and to maintain an ordered queue of active timer entries.
  */
 typedef struct {
-    int timer_id;	/* Identifier of the first available timer entry */
-#define TIMER_DATABASE_SIZE	256
+    int timer_id;   /* Identifier of the first available timer entry */
+#define TIMER_DATABASE_SIZE 256
     timer_queue_t tq[TIMER_DATABASE_SIZE];
-    timer_queue_t* head;/* Pointer to the first timer entry to be fired	 */
+    timer_queue_t *head;/* Pointer to the first timer entry to be fired  */
+
+#if !defined(EPC_BUILD)
     pthread_mutex_t mutex;
+#endif
 } nas_timer_database_t;
 
 /*
  * The timer database
  */
-static nas_timer_database_t _nas_timer_db = {0, {}, NULL, PTHREAD_MUTEX_INITIALIZER};
+static nas_timer_database_t _nas_timer_db = {
+    0,
+    {},
+    NULL
+#if !defined(EPC_BUILD)
+    , PTHREAD_MUTEX_INITIALIZER
+#endif
+};
+
+#if defined(EPC_BUILD)
+#define nas_timer_lock_db()
+#define nas_timer_unlock_db()
+#else
+#define nas_timer_lock_db()     pthread_mutex_lock(&_nas_timer_db.mutex)
+#define nas_timer_unlock_db()   pthread_mutex_unlock(&_nas_timer_db.mutex)
+#endif
 
 /*
  * The handler executed whenever the system timer expires
  */
+#if !defined(EPC_BUILD)
 static void _nas_timer_handler(int signal);
+#endif
 
 /*
  * -----------------------------------------------------------------------------
- *		Functions used to manage the timer database
+ *      Functions used to manage the timer database
  * -----------------------------------------------------------------------------
  */
 static void _nas_timer_db_init(void);
 
 static int _nas_timer_db_get_id(void);
 static int _nas_timer_db_is_active(int id);
-static nas_timer_entry_t* _nas_timer_db_create_entry(long sec, nas_timer_callback_t cb, void* args);
+static nas_timer_entry_t *_nas_timer_db_create_entry(long sec,
+        nas_timer_callback_t cb, void *args);
 static void _nas_timer_db_delete_entry(int id);
 
-static void _nas_timer_db_insert_entry(int id, nas_timer_entry_t* te);
-static int _nas_timer_db_insert(timer_queue_t* entry);
+static void _nas_timer_db_insert_entry(int id, nas_timer_entry_t *te);
+static int _nas_timer_db_insert(timer_queue_t *entry);
 
-static nas_timer_entry_t* _nas_timer_db_remove_entry(int id);
-static int _nas_timer_db_remove(timer_queue_t* entry);
+static nas_timer_entry_t *_nas_timer_db_remove_entry(int id);
+static int _nas_timer_db_remove(timer_queue_t *entry);
 
 /*
  * -----------------------------------------------------------------------------
- *		Operator functions for timeval structures
+ *      Operator functions for timeval structures
  * -----------------------------------------------------------------------------
  */
-static int _nas_timer_cmp(const struct timeval* a, const struct timeval* b);
-static void _nas_timer_add(const struct timeval* a, const struct timeval* b, struct timeval* result);
-static int _nas_timer_sub(const struct timeval* a, const struct timeval* b, struct timeval* result);
+static int _nas_timer_cmp(const struct timeval *a, const struct timeval *b);
+static void _nas_timer_add(const struct timeval *a, const struct timeval *b,
+                           struct timeval *result);
+static int _nas_timer_sub(const struct timeval *a, const struct timeval *b,
+                          struct timeval *result);
 
 /****************************************************************************/
 /******************  E X P O R T E D    F U N C T I O N S  ******************/
@@ -124,16 +153,16 @@ static int _nas_timer_sub(const struct timeval* a, const struct timeval* b, stru
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 timer_init()                                              **
+ ** Name:    timer_init()                                              **
  **                                                                        **
  ** Description: Initializes internal data used to manage timers           **
  **                                                                        **
- ** Inputs:	 None                                                      **
- **		 Others:	None                                       **
+ ** Inputs:  None                                                      **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	RETURNok, RETURNerror                      **
- **		 Others:	_nas_timer_db                              **
+ ** Outputs:     None                                                      **
+ **      Return:    RETURNok, RETURNerror                      **
+ **      Others:    _nas_timer_db                              **
  **                                                                        **
  ***************************************************************************/
 int nas_timer_init(void)
@@ -141,6 +170,7 @@ int nas_timer_init(void)
     /* Initialize the timer database */
     _nas_timer_db_init();
 
+#if !defined(EPC_BUILD)
     /* Setup the timer database handler */
     struct sigaction act;
 
@@ -152,9 +182,9 @@ int nas_timer_init(void)
     (void) sigdelset (&act.sa_mask, SIGILL);
     (void) sigdelset (&act.sa_mask, SIGTRAP);
     (void) sigdelset (&act.sa_mask, SIGIOT);
-#ifndef LINUX
+# ifndef LINUX
     (void) sigdelset (&act.sa_mask, SIGEMT);
-#endif
+# endif
     (void) sigdelset (&act.sa_mask, SIGFPE);
     (void) sigdelset (&act.sa_mask, SIGBUS);
     (void) sigdelset (&act.sa_mask, SIGSEGV);
@@ -162,112 +192,128 @@ int nas_timer_init(void)
 
     act.sa_handler = _nas_timer_handler;
     if ( sigaction (SIGALRM, &act, 0) < 0 ) {
-	return (RETURNerror);
+        return (RETURNerror);
     }
+#endif
     return (RETURNok);
 }
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 timer_start()                                             **
+ ** Name:    timer_start()                                             **
  **                                                                        **
  ** Description: Schedules the execution of the given callback function    **
- **		 upon expiration of the specified time interval            **
+ **      upon expiration of the specified time interval            **
  **                                                                        **
- ** Inputs:	 sec:		The value of the time interval in seconds  **
- **		 cb:		Function executed upon timer expiration    **
- **		 args:		Callback argument parameters               **
- **		 Others:	None                                       **
+ ** Inputs:  sec:       The value of the time interval in seconds  **
+ **      cb:        Function executed upon timer expiration    **
+ **      args:      Callback argument parameters               **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	The timer identifier when successfully     **
- **				started; NAS_TIMER_INACTIVE_ID otherwise.  **
- **		 Others:	None                                       **
+ ** Outputs:     None                                                      **
+ **      Return:    The timer identifier when successfully     **
+ **             started; NAS_TIMER_INACTIVE_ID otherwise.  **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-int nas_timer_start(long sec, nas_timer_callback_t cb, void* args)
+int nas_timer_start(long sec, nas_timer_callback_t cb, void *args)
 {
+    int id;
+    nas_timer_entry_t *te;
+#if defined(EPC_BUILD)
+    int ret;
+    long timer_id;
+#endif
+
     /* Do not start null timer */
     if (sec == 0) {
-	return (NAS_TIMER_INACTIVE_ID);
+        return (NAS_TIMER_INACTIVE_ID);
     }
 
     /* Get an identifier for the new timer entry */
-    int id = _nas_timer_db_get_id();
+    id = _nas_timer_db_get_id();
     if (id < 0) {
-	/* No available timer entry found */
-	return (NAS_TIMER_INACTIVE_ID);
+        /* No available timer entry found */
+        return (NAS_TIMER_INACTIVE_ID);
     }
 
     /* Create a new timer entry */
-    nas_timer_entry_t* te = _nas_timer_db_create_entry(sec, cb, args);
+    te = _nas_timer_db_create_entry(sec, cb, args);
     if (te == NULL) {
-	return (NAS_TIMER_INACTIVE_ID);
+        return (NAS_TIMER_INACTIVE_ID);
     }
 
     /* Insert the new entry into the timer queue */
     _nas_timer_db_insert_entry(id, te);
+#if defined(EPC_BUILD)
+    ret = timer_setup(sec, 0, TASK_NAS, INSTANCE_DEFAULT, TIMER_PERIODIC, args, &timer_id);
+
+    if (ret == -1) {
+        return NAS_TIMER_INACTIVE_ID;
+    }
+#endif
+
     return (id);
 }
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 timer_stop()                                              **
+ ** Name:    timer_stop()                                              **
  **                                                                        **
  ** Description: Stop the timer with the specified identifier              **
  **                                                                        **
- ** Inputs:	 id:		The identifier of the timer to be stopped  **
- **		 Others:	None                                       **
+ ** Inputs:  id:        The identifier of the timer to be stopped  **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	NAS_TIMER_INACTIVE_ID when successfully stop-  **
- **				ped; The timer identifier otherwise.       **
- **		 Others:	None                                       **
+ ** Outputs:     None                                                      **
+ **      Return:    NAS_TIMER_INACTIVE_ID when successfully stop-  **
+ **             ped; The timer identifier otherwise.       **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
 int nas_timer_stop(int id)
 {
     /* Check if the timer entry is active */
     if (_nas_timer_db_is_active(id)) {
-	/* Remove the entry from the timer queue */
-	(void) _nas_timer_db_remove_entry(id);
-	/* Delete the timer entry */
-	_nas_timer_db_delete_entry(id);
-	return (NAS_TIMER_INACTIVE_ID);
+        /* Remove the entry from the timer queue */
+        (void) _nas_timer_db_remove_entry(id);
+        /* Delete the timer entry */
+        _nas_timer_db_delete_entry(id);
+        return (NAS_TIMER_INACTIVE_ID);
     }
     return (id);
 }
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 timer_restart()                                           **
+ ** Name:    timer_restart()                                           **
  **                                                                        **
  ** Description: Restart the timer with the specified identifier. The ti-  **
- **		 mer is scheduled to expire after the same period of time  **
- **		 and will execute the callback function that has been set  **
- **		 when it was started.                                      **
+ **      mer is scheduled to expire after the same period of time  **
+ **      and will execute the callback function that has been set  **
+ **      when it was started.                                      **
  **                                                                        **
- ** Inputs:	 id:		The identifier of the timer to be started  **
- **				again                                      **
- **		 Others:	None                                       **
+ ** Inputs:  id:        The identifier of the timer to be started  **
+ **             again                                      **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	The timer identifier when successfully     **
- **				re-started; NAS_TIMER_INACTIVE_ID otherwise.   **
- **		 Others:	None                                       **
+ ** Outputs:     None                                                      **
+ **      Return:    The timer identifier when successfully     **
+ **             re-started; NAS_TIMER_INACTIVE_ID otherwise.   **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
 int nas_timer_restart(int id)
 {
     /* Check if the timer entry is active */
     if (_nas_timer_db_is_active(id)) {
-	/* Remove the entry from the timer queue */
-	nas_timer_entry_t* te = _nas_timer_db_remove_entry(id);
-	/* Initialize its interval timer value */
-	te->tv = te->itv;
-	/* Insert again the entry into the timer queue */
-	_nas_timer_db_insert_entry(id, te);
-	return (id);
+        /* Remove the entry from the timer queue */
+        nas_timer_entry_t *te = _nas_timer_db_remove_entry(id);
+        /* Initialize its interval timer value */
+        te->tv = te->itv;
+        /* Insert again the entry into the timer queue */
+        _nas_timer_db_insert_entry(id, te);
+        return (id);
     }
     return (NAS_TIMER_INACTIVE_ID);
 }
@@ -278,30 +324,39 @@ int nas_timer_restart(int id)
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_timer_handler()                                      **
+ ** Name:    _nas_timer_handler()                                      **
  **                                                                        **
  ** Description: The timer handler is executed whenever the system deli-   **
- **		 vers signal SIGALARM. It starts execution of the callback **
- **		 function of the first entry within the queue of active    **
- **		 timer entries. The entry is not removed from the queue of **
- **		 active timer entries and shall be explicitly removed when **
- **		 the timer expires.                                        **
+ **      vers signal SIGALARM. It starts execution of the callback **
+ **      function of the first entry within the queue of active    **
+ **      timer entries. The entry is not removed from the queue of **
+ **      active timer entries and shall be explicitly removed when **
+ **      the timer expires.                                        **
  **                                                                        **
- ** Inputs:	 None                                                      **
- **		 Others:	None                                       **
+ ** Inputs:  None                                                      **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	None                                       **
- **		 Others:	_nas_timer_db                              **
+ ** Outputs:     None                                                      **
+ **      Return:    None                                       **
+ **      Others:    _nas_timer_db                              **
  **                                                                        **
  ***************************************************************************/
+#if defined(EPC_BUILD)
+void nas_timer_handle_signal_expiry(long timer_id, void *arg_p)
+{
+    /* Get the timer entry for which the system timer expired */
+    nas_timer_entry_t *te = _nas_timer_db.head->entry;
+
+    te->cb(te->args);
+}
+#else
 static void _nas_timer_handler(int signal)
 {
     /* At least one timer has been started */
     assert( (_nas_timer_db.head != NULL) && (_nas_timer_db.head->entry != NULL) );
 
     /* Get the timer entry for which the system timer expired */
-    nas_timer_entry_t* te = _nas_timer_db.head->entry;
+    nas_timer_entry_t *te = _nas_timer_db.head->entry;
 
     /* Execute the callback function */
     pthread_attr_t attr;
@@ -313,54 +368,58 @@ static void _nas_timer_handler(int signal)
 
     /* Wait for the thread to terminate before releasing the timer entry */
     if (rc == 0) {
-	void* result = NULL;
-	(void) pthread_join(te->pid, &result);
-	/* TODO: Check returned result ??? */
-	if (result) free(result);
+        void *result = NULL;
+        (void) pthread_join(te->pid, &result);
+        /* TODO: Check returned result ??? */
+        if (result) {
+            free(result);
+        }
     }
 }
+#endif
 
 /*
  * -----------------------------------------------------------------------------
- *		Functions used to manage the timer database
+ *      Functions used to manage the timer database
  * -----------------------------------------------------------------------------
  */
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_timer_db_init()                                      **
+ ** Name:    _nas_timer_db_init()                                      **
  **                                                                        **
  ** Description: Initializes the timer database                            **
  **                                                                        **
- ** Inputs:	 None                                                      **
- **		 Others:	None                                       **
+ ** Inputs:  None                                                      **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	None                                       **
- **		 Others:	_nas_timer_db                              **
+ ** Outputs:     None                                                      **
+ **      Return:    None                                       **
+ **      Others:    _nas_timer_db                              **
  **                                                                        **
  ***************************************************************************/
 static void _nas_timer_db_init(void)
 {
-    for (int i = 0; i < TIMER_DATABASE_SIZE; i++) {
-	_nas_timer_db.tq[i].id = NAS_TIMER_INACTIVE_ID;
+    int i;
+    for (i = 0; i < TIMER_DATABASE_SIZE; i++) {
+        _nas_timer_db.tq[i].id = NAS_TIMER_INACTIVE_ID;
     }
 }
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_timer_db_get_id()                                    **
+ ** Name:    _nas_timer_db_get_id()                                    **
  **                                                                        **
  ** Description: Gets the identifier of the first available timer entry in **
- **		 the queue of active timer entries                         **
+ **      the queue of active timer entries                         **
  **                                                                        **
- ** Inputs:	 None                                                      **
- **		 Others:	_nas_timer_db                              **
+ ** Inputs:  None                                                      **
+ **      Others:    _nas_timer_db                              **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	The identifier of the first available      **
- **				timer entry if the queue of active timers  **
- **				is not full; -1 otherwise.                 **
- **		 Others:	_nas_timer_db                              **
+ ** Outputs:     None                                                      **
+ **      Return:    The identifier of the first available      **
+ **             timer entry if the queue of active timers  **
+ **             is not full; -1 otherwise.                 **
+ **      Others:    _nas_timer_db                              **
  **                                                                        **
  ***************************************************************************/
 static int _nas_timer_db_get_id(void)
@@ -368,17 +427,17 @@ static int _nas_timer_db_get_id(void)
     int i;
     /* Search from the current timer entry to the last timer entry */
     for (i = _nas_timer_db.timer_id; i < TIMER_DATABASE_SIZE; i++) {
-	if (_nas_timer_db.tq[i].id < 0 ) {
-	    _nas_timer_db.timer_id = i+1;
-	    return i;
-	}
+        if (_nas_timer_db.tq[i].id < 0 ) {
+            _nas_timer_db.timer_id = i+1;
+            return i;
+        }
     }
     /* Search from the first timer entry to the current timer entry */
     for (i = 0; i < _nas_timer_db.timer_id; i++) {
-	if (_nas_timer_db.tq[i].id < 0 ) {
-	    _nas_timer_db.timer_id = i+1;
-	    return i;
-	}
+        if (_nas_timer_db.tq[i].id < 0 ) {
+            _nas_timer_db.timer_id = i+1;
+            return i;
+        }
     }
     /* No available timer entry found */
     return (-1);
@@ -386,71 +445,71 @@ static int _nas_timer_db_get_id(void)
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_timer_db_is_active()                                 **
+ ** Name:    _nas_timer_db_is_active()                                 **
  **                                                                        **
  ** Description: Checks whether the entry with the given identifier is     **
- **		 active within the queue of active timer entries           **
+ **      active within the queue of active timer entries           **
  **                                                                        **
- ** Inputs:	 id:		Identifier of the timer entry to check     **
- **		 Others:	_nas_timer_db                              **
+ ** Inputs:  id:        Identifier of the timer entry to check     **
+ **      Others:    _nas_timer_db                              **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	TRUE if the timer entry is active; FALSE   **
- **				if it is not an active timer entry.        **
- **		 Others:	None                                       **
+ ** Outputs:     None                                                      **
+ **      Return:    TRUE if the timer entry is active; FALSE   **
+ **             if it is not an active timer entry.        **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
 static int _nas_timer_db_is_active(int id)
 {
     return ( (id != NAS_TIMER_INACTIVE_ID) &&
-	     (_nas_timer_db.tq[id].id != NAS_TIMER_INACTIVE_ID) );
+             (_nas_timer_db.tq[id].id != NAS_TIMER_INACTIVE_ID) );
 }
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_timer_db_create_entry()                              **
+ ** Name:    _nas_timer_db_create_entry()                              **
  **                                                                        **
  ** Description: Creates a new timer entry                                 **
  **                                                                        **
- ** Inputs:	 sec:		Time interval value                        **
- **		 cb:		Function executed upon timer expiration    **
- **		 args:		Callback argument parameters               **
- **		 Others:	None                                       **
+ ** Inputs:  sec:       Time interval value                        **
+ **      cb:        Function executed upon timer expiration    **
+ **      args:      Callback argument parameters               **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	A pointer to the new timer entry if        **
- **				successfully allocated; NULL otherwise     **
- **		 Others:	None                                       **
+ ** Outputs:     None                                                      **
+ **      Return:    A pointer to the new timer entry if        **
+ **             successfully allocated; NULL otherwise     **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static nas_timer_entry_t* _nas_timer_db_create_entry(
+static nas_timer_entry_t *_nas_timer_db_create_entry(
     long sec, nas_timer_callback_t cb,
-    void* args)
+    void *args)
 {
-    nas_timer_entry_t* te = (nas_timer_entry_t*)malloc(sizeof(nas_timer_entry_t));
+    nas_timer_entry_t *te = (nas_timer_entry_t *)malloc(sizeof(nas_timer_entry_t));
     if (te != NULL) {
-	te->itv.tv_sec = sec;
-	te->itv.tv_usec = 0;
-	te->tv = te->itv;
-	te->cb = cb;
-	te->args = args;
+        te->itv.tv_sec = sec;
+        te->itv.tv_usec = 0;
+        te->tv = te->itv;
+        te->cb = cb;
+        te->args = args;
     }
     return (te);
 }
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_timer_db_delete_entry()                              **
+ ** Name:    _nas_timer_db_delete_entry()                              **
  **                                                                        **
  ** Description: Deletes the entry with the given identifier from the ti-  **
- **		 mer database.                                             **
+ **      mer database.                                             **
  **                                                                        **
- ** Inputs:	 id:		Identifier of the entry to be deleted      **
- **		 Others:	None                                       **
+ ** Inputs:  id:        Identifier of the entry to be deleted      **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	None                                       **
- **		 Others:	_nas_timer_db                              **
+ ** Outputs:     None                                                      **
+ **      Return:    None                                       **
+ **      Others:    _nas_timer_db                              **
  **                                                                        **
  ***************************************************************************/
 static void _nas_timer_db_delete_entry(int id)
@@ -466,36 +525,38 @@ static void _nas_timer_db_delete_entry(int id)
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_timer_db_insert_entry()                              **
+ ** Name:    _nas_timer_db_insert_entry()                              **
  **                                                                        **
  ** Description: Inserts the entry with the given identifier into the      **
- **		 queue of active timer entries and restarts the system     **
- **		 timer if the new entry is the next entry for which the    **
- **		 timer should be scheduled to expire.                      **
+ **      queue of active timer entries and restarts the system     **
+ **      timer if the new entry is the next entry for which the    **
+ **      timer should be scheduled to expire.                      **
  **                                                                        **
- ** Inputs:	 id:		Identifier of the new entry                **
- **		 te:		Pointer to the entry to be inserted        **
- **		 Others:	None                                       **
+ ** Inputs:  id:        Identifier of the new entry                **
+ **      te:        Pointer to the entry to be inserted        **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	None                                       **
- **		 Others:	_nas_timer_db                              **
+ ** Outputs:     None                                                      **
+ **      Return:    None                                       **
+ **      Others:    _nas_timer_db                              **
  **                                                                        **
  ***************************************************************************/
-static void _nas_timer_db_insert_entry(int id, nas_timer_entry_t* te)
+static void _nas_timer_db_insert_entry(int id, nas_timer_entry_t *te)
 {
+    struct itimerval it;
+    struct timespec  ts;
+    struct timeval   current_time;
+    int restart;
+
     /* Enqueue the new timer entry */
     _nas_timer_db.tq[id].id = id;
     _nas_timer_db.tq[id].entry = te;
 
     /* Save its interval timer value */
-    struct itimerval it;
     it.it_interval.tv_sec = it.it_interval.tv_usec = 0;
     it.it_value = te->tv;
 
     /* Update its interval timer value */
-    struct timespec ts;
-    struct timeval current_time;
     clock_gettime(CLOCK_MONOTONIC, &ts);
     current_time.tv_sec = ts.tv_sec;
     current_time.tv_usec = ts.tv_nsec/1000;
@@ -503,29 +564,33 @@ static void _nas_timer_db_insert_entry(int id, nas_timer_entry_t* te)
     _nas_timer_add(&te->tv, &current_time, &te->tv);
 
     /* Insert the new timer entry into the list of active entries */
-    pthread_mutex_lock(&_nas_timer_db.mutex);
-    int restart = _nas_timer_db_insert(&_nas_timer_db.tq[id]);
-    pthread_mutex_unlock(&_nas_timer_db.mutex);
+    nas_timer_lock_db();
+    restart = _nas_timer_db_insert(&_nas_timer_db.tq[id]);
+    nas_timer_unlock_db();
 
+#if defined(EPC_BUILD)
     if (restart) {
-	/* The new entry is the first entry of the list;
-	 * restart the system timer */
-	setitimer(ITIMER_REAL, &it, 0);
+        /* The new entry is the first entry of the list;
+         * restart the system timer */
+        setitimer(ITIMER_REAL, &it, 0);
     }
+#else
+    (void)(restart);
+#endif
 }
 
-static int _nas_timer_db_insert(timer_queue_t* entry)
+static int _nas_timer_db_insert(timer_queue_t *entry)
 {
-    timer_queue_t *prev, *next;	/* previous and next entry in the list	*/
+    timer_queue_t *prev, *next; /* previous and next entry in the list  */
     /*
      * Search the list of timer entries for the first entry with an interval
      * timer value greater than the interval timer value of the new timer entry
      */
     for (prev = NULL, next = _nas_timer_db.head; next != NULL; next = next->next) {
-	if (_nas_timer_cmp(&next->entry->tv, &entry->entry->tv) > 0) {
-	    break;
-	}
-	prev = next;
+        if (_nas_timer_cmp(&next->entry->tv, &entry->entry->tv) > 0) {
+            break;
+        }
+        prev = next;
     }
     /* Insert the new entry in the list of active timer entries */
     /* prev <-- entry --> next */
@@ -533,18 +598,17 @@ static int _nas_timer_db_insert(timer_queue_t* entry)
     entry->next = next;
     /* Update the pointer from the previous entry */
     if (entry->next != NULL) {
-	/* prev <-- entry <--> next */
-	entry->next->prev = entry;
+        /* prev <-- entry <--> next */
+        entry->next->prev = entry;
     }
     /* Update the pointer from the next entry */
     if (entry->prev != NULL) {
-	/* prev <--> entry <--> next */
-	entry->prev->next = entry;
-    }
-    else {
-	/* The new entry is the first entry of the list */
-	_nas_timer_db.head = entry;
-	return TRUE;
+        /* prev <--> entry <--> next */
+        entry->prev->next = entry;
+    } else {
+        /* The new entry is the first entry of the list */
+        _nas_timer_db.head = entry;
+        return TRUE;
     }
     /* The new entry is NOT the first entry of the list */
     return FALSE;
@@ -552,87 +616,99 @@ static int _nas_timer_db_insert(timer_queue_t* entry)
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_timer_db_remove_entry()                              **
+ ** Name:    _nas_timer_db_remove_entry()                              **
  **                                                                        **
  ** Description: Removes the entry with the given identifier from the      **
- **		 queue of active timer entries and restarts the system     **
- **		 timer if the entry was the next entry for which the timer **
- **		 was scheduled to expire.                                  **
+ **      queue of active timer entries and restarts the system     **
+ **      timer if the entry was the next entry for which the timer **
+ **      was scheduled to expire.                                  **
  **                                                                        **
- ** Inputs:	 id:		Identifier of the entry to be removed      **
- **		 Others:	None                                       **
+ ** Inputs:  id:        Identifier of the entry to be removed      **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	A pointer to the removed entry             **
- **		 Others:	_nas_timer_db                              **
+ ** Outputs:     None                                                      **
+ **      Return:    A pointer to the removed entry             **
+ **      Others:    _nas_timer_db                              **
  **                                                                        **
  ***************************************************************************/
-static nas_timer_entry_t* _nas_timer_db_remove_entry(int id)
+static nas_timer_entry_t *_nas_timer_db_remove_entry(int id)
 {
+    int restart;
+
     /* The identifier of the timer is valid within the timer queue */
     assert(_nas_timer_db.tq[id].id == id);
 
     /* Remove the timer entry from the list of active entries */
-    pthread_mutex_lock(&_nas_timer_db.mutex);
-    int restart = _nas_timer_db_remove(&_nas_timer_db.tq[id]);
-    pthread_mutex_unlock(&_nas_timer_db.mutex);
+    nas_timer_lock_db();
+    restart = _nas_timer_db_remove(&_nas_timer_db.tq[id]);
+    nas_timer_unlock_db();
 
     if (restart) {
-	int rc;
-	/* The entry was the first entry of the list;
-	 * the system timer needs to be restarted */
-	struct itimerval it;
-	it.it_interval.tv_sec = it.it_interval.tv_usec = 0;
-	struct timespec ts;
-	clock_gettime(CLOCK_MONOTONIC, &ts);
-	struct timeval time;
-	time.tv_sec = ts.tv_sec;
-	time.tv_usec = ts.tv_nsec/1000;
-	/* tv = tv - time() */
-	rc = _nas_timer_sub(&_nas_timer_db.head->entry->tv, &time, &it.it_value);
-	if (rc < 0) {
-	    /* The system timer should has already expired */
-	    _nas_timer_handler(SIGALRM);
-	}
-	else {
-	    /* Restart the system timer */
-	    setitimer(ITIMER_REAL, &it, 0);
-	}
+        int rc;
+        /* The entry was the first entry of the list;
+         * the system timer needs to be restarted */
+        struct itimerval it;
+        struct timeval tv;
+        struct timespec ts;
+
+        it.it_interval.tv_sec = it.it_interval.tv_usec = 0;
+
+        clock_gettime(CLOCK_MONOTONIC, &ts);
+
+        tv.tv_sec = ts.tv_sec;
+        tv.tv_usec = ts.tv_nsec/1000;
+        /* tv = tv - time() */
+        rc = _nas_timer_sub(&_nas_timer_db.head->entry->tv, &tv, &it.it_value);
+
+#if defined(EPC_BUILD)
+        (void)(rc);
+#else
+        if (rc < 0) {
+            /* The system timer should have already expired */
+            _nas_timer_handler(SIGALRM);
+        } else {
+            /* Restart the system timer */
+            setitimer(ITIMER_REAL, &it, 0);
+        }
+#endif
     }
 
     /* Return a pointer to the removed entry */
     return (_nas_timer_db.tq[id].entry);
 }
 
-static int _nas_timer_db_remove(timer_queue_t* entry)
+static int _nas_timer_db_remove(timer_queue_t *entry)
 {
     /* Update the pointer from the previous entry */
     /* prev ---> entry ---> next */
     /* prev <--- entry <--- next */
     if (entry->next != NULL) {
-	/* prev ---> entry ---> next */
-	/* prev <-------------- next */
-	entry->next->prev = entry->prev;
+        /* prev ---> entry ---> next */
+        /* prev <-------------- next */
+        entry->next->prev = entry->prev;
     }
     /* Update the pointer from the next entry */
     if (entry->prev != NULL) {
-	/* prev --------------> next */
-	/* prev <-------------- next */
-	entry->prev->next = entry->next;
-    }
-    else {
-	/* The entry was the first entry of the list */
-	_nas_timer_db.head = entry->next;
-	if (_nas_timer_db.head != NULL) {
-	    /* Other timers are scheduled to expire */
-	    return TRUE;
-	}
-	/* No more timer is scheduled to expire; stop the system timer */
-	struct itimerval it;
-	it.it_interval.tv_sec = it.it_interval.tv_usec = 0;
-	it.it_value.tv_sec = it.it_value.tv_usec = 0;
-	setitimer(ITIMER_REAL, &it, 0);
-	return FALSE;
+        /* prev --------------> next */
+        /* prev <-------------- next */
+        entry->prev->next = entry->next;
+    } else {
+        /* The entry was the first entry of the list */
+        _nas_timer_db.head = entry->next;
+        if (_nas_timer_db.head != NULL) {
+            /* Other timers are scheduled to expire */
+            return TRUE;
+        }
+#if !defined(EPC_BUILD)
+        {
+            /* No more timer is scheduled to expire; stop the system timer */
+            struct itimerval it;
+            it.it_interval.tv_sec = it.it_interval.tv_usec = 0;
+            it.it_value.tv_sec = it.it_value.tv_usec = 0;
+            setitimer(ITIMER_REAL, &it, 0);
+            return FALSE;
+        }
+#endif
     }
     /* The entry was NOT the first entry of the list */
     return FALSE;
@@ -640,54 +716,55 @@ static int _nas_timer_db_remove(timer_queue_t* entry)
 
 /*
  * -----------------------------------------------------------------------------
- *		Operator functions for timeval structures
+ *      Operator functions for timeval structures
  * -----------------------------------------------------------------------------
  */
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_timer_cmp()                                          **
+ ** Name:    _nas_timer_cmp()                                          **
  **                                                                        **
  ** Description: Performs timeval comparaison                              **
  **                                                                        **
- ** Inputs:	 a:		The first timeval structure                **
- **		 b:		The second timeval structure               **
- **		 Others:	None                                       **
+ ** Inputs:  a:     The first timeval structure                **
+ **      b:     The second timeval structure               **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 None                                                      **
- **		 Return:	-1 if a < b; 1 if a > b; 0 if a == b       **
- **		 Others:	None                                       **
+ ** Outputs:     None                                                      **
+ **      Return:    -1 if a < b; 1 if a > b; 0 if a == b       **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _nas_timer_cmp(const struct timeval* a, const struct timeval* b)
+static int _nas_timer_cmp(const struct timeval *a, const struct timeval *b)
 {
-    if (a->tv_sec < b->tv_sec)
-	return -1;
-    else if (a->tv_sec > b->tv_sec)
-	return 1;
-    else if (a->tv_usec < b->tv_usec)
-	return -1;
-    else if (a->tv_usec > b->tv_usec)
-	return 1;
+    if (a->tv_sec < b->tv_sec) {
+        return -1;
+    } else if (a->tv_sec > b->tv_sec) {
+        return 1;
+    } else if (a->tv_usec < b->tv_usec) {
+        return -1;
+    } else if (a->tv_usec > b->tv_usec) {
+        return 1;
+    }
     return 0;
 }
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_timer_add()                                          **
+ ** Name:    _nas_timer_add()                                          **
  **                                                                        **
  ** Description: Performs timeval addition                                 **
  **                                                                        **
- ** Inputs:	 a:		The first timeval structure                **
- **		 b:		The second timeval structure               **
- **		 Others:	None                                       **
+ ** Inputs:  a:     The first timeval structure                **
+ **      b:     The second timeval structure               **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 result:	result = timeval(a + b)                    **
- **		 Return:	None                                       **
- **		 Others:	None                                       **
+ ** Outputs:     result:    result = timeval(a + b)                    **
+ **      Return:    None                                       **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static void _nas_timer_add(const struct timeval* a, const struct timeval* b,
-		       struct timeval* result)
+static void _nas_timer_add(const struct timeval *a, const struct timeval *b,
+                           struct timeval *result)
 {
     result->tv_sec = a->tv_sec + b->tv_sec;
     result->tv_usec = a->tv_usec + b->tv_usec;
@@ -699,30 +776,30 @@ static void _nas_timer_add(const struct timeval* a, const struct timeval* b,
 
 /****************************************************************************
  **                                                                        **
- ** Name:	 _nas_timer_sub()                                          **
+ ** Name:    _nas_timer_sub()                                          **
  **                                                                        **
  ** Description: Performs timeval substraction                             **
  **                                                                        **
- ** Inputs:	 a:		The first timeval structure                **
- **		 b:		The second timeval structure               **
- **		 Others:	None                                       **
+ ** Inputs:  a:     The first timeval structure                **
+ **      b:     The second timeval structure               **
+ **      Others:    None                                       **
  **                                                                        **
- ** Outputs:	 result:	a >= b, result = timeval(a - b)            **
- **		 Return:	-1 if a < b; 0 otherwise                   **
- **		 Others:	None                                       **
+ ** Outputs:     result:    a >= b, result = timeval(a - b)            **
+ **      Return:    -1 if a < b; 0 otherwise                   **
+ **      Others:    None                                       **
  **                                                                        **
  ***************************************************************************/
-static int _nas_timer_sub(const struct timeval* a, const struct timeval* b,
-		      struct timeval* result)
+static int _nas_timer_sub(const struct timeval *a, const struct timeval *b,
+                          struct timeval *result)
 {
     if (_nas_timer_cmp(a,b) > 0 ) {
-	result->tv_sec = a->tv_sec - b->tv_sec;
-	result->tv_usec = a->tv_usec - b->tv_usec;
-	if (result->tv_usec < 0) {
-	    result->tv_sec--;
-	    result->tv_usec += 1000000;
-	}
-	return 0;
+        result->tv_sec = a->tv_sec - b->tv_sec;
+        result->tv_usec = a->tv_usec - b->tv_usec;
+        if (result->tv_usec < 0) {
+            result->tv_sec--;
+            result->tv_usec += 1000000;
+        }
+        return 0;
     }
     return -1;
 }
diff --git a/openair-cn/NAS/EURECOM-NAS/src/util/nas_timer.h b/openair-cn/NAS/EURECOM-NAS/src/util/nas_timer.h
index 6ff227a80c..a4c6f48be1 100644
--- a/openair-cn/NAS/EURECOM-NAS/src/util/nas_timer.h
+++ b/openair-cn/NAS/EURECOM-NAS/src/util/nas_timer.h
@@ -1,20 +1,20 @@
 /*****************************************************************************
-			Eurecom OpenAirInterface 3
-			Copyright(c) 2012 Eurecom
+            Eurecom OpenAirInterface 3
+            Copyright(c) 2012 Eurecom
 
-Source		timer.h
+Source      timer.h
 
-Version		0.1
+Version     0.1
 
-Date		2012/11/22
+Date        2012/11/22
 
-Product		NAS stack
+Product     NAS stack
 
-Subsystem	Utilities
+Subsystem   Utilities
 
-Author		Frederic Maurel
+Author      Frederic Maurel
 
-Description	Timer utilities
+Description Timer utilities
 
 *****************************************************************************/
 #ifndef __NAS_TIMER_H__
@@ -28,7 +28,7 @@ Description	Timer utilities
  * Timer identifier returned when in inactive state (timer is stopped or has
  * failed to be started)
  */
-#define NAS_TIMER_INACTIVE_ID	(-1)
+#define NAS_TIMER_INACTIVE_ID   (-1)
 
 /****************************************************************************/
 /************************  G L O B A L    T Y P E S  ************************/
@@ -36,12 +36,12 @@ Description	Timer utilities
 
 /* Timer structure */
 struct nas_timer_t {
-    int id;		/* The timer identifier 		*/
-    long sec;		/* The timer interval value in seconds	*/
+    int id;         /* The timer identifier                 */
+    long sec;       /* The timer interval value in seconds  */
 };
 
 /* Type of the callback executed when the timer expired */
-typedef void* (*nas_timer_callback_t)(void*);
+typedef void *(*nas_timer_callback_t)(void *);
 
 /****************************************************************************/
 /********************  G L O B A L    V A R I A B L E S  ********************/
@@ -51,16 +51,13 @@ typedef void* (*nas_timer_callback_t)(void*);
 /******************  E X P O R T E D    F U N C T I O N S  ******************/
 /****************************************************************************/
 
-#if defined(NAS_MME) && defined(EPC_BUILD)
-# define nas_timer_init
-# define nas_timer_start
-# define nas_timer_stop
-# define nas_timer_restart
-#else
 int nas_timer_init(void);
-int nas_timer_start(long sec, nas_timer_callback_t cb, void* args);
+int nas_timer_start(long sec, nas_timer_callback_t cb, void *args);
 int nas_timer_stop(int id);
 int nas_timer_restart(int id);
+
+#if defined(EPC_BUILD)
+void nas_timer_handle_signal_expiry(long timer_id, void *arg_p);
 #endif
 
 #endif /* __NAS_TIMER_H__ */
diff --git a/openair-cn/NAS/Makefile.inc b/openair-cn/NAS/Makefile.inc
index 771ea1c303..cea25f83a7 100644
--- a/openair-cn/NAS/Makefile.inc
+++ b/openair-cn/NAS/Makefile.inc
@@ -370,6 +370,8 @@ libnas_ies_SRCS = \
 libnas_utils_SRCS = \
     EURECOM-NAS/src/util/nas_log.h      \
     EURECOM-NAS/src/util/nas_log.c      \
+    EURECOM-NAS/src/util/nas_timer.h      \
+    EURECOM-NAS/src/util/nas_timer.c      \
     EURECOM-NAS/src/util/TLVEncoder.h      \
     EURECOM-NAS/src/util/TLVEncoder.c      \
     EURECOM-NAS/src/util/TLVDecoder.h      \
diff --git a/openair-cn/NAS/nas_main.c b/openair-cn/NAS/nas_main.c
index 906da44ffc..521589d179 100644
--- a/openair-cn/NAS/nas_main.c
+++ b/openair-cn/NAS/nas_main.c
@@ -44,6 +44,7 @@
 # include "nas_proc.h"
 # include "emm_main.h"
 # include "nas_log.h"
+# include "nas_timer.h"
 #endif
 
 #define NAS_ERROR(x, args...) do { fprintf(stderr, "[NAS] [E]"x, ##args); } while(0)
@@ -133,6 +134,14 @@ next_message:
             } break;
 #endif
 
+            case TIMER_HAS_EXPIRED: {
+#if !defined(DISABLE_USE_NAS)
+                /* Call the NAS timer api */
+                nas_timer_handle_signal_expiry(TIMER_HAS_EXPIRED(received_message_p).timer_id,
+                                               TIMER_HAS_EXPIRED(received_message_p).arg);
+#endif
+            } break;
+
             case TERMINATE_MESSAGE: {
                 itti_exit_task();
             } break;
-- 
2.26.2