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, ¤t_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