first commit new itti
This commit is contained in:
@@ -170,11 +170,12 @@ set(CMAKE_C_FLAGS
|
||||
"${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC ")
|
||||
# add autotools definitions that were maybe used!
|
||||
set(CMAKE_C_FLAGS
|
||||
"${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -DASN_DISABLE_OER_SUPPORT -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'"
|
||||
"${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'"
|
||||
)
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 "
|
||||
"${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'"
|
||||
)
|
||||
add_definitions("-DASN_DISABLE_OER_SUPPORT")
|
||||
|
||||
|
||||
#########################
|
||||
@@ -256,16 +257,13 @@ add_boolean_option(BASIC_SIMULATOR False "Has to be True when building the b
|
||||
add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering")
|
||||
|
||||
add_boolean_option(ENABLE_ITTI True "ITTI is internal messaging, should remain enabled for most targets")
|
||||
set (ITTI_DIR ${OPENAIR_DIR}/common/utils/itti)
|
||||
set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti)
|
||||
if (${ENABLE_ITTI})
|
||||
add_library(ITTI
|
||||
# add .h files if depend on (this one is generated)
|
||||
${ITTI_DIR}/intertask_interface.h
|
||||
${ITTI_DIR}/intertask_interface.c
|
||||
${ITTI_DIR}/backtrace.c
|
||||
${ITTI_DIR}/memory_pools.c
|
||||
${ITTI_DIR}/signals.c
|
||||
${ITTI_DIR}/timer.c
|
||||
${OCP_ITTI}/intertask_interface.cpp
|
||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||
${OPENAIR_DIR}/common/utils/memory_pools.c
|
||||
)
|
||||
set(ITTI_LIB ITTI)
|
||||
set(GTPU_need_ITTI ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_eNB.c)
|
||||
@@ -744,7 +742,7 @@ include_directories("${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0")
|
||||
include_directories("${OPENAIR2_DIR}/RRC/LTE/MESSAGES")
|
||||
include_directories("${OPENAIR2_DIR}/RRC/LTE")
|
||||
include_directories("${OPENAIR_DIR}/common/utils")
|
||||
include_directories("${OPENAIR_DIR}/common/utils/itti")
|
||||
include_directories("${OPENAIR_DIR}/common/utils/ocp_itti")
|
||||
include_directories("${OPENAIR3_DIR}/NAS/COMMON")
|
||||
include_directories("${OPENAIR3_DIR}/NAS/COMMON/API/NETWORK")
|
||||
include_directories("${OPENAIR3_DIR}/NAS/COMMON/EMM/MSG")
|
||||
|
||||
@@ -19,9 +19,72 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef UTILS_ASSERTIONS_H_
|
||||
#define UTILS_ASSERTIONS_H_
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#ifdef CMAKER
|
||||
#include <platform_types.h>
|
||||
#endif
|
||||
|
||||
#include "./itti/assertions.h"
|
||||
#if defined(ENB_MODE)
|
||||
# define display_backtrace()
|
||||
#else
|
||||
# include "backtrace.h"
|
||||
#endif
|
||||
|
||||
#endif /* UTILS_ASSERTIONS_H_ */
|
||||
#ifndef ASSERTIONS_H_
|
||||
#define ASSERTIONS_H_
|
||||
|
||||
void output_log_mem(void);
|
||||
#define _Assert_Exit_ \
|
||||
{ \
|
||||
fprintf(stderr, "\nExiting execution\n"); \
|
||||
display_backtrace(); \
|
||||
fflush(stdout); \
|
||||
fflush(stderr); \
|
||||
exit(EXIT_FAILURE); \
|
||||
}
|
||||
|
||||
#define _Assert_(cOND, aCTION, fORMAT, aRGS...) \
|
||||
do { \
|
||||
if (!(cOND)) { \
|
||||
fprintf(stderr, "\nAssertion ("#cOND") failed!\n" \
|
||||
"In %s() %s:%d\n" fORMAT, \
|
||||
__FUNCTION__, __FILE__, __LINE__, ##aRGS); \
|
||||
aCTION; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define AssertFatal(cOND, fORMAT, aRGS...) _Assert_(cOND, _Assert_Exit_, fORMAT, ##aRGS)
|
||||
|
||||
#define AssertError(cOND, aCTION, fORMAT, aRGS...) _Assert_(cOND, aCTION, fORMAT, ##aRGS)
|
||||
|
||||
|
||||
|
||||
#define DevCheck(cOND, vALUE1, vALUE2, vALUE3) \
|
||||
_Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n\n", \
|
||||
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3)
|
||||
|
||||
#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \
|
||||
_Assert_(cOND, _Assert_Exit_, #vALUE1": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX "\n\n", \
|
||||
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4)
|
||||
|
||||
#define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3)
|
||||
|
||||
#define DevAssert(cOND) _Assert_(cOND, _Assert_Exit_, "")
|
||||
|
||||
#define DevMessage(mESSAGE) _Assert_(0, _Assert_Exit_, #mESSAGE)
|
||||
|
||||
#define CHECK_INIT_RETURN(fCT) \
|
||||
do { \
|
||||
int fct_ret; \
|
||||
if ((fct_ret = (fCT)) != 0) { \
|
||||
fprintf(stderr, "Function "#fCT" has failed\n" \
|
||||
"returning %d\n", fct_ret); \
|
||||
fflush(stdout); \
|
||||
fflush(stderr); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#endif /* ASSERTIONS_H_ */
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
AM_CFLAGS = @ADD_CFLAGS@ \
|
||||
-I$(top_srcdir)/UTILS \
|
||||
-I$(top_srcdir)/COMMON \
|
||||
-I$(OPENAIR2_DIR)/UTIL/LFDS/liblfds6.1.1/liblfds611/inc \
|
||||
-DENABLE_EVENT_FD
|
||||
|
||||
noinst_LTLIBRARIES = libitti.la
|
||||
|
||||
BUILT_SOURCES = $(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/bin/liblfds611.a
|
||||
|
||||
$(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/bin/liblfds611.a:
|
||||
@if [ ! -d $(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/bin ]; then mkdir -p $(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/bin; fi;
|
||||
@if [ ! -d $(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/obj ]; then mkdir -p $(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611/obj; fi;
|
||||
@$(MAKE) -C $(OPENAIR2_DIR)/UTIL/LFDS/liblfds6.1.1/liblfds611/ -f makefile.linux OUTDIR=$(abs_top_builddir)/INTERTASK_INTERFACE/UTIL/LFDS/liblfds6.1.1/liblfds611
|
||||
|
||||
libitti_la_LDFLAGS = -all-static
|
||||
libitti_la_SOURCES = \
|
||||
gtpv1_u_messages_def.h gtpv1_u_messages_types.h \
|
||||
nas_messages_def.h nas_messages_types.h \
|
||||
timer_messages_def.h timer_messages_types.h \
|
||||
s11_messages_def.h s11_messages_types.h \
|
||||
s1ap_messages_def.h s1ap_messages_types.h \
|
||||
s6a_messages_def.h s6a_messages_types.h \
|
||||
sgw_lite_def.h sgw_lite_messages_types.h \
|
||||
sctp_messages_def.h sctp_messages_types.h \
|
||||
udp_message_def.h udp_messages_types.h \
|
||||
intertask_interface.c intertask_interface.h \
|
||||
intertask_interface_dump.c intertask_interface_dump.h \
|
||||
assertions.h \
|
||||
backtrace.c backtrace.h \
|
||||
signals.c signals.h \
|
||||
timer.c timer.h
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#ifdef CMAKER
|
||||
#include <platform_types.h>
|
||||
#endif
|
||||
|
||||
#if defined(ENB_MODE)
|
||||
# define display_backtrace()
|
||||
#else
|
||||
# include "backtrace.h"
|
||||
#endif
|
||||
|
||||
#ifndef ASSERTIONS_H_
|
||||
#define ASSERTIONS_H_
|
||||
|
||||
void output_log_mem(void);
|
||||
#define _Assert_Exit_ \
|
||||
{ \
|
||||
fprintf(stderr, "\nExiting execution\n"); \
|
||||
display_backtrace(); \
|
||||
fflush(stdout); \
|
||||
fflush(stderr); \
|
||||
exit(EXIT_FAILURE); \
|
||||
}
|
||||
|
||||
#define _Assert_(cOND, aCTION, fORMAT, aRGS...) \
|
||||
do { \
|
||||
if (!(cOND)) { \
|
||||
fprintf(stderr, "\nAssertion ("#cOND") failed!\n" \
|
||||
"In %s() %s:%d\n" fORMAT, \
|
||||
__FUNCTION__, __FILE__, __LINE__, ##aRGS); \
|
||||
aCTION; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define AssertFatal(cOND, fORMAT, aRGS...) _Assert_(cOND, _Assert_Exit_, fORMAT, ##aRGS)
|
||||
|
||||
#define AssertError(cOND, aCTION, fORMAT, aRGS...) _Assert_(cOND, aCTION, fORMAT, ##aRGS)
|
||||
|
||||
|
||||
|
||||
#define DevCheck(cOND, vALUE1, vALUE2, vALUE3) \
|
||||
_Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n\n", \
|
||||
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3)
|
||||
|
||||
#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \
|
||||
_Assert_(cOND, _Assert_Exit_, #vALUE1": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX "\n\n", \
|
||||
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4)
|
||||
|
||||
#define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3)
|
||||
|
||||
#define DevAssert(cOND) _Assert_(cOND, _Assert_Exit_, "")
|
||||
|
||||
#define DevMessage(mESSAGE) _Assert_(0, _Assert_Exit_, #mESSAGE)
|
||||
|
||||
#define CHECK_INIT_RETURN(fCT) \
|
||||
do { \
|
||||
int fct_ret; \
|
||||
if ((fct_ret = (fCT)) != 0) { \
|
||||
fprintf(stderr, "Function "#fCT" has failed\n" \
|
||||
"returning %d\n", fct_ret); \
|
||||
fflush(stdout); \
|
||||
fflush(stderr); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#endif /* ASSERTIONS_H_ */
|
||||
@@ -1,930 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
#if !defined(TRUE)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#include "liblfds611.h"
|
||||
|
||||
#include "assertions.h"
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#if T_TRACER
|
||||
#include "T.h"
|
||||
#endif
|
||||
|
||||
/* Includes "intertask_interface_init.h" to check prototype coherence, but
|
||||
* disable threads and messages information generation.
|
||||
*/
|
||||
#define CHECK_PROTOTYPE_ONLY
|
||||
#include "intertask_interface_init.h"
|
||||
#undef CHECK_PROTOTYPE_ONLY
|
||||
|
||||
#include "signals.h"
|
||||
#include "timer.h"
|
||||
|
||||
/* ITTI DEBUG groups */
|
||||
#define ITTI_DEBUG_POLL (1<<0)
|
||||
#define ITTI_DEBUG_SEND (1<<1)
|
||||
#define ITTI_DEBUG_EVEN_FD (1<<2)
|
||||
#define ITTI_DEBUG_INIT (1<<3)
|
||||
#define ITTI_DEBUG_EXIT (1<<4)
|
||||
#define ITTI_DEBUG_ISSUES (1<<5)
|
||||
#define ITTI_DEBUG_MP_STATISTICS (1<<6)
|
||||
|
||||
const int itti_debug = (ITTI_DEBUG_ISSUES | ITTI_DEBUG_MP_STATISTICS);
|
||||
|
||||
# define ITTI_DEBUG(m, x, args...) do { if ((m) & itti_debug) {fprintf(stdout, "[ITTI][D]"x, ##args); fflush (stdout);} } while(0);
|
||||
#define ITTI_ERROR(x, args...) do { fprintf(stdout, "[ITTI][E]"x, ##args); fflush (stdout); } while(0);
|
||||
|
||||
/* Global message size */
|
||||
#define MESSAGE_SIZE(mESSAGEiD) (sizeof(MessageHeader) + itti_desc.messages_info[mESSAGEiD].size)
|
||||
|
||||
|
||||
extern int emulate_rf;
|
||||
|
||||
typedef enum task_state_s {
|
||||
TASK_STATE_NOT_CONFIGURED, TASK_STATE_STARTING, TASK_STATE_READY, TASK_STATE_ENDED, TASK_STATE_MAX,
|
||||
} task_state_t;
|
||||
|
||||
/* This list acts as a FIFO of messages received by tasks (RRC, NAS, ...) */
|
||||
typedef struct message_list_s {
|
||||
MessageDef *msg; ///< Pointer to the message
|
||||
|
||||
message_number_t message_number; ///< Unique message number
|
||||
uint32_t message_priority; ///< Message priority
|
||||
} message_list_t;
|
||||
|
||||
typedef struct thread_desc_s {
|
||||
/* pthread associated with the thread */
|
||||
pthread_t task_thread;
|
||||
|
||||
/* State of the thread */
|
||||
volatile task_state_t task_state;
|
||||
|
||||
/* This fd is used internally by ITTI. */
|
||||
int epoll_fd;
|
||||
|
||||
/* The thread fd */
|
||||
int task_event_fd;
|
||||
|
||||
/* Number of events to monitor */
|
||||
uint16_t nb_events;
|
||||
|
||||
|
||||
/* Array of events monitored by the task.
|
||||
* By default only one fd is monitored (the one used to received messages
|
||||
* from other tasks).
|
||||
* More events can be suscribed later by the task itself.
|
||||
*/
|
||||
struct epoll_event *events;
|
||||
|
||||
int epoll_nb_events;
|
||||
|
||||
/* Flag to mark real time thread */
|
||||
unsigned real_time;
|
||||
|
||||
/* Counter to indicate that messages are pending for the thread */
|
||||
unsigned messages_pending;
|
||||
} thread_desc_t;
|
||||
|
||||
typedef struct task_desc_s {
|
||||
/* Queue of messages belonging to the task */
|
||||
struct lfds611_queue_state *message_queue;
|
||||
} task_desc_t;
|
||||
|
||||
typedef struct itti_desc_s {
|
||||
thread_desc_t *threads;
|
||||
task_desc_t *tasks;
|
||||
|
||||
/* Current message number. Incremented every call to send_msg_to_task */
|
||||
message_number_t message_number __attribute__((aligned(8)));
|
||||
|
||||
thread_id_t thread_max;
|
||||
task_id_t task_max;
|
||||
MessagesIds messages_id_max;
|
||||
|
||||
boolean_t thread_handling_signals;
|
||||
pthread_t thread_ref;
|
||||
|
||||
const task_info_t *tasks_info;
|
||||
const message_info_t *messages_info;
|
||||
|
||||
itti_lte_time_t lte_time;
|
||||
|
||||
int running;
|
||||
|
||||
volatile uint32_t created_tasks;
|
||||
volatile uint32_t ready_tasks;
|
||||
volatile int wait_tasks;
|
||||
} itti_desc_t;
|
||||
|
||||
static itti_desc_t itti_desc;
|
||||
|
||||
void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize_t size)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
|
||||
ptr = malloc (size);
|
||||
if (ptr) memset(ptr,0,size);
|
||||
|
||||
AssertFatal (ptr != NULL, "Memory allocation of %d bytes failed (%d -> %d)!\n", (int) size, origin_task_id, destination_task_id);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int itti_free(task_id_t task_id, void *ptr)
|
||||
{
|
||||
int result = EXIT_SUCCESS;
|
||||
AssertFatal (ptr != NULL, "Trying to free a NULL pointer (%d)!\n", task_id);
|
||||
|
||||
free (ptr);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static inline message_number_t itti_increment_message_number(void)
|
||||
{
|
||||
/* Atomic operation supported by GCC: returns the current message number
|
||||
* and then increment it by 1.
|
||||
* This can be done without mutex.
|
||||
*/
|
||||
return __sync_fetch_and_add (&itti_desc.message_number, 1);
|
||||
}
|
||||
|
||||
static inline uint32_t itti_get_message_priority(MessagesIds message_id)
|
||||
{
|
||||
AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max);
|
||||
|
||||
return (itti_desc.messages_info[message_id].priority);
|
||||
}
|
||||
|
||||
const char *itti_get_message_name(MessagesIds message_id)
|
||||
{
|
||||
AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max);
|
||||
|
||||
return (itti_desc.messages_info[message_id].name);
|
||||
}
|
||||
|
||||
const char *itti_get_task_name(task_id_t task_id)
|
||||
{
|
||||
if (itti_desc.task_max > 0) {
|
||||
AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)!\n", task_id, itti_desc.task_max);
|
||||
} else {
|
||||
return ("ITTI NOT INITIALIZED !!!");
|
||||
}
|
||||
|
||||
return (itti_desc.tasks_info[task_id].name);
|
||||
}
|
||||
|
||||
static task_id_t itti_get_current_task_id(void)
|
||||
{
|
||||
task_id_t task_id;
|
||||
thread_id_t thread_id;
|
||||
pthread_t thread = pthread_self ();
|
||||
|
||||
for (task_id = TASK_FIRST; task_id < itti_desc.task_max; task_id++) {
|
||||
thread_id = TASK_GET_THREAD_ID(task_id);
|
||||
|
||||
if (itti_desc.threads[thread_id].task_thread == thread) {
|
||||
return task_id;
|
||||
}
|
||||
}
|
||||
|
||||
return TASK_UNKNOWN;
|
||||
}
|
||||
|
||||
void itti_update_lte_time(uint32_t frame, uint8_t slot)
|
||||
{
|
||||
itti_desc.lte_time.frame = frame;
|
||||
itti_desc.lte_time.slot = slot;
|
||||
}
|
||||
|
||||
int itti_send_broadcast_message(MessageDef *message_p)
|
||||
{
|
||||
task_id_t destination_task_id;
|
||||
task_id_t origin_task_id;
|
||||
thread_id_t origin_thread_id;
|
||||
uint32_t thread_id;
|
||||
int ret = 0;
|
||||
int result;
|
||||
|
||||
AssertFatal (message_p != NULL, "Trying to broadcast a NULL message!\n");
|
||||
|
||||
origin_task_id = message_p->ittiMsgHeader.originTaskId;
|
||||
origin_thread_id = TASK_GET_THREAD_ID(origin_task_id);
|
||||
|
||||
destination_task_id = TASK_FIRST;
|
||||
|
||||
for (thread_id = THREAD_FIRST; thread_id < itti_desc.thread_max; thread_id++) {
|
||||
MessageDef *new_message_p;
|
||||
|
||||
while (thread_id != TASK_GET_THREAD_ID(destination_task_id)) {
|
||||
destination_task_id++;
|
||||
}
|
||||
|
||||
/* Skip task that broadcast the message */
|
||||
if (thread_id != origin_thread_id) {
|
||||
/* Skip tasks which are not running */
|
||||
if (itti_desc.threads[thread_id].task_state == TASK_STATE_READY) {
|
||||
size_t size = sizeof(MessageHeader) + message_p->ittiMsgHeader.ittiMsgSize;
|
||||
new_message_p = itti_malloc( origin_task_id, destination_task_id, size );
|
||||
AssertFatal (new_message_p != NULL, "New message allocation failed!\n");
|
||||
|
||||
memcpy( new_message_p, message_p, size );
|
||||
result = itti_send_msg_to_task (destination_task_id, INSTANCE_DEFAULT, new_message_p);
|
||||
AssertFatal (result >= 0, "Failed to send message %d to thread %d (task %d)!\n", message_p->ittiMsgHeader.messageId, thread_id, destination_task_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MessageDef *itti_alloc_new_message_sized(task_id_t origin_task_id, MessagesIds message_id, MessageHeaderSize size)
|
||||
{
|
||||
MessageDef *temp = NULL;
|
||||
|
||||
AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max);
|
||||
|
||||
if (origin_task_id == TASK_UNKNOWN) {
|
||||
/* Try to identify real origin task ID */
|
||||
origin_task_id = itti_get_current_task_id();
|
||||
}
|
||||
|
||||
temp = 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)
|
||||
{
|
||||
return itti_alloc_new_message_sized(origin_task_id, message_id, itti_desc.messages_info[message_id].size);
|
||||
}
|
||||
|
||||
int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message)
|
||||
{
|
||||
thread_id_t destination_thread_id;
|
||||
task_id_t origin_task_id;
|
||||
message_list_t *new;
|
||||
uint32_t priority;
|
||||
message_number_t message_number;
|
||||
uint32_t message_id;
|
||||
|
||||
AssertFatal (message != NULL, "Message is NULL!\n");
|
||||
AssertFatal (destination_task_id < itti_desc.task_max, "Destination task id (%d) is out of range (%d)\n", destination_task_id, itti_desc.task_max);
|
||||
|
||||
destination_thread_id = TASK_GET_THREAD_ID(destination_task_id);
|
||||
message->ittiMsgHeader.destinationTaskId = destination_task_id;
|
||||
message->ittiMsgHeader.instance = instance;
|
||||
message->ittiMsgHeader.lte_time.frame = itti_desc.lte_time.frame;
|
||||
message->ittiMsgHeader.lte_time.slot = itti_desc.lte_time.slot;
|
||||
message_id = message->ittiMsgHeader.messageId;
|
||||
AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max);
|
||||
|
||||
origin_task_id = ITTI_MSG_ORIGIN_ID(message);
|
||||
|
||||
priority = itti_get_message_priority (message_id);
|
||||
|
||||
/* Increment the global message number */
|
||||
message_number = itti_increment_message_number ();
|
||||
|
||||
if (destination_task_id != TASK_UNKNOWN) {
|
||||
|
||||
if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED ||
|
||||
itti_desc.threads[destination_thread_id].task_state == TASK_STATE_NOT_CONFIGURED) {
|
||||
ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Message %s, number %lu with priority %d can not be sent from %s to queue (%u:%s), unconfigured or ended destination task!\n",
|
||||
itti_desc.messages_info[message_id].name,
|
||||
message_number,
|
||||
priority,
|
||||
itti_get_task_name(origin_task_id),
|
||||
destination_task_id,
|
||||
itti_get_task_name(destination_task_id));
|
||||
} else {
|
||||
if(!emulate_rf){
|
||||
/* We cannot send a message if the task is not running */
|
||||
AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY,
|
||||
"Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n",
|
||||
itti_get_task_name(origin_task_id),
|
||||
itti_desc.messages_info[message_id].name,
|
||||
message_id,
|
||||
destination_thread_id,
|
||||
itti_desc.threads[destination_thread_id].task_state);
|
||||
}
|
||||
|
||||
/* Allocate new list element */
|
||||
new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s));
|
||||
|
||||
/* Fill in members */
|
||||
new->msg = message;
|
||||
new->message_number = message_number;
|
||||
new->message_priority = priority;
|
||||
|
||||
/* Enqueue message in destination task queue */
|
||||
if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) {
|
||||
AssertFatal(0, "Error: lfds611_queue_enqueue returns 0, queue is full, exiting\n");
|
||||
}
|
||||
|
||||
{
|
||||
/* Only use event fd for tasks, subtasks will pool the queue */
|
||||
if (TASK_GET_PARENT_TASK_ID(destination_task_id) == TASK_UNKNOWN) {
|
||||
ssize_t write_ret;
|
||||
eventfd_t sem_counter = 1;
|
||||
|
||||
/* Call to write for an event fd must be of 8 bytes */
|
||||
write_ret = write (itti_desc.threads[destination_thread_id].task_event_fd, &sem_counter, sizeof(sem_counter));
|
||||
AssertFatal (write_ret == sizeof(sem_counter), "Write to task message FD (%d) failed (%d/%d)\n",
|
||||
destination_thread_id, (int) write_ret, (int) sizeof(sem_counter));
|
||||
}
|
||||
}
|
||||
|
||||
ITTI_DEBUG(ITTI_DEBUG_SEND, " Message %s, number %lu with priority %d successfully sent from %s to queue (%u:%s)\n",
|
||||
itti_desc.messages_info[message_id].name,
|
||||
message_number,
|
||||
priority,
|
||||
itti_get_task_name(origin_task_id),
|
||||
destination_task_id,
|
||||
itti_get_task_name(destination_task_id));
|
||||
}
|
||||
} else {
|
||||
/* This is a debug message to TASK_UNKNOWN, we can release safely release it */
|
||||
int result = itti_free(origin_task_id, message);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* same as itti_send_msg_to_task but returns -1 in case of failure instead of crashing */
|
||||
/* TODO: this is a hack - the whole logic needs a proper rework. */
|
||||
/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
|
||||
int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message)
|
||||
{
|
||||
thread_id_t destination_thread_id;
|
||||
task_id_t origin_task_id;
|
||||
message_list_t *new;
|
||||
uint32_t priority;
|
||||
message_number_t message_number;
|
||||
uint32_t message_id;
|
||||
|
||||
AssertFatal (message != NULL, "Message is NULL!\n");
|
||||
AssertFatal (destination_task_id < itti_desc.task_max, "Destination task id (%d) is out of range (%d)\n", destination_task_id, itti_desc.task_max);
|
||||
|
||||
destination_thread_id = TASK_GET_THREAD_ID(destination_task_id);
|
||||
message->ittiMsgHeader.destinationTaskId = destination_task_id;
|
||||
message->ittiMsgHeader.instance = instance;
|
||||
message->ittiMsgHeader.lte_time.frame = itti_desc.lte_time.frame;
|
||||
message->ittiMsgHeader.lte_time.slot = itti_desc.lte_time.slot;
|
||||
message_id = message->ittiMsgHeader.messageId;
|
||||
AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max);
|
||||
|
||||
origin_task_id = ITTI_MSG_ORIGIN_ID(message);
|
||||
|
||||
priority = itti_get_message_priority (message_id);
|
||||
|
||||
/* Increment the global message number */
|
||||
message_number = itti_increment_message_number ();
|
||||
|
||||
if (destination_task_id != TASK_UNKNOWN) {
|
||||
|
||||
if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED ||
|
||||
itti_desc.threads[destination_thread_id].task_state == TASK_STATE_NOT_CONFIGURED) {
|
||||
ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Message %s, number %lu with priority %d can not be sent from %s to queue (%u:%s), unconfigured or ended destination task!\n",
|
||||
itti_desc.messages_info[message_id].name,
|
||||
message_number,
|
||||
priority,
|
||||
itti_get_task_name(origin_task_id),
|
||||
destination_task_id,
|
||||
itti_get_task_name(destination_task_id));
|
||||
} else {
|
||||
/* We cannot send a message if the task is not running */
|
||||
AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY,
|
||||
"Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n",
|
||||
itti_get_task_name(origin_task_id),
|
||||
itti_desc.messages_info[message_id].name,
|
||||
message_id,
|
||||
destination_thread_id,
|
||||
itti_desc.threads[destination_thread_id].task_state);
|
||||
|
||||
/* Allocate new list element */
|
||||
new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s));
|
||||
|
||||
/* Fill in members */
|
||||
new->msg = message;
|
||||
new->message_number = message_number;
|
||||
new->message_priority = priority;
|
||||
|
||||
/* Enqueue message in destination task queue */
|
||||
if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) {
|
||||
itti_free(origin_task_id, new);
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
/* Only use event fd for tasks, subtasks will pool the queue */
|
||||
if (TASK_GET_PARENT_TASK_ID(destination_task_id) == TASK_UNKNOWN) {
|
||||
ssize_t write_ret;
|
||||
eventfd_t sem_counter = 1;
|
||||
|
||||
/* Call to write for an event fd must be of 8 bytes */
|
||||
write_ret = write (itti_desc.threads[destination_thread_id].task_event_fd, &sem_counter, sizeof(sem_counter));
|
||||
AssertFatal (write_ret == sizeof(sem_counter), "Write to task message FD (%d) failed (%d/%d)\n",
|
||||
destination_thread_id, (int) write_ret, (int) sizeof(sem_counter));
|
||||
}
|
||||
}
|
||||
|
||||
ITTI_DEBUG(ITTI_DEBUG_SEND, " Message %s, number %lu with priority %d successfully sent from %s to queue (%u:%s)\n",
|
||||
itti_desc.messages_info[message_id].name,
|
||||
message_number,
|
||||
priority,
|
||||
itti_get_task_name(origin_task_id),
|
||||
destination_task_id,
|
||||
itti_get_task_name(destination_task_id));
|
||||
}
|
||||
} else {
|
||||
/* This is a debug message to TASK_UNKNOWN, we can release safely release it */
|
||||
int result = itti_free(origin_task_id, message);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void itti_subscribe_event_fd(task_id_t task_id, int fd)
|
||||
{
|
||||
thread_id_t thread_id;
|
||||
struct epoll_event event;
|
||||
|
||||
AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)!\n", task_id, itti_desc.task_max);
|
||||
|
||||
thread_id = TASK_GET_THREAD_ID(task_id);
|
||||
itti_desc.threads[thread_id].nb_events++;
|
||||
|
||||
/* Reallocate the events */
|
||||
itti_desc.threads[thread_id].events = realloc(
|
||||
itti_desc.threads[thread_id].events,
|
||||
itti_desc.threads[thread_id].nb_events * sizeof(struct epoll_event));
|
||||
|
||||
event.events = EPOLLIN | EPOLLERR;
|
||||
event.data.u64 = 0;
|
||||
event.data.fd = fd;
|
||||
|
||||
/* Add the event fd to the list of monitored events */
|
||||
if (epoll_ctl(itti_desc.threads[thread_id].epoll_fd, EPOLL_CTL_ADD, fd,
|
||||
&event) != 0) {
|
||||
/* Always assert on this condition */
|
||||
AssertFatal (0, "epoll_ctl (EPOLL_CTL_ADD) failed for task %s, fd %d: %s!\n",
|
||||
itti_get_task_name(task_id), fd, strerror(errno));
|
||||
}
|
||||
|
||||
ITTI_DEBUG(ITTI_DEBUG_EVEN_FD, " Successfully subscribed fd %d for task %s\n", fd, itti_get_task_name(task_id));
|
||||
}
|
||||
|
||||
void itti_unsubscribe_event_fd(task_id_t task_id, int fd)
|
||||
{
|
||||
thread_id_t thread_id;
|
||||
|
||||
AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)!\n", task_id, itti_desc.task_max);
|
||||
AssertFatal (fd >= 0, "File descriptor (%d) is invalid!\n", fd);
|
||||
|
||||
thread_id = TASK_GET_THREAD_ID(task_id);
|
||||
|
||||
/* Add the event fd to the list of monitored events */
|
||||
if (epoll_ctl(itti_desc.threads[thread_id].epoll_fd, EPOLL_CTL_DEL, fd, NULL) != 0) {
|
||||
/* Always assert on this condition */
|
||||
AssertFatal (0, "epoll_ctl (EPOLL_CTL_DEL) failed for task %s, fd %d: %s!\n",
|
||||
itti_get_task_name(task_id), fd, strerror(errno));
|
||||
}
|
||||
|
||||
itti_desc.threads[thread_id].nb_events--;
|
||||
itti_desc.threads[thread_id].events = realloc(
|
||||
itti_desc.threads[thread_id].events,
|
||||
itti_desc.threads[thread_id].nb_events * sizeof(struct epoll_event));
|
||||
}
|
||||
|
||||
int itti_get_events(task_id_t task_id, struct epoll_event **events)
|
||||
{
|
||||
thread_id_t thread_id;
|
||||
|
||||
AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)\n", task_id, itti_desc.task_max);
|
||||
|
||||
thread_id = TASK_GET_THREAD_ID(task_id);
|
||||
*events = itti_desc.threads[thread_id].events;
|
||||
|
||||
return itti_desc.threads[thread_id].epoll_nb_events;
|
||||
}
|
||||
|
||||
static inline void itti_receive_msg_internal_event_fd(task_id_t task_id, uint8_t polling, MessageDef **received_msg)
|
||||
{
|
||||
thread_id_t thread_id;
|
||||
int epoll_ret = 0;
|
||||
int epoll_timeout = 0;
|
||||
int i;
|
||||
|
||||
AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)!\n", task_id, itti_desc.task_max);
|
||||
AssertFatal (received_msg != NULL, "Received message is NULL!\n");
|
||||
|
||||
thread_id = TASK_GET_THREAD_ID(task_id);
|
||||
*received_msg = NULL;
|
||||
|
||||
if (polling) {
|
||||
/* In polling mode we set the timeout to 0 causing epoll_wait to return
|
||||
* immediately.
|
||||
*/
|
||||
epoll_timeout = 0;
|
||||
} else {
|
||||
/* timeout = -1 causes the epoll_wait to wait indefinitely.
|
||||
*/
|
||||
epoll_timeout = -1;
|
||||
}
|
||||
|
||||
do {
|
||||
epoll_ret = epoll_wait(itti_desc.threads[thread_id].epoll_fd,
|
||||
itti_desc.threads[thread_id].events,
|
||||
itti_desc.threads[thread_id].nb_events,
|
||||
epoll_timeout);
|
||||
} while (epoll_ret < 0 && errno == EINTR);
|
||||
|
||||
if (epoll_ret < 0) {
|
||||
AssertFatal (0, "epoll_wait failed for task %s: %s!\n", itti_get_task_name(task_id), strerror(errno));
|
||||
}
|
||||
|
||||
if (epoll_ret == 0 && polling) {
|
||||
/* No data to read -> return */
|
||||
return;
|
||||
}
|
||||
|
||||
itti_desc.threads[thread_id].epoll_nb_events = epoll_ret;
|
||||
|
||||
for (i = 0; i < epoll_ret; i++) {
|
||||
/* Check if there is an event for ITTI for the event fd */
|
||||
if ((itti_desc.threads[thread_id].events[i].events & EPOLLIN) &&
|
||||
(itti_desc.threads[thread_id].events[i].data.fd == itti_desc.threads[thread_id].task_event_fd)) {
|
||||
struct message_list_s *message = NULL;
|
||||
eventfd_t sem_counter;
|
||||
ssize_t read_ret;
|
||||
int result;
|
||||
|
||||
/* Read will always return 1 */
|
||||
read_ret = read (itti_desc.threads[thread_id].task_event_fd, &sem_counter, sizeof(sem_counter));
|
||||
AssertFatal (read_ret == sizeof(sem_counter), "Read from task message FD (%d) failed (%d/%d)!\n", thread_id, (int) read_ret, (int) sizeof(sem_counter));
|
||||
|
||||
if (lfds611_queue_dequeue (itti_desc.tasks[task_id].message_queue, (void **) &message) == 0) {
|
||||
/* No element in list -> this should not happen */
|
||||
AssertFatal (0, "No message in queue for task %d while there are %d events and some for the messages queue!\n", task_id, epoll_ret);
|
||||
}
|
||||
|
||||
AssertFatal(message != NULL, "Message from message queue is NULL!\n");
|
||||
*received_msg = message->msg;
|
||||
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(*received_msg), message);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
|
||||
|
||||
/* Mark that the event has been processed */
|
||||
itti_desc.threads[thread_id].events[i].events &= ~EPOLLIN;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void itti_receive_msg(task_id_t task_id, MessageDef **received_msg)
|
||||
{
|
||||
|
||||
itti_receive_msg_internal_event_fd(task_id, 0, received_msg);
|
||||
|
||||
}
|
||||
|
||||
void itti_poll_msg(task_id_t task_id, MessageDef **received_msg)
|
||||
{
|
||||
AssertFatal (task_id < itti_desc.task_max, "Task id (%d) is out of range (%d)!\n", task_id, itti_desc.task_max);
|
||||
|
||||
*received_msg = NULL;
|
||||
|
||||
{
|
||||
struct message_list_s *message;
|
||||
|
||||
if (lfds611_queue_dequeue (itti_desc.tasks[task_id].message_queue, (void **) &message) == 1) {
|
||||
int result;
|
||||
|
||||
*received_msg = message->msg;
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(*received_msg), message);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
}
|
||||
|
||||
if (*received_msg == NULL) {
|
||||
ITTI_DEBUG(ITTI_DEBUG_POLL, " No message in queue[(%u:%s)]\n", task_id, itti_get_task_name(task_id));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *args_p)
|
||||
{
|
||||
thread_id_t thread_id = TASK_GET_THREAD_ID(task_id);
|
||||
int result;
|
||||
|
||||
AssertFatal (start_routine != NULL, "Start routine is NULL!\n");
|
||||
AssertFatal (thread_id < itti_desc.thread_max, "Thread id (%d) is out of range (%d)!\n", thread_id, itti_desc.thread_max);
|
||||
AssertFatal (itti_desc.threads[thread_id].task_state == TASK_STATE_NOT_CONFIGURED, "Task %d, thread %d state is not correct (%d)!\n",
|
||||
task_id, thread_id, itti_desc.threads[thread_id].task_state);
|
||||
|
||||
itti_desc.threads[thread_id].task_state = TASK_STATE_STARTING;
|
||||
|
||||
ITTI_DEBUG(ITTI_DEBUG_INIT, " Creating thread for task %s ...\n", itti_get_task_name(task_id));
|
||||
|
||||
result = pthread_create (&itti_desc.threads[thread_id].task_thread, NULL, start_routine, args_p);
|
||||
AssertFatal (result >= 0, "Thread creation for task %d, thread %d failed (%d)!\n", task_id, thread_id, result);
|
||||
char name[16];
|
||||
snprintf( name, sizeof(name), "ITTI %d", thread_id );
|
||||
pthread_setname_np( itti_desc.threads[thread_id].task_thread, name );
|
||||
|
||||
itti_desc.created_tasks ++;
|
||||
|
||||
/* Wait till the thread is completely ready */
|
||||
while (itti_desc.threads[thread_id].task_state != TASK_STATE_READY)
|
||||
usleep (1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void itti_set_task_real_time(task_id_t task_id)
|
||||
{
|
||||
thread_id_t thread_id = TASK_GET_THREAD_ID(task_id);
|
||||
|
||||
DevCheck(thread_id < itti_desc.thread_max, thread_id, itti_desc.thread_max, 0);
|
||||
|
||||
itti_desc.threads[thread_id].real_time = TRUE;
|
||||
}
|
||||
|
||||
void itti_wait_ready(int wait_tasks)
|
||||
{
|
||||
itti_desc.wait_tasks = wait_tasks;
|
||||
|
||||
ITTI_DEBUG(ITTI_DEBUG_INIT,
|
||||
" wait for tasks: %s, created tasks %d, ready tasks %d\n",
|
||||
itti_desc.wait_tasks ? "yes" : "no",
|
||||
itti_desc.created_tasks,
|
||||
itti_desc.ready_tasks);
|
||||
|
||||
AssertFatal (itti_desc.created_tasks == itti_desc.ready_tasks, "Number of created tasks (%d) does not match ready tasks (%d), wait task %d!\n",
|
||||
itti_desc.created_tasks, itti_desc.ready_tasks, itti_desc.wait_tasks);
|
||||
}
|
||||
|
||||
void itti_mark_task_ready(task_id_t task_id)
|
||||
{
|
||||
thread_id_t thread_id = TASK_GET_THREAD_ID(task_id);
|
||||
|
||||
AssertFatal (thread_id < itti_desc.thread_max, "Thread id (%d) is out of range (%d)!\n", thread_id, itti_desc.thread_max);
|
||||
|
||||
/* Mark the thread as using LFDS queue */
|
||||
lfds611_queue_use(itti_desc.tasks[task_id].message_queue);
|
||||
|
||||
#if defined(UE_EXPANSION) || defined(RTAI)
|
||||
/* Assign low priority to created threads */
|
||||
{
|
||||
struct sched_param sched_param;
|
||||
sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 1;
|
||||
sched_setscheduler(0, SCHED_FIFO, &sched_param);
|
||||
}
|
||||
#endif
|
||||
|
||||
itti_desc.threads[thread_id].task_state = TASK_STATE_READY;
|
||||
itti_desc.ready_tasks ++;
|
||||
|
||||
while (itti_desc.wait_tasks != 0) {
|
||||
usleep (10000);
|
||||
}
|
||||
|
||||
ITTI_DEBUG(ITTI_DEBUG_INIT, " task %s started\n", itti_get_task_name(task_id));
|
||||
}
|
||||
|
||||
void itti_exit_task(void)
|
||||
{
|
||||
task_id_t task_id = itti_get_current_task_id();
|
||||
thread_id_t thread_id = TASK_GET_THREAD_ID(task_id);
|
||||
|
||||
#if defined(OAI_EMU) || defined(RTAI)
|
||||
if (task_id > TASK_UNKNOWN) {
|
||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG,
|
||||
__sync_and_and_fetch (&itti_desc.vcd_receive_msg, ~(1L << task_id)));
|
||||
}
|
||||
#endif
|
||||
|
||||
itti_desc.threads[thread_id].task_state = TASK_STATE_NOT_CONFIGURED;
|
||||
itti_desc.created_tasks--;
|
||||
ITTI_DEBUG(ITTI_DEBUG_EXIT, "Thread for task %s (%d) exits\n", itti_get_task_name(task_id), task_id);
|
||||
pthread_exit (NULL);
|
||||
}
|
||||
|
||||
void itti_terminate_tasks(task_id_t task_id)
|
||||
{
|
||||
// Sends Terminate signals to all tasks.
|
||||
itti_send_terminate_message (task_id);
|
||||
|
||||
if (itti_desc.thread_handling_signals) {
|
||||
pthread_kill (itti_desc.thread_ref, SIGUSR1);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
task_id_t task_id;
|
||||
thread_id_t thread_id;
|
||||
int ret;
|
||||
|
||||
itti_desc.message_number = 1;
|
||||
|
||||
ITTI_DEBUG(ITTI_DEBUG_INIT, " Init: %d tasks, %d threads, %d messages\n", task_max, thread_max, messages_id_max);
|
||||
|
||||
CHECK_INIT_RETURN(signal_mask());
|
||||
|
||||
/* Saves threads and messages max values */
|
||||
itti_desc.task_max = task_max;
|
||||
itti_desc.thread_max = thread_max;
|
||||
itti_desc.messages_id_max = messages_id_max;
|
||||
itti_desc.thread_handling_signals = FALSE;
|
||||
itti_desc.tasks_info = tasks_info;
|
||||
itti_desc.messages_info = messages_info;
|
||||
|
||||
/* Allocates memory for tasks info */
|
||||
itti_desc.tasks = calloc (itti_desc.task_max, sizeof(task_desc_t));
|
||||
|
||||
/* Allocates memory for threads info */
|
||||
itti_desc.threads = calloc (itti_desc.thread_max, sizeof(thread_desc_t));
|
||||
|
||||
/* Initializing each queue and related stuff */
|
||||
for (task_id = TASK_FIRST; task_id < itti_desc.task_max; task_id++) {
|
||||
ITTI_DEBUG(ITTI_DEBUG_INIT, " Initializing %stask %s%s%s\n",
|
||||
itti_desc.tasks_info[task_id].parent_task != TASK_UNKNOWN ? "sub-" : "",
|
||||
itti_desc.tasks_info[task_id].name,
|
||||
itti_desc.tasks_info[task_id].parent_task != TASK_UNKNOWN ? " with parent " : "",
|
||||
itti_desc.tasks_info[task_id].parent_task != TASK_UNKNOWN ?
|
||||
itti_get_task_name(itti_desc.tasks_info[task_id].parent_task) : "");
|
||||
|
||||
ITTI_DEBUG(ITTI_DEBUG_INIT, " Creating queue of message of size %u\n", itti_desc.tasks_info[task_id].queue_size);
|
||||
|
||||
ret = lfds611_queue_new(&itti_desc.tasks[task_id].message_queue, itti_desc.tasks_info[task_id].queue_size);
|
||||
|
||||
if (0 == ret) {
|
||||
AssertFatal (0, "lfds611_queue_new failed for task %s!\n", itti_get_task_name(task_id));
|
||||
}
|
||||
}
|
||||
|
||||
/* Initializing each thread */
|
||||
for (thread_id = THREAD_FIRST; thread_id < itti_desc.thread_max; thread_id++) {
|
||||
itti_desc.threads[thread_id].task_state = TASK_STATE_NOT_CONFIGURED;
|
||||
|
||||
itti_desc.threads[thread_id].epoll_fd = epoll_create1(0);
|
||||
|
||||
if (itti_desc.threads[thread_id].epoll_fd == -1) {
|
||||
/* Always assert on this condition */
|
||||
AssertFatal (0, "Failed to create new epoll fd: %s!\n", strerror(errno));
|
||||
}
|
||||
|
||||
itti_desc.threads[thread_id].task_event_fd = eventfd(0, EFD_SEMAPHORE);
|
||||
|
||||
if (itti_desc.threads[thread_id].task_event_fd == -1) {
|
||||
/* Always assert on this condition */
|
||||
AssertFatal (0, " eventfd failed: %s!\n", strerror(errno));
|
||||
}
|
||||
|
||||
itti_desc.threads[thread_id].nb_events = 1;
|
||||
|
||||
itti_desc.threads[thread_id].events = calloc(1, sizeof(struct epoll_event));
|
||||
|
||||
itti_desc.threads[thread_id].events->events = EPOLLIN | EPOLLERR;
|
||||
itti_desc.threads[thread_id].events->data.fd = itti_desc.threads[thread_id].task_event_fd;
|
||||
|
||||
/* Add the event fd to the list of monitored events */
|
||||
if (epoll_ctl(itti_desc.threads[thread_id].epoll_fd, EPOLL_CTL_ADD,
|
||||
itti_desc.threads[thread_id].task_event_fd, itti_desc.threads[thread_id].events) != 0) {
|
||||
/* Always assert on this condition */
|
||||
AssertFatal (0, " epoll_ctl (EPOLL_CTL_ADD) failed: %s!\n", strerror(errno));
|
||||
}
|
||||
|
||||
ITTI_DEBUG(ITTI_DEBUG_EVEN_FD, " Successfully subscribed fd %d for thread %d\n",
|
||||
itti_desc.threads[thread_id].task_event_fd, thread_id);
|
||||
|
||||
}
|
||||
|
||||
itti_desc.running = 1;
|
||||
itti_desc.wait_tasks = 0;
|
||||
itti_desc.created_tasks = 0;
|
||||
itti_desc.ready_tasks = 0;
|
||||
CHECK_INIT_RETURN(timer_init ());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void itti_wait_tasks_end(void)
|
||||
{
|
||||
int end = 0;
|
||||
int thread_id;
|
||||
task_id_t task_id;
|
||||
int ready_tasks;
|
||||
int result;
|
||||
int retries = 10;
|
||||
|
||||
itti_desc.thread_handling_signals = TRUE;
|
||||
itti_desc.thread_ref=pthread_self ();
|
||||
|
||||
/* Handle signals here */
|
||||
while (end == 0) {
|
||||
signal_handle (&end);
|
||||
}
|
||||
|
||||
printf("closing all tasks\n");
|
||||
sleep(1);
|
||||
|
||||
do {
|
||||
ready_tasks = 0;
|
||||
|
||||
task_id = TASK_FIRST;
|
||||
|
||||
for (thread_id = THREAD_FIRST; thread_id < itti_desc.thread_max; thread_id++) {
|
||||
/* Skip tasks which are not running */
|
||||
if (itti_desc.threads[thread_id].task_state == TASK_STATE_READY) {
|
||||
while (thread_id != TASK_GET_THREAD_ID(task_id)) {
|
||||
task_id++;
|
||||
}
|
||||
|
||||
result = pthread_tryjoin_np (itti_desc.threads[thread_id].task_thread, NULL);
|
||||
|
||||
ITTI_DEBUG(ITTI_DEBUG_EXIT, " Thread %s join status %d\n", itti_get_task_name(task_id), result);
|
||||
|
||||
if (result == 0) {
|
||||
/* Thread has terminated */
|
||||
itti_desc.threads[thread_id].task_state = TASK_STATE_ENDED;
|
||||
} else {
|
||||
/* Thread is still running, count it */
|
||||
ready_tasks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ready_tasks > 0) {
|
||||
usleep (100 * 1000);
|
||||
}
|
||||
} while ((ready_tasks > 0) && (retries--)&& (!end) );
|
||||
|
||||
printf("ready_tasks %d\n",ready_tasks);
|
||||
|
||||
itti_desc.running = 0;
|
||||
|
||||
if (ready_tasks > 0) {
|
||||
ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Some threads are still running, force exit\n");
|
||||
exit (0);
|
||||
}
|
||||
}
|
||||
|
||||
void itti_send_terminate_message(task_id_t task_id)
|
||||
{
|
||||
MessageDef *terminate_message_p;
|
||||
|
||||
terminate_message_p = itti_alloc_new_message (task_id, TERMINATE_MESSAGE);
|
||||
|
||||
itti_send_broadcast_message (terminate_message_p);
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/** @defgroup _intertask_interface_impl_ Intertask Interface Mechanisms
|
||||
* Implementation
|
||||
* @ingroup _ref_implementation_
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#ifndef INTERTASK_INTERFACE_H_
|
||||
#define INTERTASK_INTERFACE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "intertask_interface_conf.h"
|
||||
#include "intertask_interface_types.h"
|
||||
|
||||
#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))
|
||||
|
||||
/* Make the message number platform specific */
|
||||
typedef unsigned long message_number_t;
|
||||
#define MESSAGE_NUMBER_SIZE (sizeof(unsigned long))
|
||||
|
||||
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;
|
||||
|
||||
typedef struct message_info_s {
|
||||
task_id_t id;
|
||||
message_priorities_t priority;
|
||||
/* Message payload size */
|
||||
MessageHeaderSize size;
|
||||
/* Printable name */
|
||||
const char * const name;
|
||||
} message_info_t;
|
||||
|
||||
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_info_s {
|
||||
thread_id_t thread;
|
||||
task_id_t parent_task;
|
||||
task_priorities_t priority;
|
||||
unsigned int queue_size;
|
||||
/* Printable name */
|
||||
const char * const name;
|
||||
} task_info_t;
|
||||
|
||||
/** \brief Update the itti LTE time reference for messages
|
||||
\param current reference frame
|
||||
\param current reference slot
|
||||
@returns < 0 on failure, 0 otherwise
|
||||
**/
|
||||
void itti_update_lte_time(uint32_t frame, uint8_t slot);
|
||||
|
||||
/** \brief Send a broadcast message to every task
|
||||
\param message_p Pointer to the message to send
|
||||
@returns < 0 on failure, 0 otherwise
|
||||
**/
|
||||
int itti_send_broadcast_message(MessageDef *message_p);
|
||||
|
||||
/** \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);
|
||||
|
||||
/* TODO: this is a hack. Almost no caller of itti_send_msg_to_task checks
|
||||
* the return value so it has been changed to crash the program in case
|
||||
* of failure instead of returning -1 as the documentation above says.
|
||||
* The RLC UM code may receive too much data when doing UDP at a higher
|
||||
* throughput than the link allows and so for this specific case we need
|
||||
* a version that actually returns -1 on failure.
|
||||
*
|
||||
* This needs to be cleaned at some point.
|
||||
*/
|
||||
/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
|
||||
int itti_try_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 Mark the task as a real time task
|
||||
* \param task_id task to mark as real time
|
||||
**/
|
||||
void itti_set_task_real_time(task_id_t task_id);
|
||||
|
||||
/** \brief Indicates to ITTI if newly created tasks should wait for all tasks to be ready
|
||||
* \param wait_tasks non 0 to make new created tasks to wait, 0 to let created tasks to run
|
||||
**/
|
||||
void itti_wait_ready(int wait_tasks);
|
||||
|
||||
/** \brief Mark the task as in ready state
|
||||
* \param task_id task to mark as ready
|
||||
**/
|
||||
void itti_mark_task_ready(task_id_t task_id);
|
||||
|
||||
/** \brief Exit the current task.
|
||||
**/
|
||||
void itti_exit_task(void);
|
||||
|
||||
/** \brief Indicate that the task is completed and initiate termination of all tasks.
|
||||
* \param task_id task that is completed
|
||||
**/
|
||||
void itti_terminate_tasks(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);
|
||||
|
||||
/** \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);
|
||||
|
||||
int itti_free(task_id_t task_id, void *ptr);
|
||||
|
||||
#endif /* INTERTASK_INTERFACE_H_ */
|
||||
/* @} */
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/** @defgroup _intertask_interface_impl_ Intertask Interface Mechanisms
|
||||
* Implementation
|
||||
* @ingroup _ref_implementation_
|
||||
* @{
|
||||
*/
|
||||
|
||||
/********************************************************************************
|
||||
*
|
||||
* !!! This header should only be included by the file that initialize
|
||||
* the intertask interface module for the process !!!
|
||||
*
|
||||
* Other files should include "intertask_interface.h"
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef INTERTASK_INTERFACE_INIT_H_
|
||||
#define INTERTASK_INTERFACE_INIT_H_
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#ifndef CHECK_PROTOTYPE_ONLY
|
||||
|
||||
/* Map task id to printable name. */
|
||||
const task_info_t tasks_info[] = {
|
||||
{0, TASK_UNKNOWN, 0, 0, "TASK_UNKNOWN"},
|
||||
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) { tHREADiD##_THREAD, TASK_UNKNOWN, pRIO, qUEUEsIZE, #tHREADiD },
|
||||
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) { sUBtASKiD##_THREAD, tHREADiD##_THREAD, 0, qUEUEsIZE, #sUBtASKiD },
|
||||
#include <tasks_def.h>
|
||||
#undef SUB_TASK_DEF
|
||||
#undef TASK_DEF
|
||||
};
|
||||
|
||||
/* Map message id to message information */
|
||||
const message_info_t messages_info[] = {
|
||||
#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) { iD, pRIO, sizeof(sTRUCT), #iD },
|
||||
#include <messages_def.h>
|
||||
#undef MESSAGE_DEF
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/** \brief Init function for the intertask interface. Init queues, Mutexes and Cond vars.
|
||||
* \param thread_max Maximum number of threads
|
||||
* \param messages_id_max Maximum message id
|
||||
* \param threads_name Pointer on the threads name information as created by this include file
|
||||
* \param messages_info Pointer on messages information as created by this include file
|
||||
**/
|
||||
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);
|
||||
|
||||
#endif /* INTERTASK_INTERFACE_INIT_H_ */
|
||||
/* @} */
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/** @defgroup _intertask_interface_impl_ Intertask Interface Mechanisms
|
||||
* Implementation
|
||||
* @ingroup _ref_implementation_
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef INTERTASK_INTERFACE_TYPES_H_
|
||||
#define INTERTASK_INTERFACE_TYPES_H_
|
||||
|
||||
#include "itti_types.h"
|
||||
#include "platform_types.h"
|
||||
|
||||
/* Defines to handle bit fields on unsigned long values */
|
||||
#define UL_BIT_MASK(lENGTH) ((1UL << (lENGTH)) - 1UL)
|
||||
#define UL_BIT_SHIFT(vALUE, oFFSET) ((vALUE) << (oFFSET))
|
||||
#define UL_BIT_UNSHIFT(vALUE, oFFSET) ((vALUE) >> (oFFSET))
|
||||
|
||||
#define UL_FIELD_MASK(oFFSET, lENGTH) UL_BIT_SHIFT(UL_BIT_MASK(lENGTH), (oFFSET))
|
||||
#define UL_FIELD_INSERT(vALUE, fIELD, oFFSET, lENGTH) (((vALUE) & (~UL_FIELD_MASK(oFFSET, lENGTH))) | UL_BIT_SHIFT(((fIELD) & UL_BIT_MASK(lENGTH)), oFFSET))
|
||||
#define UL_FIELD_EXTRACT(vALUE, oFFSET, lENGTH) (UL_BIT_UNSHIFT((vALUE), (oFFSET)) & UL_BIT_MASK(lENGTH))
|
||||
|
||||
/* Definitions of task ID fields */
|
||||
#define TASK_THREAD_ID_OFFSET 8
|
||||
#define TASK_THREAD_ID_LENGTH 8
|
||||
|
||||
#define TASK_SUB_TASK_ID_OFFSET 0
|
||||
#define TASK_SUB_TASK_ID_LENGTH 8
|
||||
|
||||
/* Defines to extract task ID fields */
|
||||
#define TASK_GET_THREAD_ID(tASKiD) (itti_desc.tasks_info[tASKiD].thread)
|
||||
#define TASK_GET_PARENT_TASK_ID(tASKiD) (itti_desc.tasks_info[tASKiD].parent_task)
|
||||
/* Extract the instance from a message */
|
||||
#define ITTI_MESSAGE_GET_INSTANCE(mESSAGE) ((mESSAGE)->ittiMsgHeader.instance)
|
||||
|
||||
#include <messages_types.h>
|
||||
|
||||
/* This enum defines messages ids. Each one is unique. */
|
||||
typedef enum {
|
||||
#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) iD,
|
||||
#include <messages_def.h>
|
||||
#undef MESSAGE_DEF
|
||||
|
||||
MESSAGES_ID_MAX,
|
||||
} MessagesIds;
|
||||
|
||||
//! Thread id of each task
|
||||
typedef enum {
|
||||
THREAD_NULL = 0,
|
||||
|
||||
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) THREAD_##tHREADiD,
|
||||
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE)
|
||||
#include <tasks_def.h>
|
||||
#undef SUB_TASK_DEF
|
||||
#undef TASK_DEF
|
||||
|
||||
THREAD_MAX,
|
||||
THREAD_FIRST = 1,
|
||||
} thread_id_t;
|
||||
|
||||
//! Sub-tasks id, to defined offset form thread id
|
||||
typedef enum {
|
||||
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) tHREADiD##_THREAD = THREAD_##tHREADiD,
|
||||
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) sUBtASKiD##_THREAD = THREAD_##tHREADiD,
|
||||
#include <tasks_def.h>
|
||||
#undef SUB_TASK_DEF
|
||||
#undef TASK_DEF
|
||||
} task_thread_id_t;
|
||||
|
||||
//! Tasks id of each task
|
||||
typedef enum {
|
||||
TASK_UNKNOWN = 0,
|
||||
|
||||
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) tHREADiD,
|
||||
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) sUBtASKiD,
|
||||
#include <tasks_def.h>
|
||||
#undef SUB_TASK_DEF
|
||||
#undef TASK_DEF
|
||||
|
||||
TASK_MAX,
|
||||
TASK_FIRST = 1,
|
||||
} task_id_t;
|
||||
|
||||
typedef union msg_s {
|
||||
#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) sTRUCT fIELDnAME;
|
||||
#include <messages_def.h>
|
||||
#undef MESSAGE_DEF
|
||||
} msg_t;
|
||||
|
||||
typedef uint16_t MessageHeaderSize;
|
||||
|
||||
typedef struct itti_lte_time_s {
|
||||
uint32_t frame;
|
||||
uint8_t slot;
|
||||
} itti_lte_time_t;
|
||||
|
||||
/** @struct MessageHeader
|
||||
* @brief Message Header structure for inter-task communication.
|
||||
*/
|
||||
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 */
|
||||
|
||||
MessageHeaderSize ittiMsgSize; /**< Message size (not including header size) */
|
||||
|
||||
itti_lte_time_t lte_time; /**< Reference LTE time */
|
||||
} MessageHeader;
|
||||
|
||||
/** @struct MessageDef
|
||||
* @brief Message structure for inter-task communication.
|
||||
* \internal
|
||||
* The attached attribute \c __packed__ is neccessary, because the memory allocation code expects \ref ittiMsg directly following \ref ittiMsgHeader.
|
||||
*/
|
||||
typedef struct __attribute__ ((__packed__)) MessageDef_s {
|
||||
MessageHeader ittiMsgHeader; /**< Message header */
|
||||
msg_t ittiMsg; /**< Union of payloads as defined in x_messages_def.h headers */
|
||||
} MessageDef;
|
||||
|
||||
#endif /* INTERTASK_INTERFACE_TYPES_H_ */
|
||||
/* @} */
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/* This message asks for task initialization */
|
||||
MESSAGE_DEF(INITIALIZE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, initialize_message)
|
||||
|
||||
/* This message asks for task activation */
|
||||
MESSAGE_DEF(ACTIVATE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, activate_message)
|
||||
|
||||
/* This message asks for task deactivation */
|
||||
MESSAGE_DEF(DEACTIVATE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, deactivate_message)
|
||||
|
||||
/* This message asks for task termination */
|
||||
MESSAGE_DEF(TERMINATE_MESSAGE, MESSAGE_PRIORITY_MAX, IttiMsgEmpty, terminate_message)
|
||||
|
||||
/* Test message used for debug */
|
||||
MESSAGE_DEF(MESSAGE_TEST, MESSAGE_PRIORITY_MED, IttiMsgEmpty, message_test)
|
||||
|
||||
/* Error message */
|
||||
MESSAGE_DEF(ERROR_LOG, MESSAGE_PRIORITY_MAX, IttiMsgEmpty, error_log)
|
||||
/* Warning message */
|
||||
MESSAGE_DEF(WARNING_LOG, MESSAGE_PRIORITY_MAX, IttiMsgEmpty, warning_log)
|
||||
/* Notice message */
|
||||
MESSAGE_DEF(NOTICE_LOG, MESSAGE_PRIORITY_MED, IttiMsgEmpty, notice_log)
|
||||
/* Info message */
|
||||
MESSAGE_DEF(INFO_LOG, MESSAGE_PRIORITY_MED, IttiMsgEmpty, info_log)
|
||||
/* Debug message */
|
||||
MESSAGE_DEF(DEBUG_LOG, MESSAGE_PRIORITY_MED, IttiMsgEmpty, debug_log)
|
||||
|
||||
/* Generic log message for text */
|
||||
MESSAGE_DEF(GENERIC_LOG, MESSAGE_PRIORITY_MED, IttiMsgEmpty, generic_log)
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* intertask_messages_types.h
|
||||
*
|
||||
* Created on: Jan 14, 2014
|
||||
* Author: laurent winckel
|
||||
*/
|
||||
|
||||
#ifndef INTERTASK_MESSAGES_TYPES_H_
|
||||
#define INTERTASK_MESSAGES_TYPES_H_
|
||||
|
||||
typedef struct IttiMsgEmpty_s {
|
||||
} IttiMsgEmpty;
|
||||
|
||||
typedef struct IttiMsgText_s {
|
||||
uint32_t size;
|
||||
char text[];
|
||||
} IttiMsgText;
|
||||
|
||||
#endif /* INTERTASK_MESSAGES_TYPES_H_ */
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/** @brief Intertask Interface common types
|
||||
* Contains type definitions used for generating and parsing ITTI messages.
|
||||
* @author Laurent Winckel <laurent.winckel@eurecom.fr>
|
||||
*/
|
||||
|
||||
#ifndef _ITTI_TYPES_H_
|
||||
#define _ITTI_TYPES_H_
|
||||
|
||||
/* The current file is included in the ue_ip.ko compilation.
|
||||
* For it to work we need to include linux/types.h and
|
||||
* not stdint.h.
|
||||
* A solution to this problem is to use #ifndef __KERNEL__.
|
||||
* Maybe a better solution would be to clean things up
|
||||
* so that ue_ip.ko does not include the current file.
|
||||
*/
|
||||
#ifndef __KERNEL__
|
||||
# include <stdint.h>
|
||||
#else
|
||||
# include <linux/types.h>
|
||||
#endif
|
||||
|
||||
#define CHARS_TO_UINT32(c1, c2, c3, c4) (((c4) << 24) | ((c3) << 16) | ((c2) << 8) | (c1))
|
||||
|
||||
#define MESSAGE_NUMBER_CHAR_FORMAT "%11u"
|
||||
|
||||
/* Intertask message types */
|
||||
enum itti_message_types_e {
|
||||
ITTI_DUMP_XML_DEFINITION = CHARS_TO_UINT32 ('\n', 'I', 'x', 'd'),
|
||||
ITTI_DUMP_XML_DEFINITION_END = CHARS_TO_UINT32 ('i', 'X', 'D', '\n'),
|
||||
|
||||
ITTI_DUMP_MESSAGE_TYPE = CHARS_TO_UINT32 ('\n', 'I', 'm', 's'),
|
||||
ITTI_DUMP_MESSAGE_TYPE_END = CHARS_TO_UINT32 ('i', 'M', 'S', '\n'),
|
||||
|
||||
ITTI_STATISTIC_MESSAGE_TYPE = CHARS_TO_UINT32 ('\n', 'I', 's', 't'),
|
||||
ITTI_STATISTIC_MESSAGE_TYPE_END = CHARS_TO_UINT32 ('i', 'S', 'T', '\n'),
|
||||
|
||||
/* This signal is not meant to be used by remote analyzer */
|
||||
ITTI_DUMP_EXIT_SIGNAL = CHARS_TO_UINT32 ('e', 'X', 'I', 'T'),
|
||||
};
|
||||
|
||||
typedef uint32_t itti_message_types_t;
|
||||
|
||||
/* Message header is the common part that should never change between
|
||||
* remote process and this one.
|
||||
*/
|
||||
typedef struct {
|
||||
/* The size of this structure */
|
||||
uint32_t message_size;
|
||||
itti_message_types_t message_type;
|
||||
} itti_socket_header_t;
|
||||
|
||||
typedef struct {
|
||||
char message_number_char[12]; /* 9 chars are needed to store an unsigned 32 bits value in decimal, but must be a multiple of 32 bits to avoid alignment issues */
|
||||
} itti_signal_header_t;
|
||||
|
||||
|
||||
#define INSTANCE_DEFAULT (UINT16_MAX - 1)
|
||||
#define INSTANCE_ALL (UINT16_MAX)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
// These messages files are mandatory and must always be placed in first position
|
||||
#include "intertask_messages_def.h"
|
||||
#include "timer_messages_def.h"
|
||||
|
||||
// Dummy file for the generic intertask interface definition. Actual definition should be in top level build directory.
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* messages_types.h
|
||||
*
|
||||
* Created on: Oct 14, 2013
|
||||
* Author: winckel
|
||||
*/
|
||||
|
||||
#ifndef MESSAGES_TYPES_H_
|
||||
#define MESSAGES_TYPES_H_
|
||||
|
||||
#include "intertask_messages_types.h"
|
||||
#include "timer_messages_types.h"
|
||||
|
||||
// Dummy file for the generic intertask interface definition. Actual definition should be in top level build directory.
|
||||
|
||||
#endif /* MESSAGES_TYPES_H_ */
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "timer.h"
|
||||
#include "backtrace.h"
|
||||
#include "assertions.h"
|
||||
|
||||
#include "signals.h"
|
||||
#include "log.h"
|
||||
|
||||
#if defined (LOG_D) && defined (LOG_E)
|
||||
# define SIG_DEBUG(x, args...) LOG_D(RRC, x, ##args)
|
||||
# define SIG_ERROR(x, args...) LOG_E(RRC, x, ##args)
|
||||
#endif
|
||||
|
||||
#ifndef SIG_DEBUG
|
||||
# define SIG_DEBUG(x, args...) do { fprintf(stdout, "[SIG][D]"x, ##args); } while(0)
|
||||
#endif
|
||||
#ifndef SIG_ERROR
|
||||
# define SIG_ERROR(x, args...) do { fprintf(stdout, "[SIG][E]"x, ##args); } while(0)
|
||||
#endif
|
||||
|
||||
static sigset_t set;
|
||||
|
||||
int signal_mask(void)
|
||||
{
|
||||
/* We set the signal mask to avoid threads other than the main thread
|
||||
* to receive the timer signal. Note that threads created will inherit this
|
||||
* configuration.
|
||||
*/
|
||||
sigemptyset(&set);
|
||||
|
||||
sigaddset (&set, SIGTIMER);
|
||||
sigaddset (&set, SIGUSR1);
|
||||
sigaddset (&set, SIGABRT);
|
||||
sigaddset (&set, SIGSEGV);
|
||||
sigaddset (&set, SIGINT);
|
||||
|
||||
if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) {
|
||||
perror ("sigprocmask");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int signal_handle(int *end)
|
||||
{
|
||||
int ret;
|
||||
siginfo_t info;
|
||||
|
||||
sigemptyset(&set);
|
||||
|
||||
sigaddset (&set, SIGTIMER);
|
||||
sigaddset (&set, SIGUSR1);
|
||||
sigaddset (&set, SIGABRT);
|
||||
sigaddset (&set, SIGSEGV);
|
||||
sigaddset (&set, SIGINT);
|
||||
|
||||
if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) {
|
||||
perror ("sigprocmask");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Block till a signal is received.
|
||||
* NOTE: The signals defined by set are required to be blocked at the time
|
||||
* of the call to sigwait() otherwise sigwait() is not successful.
|
||||
*/
|
||||
if ((ret = sigwaitinfo(&set, &info)) == -1) {
|
||||
perror ("sigwait");
|
||||
return ret;
|
||||
}
|
||||
|
||||
//printf("Received signal %d\n", info.si_signo);
|
||||
|
||||
/* Real-time signals are non constant and are therefore not suitable for
|
||||
* use in switch.
|
||||
*/
|
||||
if (info.si_signo == SIGTIMER) {
|
||||
timer_handle_signal(&info);
|
||||
} else {
|
||||
/* Dispatch the signal to sub-handlers */
|
||||
switch(info.si_signo) {
|
||||
case SIGUSR1:
|
||||
SIG_DEBUG("Received SIGUSR1\n");
|
||||
*end = 1;
|
||||
break;
|
||||
|
||||
case SIGSEGV: /* Fall through */
|
||||
case SIGABRT:
|
||||
SIG_DEBUG("Received SIGABORT\n");
|
||||
backtrace_handle_signal(&info);
|
||||
break;
|
||||
|
||||
case SIGINT:
|
||||
printf("Received SIGINT\n");
|
||||
itti_send_terminate_message(TASK_UNKNOWN);
|
||||
*end = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
SIG_ERROR("Received unknown signal %d\n", info.si_signo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef SIGNALS_H_
|
||||
#define SIGNALS_H_
|
||||
|
||||
int signal_mask(void);
|
||||
|
||||
int signal_handle(int *end);
|
||||
|
||||
#endif /* SIGNALS_H_ */
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
// This task is mandatory and must always be placed in first position
|
||||
TASK_DEF(TASK_TIMER, TASK_PRIORITY_MED, 10)
|
||||
|
||||
// Dummy file for the generic intertask interface definition. Actual definition should be in top level build directory.
|
||||
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "timer.h"
|
||||
#include "log.h"
|
||||
#include "queue.h"
|
||||
|
||||
#if defined (LOG_D) && defined (LOG_E)
|
||||
# define TMR_DEBUG(x, args...) LOG_D(TMR, x, ##args)
|
||||
# define TMR_ERROR(x, args...) LOG_E(TMR, x, ##args)
|
||||
#endif
|
||||
|
||||
#ifndef TMR_DEBUG
|
||||
# define TMR_DEBUG(x, args...) do { fprintf(stdout, "[TMR][D]"x, ##args); } while(0)
|
||||
#endif
|
||||
#ifndef TMR_ERROR
|
||||
# define TMR_ERROR(x, args...) do { fprintf(stdout, "[TMR][E]"x, ##args); } while(0)
|
||||
#endif
|
||||
|
||||
int timer_handle_signal(siginfo_t *info);
|
||||
|
||||
struct timer_elm_s {
|
||||
task_id_t task_id; ///< Task ID which has requested the timer
|
||||
int32_t instance; ///< Instance of the task which has requested the timer
|
||||
timer_t timer; ///< Unique timer id
|
||||
timer_type_t type; ///< Timer type
|
||||
void *timer_arg; ///< Optional argument that will be passed when timer expires
|
||||
STAILQ_ENTRY(timer_elm_s) entries; ///< Pointer to next element
|
||||
};
|
||||
|
||||
typedef struct timer_desc_s {
|
||||
STAILQ_HEAD(timer_list_head, timer_elm_s) timer_queue;
|
||||
pthread_mutex_t timer_list_mutex;
|
||||
struct timespec timeout;
|
||||
} timer_desc_t;
|
||||
|
||||
static timer_desc_t timer_desc;
|
||||
|
||||
#define TIMER_SEARCH(vAR, tIMERfIELD, tIMERvALUE, tIMERqUEUE) \
|
||||
do { \
|
||||
STAILQ_FOREACH(vAR, tIMERqUEUE, entries) { \
|
||||
if (((vAR)->tIMERfIELD == tIMERvALUE)) \
|
||||
break; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
int timer_handle_signal(siginfo_t *info)
|
||||
{
|
||||
struct timer_elm_s *timer_p;
|
||||
MessageDef *message_p;
|
||||
timer_has_expired_t *timer_expired_p;
|
||||
task_id_t task_id;
|
||||
int32_t instance;
|
||||
|
||||
/* Get back pointer to timer list element */
|
||||
timer_p = (struct timer_elm_s *)info->si_ptr;
|
||||
|
||||
// LG: To many traces for msc timer:
|
||||
TMR_DEBUG("Timer with id 0x%lx has expired\n", (long)timer_p->timer);
|
||||
|
||||
task_id = timer_p->task_id;
|
||||
instance = timer_p->instance;
|
||||
message_p = itti_alloc_new_message(TASK_TIMER, TIMER_HAS_EXPIRED);
|
||||
|
||||
timer_expired_p = &message_p->ittiMsg.timer_has_expired;
|
||||
|
||||
timer_expired_p->timer_id = (long)timer_p->timer;
|
||||
timer_expired_p->arg = timer_p->timer_arg;
|
||||
|
||||
/* Timer is a one shot timer, remove it */
|
||||
if (timer_p->type == TIMER_ONE_SHOT) {
|
||||
// if (timer_delete(timer_p->timer) < 0) {
|
||||
// TMR_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer);
|
||||
// }
|
||||
// TMR_DEBUG("Removed timer 0x%lx\n", (long)timer_p->timer);
|
||||
// pthread_mutex_lock(&timer_desc.timer_list_mutex);
|
||||
// STAILQ_REMOVE(&timer_desc.timer_queue, timer_p, timer_elm_s, entries);
|
||||
// pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
||||
// free(timer_p);
|
||||
// timer_p = NULL;
|
||||
if (timer_remove((long)timer_p->timer) != 0) {
|
||||
TMR_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer);
|
||||
}
|
||||
}
|
||||
|
||||
/* Notify task of timer expiry */
|
||||
if (itti_send_msg_to_task(task_id, instance, message_p) < 0) {
|
||||
TMR_DEBUG("Failed to send msg TIMER_HAS_EXPIRED to task %u\n", task_id);
|
||||
free(message_p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(ENB_AGENT_SB_IF)
|
||||
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
struct sigevent se;
|
||||
struct itimerspec its;
|
||||
struct timer_elm_s *timer_p;
|
||||
timer_t timer;
|
||||
|
||||
if (timer_id == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
AssertFatal (type < TIMER_TYPE_MAX, "Invalid timer type (%d/%d)!\n", type, TIMER_TYPE_MAX);
|
||||
|
||||
/* Allocate new timer list element */
|
||||
timer_p = malloc(sizeof(struct timer_elm_s));
|
||||
|
||||
if (timer_p == NULL) {
|
||||
TMR_ERROR("Failed to create new timer element\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&timer, 0, sizeof(timer_t));
|
||||
memset(&se, 0, sizeof(struct sigevent));
|
||||
|
||||
timer_p->task_id = task_id;
|
||||
timer_p->instance = instance;
|
||||
timer_p->type = type;
|
||||
timer_p->timer_arg = timer_arg;
|
||||
|
||||
/* Setting up alarm */
|
||||
/* Set and enable alarm */
|
||||
se.sigev_notify = SIGEV_SIGNAL;
|
||||
se.sigev_signo = SIGTIMER;
|
||||
se.sigev_value.sival_ptr = timer_p;
|
||||
|
||||
/* At the timer creation, the timer structure will be filled in with timer_id,
|
||||
* which is unique for this process. This id is allocated by kernel and the
|
||||
* value might be used to distinguish timers.
|
||||
*/
|
||||
if (timer_create(CLOCK_REALTIME, &se, &timer) < 0) {
|
||||
TMR_ERROR("Failed to create timer: (%s:%d)\n", strerror(errno), errno);
|
||||
free(timer_p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Fill in the first expiration value. */
|
||||
its.it_value.tv_sec = interval_sec;
|
||||
its.it_value.tv_nsec = interval_us * 1000;
|
||||
|
||||
if (type == TIMER_PERIODIC) {
|
||||
/* Asked for periodic timer. We set the interval time */
|
||||
its.it_interval.tv_sec = interval_sec;
|
||||
its.it_interval.tv_nsec = interval_us * 1000;
|
||||
} else {
|
||||
/* Asked for one-shot timer. Do not set the interval field */
|
||||
its.it_interval.tv_sec = 0;
|
||||
its.it_interval.tv_nsec = 0;
|
||||
}
|
||||
|
||||
timer_settime(timer, 0, &its, NULL);
|
||||
/* Simply set the timer_id argument. so it can be used by caller */
|
||||
*timer_id = (long)timer;
|
||||
TMR_DEBUG("Requesting new %s timer with id 0x%lx that expires within "
|
||||
"%d sec and %d usec\n",
|
||||
type == TIMER_PERIODIC ? "periodic" : "single shot",
|
||||
*timer_id, interval_sec, interval_us);
|
||||
|
||||
timer_p->timer = timer;
|
||||
|
||||
/* Lock the queue and insert the timer at the tail */
|
||||
pthread_mutex_lock(&timer_desc.timer_list_mutex);
|
||||
STAILQ_INSERT_TAIL(&timer_desc.timer_queue, timer_p, entries);
|
||||
pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_remove(long timer_id)
|
||||
{
|
||||
int rc = 0;
|
||||
struct timer_elm_s *timer_p;
|
||||
|
||||
TMR_DEBUG("Removing timer 0x%lx\n", timer_id);
|
||||
|
||||
pthread_mutex_lock(&timer_desc.timer_list_mutex);
|
||||
TIMER_SEARCH(timer_p, timer, ((timer_t)timer_id), &timer_desc.timer_queue);
|
||||
|
||||
/* We didn't find the timer in list */
|
||||
if (timer_p == NULL) {
|
||||
pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
||||
TMR_ERROR("Didn't find timer 0x%lx in list\n", timer_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
STAILQ_REMOVE(&timer_desc.timer_queue, timer_p, timer_elm_s, entries);
|
||||
pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
||||
|
||||
if (timer_delete(timer_p->timer) < 0) {
|
||||
TMR_ERROR("Failed to delete timer 0x%lx\n", (long)timer_p->timer);
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
free(timer_p);
|
||||
timer_p = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
TMR_DEBUG("Initializing TIMER task interface\n");
|
||||
|
||||
memset(&timer_desc, 0, sizeof(timer_desc_t));
|
||||
|
||||
STAILQ_INIT(&timer_desc.timer_queue);
|
||||
pthread_mutex_init(&timer_desc.timer_list_mutex, NULL);
|
||||
|
||||
TMR_DEBUG("Initializing TIMER task interface: DONE\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef TIMER_H_
|
||||
#define TIMER_H_
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#define SIGTIMER SIGRTMIN
|
||||
|
||||
typedef enum timer_type_s {
|
||||
TIMER_PERIODIC,
|
||||
TIMER_ONE_SHOT,
|
||||
TIMER_TYPE_MAX,
|
||||
} timer_type_t;
|
||||
|
||||
int timer_handle_signal(siginfo_t *info);
|
||||
|
||||
/** \brief Request a new timer
|
||||
* \param interval_sec timer interval in seconds
|
||||
* \param interval_us timer interval in micro seconds
|
||||
* \param task_id task id of the task requesting the timer
|
||||
* \param instance instance of the task requesting the timer
|
||||
* \param type timer type
|
||||
* \param timer_id unique timer identifier
|
||||
* @returns -1 on failure, 0 otherwise
|
||||
**/
|
||||
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);
|
||||
|
||||
/** \brief Remove the timer from list
|
||||
* \param timer_id unique timer id
|
||||
* @returns -1 on failure, 0 otherwise
|
||||
**/
|
||||
|
||||
int timer_remove(long timer_id);
|
||||
#define timer_stop timer_remove
|
||||
|
||||
/** \brief Initialize timer task and its API
|
||||
* \param mme_config MME common configuration
|
||||
* @returns -1 on failure, 0 otherwise
|
||||
**/
|
||||
int timer_init(void);
|
||||
|
||||
#endif
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
MESSAGE_DEF(TIMER_HAS_EXPIRED, MESSAGE_PRIORITY_MED_PLUS, timer_has_expired_t, timer_has_expired)
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef TIMER_MESSAGES_TYPES_H_
|
||||
#define TIMER_MESSAGES_TYPES_H_
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// Defines to access message fields.
|
||||
#define TIMER_HAS_EXPIRED(mSGpTR) (mSGpTR)->ittiMsg.timer_has_expired
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
typedef struct {
|
||||
void *arg;
|
||||
long timer_id;
|
||||
} timer_has_expired_t;
|
||||
|
||||
#endif /* TIMER_MESSAGES_TYPES_H_ */
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
#include "liblfds611.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "msc.h"
|
||||
#include "assertions.h"
|
||||
|
||||
@@ -33,10 +33,10 @@
|
||||
#include "PHY/defs_eNB.h"
|
||||
#include "PHY/TOOLS/alaw_lut.h"
|
||||
|
||||
#include "time_utils.h"
|
||||
|
||||
//#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
|
||||
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
|
||||
#include <intertask_interface.h>
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
//#define DEBUG_DL_MOBIPASS
|
||||
//#define DEBUG_UL_MOBIPASS
|
||||
|
||||
@@ -33,7 +33,9 @@
|
||||
#define __PHY_DEFS_COMMON_H__
|
||||
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "SCHED/defs.h"
|
||||
#include "SCHED/vars.h"
|
||||
#include "LAYER2/MAC/vars.h"
|
||||
#include "intertask_interface_init.h"
|
||||
|
||||
#include "OCG_vars.h"
|
||||
#include "UTIL/LOG/log_extern.h"
|
||||
|
||||
@@ -34,9 +34,6 @@
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
#include "itti_types.h"
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
// GENERIC TYPES
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
# include "intertask_interface.h"
|
||||
# include "timer.h"
|
||||
# if defined(ENABLE_USE_MME)
|
||||
# include "s1ap_eNB.h"
|
||||
# include "sctp_eNB_task.h"
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
#else
|
||||
#include "RRC/LTE/MESSAGES/SystemInformationBlockType2.h"
|
||||
#endif
|
||||
#include "intertask_interface_types.h"
|
||||
#include "RRC/LTE/rrc_defs.h"
|
||||
|
||||
#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
|
||||
# include "tree.h"
|
||||
# include "intertask_interface.h"
|
||||
# include "timer.h"
|
||||
|
||||
#define FLEXRAN_VERSION 0
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
|
||||
# include "tree.h"
|
||||
# include "intertask_interface.h"
|
||||
# include "timer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -32,12 +32,17 @@
|
||||
# define __MEM_BLOCK_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "openair2/COMMON/platform_constants.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef struct mem_block_t {
|
||||
struct mem_block_t *next;
|
||||
struct mem_block_t *previous;
|
||||
size_t size;
|
||||
unsigned char pool_id;
|
||||
unsigned char *data;
|
||||
} mem_block_t;
|
||||
@@ -175,5 +180,7 @@ typedef struct {
|
||||
|
||||
mem_pool mem_block_var;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
|
||||
#include "assertions.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "timer.h"
|
||||
#include "msc.h"
|
||||
|
||||
#include "gtpv1u.h"
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#ifndef GTPV1U_ENB_TASK_H_
|
||||
#define GTPV1U_ENB_TASK_H_
|
||||
|
||||
#include "messages_types.h"
|
||||
|
||||
/*
|
||||
int
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
#include "assertions.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "gtpv1u.h"
|
||||
#include "NwGtpv1u.h"
|
||||
|
||||
@@ -46,7 +46,6 @@ Description Timer utilities
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
# include "intertask_interface.h"
|
||||
# include "timer.h"
|
||||
#else
|
||||
# include <signal.h>
|
||||
# include <time.h> // clock_gettime
|
||||
|
||||
@@ -46,8 +46,6 @@
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
#include "intertask_interface_init.h"
|
||||
#include "timer.h"
|
||||
#include "assertions.h"
|
||||
#include "s1ap_common.h"
|
||||
#include "intertask_interface.h"
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include "play_scenario.h"
|
||||
#include "s1ap_ies_defs.h"
|
||||
#include "play_scenario_s1ap_eNB_defs.h"
|
||||
#include "timer.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
extern int g_max_speed;
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "timer.h"
|
||||
#include "platform_types.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "timer.h"
|
||||
#include "platform_types.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
|
||||
@@ -32,13 +32,12 @@
|
||||
#include "mme_config.h"
|
||||
#include "gtpv1u_sgw_defs.h"
|
||||
|
||||
#include "intertask_interface_init.h"
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "sctp_primitives_server.h"
|
||||
#include "udp_primitives_server.h"
|
||||
#include "s1ap_mme.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "sgw_lite_defs.h"
|
||||
#include "ipv4_defs.h"
|
||||
|
||||
|
||||
@@ -40,9 +40,7 @@
|
||||
|
||||
#include "UTIL/LOG/log_extern.h"
|
||||
#include "assertions.h"
|
||||
#include "intertask_interface_init.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "timer.h"
|
||||
#include "sctp_eNB_task.h"
|
||||
#include "s1ap_eNB.h"
|
||||
#include "enb_config.h"
|
||||
|
||||
@@ -276,7 +276,7 @@ void udp_eNB_receiver(struct udp_socket_desc_s *udp_sock_pP)
|
||||
* if the queue is full.
|
||||
*/
|
||||
/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
|
||||
if (itti_try_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) {
|
||||
if (itti_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) {
|
||||
LOG_E(UDP_, "Failed to send message %d to task %d\n",
|
||||
UDP_DATA_IND,
|
||||
udp_sock_pP->task_id);
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#ifndef UDP_ENB_TASK_H_
|
||||
#define UDP_ENB_TASK_H_
|
||||
#include "enb_config.h"
|
||||
#include "intertask_interface_types.h"
|
||||
|
||||
|
||||
/** \brief UDP recv callback prototype. Will be called every time a payload is
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <pthread.h>
|
||||
|
||||
#include "time_utils.h"
|
||||
|
||||
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||
|
||||
|
||||
@@ -83,7 +83,6 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
#include "intertask_interface_init.h"
|
||||
#include "create_tasks.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
#include "intertask_interface_init.h"
|
||||
#include "create_tasks.h"
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user