commit new itti code
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
#include "openair2/COMMON/phy_messages_def.h"
|
||||
#include "openair2/COMMON/mac_messages_def.h"
|
||||
#include "openair2/COMMON/rlc_messages_def.h"
|
||||
#include "openair2/COMMON/pdcp_messages_def.h"
|
||||
#include "openair2/COMMON/rrc_messages_def.h"
|
||||
#include "openair2/COMMON/nas_messages_def.h"
|
||||
#if ENABLE_RAL
|
||||
#include "openair2/COMMON/ral_messages_def.h"
|
||||
#endif
|
||||
#include "openair2/COMMON/s1ap_messages_def.h"
|
||||
#include "openair2/COMMON/x2ap_messages_def.h"
|
||||
#include "openair2/COMMON/sctp_messages_def.h"
|
||||
#include "openair2/COMMON/udp_messages_def.h"
|
||||
#include "openair2/COMMON/gtpv1_u_messages_def.h"
|
||||
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
Author: Laurent THOMAS, Open Cells
|
||||
copyleft: OpenAirInterface Software Alliance
|
||||
*/
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
|
||||
#include <intertask_interface.h>
|
||||
|
||||
typedef struct timer_elm_s {
|
||||
timer_type_t type; ///< Timer type
|
||||
long instance;
|
||||
long duration;
|
||||
uint64_t timeout;
|
||||
void *timer_arg; ///< Optional argument that will be passed when timer expires
|
||||
} timer_elm_t ;
|
||||
|
||||
typedef struct task_list_s {
|
||||
task_info_t admin;
|
||||
pthread_t thread;
|
||||
pthread_mutex_t queue_cond_lock;
|
||||
std::vector<MessageDef *> message_queue;
|
||||
std::map<long,timer_elm_t> timer_map;
|
||||
uint64_t next_timer=UINT64_MAX;
|
||||
struct epoll_event *events =NULL;
|
||||
int nb_fd_epoll=0;
|
||||
int nb_events=0;
|
||||
int epoll_fd=-1;
|
||||
int sem_fd=-1;
|
||||
} task_list_t;
|
||||
|
||||
int timer_expired(int fd);
|
||||
task_list_t tasks[TASK_MAX];
|
||||
|
||||
extern "C" {
|
||||
void *pool_buffer_init (void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *pool_buffer_clean (void *arg) {
|
||||
//-----------------------------------------------------------------------------
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_mem_block (mem_block_t *leP, const char *caller) {
|
||||
AssertFatal(leP!=NULL,"");
|
||||
free(leP);
|
||||
}
|
||||
|
||||
mem_block_t *get_free_mem_block (uint32_t sizeP, const char *caller) {
|
||||
mem_block_t *ptr=(mem_block_t *)malloc(sizeP+sizeof(mem_block_t));
|
||||
ptr->data=((unsigned char *)ptr)+sizeof(mem_block_t);
|
||||
ptr->size=sizeP;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize_t size) {
|
||||
void *ptr = NULL;
|
||||
AssertFatal ((ptr=malloc (size)) != NULL, "Memory allocation of %zu bytes failed (%d -> %d)!\n",
|
||||
size, origin_task_id, destination_task_id);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int itti_free(task_id_t task_id, void *ptr) {
|
||||
AssertFatal (ptr != NULL, "Trying to free a NULL pointer (%d)!\n", task_id);
|
||||
free (ptr);
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
MessageDef *itti_alloc_new_message_sized(task_id_t origin_task_id, MessagesIds message_id, MessageHeaderSize size) {
|
||||
MessageDef *temp = (MessageDef *)itti_malloc (origin_task_id, TASK_UNKNOWN, sizeof(MessageHeader) + size);
|
||||
temp->ittiMsgHeader.messageId = message_id;
|
||||
temp->ittiMsgHeader.originTaskId = origin_task_id;
|
||||
temp->ittiMsgHeader.ittiMsgSize = size;
|
||||
return temp;
|
||||
}
|
||||
|
||||
MessageDef *itti_alloc_new_message(task_id_t origin_task_id, MessagesIds message_id) {
|
||||
int size=sizeof(MessageHeader) + messages_info[message_id].size;
|
||||
MessageDef *temp = (MessageDef *)itti_malloc (origin_task_id, TASK_UNKNOWN, size);
|
||||
temp->ittiMsgHeader.messageId = message_id;
|
||||
temp->ittiMsgHeader.originTaskId = origin_task_id;
|
||||
temp->ittiMsgHeader.ittiMsgSize = size;
|
||||
return temp;
|
||||
//return itti_alloc_new_message_sized(origin_task_id, message_id, messages_info[message_id].size);
|
||||
}
|
||||
|
||||
static inline int itti_send_msg_to_task_locked(task_id_t destination_task_id, instance_t instance, MessageDef *message) {
|
||||
task_list_t *t=tasks+destination_task_id;
|
||||
message->ittiMsgHeader.destinationTaskId = destination_task_id;
|
||||
message->ittiMsgHeader.instance = instance;
|
||||
message->ittiMsgHeader.lte_time.frame = 0;
|
||||
message->ittiMsgHeader.lte_time.slot = 0;
|
||||
int message_id = message->ittiMsgHeader.messageId;
|
||||
size_t s=t->message_queue.size();
|
||||
|
||||
if ( s > t->admin.queue_size )
|
||||
LOG_E(TMR,"Queue for %s task contains %ld messages\n", itti_get_task_name(destination_task_id), s );
|
||||
|
||||
if ( s > 50 )
|
||||
LOG_I(TMR,"Queue for %s task size: %ld\n",itti_get_task_name(destination_task_id), s+1);
|
||||
|
||||
t->message_queue.insert(t->message_queue.begin(), message);
|
||||
eventfd_t sem_counter = 1;
|
||||
AssertFatal ( sizeof(sem_counter) == write(t->sem_fd, &sem_counter, sizeof(sem_counter)), "");
|
||||
LOG_D(TMR,"sent messages id=%d to %s\n",message_id, t->admin.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message) {
|
||||
task_list_t *t=&tasks[destination_task_id];
|
||||
pthread_mutex_lock (&t->queue_cond_lock);
|
||||
int ret=itti_send_msg_to_task_locked(destination_task_id, instance, message);
|
||||
pthread_mutex_unlock (&t->queue_cond_lock);
|
||||
|
||||
while ( t->message_queue.size()>0 && t->admin.func != NULL )
|
||||
t->admin.func(NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void itti_subscribe_event_fd(task_id_t task_id, int fd) {
|
||||
struct epoll_event event;
|
||||
task_list_t *t=&tasks[task_id];
|
||||
t->nb_fd_epoll++;
|
||||
t->events = (struct epoll_event *)realloc((void *)t->events,
|
||||
t->nb_fd_epoll * sizeof(struct epoll_event));
|
||||
event.events = EPOLLIN | EPOLLERR;
|
||||
event.data.u64 = 0;
|
||||
event.data.fd = fd;
|
||||
AssertFatal(epoll_ctl(t->epoll_fd, EPOLL_CTL_ADD, fd, &event) == 0,
|
||||
"epoll_ctl (EPOLL_CTL_ADD) failed for task %s, fd %d: %s!\n",
|
||||
itti_get_task_name(task_id), fd, strerror(errno));
|
||||
}
|
||||
|
||||
void itti_unsubscribe_event_fd(task_id_t task_id, int fd) {
|
||||
task_list_t *t=&tasks[task_id];
|
||||
AssertFatal (epoll_ctl(t->epoll_fd, EPOLL_CTL_DEL, fd, NULL) == 0,
|
||||
"epoll_ctl (EPOLL_CTL_DEL) failed for task %s, fd %d: %s!\n",
|
||||
itti_get_task_name(task_id), fd, strerror(errno));
|
||||
t->nb_fd_epoll--;
|
||||
}
|
||||
|
||||
static inline int itti_get_events_locked(task_id_t task_id, struct epoll_event **events) {
|
||||
task_list_t *t=&tasks[task_id];
|
||||
uint64_t current_time=0;
|
||||
|
||||
do {
|
||||
if ( t->next_timer != UINT64_MAX ) {
|
||||
struct timespec tp;
|
||||
clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
current_time=(uint64_t)tp.tv_sec*1000+tp.tv_nsec/(1000*1000);
|
||||
|
||||
if ( t->next_timer < current_time) {
|
||||
t->next_timer=UINT64_MAX;
|
||||
|
||||
// Proceed expired timer
|
||||
for ( auto it=t->timer_map.begin() ; it != t->timer_map.end() ; ++it ) {
|
||||
if ( it->second.timeout < current_time ) {
|
||||
MessageDef *message = itti_alloc_new_message(TASK_TIMER, TIMER_HAS_EXPIRED);
|
||||
message->ittiMsg.timer_has_expired.timer_id=it->first;
|
||||
message->ittiMsg.timer_has_expired.arg=it->second.timer_arg;
|
||||
|
||||
if (itti_send_msg_to_task_locked(task_id, it->second.instance, message) < 0) {
|
||||
LOG_W(TMR,"Failed to send msg TIMER_HAS_EXPIRED to task %u\n", task_id);
|
||||
free(message);
|
||||
t->timer_map.erase(it);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( it->second.type==TIMER_PERIODIC ) {
|
||||
it->second.timeout+=it->second.duration;
|
||||
|
||||
if (it->second.timeout < t->next_timer)
|
||||
t->next_timer=it->second.timeout;
|
||||
} else
|
||||
t->timer_map.erase(it);
|
||||
} else if (it->second.timeout < t->next_timer)
|
||||
t->next_timer=it->second.timeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int epoll_timeout = -1;
|
||||
|
||||
if ( t->next_timer != UINT64_MAX )
|
||||
epoll_timeout = t->next_timer-current_time;
|
||||
|
||||
pthread_mutex_unlock(&t->queue_cond_lock);
|
||||
LOG_D(TMR,"enter blocking wait for %s\n", itti_get_task_name(task_id));
|
||||
t->nb_events = epoll_wait(t->epoll_fd,t->events,t->nb_fd_epoll, epoll_timeout);
|
||||
} while (t->nb_events < 0 && (errno == EINTR || errno == EAGAIN ) );
|
||||
|
||||
AssertFatal (t->nb_events >=0,
|
||||
"epoll_wait failed for task %s, nb fds %d, timeout %lu: %s!\n",
|
||||
itti_get_task_name(task_id), t->nb_fd_epoll, t->next_timer != UINT64_MAX ? t->next_timer-current_time : -1, strerror(errno));
|
||||
LOG_D(TMR,"receive on %d descriptors for %s\n", t->nb_events, itti_get_task_name(task_id));
|
||||
|
||||
if (t->nb_events == 0)
|
||||
/* No data to read -> return */
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < t->nb_events; i++) {
|
||||
/* Check if there is an event for ITTI for the event fd */
|
||||
if ((t->events[i].events & EPOLLIN) &&
|
||||
(t->events[i].data.fd == t->sem_fd)) {
|
||||
eventfd_t sem_counter;
|
||||
/* Read will always return 1 */
|
||||
AssertFatal( sizeof(sem_counter) == read (t->sem_fd, &sem_counter, sizeof(sem_counter)), "");
|
||||
/* Mark that the event has been processed */
|
||||
t->events[i].events &= ~EPOLLIN;
|
||||
}
|
||||
}
|
||||
|
||||
*events = t->events;
|
||||
return t->nb_events;
|
||||
}
|
||||
|
||||
int itti_get_events(task_id_t task_id, struct epoll_event **events) {
|
||||
pthread_mutex_lock(&tasks[task_id].queue_cond_lock);
|
||||
return itti_get_events_locked(task_id, events);
|
||||
}
|
||||
|
||||
void itti_receive_msg(task_id_t task_id, MessageDef **received_msg) {
|
||||
// Reception of one message, blocking caller
|
||||
task_list_t *t=&tasks[task_id];
|
||||
pthread_mutex_lock(&t->queue_cond_lock);
|
||||
|
||||
// Weird condition to deal with crap legacy itti interface
|
||||
if ( t->nb_fd_epoll == 1 ) {
|
||||
while (t->message_queue.empty()) {
|
||||
itti_get_events_locked(task_id, &t->events);
|
||||
pthread_mutex_lock(&t->queue_cond_lock);
|
||||
}
|
||||
} else {
|
||||
if (t->message_queue.empty()) {
|
||||
itti_get_events_locked(task_id, &t->events);
|
||||
pthread_mutex_lock(&t->queue_cond_lock);
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy design: we return even if we have no message
|
||||
// in this case, *received_msg is NULL
|
||||
if (t->message_queue.empty()) {
|
||||
*received_msg=NULL;
|
||||
LOG_D(TMR,"task %s received even from other fd (total fds: %d), returning msg NULL\n",t->admin.name, t->nb_fd_epoll);
|
||||
} else {
|
||||
*received_msg=t->message_queue.back();
|
||||
t->message_queue.pop_back();
|
||||
LOG_D(TMR,"task %s received a message\n",t->admin.name);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&t->queue_cond_lock);
|
||||
}
|
||||
|
||||
void itti_poll_msg(task_id_t task_id, MessageDef **received_msg) {
|
||||
//reception of one message, non-blocking
|
||||
task_list_t *t=&tasks[task_id];
|
||||
pthread_mutex_lock(&t->queue_cond_lock);
|
||||
|
||||
if (!t->message_queue.empty()) {
|
||||
LOG_D(TMR,"task %s received a message in polling mode\n",t->admin.name);
|
||||
*received_msg=t->message_queue.back();
|
||||
t->message_queue.pop_back();
|
||||
} else
|
||||
*received_msg=NULL;
|
||||
|
||||
pthread_mutex_unlock (&t->queue_cond_lock);
|
||||
}
|
||||
|
||||
int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *args_p) {
|
||||
task_list_t *t=&tasks[task_id];
|
||||
AssertFatal ( pthread_create (&t->thread, NULL, start_routine, args_p) ==0,
|
||||
"Thread creation for task %d failed!\n", task_id);
|
||||
pthread_setname_np( t->thread, itti_get_task_name(task_id) );
|
||||
LOG_I(TMR,"Created Posix thread %s\n", itti_get_task_name(task_id) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
void itti_exit_task(void) {
|
||||
pthread_exit (NULL);
|
||||
}
|
||||
|
||||
void itti_terminate_tasks(task_id_t task_id) {
|
||||
// Sends Terminate signals to all tasks.
|
||||
itti_send_terminate_message (task_id);
|
||||
pthread_exit (NULL);
|
||||
}
|
||||
|
||||
int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_id_max, const task_info_t *tasks_info,
|
||||
const message_info_t *messages_info) {
|
||||
AssertFatal(TASK_MAX<UINT16_MAX, "Max itti tasks");
|
||||
|
||||
for(int i=0; i<task_max; ++i) {
|
||||
LOG_I(TMR,"Starting itti queue: %s as task %d\n", tasks_info[i].name, i);
|
||||
pthread_mutex_init(&tasks[i].queue_cond_lock, NULL);
|
||||
memcpy(&tasks[i].admin, &tasks_info[i], sizeof(task_info_t));
|
||||
AssertFatal( ( tasks[i].epoll_fd = epoll_create1(0) ) >=0, "");
|
||||
AssertFatal( ( tasks[i].sem_fd = eventfd(0, EFD_SEMAPHORE) ) >=0, "");
|
||||
itti_subscribe_event_fd((task_id_t)i, tasks[i].sem_fd);
|
||||
|
||||
if (tasks[i].admin.threadFunc != NULL)
|
||||
itti_create_task((task_id_t)i, tasks[i].admin.threadFunc, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_setup(
|
||||
uint32_t interval_sec,
|
||||
uint32_t interval_us,
|
||||
task_id_t task_id,
|
||||
int32_t instance,
|
||||
timer_type_t type,
|
||||
void *timer_arg,
|
||||
long *timer_id) {
|
||||
task_list_t *t=&tasks[task_id];
|
||||
|
||||
do {
|
||||
// set the taskid in the timer id to keep compatible with the legacy API
|
||||
// timer_remove() takes only the timer id as parameter
|
||||
*timer_id=(random()%UINT16_MAX) << 16 | task_id ;
|
||||
} while ( t->timer_map.find(*timer_id) != t->timer_map.end());
|
||||
|
||||
/* Allocate new timer list element */
|
||||
timer_elm_t timer;
|
||||
struct timespec tp;
|
||||
clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
|
||||
if (interval_us%1000 != 0)
|
||||
LOG_W(TMR, "Can't set timer precision below 1ms, rounding it\n");
|
||||
|
||||
timer.duration = interval_sec*1000+interval_us/1000;
|
||||
timer.timeout= ((uint64_t)tp.tv_sec*1000+tp.tv_nsec/(1000*1000)+timer.duration);
|
||||
timer.instance = instance;
|
||||
timer.type = type;
|
||||
timer.timer_arg = timer_arg;
|
||||
pthread_mutex_lock (&t->queue_cond_lock);
|
||||
t->timer_map[*timer_id]= timer;
|
||||
|
||||
if (timer.timeout < t->next_timer)
|
||||
t->next_timer=timer.timeout;
|
||||
|
||||
eventfd_t sem_counter = 1;
|
||||
AssertFatal ( sizeof(sem_counter) == write(t->sem_fd, &sem_counter, sizeof(sem_counter)), "");
|
||||
pthread_mutex_unlock (&t->queue_cond_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_remove(long timer_id) {
|
||||
task_id_t task_id=(task_id_t)(timer_id&0xffff);
|
||||
int ret;
|
||||
pthread_mutex_lock (&tasks[task_id].queue_cond_lock);
|
||||
ret=tasks[task_id].timer_map.erase(timer_id);
|
||||
pthread_mutex_unlock (&tasks[task_id].queue_cond_lock);
|
||||
|
||||
if (ret==1)
|
||||
return 0;
|
||||
else {
|
||||
LOG_W(TMR, "tried to remove a non existing timer\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
const char *itti_get_message_name(MessagesIds message_id) {
|
||||
return messages_info[message_id].name;
|
||||
}
|
||||
|
||||
const char *itti_get_task_name(task_id_t task_id) {
|
||||
return tasks[task_id].admin.name;
|
||||
}
|
||||
|
||||
// void for compatibility
|
||||
void itti_send_terminate_message(task_id_t task_id) {
|
||||
}
|
||||
|
||||
void itti_wait_tasks_end(void) {
|
||||
while(1)
|
||||
sleep(24*3600);
|
||||
}
|
||||
|
||||
void itti_update_lte_time(uint32_t frame, uint8_t slot) {}
|
||||
void itti_set_task_real_time(task_id_t task_id) {}
|
||||
void itti_mark_task_ready(task_id_t task_id) {
|
||||
// Function meaning is clear, but legacy implementation is wrong
|
||||
// keep it void is fine: today implementation accepts messages in the queue before task is ready
|
||||
}
|
||||
void itti_wait_ready(int wait_tasks) {
|
||||
// Stupid function, kept for compatibility (the parameter is meaningless!!!)
|
||||
}
|
||||
int signal_mask(void) { return 0;}
|
||||
}
|
||||
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
Author: Laurent THOMAS, Open Cells
|
||||
Copyleft: OpenAirInterface software alliance
|
||||
*/
|
||||
#ifndef INTERTASK_INTERFACE_H_
|
||||
#define INTERTASK_INTERFACE_H_
|
||||
#include <stdint.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#include <mem_block.h>
|
||||
#include <assertions.h>
|
||||
|
||||
|
||||
typedef enum timer_type_s {
|
||||
TIMER_PERIODIC,
|
||||
TIMER_ONE_SHOT,
|
||||
TIMER_TYPE_MAX,
|
||||
} timer_type_t;
|
||||
|
||||
typedef struct {
|
||||
void *arg;
|
||||
long timer_id;
|
||||
} timer_has_expired_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t interval_sec;
|
||||
uint32_t interval_us;
|
||||
long task_id;
|
||||
int32_t instance;
|
||||
timer_type_t type;
|
||||
void *timer_arg;
|
||||
long timer_id;
|
||||
} timer_create_t;
|
||||
|
||||
typedef struct {
|
||||
long task_id;
|
||||
long timer_id;
|
||||
} timer_delete_t;
|
||||
|
||||
|
||||
typedef struct itti_lte_time_s {
|
||||
uint32_t frame;
|
||||
uint8_t slot;
|
||||
} itti_lte_time_t;
|
||||
|
||||
|
||||
typedef struct IttiMsgEmpty_s {
|
||||
} IttiMsgEmpty;
|
||||
|
||||
typedef struct IttiMsgText_s {
|
||||
uint32_t size;
|
||||
char text[];
|
||||
} IttiMsgText;
|
||||
|
||||
#include <openair2/COMMON/phy_messages_types.h>
|
||||
#include <openair2/COMMON/mac_messages_types.h>
|
||||
#include <openair2/COMMON/rlc_messages_types.h>
|
||||
#include <openair2/COMMON/pdcp_messages_types.h>
|
||||
#include <openair2/COMMON/networkDef.h>
|
||||
#include <openair2/COMMON/as_message.h>
|
||||
#include <openair2/RRC/LTE/rrc_types.h>
|
||||
#include <openair2/COMMON/rrc_messages_types.h>
|
||||
|
||||
#include <openair3/NAS/COMMON/UTIL/OctetString.h>
|
||||
#include <openair3/NAS/COMMON/IES/AccessPointName.h>
|
||||
#include <openair3/NAS/COMMON/IES/AdditionalUpdateResult.h>
|
||||
#include <openair3/NAS/COMMON/IES/AdditionalUpdateType.h>
|
||||
#include <openair3/NAS/COMMON/IES/ApnAggregateMaximumBitRate.h>
|
||||
#include <openair3/NAS/COMMON/IES/AuthenticationFailureParameter.h>
|
||||
#include <openair3/NAS/COMMON/IES/AuthenticationParameterAutn.h>
|
||||
#include <openair3/NAS/COMMON/IES/AuthenticationParameterRand.h>
|
||||
#include <openair3/NAS/COMMON/IES/AuthenticationResponseParameter.h>
|
||||
#include <openair3/NAS/COMMON/IES/CipheringKeySequenceNumber.h>
|
||||
#include <openair3/NAS/COMMON/IES/Cli.h>
|
||||
#include <openair3/NAS/COMMON/IES/CsfbResponse.h>
|
||||
#include <openair3/NAS/COMMON/IES/DaylightSavingTime.h>
|
||||
#include <openair3/NAS/COMMON/IES/DetachType.h>
|
||||
#include <openair3/NAS/COMMON/IES/DrxParameter.h>
|
||||
#include <openair3/NAS/COMMON/IES/EmergencyNumberList.h>
|
||||
#include <openair3/NAS/COMMON/IES/EmmCause.h>
|
||||
#include <openair3/NAS/COMMON/IES/EpsAttachResult.h>
|
||||
#include <openair3/NAS/COMMON/IES/EpsAttachType.h>
|
||||
#include <openair3/NAS/COMMON/IES/EpsBearerContextStatus.h>
|
||||
#include <openair3/NAS/COMMON/IES/EpsBearerIdentity.h>
|
||||
#include <openair3/NAS/COMMON/IES/EpsMobileIdentity.h>
|
||||
#include <openair3/NAS/COMMON/IES/EpsNetworkFeatureSupport.h>
|
||||
#include <openair3/NAS/COMMON/IES/EpsQualityOfService.h>
|
||||
#include <openair3/NAS/COMMON/IES/EpsUpdateResult.h>
|
||||
#include <openair3/NAS/COMMON/IES/EpsUpdateType.h>
|
||||
#include <openair3/NAS/COMMON/IES/EsmCause.h>
|
||||
#include <openair3/NAS/COMMON/IES/EsmInformationTransferFlag.h>
|
||||
#include <openair3/NAS/COMMON/IES/EsmMessageContainer.h>
|
||||
#include <openair3/NAS/COMMON/IES/GprsTimer.h>
|
||||
#include <openair3/NAS/COMMON/IES/GutiType.h>
|
||||
#include <openair3/NAS/COMMON/IES/IdentityType2.h>
|
||||
#include <openair3/NAS/COMMON/IES/ImeisvRequest.h>
|
||||
#include <openair3/NAS/COMMON/IES/KsiAndSequenceNumber.h>
|
||||
#include <openair3/NAS/COMMON/IES/LcsClientIdentity.h>
|
||||
#include <openair3/NAS/COMMON/IES/LcsIndicator.h>
|
||||
#include <openair3/NAS/COMMON/IES/LinkedEpsBearerIdentity.h>
|
||||
#include <openair3/NAS/COMMON/IES/LlcServiceAccessPointIdentifier.h>
|
||||
#include <openair3/NAS/COMMON/IES/LocationAreaIdentification.h>
|
||||
#include <openair3/NAS/COMMON/IES/MessageType.h>
|
||||
#include <openair3/NAS/COMMON/IES/MobileIdentity.h>
|
||||
#include <openair3/NAS/COMMON/IES/MobileStationClassmark2.h>
|
||||
#include <openair3/NAS/COMMON/IES/MobileStationClassmark3.h>
|
||||
#include <openair3/NAS/COMMON/IES/MsNetworkCapability.h>
|
||||
#include <openair3/NAS/COMMON/IES/MsNetworkFeatureSupport.h>
|
||||
#include <openair3/NAS/COMMON/IES/NasKeySetIdentifier.h>
|
||||
#include <openair3/NAS/COMMON/IES/NasMessageContainer.h>
|
||||
#include <openair3/NAS/COMMON/IES/NasRequestType.h>
|
||||
#include <openair3/NAS/COMMON/IES/NasSecurityAlgorithms.h>
|
||||
#include <openair3/NAS/COMMON/IES/NetworkName.h>
|
||||
#include <openair3/NAS/COMMON/IES/Nonce.h>
|
||||
#include <openair3/NAS/COMMON/IES/PacketFlowIdentifier.h>
|
||||
#include <openair3/NAS/COMMON/IES/PagingIdentity.h>
|
||||
#include <openair3/NAS/COMMON/IES/PdnAddress.h>
|
||||
#include <openair3/NAS/COMMON/IES/PdnType.h>
|
||||
#include <openair3/NAS/COMMON/IES/PlmnList.h>
|
||||
#include <openair3/NAS/COMMON/IES/ProcedureTransactionIdentity.h>
|
||||
#include <openair3/NAS/COMMON/IES/ProtocolConfigurationOptions.h>
|
||||
#include <openair3/NAS/COMMON/IES/ProtocolDiscriminator.h>
|
||||
#include <openair3/NAS/COMMON/IES/PTmsiSignature.h>
|
||||
#include <openair3/NAS/COMMON/IES/QualityOfService.h>
|
||||
#include <openair3/NAS/COMMON/IES/RadioPriority.h>
|
||||
#include <openair3/NAS/COMMON/IES/SecurityHeaderType.h>
|
||||
#include <openair3/NAS/COMMON/IES/ServiceType.h>
|
||||
#include <openair3/NAS/COMMON/IES/ShortMac.h>
|
||||
#include <openair3/NAS/COMMON/IES/SsCode.h>
|
||||
#include <openair3/NAS/COMMON/IES/SupportedCodecList.h>
|
||||
#include <openair3/NAS/COMMON/IES/TimeZoneAndTime.h>
|
||||
#include <openair3/NAS/COMMON/IES/TimeZone.h>
|
||||
#include <openair3/NAS/COMMON/IES/TmsiStatus.h>
|
||||
#include <openair3/NAS/COMMON/IES/TrackingAreaIdentity.h>
|
||||
#include <openair3/NAS/COMMON/IES/TrackingAreaIdentityList.h>
|
||||
#include <openair3/NAS/COMMON/IES/TrafficFlowAggregateDescription.h>
|
||||
#include <openair3/NAS/COMMON/IES/TrafficFlowTemplate.h>
|
||||
#include <openair3/NAS/COMMON/IES/TransactionIdentifier.h>
|
||||
#include <openair3/NAS/COMMON/IES/UeNetworkCapability.h>
|
||||
#include <openair3/NAS/COMMON/IES/UeRadioCapabilityInformationUpdateNeeded.h>
|
||||
#include <openair3/NAS/COMMON/IES/UeSecurityCapability.h>
|
||||
#include <openair3/NAS/COMMON/IES/VoiceDomainPreferenceAndUeUsageSetting.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextAccept.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextReject.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextRequest.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/ActivateDefaultEpsBearerContextAccept.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/ActivateDefaultEpsBearerContextReject.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/ActivateDefaultEpsBearerContextRequest.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceAllocationReject.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceAllocationRequest.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceModificationReject.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceModificationRequest.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/DeactivateEpsBearerContextAccept.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/DeactivateEpsBearerContextRequest.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/esm_cause.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/EsmInformationRequest.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/EsmInformationResponse.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/EsmStatus.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/ModifyEpsBearerContextAccept.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/ModifyEpsBearerContextReject.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/ModifyEpsBearerContextRequest.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/PdnConnectivityReject.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/PdnConnectivityRequest.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/PdnDisconnectReject.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/PdnDisconnectRequest.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/esm_msgDef.h>
|
||||
#include <openair3/NAS/COMMON/ESM/MSG/esm_msg.h>
|
||||
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/AttachAccept.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/AttachComplete.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/AttachReject.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/AttachRequest.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationFailure.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationReject.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationResponse.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/CsServiceNotification.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/DetachAccept.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/DetachRequest.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/DownlinkNasTransport.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/emm_cause.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/EmmInformation.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/EmmStatus.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/ExtendedServiceRequest.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/GutiReallocationCommand.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/GutiReallocationComplete.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/IdentityRequest.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/IdentityResponse.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/NASSecurityModeCommand.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/NASSecurityModeComplete.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/SecurityModeReject.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/ServiceReject.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/ServiceRequest.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateAccept.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateComplete.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateReject.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateRequest.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/UplinkNasTransport.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/emm_msgDef.h>
|
||||
#include <openair3/NAS/COMMON/EMM/MSG/emm_msg.h>
|
||||
|
||||
#include <openair3/NAS/COMMON/API/NETWORK/nas_message.h>
|
||||
#include <openair2/COMMON/nas_messages_types.h>
|
||||
#if ENABLE_RAL
|
||||
#include <ral_messages_types.h>
|
||||
#endif
|
||||
#include <openair2/COMMON/s1ap_messages_types.h>
|
||||
#include <openair2/COMMON/x2ap_messages_types.h>
|
||||
#include <openair2/COMMON/sctp_messages_types.h>
|
||||
#include <openair2/COMMON/udp_messages_types.h>
|
||||
#include <openair2/COMMON/gtpv1_u_messages_types.h>
|
||||
#include <openair3/SCTP/sctp_eNB_task.h>
|
||||
#include <openair3/NAS/UE/nas_proc_defs.h>
|
||||
#include <openair3/NAS/UE/ESM/esmData.h>
|
||||
#include <openair3/NAS/COMMON/UTIL/nas_timer.h>
|
||||
#include <openair3/NAS/UE/ESM/esm_pt_defs.h>
|
||||
#include <openair3/NAS/UE/EMM/emm_proc_defs.h>
|
||||
#include <openair3/NAS/UE/EMM/emmData.h>
|
||||
#include <openair3/NAS/UE/EMM/IdleMode_defs.h>
|
||||
#include <openair3/NAS/UE/EMM/emm_fsm_defs.h>
|
||||
#include <openair3/NAS/UE/EMM/emmData.h>
|
||||
#include <openair3/NAS/COMMON/securityDef.h>
|
||||
#include <openair3/NAS/UE/EMM/Authentication.h>
|
||||
#include <openair3/NAS/UE/EMM/SecurityModeControl.h>
|
||||
#include <openair3/NAS/UE/API/USIM/usim_api.h>
|
||||
#include <openair3/NAS/COMMON/userDef.h>
|
||||
#include <openair3/NAS/UE/API/USER/at_command.h>
|
||||
#include <openair3/NAS/UE/API/USER/at_response.h>
|
||||
#include <openair3/NAS/UE/API/USER/user_api_defs.h>
|
||||
#include <openair3/NAS/UE/EMM/LowerLayer_defs.h>
|
||||
#include <openair3/NAS/UE/user_defs.h>
|
||||
#include <openair3/NAS/UE/nas_ue_task.h>
|
||||
#include <openair3/S1AP/s1ap_eNB.h>
|
||||
//#include <proto.h>
|
||||
|
||||
/*
|
||||
static const char *const messages_definition_xml = {
|
||||
#include <messages_xml.h>
|
||||
};
|
||||
*/
|
||||
|
||||
typedef uint32_t MessageHeaderSize;
|
||||
typedef uint32_t itti_message_types_t;
|
||||
typedef unsigned long message_number_t;
|
||||
#define MESSAGE_NUMBER_SIZE (sizeof(unsigned long))
|
||||
|
||||
typedef enum task_priorities_e {
|
||||
TASK_PRIORITY_MAX = 100,
|
||||
TASK_PRIORITY_MAX_LEAST = 85,
|
||||
TASK_PRIORITY_MED_PLUS = 70,
|
||||
TASK_PRIORITY_MED = 55,
|
||||
TASK_PRIORITY_MED_LEAST = 40,
|
||||
TASK_PRIORITY_MIN_PLUS = 25,
|
||||
TASK_PRIORITY_MIN = 10,
|
||||
} task_priorities_t;
|
||||
|
||||
typedef struct {
|
||||
task_priorities_t priority;
|
||||
unsigned int queue_size;
|
||||
/* Printable name */
|
||||
char name[256];
|
||||
void *(*func)(void *) ;
|
||||
void *(*threadFunc)(void *) ;
|
||||
} task_info_t;
|
||||
//
|
||||
//TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL)
|
||||
//TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL)
|
||||
//TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)
|
||||
//TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL)
|
||||
|
||||
#define FOREACH_TASK(TASK_DEF) \
|
||||
TASK_DEF(TASK_UNKNOWN, TASK_PRIORITY_MED, 50, NULL, NULL) \
|
||||
TASK_DEF(TASK_TIMER, TASK_PRIORITY_MED, 10, NULL, NULL) \
|
||||
TASK_DEF(TASK_L2L1, TASK_PRIORITY_MAX, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_BM, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_PHY_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_MAC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_RLC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_PDCP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL)\
|
||||
TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_SCTP, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_ENB_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_FLEXRAN_AGENT,TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_PHY_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_MAC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_RLC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_PDCP_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_RRC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_NAS_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_RAL_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
|
||||
TASK_DEF(TASK_MSC, TASK_PRIORITY_MED, 200, NULL, NULL)\
|
||||
TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)\
|
||||
TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL)\
|
||||
TASK_DEF(TASK_MAX, TASK_PRIORITY_MED, 200, NULL, NULL)
|
||||
|
||||
#define TASK_DEF(TaskID, pRIO, qUEUEsIZE, FuNc, ThreadFunc) { pRIO, qUEUEsIZE, #TaskID, FuNc, ThreadFunc },
|
||||
|
||||
/* Map task id to printable name. */
|
||||
static const task_info_t tasks_info[] = {
|
||||
FOREACH_TASK(TASK_DEF)
|
||||
};
|
||||
|
||||
#define TASK_ENUM(TaskID, pRIO, qUEUEsIZE, FuNc,ThreadFunc ) TaskID,
|
||||
//! Tasks id of each task
|
||||
typedef enum {
|
||||
FOREACH_TASK(TASK_ENUM)
|
||||
} task_id_t;
|
||||
|
||||
|
||||
typedef task_id_t thread_id_t;
|
||||
|
||||
typedef enum message_priorities_e {
|
||||
MESSAGE_PRIORITY_MAX = 100,
|
||||
MESSAGE_PRIORITY_MAX_LEAST = 85,
|
||||
MESSAGE_PRIORITY_MED_PLUS = 70,
|
||||
MESSAGE_PRIORITY_MED = 55,
|
||||
MESSAGE_PRIORITY_MED_LEAST = 40,
|
||||
MESSAGE_PRIORITY_MIN_PLUS = 25,
|
||||
MESSAGE_PRIORITY_MIN = 10,
|
||||
} message_priorities_t;
|
||||
|
||||
|
||||
#define FOREACH_MSG(INTERNAL_MSG) \
|
||||
INTERNAL_MSG(TIMER_HAS_EXPIRED, MESSAGE_PRIORITY_MED, timer_has_expired_t, timer_has_expired) \
|
||||
INTERNAL_MSG(INITIALIZE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, initialize_message) \
|
||||
INTERNAL_MSG(ACTIVATE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, activate_message) \
|
||||
INTERNAL_MSG(DEACTIVATE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, deactivate_message) \
|
||||
INTERNAL_MSG(TERMINATE_MESSAGE, MESSAGE_PRIORITY_MAX, IttiMsgEmpty, terminate_message) \
|
||||
INTERNAL_MSG(MESSAGE_TEST, MESSAGE_PRIORITY_MED, IttiMsgEmpty, message_test)
|
||||
|
||||
/* This enum defines messages ids. Each one is unique. */
|
||||
typedef enum {
|
||||
#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) iD,
|
||||
FOREACH_MSG(MESSAGE_DEF)
|
||||
#include <all_msg.h>
|
||||
#undef MESSAGE_DEF
|
||||
MESSAGES_ID_MAX,
|
||||
} MessagesIds;
|
||||
|
||||
typedef union msg_s {
|
||||
#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) sTRUCT fIELDnAME;
|
||||
FOREACH_MSG(MESSAGE_DEF)
|
||||
#include <all_msg.h>
|
||||
#undef MESSAGE_DEF
|
||||
} msg_t;
|
||||
|
||||
typedef struct MessageHeader_s {
|
||||
MessagesIds messageId; /**< Unique message id as referenced in enum MessagesIds */
|
||||
task_id_t originTaskId; /**< ID of the sender task */
|
||||
task_id_t destinationTaskId; /**< ID of the destination task */
|
||||
instance_t instance; /**< Task instance for virtualization */
|
||||
itti_lte_time_t lte_time;
|
||||
MessageHeaderSize ittiMsgSize; /**< Message size (not including header size) */
|
||||
} MessageHeader;
|
||||
|
||||
typedef struct message_info_s {
|
||||
int id;
|
||||
message_priorities_t priority;
|
||||
/* Message payload size */
|
||||
MessageHeaderSize size;
|
||||
/* Printable name */
|
||||
const char name[256];
|
||||
} message_info_t;
|
||||
|
||||
/* Map message id to message information */
|
||||
static const message_info_t messages_info[] = {
|
||||
#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) { iD, pRIO, sizeof(sTRUCT), #iD },
|
||||
FOREACH_MSG(MESSAGE_DEF)
|
||||
#include <all_msg.h>
|
||||
#undef MESSAGE_DEF
|
||||
};
|
||||
|
||||
typedef struct __attribute__ ((__packed__)) MessageDef_s {
|
||||
MessageHeader ittiMsgHeader; /**< Message header */
|
||||
msg_t ittiMsg;
|
||||
} MessageDef;
|
||||
|
||||
|
||||
|
||||
/* Extract the instance from a message */
|
||||
#define ITTI_MESSAGE_GET_INSTANCE(mESSAGE) ((mESSAGE)->ittiMsgHeader.instance)
|
||||
#define ITTI_MSG_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.messageId)
|
||||
#define ITTI_MSG_ORIGIN_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.originTaskId)
|
||||
#define ITTI_MSG_DESTINATION_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.destinationTaskId)
|
||||
#define ITTI_MSG_INSTANCE(mSGpTR) ((mSGpTR)->ittiMsgHeader.instance)
|
||||
#define ITTI_MSG_NAME(mSGpTR) itti_get_message_name(ITTI_MSG_ID(mSGpTR))
|
||||
#define ITTI_MSG_ORIGIN_NAME(mSGpTR) itti_get_task_name(ITTI_MSG_ORIGIN_ID(mSGpTR))
|
||||
#define ITTI_MSG_DESTINATION_NAME(mSGpTR) itti_get_task_name(ITTI_MSG_DESTINATION_ID(mSGpTR))
|
||||
#define TIMER_HAS_EXPIRED(mSGpTR) (mSGpTR)->ittiMsg.timer_has_expired
|
||||
|
||||
#define INSTANCE_DEFAULT (UINT16_MAX - 1)
|
||||
|
||||
static inline int64_t clock_difftime_ns(struct timespec start, struct timespec end) {
|
||||
return (int64_t)( end.tv_sec-start.tv_sec) * (int64_t)(1000*1000*1000) + end.tv_nsec-start.tv_nsec;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \brief Send a message to a task (could be itself)
|
||||
\param task_id Task ID
|
||||
\param instance Instance of the task used for virtualization
|
||||
\param message Pointer to the message to send
|
||||
@returns -1 on failure, 0 otherwise
|
||||
**/
|
||||
int itti_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message);
|
||||
|
||||
/** \brief Add a new fd to monitor.
|
||||
NOTE: it is up to the user to read data associated with the fd
|
||||
\param task_id Task ID of the receiving task
|
||||
\param fd The file descriptor to monitor
|
||||
**/
|
||||
void itti_subscribe_event_fd(task_id_t task_id, int fd);
|
||||
|
||||
/** \brief Remove a fd from the list of fd to monitor
|
||||
\param task_id Task ID of the task
|
||||
\param fd The file descriptor to remove
|
||||
**/
|
||||
void itti_unsubscribe_event_fd(task_id_t task_id, int fd);
|
||||
|
||||
/** \brief Return the list of events excluding the fd associated with itti
|
||||
\param task_id Task ID of the task
|
||||
\param events events list
|
||||
@returns number of events to handle
|
||||
**/
|
||||
int itti_get_events(task_id_t task_id, struct epoll_event **events);
|
||||
|
||||
/** \brief Retrieves a message in the queue associated to task_id.
|
||||
If the queue is empty, the thread is blocked till a new message arrives.
|
||||
\param task_id Task ID of the receiving task
|
||||
\param received_msg Pointer to the allocated message
|
||||
**/
|
||||
void itti_receive_msg(task_id_t task_id, MessageDef **received_msg);
|
||||
|
||||
/** \brief Try to retrieves a message in the queue associated to task_id.
|
||||
\param task_id Task ID of the receiving task
|
||||
\param received_msg Pointer to the allocated message
|
||||
**/
|
||||
void itti_poll_msg(task_id_t task_id, MessageDef **received_msg);
|
||||
|
||||
/** \brief Start thread associated to the task
|
||||
\param task_id task to start
|
||||
\param start_routine entry point for the task
|
||||
\param args_p Optional argument to pass to the start routine
|
||||
@returns -1 on failure, 0 otherwise
|
||||
**/
|
||||
int itti_create_task(task_id_t task_id,
|
||||
void *(*start_routine) (void *),
|
||||
void *args_p);
|
||||
|
||||
/** \brief Exit the current task.
|
||||
**/
|
||||
void itti_exit_task(void);
|
||||
|
||||
/** \brief Initiate termination of all tasks.
|
||||
\param task_id task that is completed
|
||||
**/
|
||||
void itti_terminate_tasks(task_id_t task_id);
|
||||
|
||||
// Void for legacy compatibility
|
||||
void itti_wait_ready(int wait_tasks);
|
||||
void itti_mark_task_ready(task_id_t task_id);
|
||||
|
||||
/** \brief Return the printable string associated with the message
|
||||
\param message_id Id of the message
|
||||
**/
|
||||
const char *itti_get_message_name(MessagesIds message_id);
|
||||
|
||||
/** \brief Return the printable string associated with a task id
|
||||
\param thread_id Id of the task
|
||||
**/
|
||||
const char *itti_get_task_name(task_id_t task_id);
|
||||
|
||||
/** \brief Alloc and memset(0) a new itti message.
|
||||
\param origin_task_id Task ID of the sending task
|
||||
\param message_id Message ID
|
||||
@returns NULL in case of failure or newly allocated mesage ref
|
||||
**/
|
||||
MessageDef *itti_alloc_new_message(
|
||||
task_id_t origin_task_id,
|
||||
MessagesIds message_id);
|
||||
|
||||
/** \brief Alloc and memset(0) a new itti message.
|
||||
\param origin_task_id Task ID of the sending task
|
||||
\param message_id Message ID
|
||||
\param size size of the payload to send
|
||||
@returns NULL in case of failure or newly allocated mesage ref
|
||||
**/
|
||||
MessageDef *itti_alloc_new_message_sized(
|
||||
task_id_t origin_task_id,
|
||||
MessagesIds message_id,
|
||||
MessageHeaderSize size);
|
||||
|
||||
/** \brief handle signals and wait for all threads to join when the process complete.
|
||||
This function should be called from the main thread after having created all ITTI tasks.
|
||||
**/
|
||||
void itti_wait_tasks_end(void);
|
||||
#define THREAD_MAX 0 //for compatibility
|
||||
void itti_set_task_real_time(task_id_t task_id);
|
||||
|
||||
/** \brief Send a termination message to all tasks.
|
||||
\param task_id task that is broadcasting the message.
|
||||
**/
|
||||
void itti_send_terminate_message(task_id_t task_id);
|
||||
|
||||
void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize_t size);
|
||||
void *calloc_or_fail(size_t size);
|
||||
void *malloc_or_fail(size_t size);
|
||||
int memory_read(const char *datafile, void *data, size_t size);
|
||||
int itti_free(task_id_t task_id, void *ptr);
|
||||
|
||||
int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_id_max, const task_info_t *tasks_info,
|
||||
const message_info_t *messages_info);
|
||||
int timer_setup(
|
||||
uint32_t interval_sec,
|
||||
uint32_t interval_us,
|
||||
task_id_t task_id,
|
||||
int32_t instance,
|
||||
timer_type_t type,
|
||||
void *timer_arg,
|
||||
long *timer_id);
|
||||
|
||||
|
||||
int timer_remove(long timer_id);
|
||||
#define timer_stop timer_remove
|
||||
int signal_handle(int *end);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* INTERTASK_INTERFACE_H_ */
|
||||
Reference in New Issue
Block a user