diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index c795ec6f4aa3610cfbc0d54edfd354b3e25f9a5b..05ea37082b838ca74f554a0bcded2f11197d7ff0 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -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) @@ -754,11 +752,14 @@ 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") include_directories("${OPENAIR3_DIR}/NAS/COMMON/ESM/MSG") +include_directories("${OPENAIR3_DIR}/NAS/UE/ESM") +include_directories("${OPENAIR3_DIR}/NAS/UE/EMM") +include_directories("${OPENAIR3_DIR}/NAS/UE/API/USER") include_directories("${OPENAIR3_DIR}/NAS/COMMON/IES") include_directories("${OPENAIR3_DIR}/NAS/COMMON/UTIL") include_directories("${OPENAIR3_DIR}/SECU") diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index c9b1c32378f8a9276369151898b5188f0c5be9a8..2e6b21dea4cd0bbc91b109dc5514351a64947b67 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -35,6 +35,7 @@ #include <stdio.h> #include <ctype.h> #include <errno.h> +#include <platform_types.h> #include "config_userapi.h" diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 3f3651aa011d7743a342ded3550e87eb11a3efc1..57a680044b1c772382f1d6a5fec30bda4e6a3e10 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -37,8 +37,8 @@ #include <dlfcn.h> #include <arpa/inet.h> +#include <platform_types.h> #include "config_userapi.h" -extern void exit_fun(const char* s); // lte-softmodem clean exit function configmodule_interface_t *config_get_if(void) diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index 217310db36ee4c71fdbbe811361c5b2304080354..25306b8778d844f70db17826d14e26fccc72b35d 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -38,8 +38,6 @@ extern "C" { #endif -/* get rid of "exit_fun undeclared" warning */ -extern void exit_fun(const char* s); #define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode ) #define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP ) diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index 607fe857031ca1a06ea747bae8e1b36d26396c11..666bf46d44135b7a6cb233032426e24f438e38f1 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -44,7 +44,6 @@ #include <unistd.h> #include "assertions.h" -#include "signals.h" #include "vcd_signal_dumper.h" diff --git a/common/utils/assertions.h b/common/utils/assertions.h index f6728caf7bb5ee213b4f1c8b175c911d92a8962d..b872b009e258408e799f6dfaaf0cc2697c1913f4 100644 --- a/common/utils/assertions.h +++ b/common/utils/assertions.h @@ -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_ */ diff --git a/common/utils/itti/backtrace.c b/common/utils/backtrace.c similarity index 100% rename from common/utils/itti/backtrace.c rename to common/utils/backtrace.c diff --git a/common/utils/itti/backtrace.h b/common/utils/backtrace.h similarity index 100% rename from common/utils/itti/backtrace.h rename to common/utils/backtrace.h diff --git a/common/utils/itti/Makefile.am b/common/utils/itti/Makefile.am deleted file mode 100644 index 93f57046032a3db9fea32c30b12488a59da1e0c2..0000000000000000000000000000000000000000 --- a/common/utils/itti/Makefile.am +++ /dev/null @@ -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 diff --git a/common/utils/itti/assertions.h b/common/utils/itti/assertions.h deleted file mode 100644 index b872b009e258408e799f6dfaaf0cc2697c1913f4..0000000000000000000000000000000000000000 --- a/common/utils/itti/assertions.h +++ /dev/null @@ -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_ */ diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c deleted file mode 100644 index d088b59c041b8abeaf2408f0369a98588574537a..0000000000000000000000000000000000000000 --- a/common/utils/itti/intertask_interface.c +++ /dev/null @@ -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_VARIABLES_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); -} diff --git a/common/utils/itti/intertask_interface.h b/common/utils/itti/intertask_interface.h deleted file mode 100644 index ada34ce1b722a09722373cc5a650870364891b4e..0000000000000000000000000000000000000000 --- a/common/utils/itti/intertask_interface.h +++ /dev/null @@ -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_ */ -/* @} */ diff --git a/common/utils/itti/intertask_interface_init.h b/common/utils/itti/intertask_interface_init.h deleted file mode 100644 index dbd4e1b2ec061c2a0e334c9a8c5e80dae0b51964..0000000000000000000000000000000000000000 --- a/common/utils/itti/intertask_interface_init.h +++ /dev/null @@ -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_ */ -/* @} */ diff --git a/common/utils/itti/intertask_interface_types.h b/common/utils/itti/intertask_interface_types.h deleted file mode 100644 index af1b4e9aa98931b52de2cea454f720e13748171a..0000000000000000000000000000000000000000 --- a/common/utils/itti/intertask_interface_types.h +++ /dev/null @@ -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_ */ -/* @} */ diff --git a/common/utils/itti/intertask_messages_def.h b/common/utils/itti/intertask_messages_def.h deleted file mode 100644 index 57c344c8132b5b4f216ab4c5e05f25c48c8ea73e..0000000000000000000000000000000000000000 --- a/common/utils/itti/intertask_messages_def.h +++ /dev/null @@ -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) diff --git a/common/utils/itti/intertask_messages_types.h b/common/utils/itti/intertask_messages_types.h deleted file mode 100644 index 145f57648ffcd62288d501ac49182652465ea72d..0000000000000000000000000000000000000000 --- a/common/utils/itti/intertask_messages_types.h +++ /dev/null @@ -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_ */ diff --git a/common/utils/itti/itti_types.h b/common/utils/itti/itti_types.h deleted file mode 100644 index 2607c003b130f1d261923c6ebae21cec657d42b0..0000000000000000000000000000000000000000 --- a/common/utils/itti/itti_types.h +++ /dev/null @@ -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 - diff --git a/common/utils/itti/messages_def.h b/common/utils/itti/messages_def.h deleted file mode 100644 index f312669848120a2ea022a4ac50ad172471e51ce4..0000000000000000000000000000000000000000 --- a/common/utils/itti/messages_def.h +++ /dev/null @@ -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. diff --git a/common/utils/itti/messages_types.h b/common/utils/itti/messages_types.h deleted file mode 100644 index d390bf0159c18ab58767e44f467fe2b4019c667b..0000000000000000000000000000000000000000 --- a/common/utils/itti/messages_types.h +++ /dev/null @@ -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_ */ diff --git a/common/utils/itti/signals.c b/common/utils/itti/signals.c deleted file mode 100644 index f8dfe2d49bb97071c9f28dab06838b92b10d83e4..0000000000000000000000000000000000000000 --- a/common/utils/itti/signals.c +++ /dev/null @@ -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 "common/utils/LOG/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; -} diff --git a/common/utils/itti/signals.h b/common/utils/itti/signals.h deleted file mode 100644 index 5277e216a3d4a19230991d2f8eafdb86abfd2d16..0000000000000000000000000000000000000000 --- a/common/utils/itti/signals.h +++ /dev/null @@ -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_ */ diff --git a/common/utils/itti/tasks_def.h b/common/utils/itti/tasks_def.h deleted file mode 100644 index d54d09a26aee84822bb4714ab0857869682f1da5..0000000000000000000000000000000000000000 --- a/common/utils/itti/tasks_def.h +++ /dev/null @@ -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. diff --git a/common/utils/itti/timer.c b/common/utils/itti/timer.c deleted file mode 100644 index 720cf70d1f428b8457bd5bf648480155d5c0c67f..0000000000000000000000000000000000000000 --- a/common/utils/itti/timer.c +++ /dev/null @@ -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 "common/utils/LOG/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; -} diff --git a/common/utils/itti/timer.h b/common/utils/itti/timer.h deleted file mode 100644 index 4f568a348c5755802f7fadb018d8b2790935b608..0000000000000000000000000000000000000000 --- a/common/utils/itti/timer.h +++ /dev/null @@ -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 diff --git a/common/utils/itti/timer_messages_def.h b/common/utils/itti/timer_messages_def.h deleted file mode 100644 index 761034730d236136692f3d879aa44f252acc205c..0000000000000000000000000000000000000000 --- a/common/utils/itti/timer_messages_def.h +++ /dev/null @@ -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) diff --git a/common/utils/itti/timer_messages_types.h b/common/utils/itti/timer_messages_types.h deleted file mode 100644 index 0d06e3eebfd15c33e9fe9555b0ba7fb5c6253fb0..0000000000000000000000000000000000000000 --- a/common/utils/itti/timer_messages_types.h +++ /dev/null @@ -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_ */ diff --git a/common/utils/itti/memory_pools.c b/common/utils/memory_pools.c similarity index 100% rename from common/utils/itti/memory_pools.c rename to common/utils/memory_pools.c diff --git a/common/utils/itti/memory_pools.h b/common/utils/memory_pools.h similarity index 100% rename from common/utils/itti/memory_pools.h rename to common/utils/memory_pools.h diff --git a/common/utils/msc/msc.c b/common/utils/msc/msc.c index 8ff8846b70de9fc5bbfc999d0df0dfe58ae75a50..4c9e3827b069ee20ced71cbb6304533551c3e937 100644 --- a/common/utils/msc/msc.c +++ b/common/utils/msc/msc.c @@ -37,7 +37,6 @@ #include "liblfds611.h" #include "intertask_interface.h" -#include "timer.h" diff --git a/common/utils/ocp_itti/all_msg.h b/common/utils/ocp_itti/all_msg.h new file mode 100644 index 0000000000000000000000000000000000000000..e296502909592e8bcd8e6484391ad11af5421b49 --- /dev/null +++ b/common/utils/ocp_itti/all_msg.h @@ -0,0 +1,14 @@ +#include "openair2/COMMON/phy_messages_def.h" +#include "openair2/COMMON/mac_messages_def.h" +#include "openair2/COMMON/rlc_messages_def.h" +#include "openair2/COMMON/pdcp_messages_def.h" +#include "openair2/COMMON/rrc_messages_def.h" +#include "openair2/COMMON/nas_messages_def.h" +#if ENABLE_RAL + #include "openair2/COMMON/ral_messages_def.h" +#endif +#include "openair2/COMMON/s1ap_messages_def.h" +#include "openair2/COMMON/x2ap_messages_def.h" +#include "openair2/COMMON/sctp_messages_def.h" +#include "openair2/COMMON/udp_messages_def.h" +#include "openair2/COMMON/gtpv1_u_messages_def.h" diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..931eb40c0fc04a1798d51cc40ec207837e5688d0 --- /dev/null +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -0,0 +1,396 @@ +/* + Author: Laurent THOMAS, Open Cells + copyleft: OpenAirInterface Software Alliance and it's licence +*/ +#include <vector> +#include <map> +#include <sys/eventfd.h> + + +#include <intertask_interface.h> + +typedef struct timer_elm_s { + timer_type_t type; ///< Timer type + long instance; + long duration; + uint64_t timeout; + void *timer_arg; ///< Optional argument that will be passed when timer expires +} timer_elm_t ; + +typedef struct task_list_s { + task_info_t admin; + pthread_t thread; + pthread_mutex_t queue_cond_lock; + std::vector<MessageDef *> message_queue; + std::map<long,timer_elm_t> timer_map; + uint64_t next_timer=UINT64_MAX; + struct epoll_event *events =NULL; + int nb_fd_epoll=0; + int nb_events=0; + int epoll_fd=-1; + int sem_fd=-1; +} task_list_t; + +int timer_expired(int fd); +task_list_t tasks[TASK_MAX]; + +extern "C" { + void *pool_buffer_init (void) { + return 0; + } + + void *pool_buffer_clean (void *arg) { + //----------------------------------------------------------------------------- + return 0; + } + + void free_mem_block (mem_block_t *leP, const char *caller) { + AssertFatal(leP!=NULL,""); + free(leP); + } + + mem_block_t *get_free_mem_block (uint32_t sizeP, const char *caller) { + mem_block_t *ptr=(mem_block_t *)malloc(sizeP+sizeof(mem_block_t)); + ptr->next = NULL; + ptr->previous = NULL; + ptr->data=((unsigned char *)ptr)+sizeof(mem_block_t); + ptr->size=sizeP; + return ptr; + } + + void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize_t size) { + void *ptr = NULL; + AssertFatal ((ptr=malloc (size)) != NULL, "Memory allocation of %zu bytes failed (%d -> %d)!\n", + size, origin_task_id, destination_task_id); + return ptr; + } + + int itti_free(task_id_t task_id, void *ptr) { + AssertFatal (ptr != NULL, "Trying to free a NULL pointer (%d)!\n", task_id); + free (ptr); + return (EXIT_SUCCESS); + } + + MessageDef *itti_alloc_new_message_sized(task_id_t origin_task_id, MessagesIds message_id, MessageHeaderSize size) { + MessageDef *temp = (MessageDef *)itti_malloc (origin_task_id, TASK_UNKNOWN, sizeof(MessageHeader) + size); + temp->ittiMsgHeader.messageId = message_id; + temp->ittiMsgHeader.originTaskId = origin_task_id; + temp->ittiMsgHeader.ittiMsgSize = size; + return temp; + } + + MessageDef *itti_alloc_new_message(task_id_t origin_task_id, MessagesIds message_id) { + int size=sizeof(MessageHeader) + messages_info[message_id].size; + MessageDef *temp = (MessageDef *)itti_malloc (origin_task_id, TASK_UNKNOWN, size); + temp->ittiMsgHeader.messageId = message_id; + temp->ittiMsgHeader.originTaskId = origin_task_id; + temp->ittiMsgHeader.ittiMsgSize = size; + return temp; + //return itti_alloc_new_message_sized(origin_task_id, message_id, messages_info[message_id].size); + } + + static inline int itti_send_msg_to_task_locked(task_id_t destination_task_id, instance_t instance, MessageDef *message) { + task_list_t *t=tasks+destination_task_id; + message->ittiMsgHeader.destinationTaskId = destination_task_id; + message->ittiMsgHeader.instance = instance; + message->ittiMsgHeader.lte_time.frame = 0; + message->ittiMsgHeader.lte_time.slot = 0; + int message_id = message->ittiMsgHeader.messageId; + size_t s=t->message_queue.size(); + + if ( s > t->admin.queue_size ) + LOG_E(TMR,"Queue for %s task contains %ld messages\n", itti_get_task_name(destination_task_id), s ); + + if ( s > 50 ) + LOG_I(TMR,"Queue for %s task size: %ld\n",itti_get_task_name(destination_task_id), s+1); + + t->message_queue.insert(t->message_queue.begin(), message); + eventfd_t sem_counter = 1; + AssertFatal ( sizeof(sem_counter) == write(t->sem_fd, &sem_counter, sizeof(sem_counter)), ""); + LOG_D(TMR,"sent messages id=%d to %s\n",message_id, t->admin.name); + return 0; + } + + int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message) { + task_list_t *t=&tasks[destination_task_id]; + pthread_mutex_lock (&t->queue_cond_lock); + int ret=itti_send_msg_to_task_locked(destination_task_id, instance, message); + pthread_mutex_unlock (&t->queue_cond_lock); + + while ( t->message_queue.size()>0 && t->admin.func != NULL ) + t->admin.func(NULL); + + return ret; + } + + void itti_subscribe_event_fd(task_id_t task_id, int fd) { + struct epoll_event event; + task_list_t *t=&tasks[task_id]; + t->nb_fd_epoll++; + t->events = (struct epoll_event *)realloc((void *)t->events, + t->nb_fd_epoll * sizeof(struct epoll_event)); + event.events = EPOLLIN | EPOLLERR; + event.data.u64 = 0; + event.data.fd = fd; + AssertFatal(epoll_ctl(t->epoll_fd, EPOLL_CTL_ADD, fd, &event) == 0, + "epoll_ctl (EPOLL_CTL_ADD) failed for task %s, fd %d: %s!\n", + itti_get_task_name(task_id), fd, strerror(errno)); + } + + void itti_unsubscribe_event_fd(task_id_t task_id, int fd) { + task_list_t *t=&tasks[task_id]; + AssertFatal (epoll_ctl(t->epoll_fd, EPOLL_CTL_DEL, fd, NULL) == 0, + "epoll_ctl (EPOLL_CTL_DEL) failed for task %s, fd %d: %s!\n", + itti_get_task_name(task_id), fd, strerror(errno)); + t->nb_fd_epoll--; + } + + static inline int itti_get_events_locked(task_id_t task_id, struct epoll_event **events) { + task_list_t *t=&tasks[task_id]; + uint64_t current_time=0; + + do { + if ( t->next_timer != UINT64_MAX ) { + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC, &tp); + current_time=(uint64_t)tp.tv_sec*1000+tp.tv_nsec/(1000*1000); + + if ( t->next_timer < current_time) { + t->next_timer=UINT64_MAX; + + // Proceed expired timer + for ( auto it=t->timer_map.begin() ; it != t->timer_map.end() ; ++it ) { + if ( it->second.timeout < current_time ) { + MessageDef *message = itti_alloc_new_message(TASK_TIMER, TIMER_HAS_EXPIRED); + message->ittiMsg.timer_has_expired.timer_id=it->first; + message->ittiMsg.timer_has_expired.arg=it->second.timer_arg; + + if (itti_send_msg_to_task_locked(task_id, it->second.instance, message) < 0) { + LOG_W(TMR,"Failed to send msg TIMER_HAS_EXPIRED to task %u\n", task_id); + free(message); + t->timer_map.erase(it); + return -1; + } + + if ( it->second.type==TIMER_PERIODIC ) { + it->second.timeout+=it->second.duration; + + if (it->second.timeout < t->next_timer) + t->next_timer=it->second.timeout; + } else + t->timer_map.erase(it); + } else if (it->second.timeout < t->next_timer) + t->next_timer=it->second.timeout; + } + } + } + + int epoll_timeout = -1; + + if ( t->next_timer != UINT64_MAX ) + epoll_timeout = t->next_timer-current_time; + + pthread_mutex_unlock(&t->queue_cond_lock); + LOG_D(TMR,"enter blocking wait for %s\n", itti_get_task_name(task_id)); + t->nb_events = epoll_wait(t->epoll_fd,t->events,t->nb_fd_epoll, epoll_timeout); + } while (t->nb_events < 0 && (errno == EINTR || errno == EAGAIN ) ); + + AssertFatal (t->nb_events >=0, + "epoll_wait failed for task %s, nb fds %d, timeout %lu: %s!\n", + itti_get_task_name(task_id), t->nb_fd_epoll, t->next_timer != UINT64_MAX ? t->next_timer-current_time : -1, strerror(errno)); + LOG_D(TMR,"receive on %d descriptors for %s\n", t->nb_events, itti_get_task_name(task_id)); + + if (t->nb_events == 0) + /* No data to read -> return */ + return 0; + + for (int i = 0; i < t->nb_events; i++) { + /* Check if there is an event for ITTI for the event fd */ + if ((t->events[i].events & EPOLLIN) && + (t->events[i].data.fd == t->sem_fd)) { + eventfd_t sem_counter; + /* Read will always return 1 */ + AssertFatal( sizeof(sem_counter) == read (t->sem_fd, &sem_counter, sizeof(sem_counter)), ""); + /* Mark that the event has been processed */ + t->events[i].events &= ~EPOLLIN; + } + } + + *events = t->events; + return t->nb_events; + } + + int itti_get_events(task_id_t task_id, struct epoll_event **events) { + pthread_mutex_lock(&tasks[task_id].queue_cond_lock); + return itti_get_events_locked(task_id, events); + } + + void itti_receive_msg(task_id_t task_id, MessageDef **received_msg) { + // Reception of one message, blocking caller + task_list_t *t=&tasks[task_id]; + pthread_mutex_lock(&t->queue_cond_lock); + + // Weird condition to deal with crap legacy itti interface + if ( t->nb_fd_epoll == 1 ) { + while (t->message_queue.empty()) { + itti_get_events_locked(task_id, &t->events); + pthread_mutex_lock(&t->queue_cond_lock); + } + } else { + if (t->message_queue.empty()) { + itti_get_events_locked(task_id, &t->events); + pthread_mutex_lock(&t->queue_cond_lock); + } + } + + // Legacy design: we return even if we have no message + // in this case, *received_msg is NULL + if (t->message_queue.empty()) { + *received_msg=NULL; + LOG_D(TMR,"task %s received even from other fd (total fds: %d), returning msg NULL\n",t->admin.name, t->nb_fd_epoll); + } else { + *received_msg=t->message_queue.back(); + t->message_queue.pop_back(); + LOG_D(TMR,"task %s received a message\n",t->admin.name); + } + + pthread_mutex_unlock (&t->queue_cond_lock); + } + + void itti_poll_msg(task_id_t task_id, MessageDef **received_msg) { + //reception of one message, non-blocking + task_list_t *t=&tasks[task_id]; + pthread_mutex_lock(&t->queue_cond_lock); + + if (!t->message_queue.empty()) { + LOG_D(TMR,"task %s received a message in polling mode\n",t->admin.name); + *received_msg=t->message_queue.back(); + t->message_queue.pop_back(); + } else + *received_msg=NULL; + + pthread_mutex_unlock (&t->queue_cond_lock); + } + + int itti_create_task(task_id_t task_id, void *(*start_routine)(void *), void *args_p) { + task_list_t *t=&tasks[task_id]; + AssertFatal ( pthread_create (&t->thread, NULL, start_routine, args_p) ==0, + "Thread creation for task %d failed!\n", task_id); + pthread_setname_np( t->thread, itti_get_task_name(task_id) ); + LOG_I(TMR,"Created Posix thread %s\n", itti_get_task_name(task_id) ); + return 0; + } + + void itti_exit_task(void) { + pthread_exit (NULL); + } + + void itti_terminate_tasks(task_id_t task_id) { + // Sends Terminate signals to all tasks. + itti_send_terminate_message (task_id); + usleep(100*1000); // Allow the tasks to receive the message before going returning to main thread + } + + int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_id_max, const task_info_t *tasks_info, + const message_info_t *messages_info) { + AssertFatal(TASK_MAX<UINT16_MAX, "Max itti tasks"); + + for(int i=0; i<task_max; ++i) { + LOG_I(TMR,"Starting itti queue: %s as task %d\n", tasks_info[i].name, i); + pthread_mutex_init(&tasks[i].queue_cond_lock, NULL); + memcpy(&tasks[i].admin, &tasks_info[i], sizeof(task_info_t)); + AssertFatal( ( tasks[i].epoll_fd = epoll_create1(0) ) >=0, ""); + AssertFatal( ( tasks[i].sem_fd = eventfd(0, EFD_SEMAPHORE) ) >=0, ""); + itti_subscribe_event_fd((task_id_t)i, tasks[i].sem_fd); + + if (tasks[i].admin.threadFunc != NULL) + itti_create_task((task_id_t)i, tasks[i].admin.threadFunc, NULL); + } + + return 0; + } + + int timer_setup( + uint32_t interval_sec, + uint32_t interval_us, + task_id_t task_id, + int32_t instance, + timer_type_t type, + void *timer_arg, + long *timer_id) { + task_list_t *t=&tasks[task_id]; + + do { + // set the taskid in the timer id to keep compatible with the legacy API + // timer_remove() takes only the timer id as parameter + *timer_id=(random()%UINT16_MAX) << 16 | task_id ; + } while ( t->timer_map.find(*timer_id) != t->timer_map.end()); + + /* Allocate new timer list element */ + timer_elm_t timer; + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC, &tp); + + if (interval_us%1000 != 0) + LOG_W(TMR, "Can't set timer precision below 1ms, rounding it\n"); + + timer.duration = interval_sec*1000+interval_us/1000; + timer.timeout= ((uint64_t)tp.tv_sec*1000+tp.tv_nsec/(1000*1000)+timer.duration); + timer.instance = instance; + timer.type = type; + timer.timer_arg = timer_arg; + pthread_mutex_lock (&t->queue_cond_lock); + t->timer_map[*timer_id]= timer; + + if (timer.timeout < t->next_timer) + t->next_timer=timer.timeout; + + eventfd_t sem_counter = 1; + AssertFatal ( sizeof(sem_counter) == write(t->sem_fd, &sem_counter, sizeof(sem_counter)), ""); + pthread_mutex_unlock (&t->queue_cond_lock); + return 0; + } + + int timer_remove(long timer_id) { + task_id_t task_id=(task_id_t)(timer_id&0xffff); + int ret; + pthread_mutex_lock (&tasks[task_id].queue_cond_lock); + ret=tasks[task_id].timer_map.erase(timer_id); + pthread_mutex_unlock (&tasks[task_id].queue_cond_lock); + + if (ret==1) + return 0; + else { + LOG_W(TMR, "tried to remove a non existing timer\n"); + return 1; + } + } + + const char *itti_get_message_name(MessagesIds message_id) { + return messages_info[message_id].name; + } + + const char *itti_get_task_name(task_id_t task_id) { + return tasks[task_id].admin.name; + } + + // void for compatibility + void itti_send_terminate_message(task_id_t task_id) { + } + + void itti_wait_tasks_end(void) { + while(1) + sleep(24*3600); + } + + void itti_update_lte_time(uint32_t frame, uint8_t slot) {} + void itti_set_task_real_time(task_id_t task_id) {} + void itti_mark_task_ready(task_id_t task_id) { + // Function meaning is clear, but legacy implementation is wrong + // keep it void is fine: today implementation accepts messages in the queue before task is ready + } + void itti_wait_ready(int wait_tasks) { + // Stupid function, kept for compatibility (the parameter is meaningless!!!) + } + int signal_mask(void) { return 0;} +} diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..7d07724cc14be3c0b3aee2f2f23de62318a7e799 --- /dev/null +++ b/common/utils/ocp_itti/intertask_interface.h @@ -0,0 +1,536 @@ +/* + Author: Laurent THOMAS, Open Cells + Copyleft: OpenAirInterface software alliance and it's licence +*/ +#ifndef INTERTASK_INTERFACE_H_ +#define INTERTASK_INTERFACE_H_ +#include <stdint.h> +#include <sys/epoll.h> + +#include <mem_block.h> +#include <assertions.h> + + +typedef enum timer_type_s { + TIMER_PERIODIC, + TIMER_ONE_SHOT, + TIMER_TYPE_MAX, +} timer_type_t; + +typedef struct { + void *arg; + long timer_id; +} timer_has_expired_t; + +typedef struct { + uint32_t interval_sec; + uint32_t interval_us; + long task_id; + int32_t instance; + timer_type_t type; + void *timer_arg; + long timer_id; +} timer_create_t; + +typedef struct { + long task_id; + long timer_id; +} timer_delete_t; + + +typedef struct itti_lte_time_s { + uint32_t frame; + uint8_t slot; +} itti_lte_time_t; + + +typedef struct IttiMsgEmpty_s { +} IttiMsgEmpty; + +typedef struct IttiMsgText_s { + uint32_t size; + char text[]; +} IttiMsgText; + +#include <openair2/COMMON/phy_messages_types.h> +#include <openair2/COMMON/mac_messages_types.h> +#include <openair2/COMMON/rlc_messages_types.h> +#include <openair2/COMMON/pdcp_messages_types.h> +#include <openair2/COMMON/networkDef.h> +#include <openair2/COMMON/as_message.h> +#include <openair2/RRC/LTE/rrc_types.h> +#include <openair2/COMMON/rrc_messages_types.h> + +#include <openair3/NAS/COMMON/UTIL/OctetString.h> +#include <openair3/NAS/COMMON/IES/AccessPointName.h> +#include <openair3/NAS/COMMON/IES/AdditionalUpdateResult.h> +#include <openair3/NAS/COMMON/IES/AdditionalUpdateType.h> +#include <openair3/NAS/COMMON/IES/ApnAggregateMaximumBitRate.h> +#include <openair3/NAS/COMMON/IES/AuthenticationFailureParameter.h> +#include <openair3/NAS/COMMON/IES/AuthenticationParameterAutn.h> +#include <openair3/NAS/COMMON/IES/AuthenticationParameterRand.h> +#include <openair3/NAS/COMMON/IES/AuthenticationResponseParameter.h> +#include <openair3/NAS/COMMON/IES/CipheringKeySequenceNumber.h> +#include <openair3/NAS/COMMON/IES/Cli.h> +#include <openair3/NAS/COMMON/IES/CsfbResponse.h> +#include <openair3/NAS/COMMON/IES/DaylightSavingTime.h> +#include <openair3/NAS/COMMON/IES/DetachType.h> +#include <openair3/NAS/COMMON/IES/DrxParameter.h> +#include <openair3/NAS/COMMON/IES/EmergencyNumberList.h> +#include <openair3/NAS/COMMON/IES/EmmCause.h> +#include <openair3/NAS/COMMON/IES/EpsAttachResult.h> +#include <openair3/NAS/COMMON/IES/EpsAttachType.h> +#include <openair3/NAS/COMMON/IES/EpsBearerContextStatus.h> +#include <openair3/NAS/COMMON/IES/EpsBearerIdentity.h> +#include <openair3/NAS/COMMON/IES/EpsMobileIdentity.h> +#include <openair3/NAS/COMMON/IES/EpsNetworkFeatureSupport.h> +#include <openair3/NAS/COMMON/IES/EpsQualityOfService.h> +#include <openair3/NAS/COMMON/IES/EpsUpdateResult.h> +#include <openair3/NAS/COMMON/IES/EpsUpdateType.h> +#include <openair3/NAS/COMMON/IES/EsmCause.h> +#include <openair3/NAS/COMMON/IES/EsmInformationTransferFlag.h> +#include <openair3/NAS/COMMON/IES/EsmMessageContainer.h> +#include <openair3/NAS/COMMON/IES/GprsTimer.h> +#include <openair3/NAS/COMMON/IES/GutiType.h> +#include <openair3/NAS/COMMON/IES/IdentityType2.h> +#include <openair3/NAS/COMMON/IES/ImeisvRequest.h> +#include <openair3/NAS/COMMON/IES/KsiAndSequenceNumber.h> +#include <openair3/NAS/COMMON/IES/LcsClientIdentity.h> +#include <openair3/NAS/COMMON/IES/LcsIndicator.h> +#include <openair3/NAS/COMMON/IES/LinkedEpsBearerIdentity.h> +#include <openair3/NAS/COMMON/IES/LlcServiceAccessPointIdentifier.h> +#include <openair3/NAS/COMMON/IES/LocationAreaIdentification.h> +#include <openair3/NAS/COMMON/IES/MessageType.h> +#include <openair3/NAS/COMMON/IES/MobileIdentity.h> +#include <openair3/NAS/COMMON/IES/MobileStationClassmark2.h> +#include <openair3/NAS/COMMON/IES/MobileStationClassmark3.h> +#include <openair3/NAS/COMMON/IES/MsNetworkCapability.h> +#include <openair3/NAS/COMMON/IES/MsNetworkFeatureSupport.h> +#include <openair3/NAS/COMMON/IES/NasKeySetIdentifier.h> +#include <openair3/NAS/COMMON/IES/NasMessageContainer.h> +#include <openair3/NAS/COMMON/IES/NasRequestType.h> +#include <openair3/NAS/COMMON/IES/NasSecurityAlgorithms.h> +#include <openair3/NAS/COMMON/IES/NetworkName.h> +#include <openair3/NAS/COMMON/IES/Nonce.h> +#include <openair3/NAS/COMMON/IES/PacketFlowIdentifier.h> +#include <openair3/NAS/COMMON/IES/PagingIdentity.h> +#include <openair3/NAS/COMMON/IES/PdnAddress.h> +#include <openair3/NAS/COMMON/IES/PdnType.h> +#include <openair3/NAS/COMMON/IES/PlmnList.h> +#include <openair3/NAS/COMMON/IES/ProcedureTransactionIdentity.h> +#include <openair3/NAS/COMMON/IES/ProtocolConfigurationOptions.h> +#include <openair3/NAS/COMMON/IES/ProtocolDiscriminator.h> +#include <openair3/NAS/COMMON/IES/PTmsiSignature.h> +#include <openair3/NAS/COMMON/IES/QualityOfService.h> +#include <openair3/NAS/COMMON/IES/RadioPriority.h> +#include <openair3/NAS/COMMON/IES/SecurityHeaderType.h> +#include <openair3/NAS/COMMON/IES/ServiceType.h> +#include <openair3/NAS/COMMON/IES/ShortMac.h> +#include <openair3/NAS/COMMON/IES/SsCode.h> +#include <openair3/NAS/COMMON/IES/SupportedCodecList.h> +#include <openair3/NAS/COMMON/IES/TimeZoneAndTime.h> +#include <openair3/NAS/COMMON/IES/TimeZone.h> +#include <openair3/NAS/COMMON/IES/TmsiStatus.h> +#include <openair3/NAS/COMMON/IES/TrackingAreaIdentity.h> +#include <openair3/NAS/COMMON/IES/TrackingAreaIdentityList.h> +#include <openair3/NAS/COMMON/IES/TrafficFlowAggregateDescription.h> +#include <openair3/NAS/COMMON/IES/TrafficFlowTemplate.h> +#include <openair3/NAS/COMMON/IES/TransactionIdentifier.h> +#include <openair3/NAS/COMMON/IES/UeNetworkCapability.h> +#include <openair3/NAS/COMMON/IES/UeRadioCapabilityInformationUpdateNeeded.h> +#include <openair3/NAS/COMMON/IES/UeSecurityCapability.h> +#include <openair3/NAS/COMMON/IES/VoiceDomainPreferenceAndUeUsageSetting.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextAccept.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDefaultEpsBearerContextAccept.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDefaultEpsBearerContextReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/ActivateDefaultEpsBearerContextRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceAllocationReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceAllocationRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceModificationReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/BearerResourceModificationRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/DeactivateEpsBearerContextAccept.h> +#include <openair3/NAS/COMMON/ESM/MSG/DeactivateEpsBearerContextRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/esm_cause.h> +#include <openair3/NAS/COMMON/ESM/MSG/EsmInformationRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/EsmInformationResponse.h> +#include <openair3/NAS/COMMON/ESM/MSG/EsmStatus.h> +#include <openair3/NAS/COMMON/ESM/MSG/ModifyEpsBearerContextAccept.h> +#include <openair3/NAS/COMMON/ESM/MSG/ModifyEpsBearerContextReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/ModifyEpsBearerContextRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/PdnConnectivityReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/PdnConnectivityRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/PdnDisconnectReject.h> +#include <openair3/NAS/COMMON/ESM/MSG/PdnDisconnectRequest.h> +#include <openair3/NAS/COMMON/ESM/MSG/esm_msgDef.h> +#include <openair3/NAS/COMMON/ESM/MSG/esm_msg.h> + +#include <openair3/NAS/COMMON/EMM/MSG/AttachAccept.h> +#include <openair3/NAS/COMMON/EMM/MSG/AttachComplete.h> +#include <openair3/NAS/COMMON/EMM/MSG/AttachReject.h> +#include <openair3/NAS/COMMON/EMM/MSG/AttachRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationFailure.h> +#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationReject.h> +#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/AuthenticationResponse.h> +#include <openair3/NAS/COMMON/EMM/MSG/CsServiceNotification.h> +#include <openair3/NAS/COMMON/EMM/MSG/DetachAccept.h> +#include <openair3/NAS/COMMON/EMM/MSG/DetachRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/DownlinkNasTransport.h> +#include <openair3/NAS/COMMON/EMM/MSG/emm_cause.h> +#include <openair3/NAS/COMMON/EMM/MSG/EmmInformation.h> +#include <openair3/NAS/COMMON/EMM/MSG/EmmStatus.h> +#include <openair3/NAS/COMMON/EMM/MSG/ExtendedServiceRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/GutiReallocationCommand.h> +#include <openair3/NAS/COMMON/EMM/MSG/GutiReallocationComplete.h> +#include <openair3/NAS/COMMON/EMM/MSG/IdentityRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/IdentityResponse.h> +#include <openair3/NAS/COMMON/EMM/MSG/NASSecurityModeCommand.h> +#include <openair3/NAS/COMMON/EMM/MSG/NASSecurityModeComplete.h> +#include <openair3/NAS/COMMON/EMM/MSG/SecurityModeReject.h> +#include <openair3/NAS/COMMON/EMM/MSG/ServiceReject.h> +#include <openair3/NAS/COMMON/EMM/MSG/ServiceRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateAccept.h> +#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateComplete.h> +#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateReject.h> +#include <openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateRequest.h> +#include <openair3/NAS/COMMON/EMM/MSG/UplinkNasTransport.h> +#include <openair3/NAS/COMMON/EMM/MSG/emm_msgDef.h> +#include <openair3/NAS/COMMON/EMM/MSG/emm_msg.h> + +#include <openair3/NAS/COMMON/API/NETWORK/nas_message.h> +#include <openair2/COMMON/nas_messages_types.h> +#if ENABLE_RAL + #include <ral_messages_types.h> +#endif +#include <openair2/COMMON/s1ap_messages_types.h> +#include <openair2/COMMON/x2ap_messages_types.h> +#include <openair2/COMMON/sctp_messages_types.h> +#include <openair2/COMMON/udp_messages_types.h> +#include <openair2/COMMON/gtpv1_u_messages_types.h> +#include <openair3/SCTP/sctp_eNB_task.h> +#include <openair3/NAS/UE/nas_proc_defs.h> +#include <openair3/NAS/UE/ESM/esmData.h> +#include <openair3/NAS/COMMON/UTIL/nas_timer.h> +#include <openair3/NAS/UE/ESM/esm_pt_defs.h> +#include <openair3/NAS/UE/EMM/emm_proc_defs.h> +#include <openair3/NAS/UE/EMM/emmData.h> +#include <openair3/NAS/UE/EMM/IdleMode_defs.h> +#include <openair3/NAS/UE/EMM/emm_fsm_defs.h> +#include <openair3/NAS/UE/EMM/emmData.h> +#include <openair3/NAS/COMMON/securityDef.h> +#include <openair3/NAS/UE/EMM/Authentication.h> +#include <openair3/NAS/UE/EMM/SecurityModeControl.h> +#include <openair3/NAS/UE/API/USIM/usim_api.h> +#include <openair3/NAS/COMMON/userDef.h> +#include <openair3/NAS/UE/API/USER/at_command.h> +#include <openair3/NAS/UE/API/USER/at_response.h> +#include <openair3/NAS/UE/API/USER/user_api_defs.h> +#include <openair3/NAS/UE/EMM/LowerLayer_defs.h> +#include <openair3/NAS/UE/user_defs.h> +#include <openair3/NAS/UE/nas_ue_task.h> +#include <openair3/S1AP/s1ap_eNB.h> +//#include <proto.h> + +/* + static const char *const messages_definition_xml = { + #include <messages_xml.h> + }; +*/ + +typedef uint32_t MessageHeaderSize; +typedef uint32_t itti_message_types_t; +typedef unsigned long message_number_t; +#define MESSAGE_NUMBER_SIZE (sizeof(unsigned long)) + +typedef enum task_priorities_e { + TASK_PRIORITY_MAX = 100, + TASK_PRIORITY_MAX_LEAST = 85, + TASK_PRIORITY_MED_PLUS = 70, + TASK_PRIORITY_MED = 55, + TASK_PRIORITY_MED_LEAST = 40, + TASK_PRIORITY_MIN_PLUS = 25, + TASK_PRIORITY_MIN = 10, +} task_priorities_t; + +typedef struct { + task_priorities_t priority; + unsigned int queue_size; + /* Printable name */ + char name[256]; + void *(*func)(void *) ; + void *(*threadFunc)(void *) ; +} task_info_t; +// +//TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL) +//TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) +//TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL) +//TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL) + +#define FOREACH_TASK(TASK_DEF) \ + TASK_DEF(TASK_UNKNOWN, TASK_PRIORITY_MED, 50, NULL, NULL) \ + TASK_DEF(TASK_TIMER, TASK_PRIORITY_MED, 10, NULL, NULL) \ + TASK_DEF(TASK_L2L1, TASK_PRIORITY_MAX, 200, NULL, NULL) \ + TASK_DEF(TASK_BM, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_PHY_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_MAC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RLC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_PDCP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL)\ + TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_SCTP, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_ENB_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_FLEXRAN_AGENT,TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_PHY_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_MAC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RLC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_PDCP_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RRC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_NAS_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RAL_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_MSC, TASK_PRIORITY_MED, 200, NULL, NULL)\ + TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)\ + TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL)\ + TASK_DEF(TASK_MAX, TASK_PRIORITY_MED, 200, NULL, NULL) + +#define TASK_DEF(TaskID, pRIO, qUEUEsIZE, FuNc, ThreadFunc) { pRIO, qUEUEsIZE, #TaskID, FuNc, ThreadFunc }, + +/* Map task id to printable name. */ +static const task_info_t tasks_info[] = { + FOREACH_TASK(TASK_DEF) +}; + +#define TASK_ENUM(TaskID, pRIO, qUEUEsIZE, FuNc,ThreadFunc ) TaskID, +//! Tasks id of each task +typedef enum { + FOREACH_TASK(TASK_ENUM) +} task_id_t; + + +typedef task_id_t thread_id_t; + +typedef enum message_priorities_e { + MESSAGE_PRIORITY_MAX = 100, + MESSAGE_PRIORITY_MAX_LEAST = 85, + MESSAGE_PRIORITY_MED_PLUS = 70, + MESSAGE_PRIORITY_MED = 55, + MESSAGE_PRIORITY_MED_LEAST = 40, + MESSAGE_PRIORITY_MIN_PLUS = 25, + MESSAGE_PRIORITY_MIN = 10, +} message_priorities_t; + + +#define FOREACH_MSG(INTERNAL_MSG) \ + INTERNAL_MSG(TIMER_HAS_EXPIRED, MESSAGE_PRIORITY_MED, timer_has_expired_t, timer_has_expired) \ + INTERNAL_MSG(INITIALIZE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, initialize_message) \ + INTERNAL_MSG(ACTIVATE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, activate_message) \ + INTERNAL_MSG(DEACTIVATE_MESSAGE, MESSAGE_PRIORITY_MED, IttiMsgEmpty, deactivate_message) \ + INTERNAL_MSG(TERMINATE_MESSAGE, MESSAGE_PRIORITY_MAX, IttiMsgEmpty, terminate_message) \ + INTERNAL_MSG(MESSAGE_TEST, MESSAGE_PRIORITY_MED, IttiMsgEmpty, message_test) + +/* This enum defines messages ids. Each one is unique. */ +typedef enum { +#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) iD, + FOREACH_MSG(MESSAGE_DEF) +#include <all_msg.h> +#undef MESSAGE_DEF + MESSAGES_ID_MAX, +} MessagesIds; + +typedef union msg_s { +#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) sTRUCT fIELDnAME; + FOREACH_MSG(MESSAGE_DEF) +#include <all_msg.h> +#undef MESSAGE_DEF +} msg_t; + +typedef struct MessageHeader_s { + MessagesIds messageId; /**< Unique message id as referenced in enum MessagesIds */ + task_id_t originTaskId; /**< ID of the sender task */ + task_id_t destinationTaskId; /**< ID of the destination task */ + instance_t instance; /**< Task instance for virtualization */ + itti_lte_time_t lte_time; + MessageHeaderSize ittiMsgSize; /**< Message size (not including header size) */ +} MessageHeader; + +typedef struct message_info_s { + int id; + message_priorities_t priority; + /* Message payload size */ + MessageHeaderSize size; + /* Printable name */ + const char name[256]; +} message_info_t; + +/* Map message id to message information */ +static const message_info_t messages_info[] = { +#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) { iD, pRIO, sizeof(sTRUCT), #iD }, + FOREACH_MSG(MESSAGE_DEF) +#include <all_msg.h> +#undef MESSAGE_DEF +}; + +typedef struct __attribute__ ((__packed__)) MessageDef_s { + MessageHeader ittiMsgHeader; /**< Message header */ + msg_t ittiMsg; +} MessageDef; + + + +/* Extract the instance from a message */ +#define ITTI_MESSAGE_GET_INSTANCE(mESSAGE) ((mESSAGE)->ittiMsgHeader.instance) +#define ITTI_MSG_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.messageId) +#define ITTI_MSG_ORIGIN_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.originTaskId) +#define ITTI_MSG_DESTINATION_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.destinationTaskId) +#define ITTI_MSG_INSTANCE(mSGpTR) ((mSGpTR)->ittiMsgHeader.instance) +#define ITTI_MSG_NAME(mSGpTR) itti_get_message_name(ITTI_MSG_ID(mSGpTR)) +#define ITTI_MSG_ORIGIN_NAME(mSGpTR) itti_get_task_name(ITTI_MSG_ORIGIN_ID(mSGpTR)) +#define ITTI_MSG_DESTINATION_NAME(mSGpTR) itti_get_task_name(ITTI_MSG_DESTINATION_ID(mSGpTR)) +#define TIMER_HAS_EXPIRED(mSGpTR) (mSGpTR)->ittiMsg.timer_has_expired + +#define INSTANCE_DEFAULT (UINT16_MAX - 1) + +static inline int64_t clock_difftime_ns(struct timespec start, struct timespec end) { + return (int64_t)( end.tv_sec-start.tv_sec) * (int64_t)(1000*1000*1000) + end.tv_nsec-start.tv_nsec; +} + +#ifdef __cplusplus +extern "C" { +#endif + +/** \brief Send a message to a task (could be itself) + \param task_id Task ID + \param instance Instance of the task used for virtualization + \param message Pointer to the message to send + @returns -1 on failure, 0 otherwise + **/ +int itti_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message); + +/** \brief Add a new fd to monitor. + NOTE: it is up to the user to read data associated with the fd + \param task_id Task ID of the receiving task + \param fd The file descriptor to monitor + **/ +void itti_subscribe_event_fd(task_id_t task_id, int fd); + +/** \brief Remove a fd from the list of fd to monitor + \param task_id Task ID of the task + \param fd The file descriptor to remove + **/ +void itti_unsubscribe_event_fd(task_id_t task_id, int fd); + +/** \brief Return the list of events excluding the fd associated with itti + \param task_id Task ID of the task + \param events events list + @returns number of events to handle + **/ +int itti_get_events(task_id_t task_id, struct epoll_event **events); + +/** \brief Retrieves a message in the queue associated to task_id. + If the queue is empty, the thread is blocked till a new message arrives. + \param task_id Task ID of the receiving task + \param received_msg Pointer to the allocated message + **/ +void itti_receive_msg(task_id_t task_id, MessageDef **received_msg); + +/** \brief Try to retrieves a message in the queue associated to task_id. + \param task_id Task ID of the receiving task + \param received_msg Pointer to the allocated message + **/ +void itti_poll_msg(task_id_t task_id, MessageDef **received_msg); + +/** \brief Start thread associated to the task + \param task_id task to start + \param start_routine entry point for the task + \param args_p Optional argument to pass to the start routine + @returns -1 on failure, 0 otherwise + **/ +int itti_create_task(task_id_t task_id, + void *(*start_routine) (void *), + void *args_p); + +/** \brief Exit the current task. + **/ +void itti_exit_task(void); + +/** \brief Initiate termination of all tasks. + \param task_id task that is completed + **/ +void itti_terminate_tasks(task_id_t task_id); + +// Void for legacy compatibility +void itti_wait_ready(int wait_tasks); +void itti_mark_task_ready(task_id_t task_id); + +/** \brief Return the printable string associated with the message + \param message_id Id of the message + **/ +const char *itti_get_message_name(MessagesIds message_id); + +/** \brief Return the printable string associated with a task id + \param thread_id Id of the task + **/ +const char *itti_get_task_name(task_id_t task_id); + +/** \brief Alloc and memset(0) a new itti message. + \param origin_task_id Task ID of the sending task + \param message_id Message ID + @returns NULL in case of failure or newly allocated mesage ref + **/ +MessageDef *itti_alloc_new_message( + task_id_t origin_task_id, + MessagesIds message_id); + +/** \brief Alloc and memset(0) a new itti message. + \param origin_task_id Task ID of the sending task + \param message_id Message ID + \param size size of the payload to send + @returns NULL in case of failure or newly allocated mesage ref + **/ +MessageDef *itti_alloc_new_message_sized( + task_id_t origin_task_id, + MessagesIds message_id, + MessageHeaderSize size); + +/** \brief handle signals and wait for all threads to join when the process complete. + This function should be called from the main thread after having created all ITTI tasks. + **/ +void itti_wait_tasks_end(void); +#define THREAD_MAX 0 //for compatibility +void itti_set_task_real_time(task_id_t task_id); + +/** \brief Send a termination message to all tasks. + \param task_id task that is broadcasting the message. + **/ +void itti_send_terminate_message(task_id_t task_id); + +void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize_t size); +void *calloc_or_fail(size_t size); +void *malloc_or_fail(size_t size); +int memory_read(const char *datafile, void *data, size_t size); +int itti_free(task_id_t task_id, void *ptr); + +int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_id_max, const task_info_t *tasks_info, + const message_info_t *messages_info); +int timer_setup( + uint32_t interval_sec, + uint32_t interval_us, + task_id_t task_id, + int32_t instance, + timer_type_t type, + void *timer_arg, + long *timer_id); + + +int timer_remove(long timer_id); +#define timer_stop timer_remove +int signal_handle(int *end); + +#ifdef __cplusplus +} +#endif +#endif /* INTERTASK_INTERFACE_H_ */ diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c index ba1b01151391d5ed884ae961f22c7c394c0cf0c9..3b423bd4655e47d15e711e972c4b5d722dbcafec 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.c +++ b/common/utils/telnetsrv/telnetsrv_proccmd.c @@ -303,8 +303,6 @@ char sv1[64]; } int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt) { -extern void exit_fun(const char* s); - if (debug > 0) prnt("process module received %s\n",buf); diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c index 9f4ab3a580ad3542812d0fd989decaea6f89c4d2..77f060a4336d1bb654d3555ba8478b8737316895 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c @@ -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 diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index fce7f1b8851ae473ab0037fdcf47845b88a21da9..75e6d3fce3756ca25a8ef0a3c7348b0925e53b46 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -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> @@ -928,7 +930,6 @@ typedef enum { #endif -void exit_fun(const char* s); #include "common/utils/LOG/log_extern.h" extern pthread_cond_t sync_cond; diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c index b9e059529b6b3d98b5065b1a1b7d07008d72f75f..ad236a6f7568bb9a7d6aeb4a81195bf48a60039e 100644 --- a/openair1/SIMULATION/LTE_PHY/pucchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c @@ -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" diff --git a/openair1/SIMULATION/LTE_PHY/unitary_defs.h b/openair1/SIMULATION/LTE_PHY/unitary_defs.h index 133656a5626cdf920c4e1ae095ca2de83cf295c5..eea8e89fbe6a02842e4058c074711da6ff590954 100644 --- a/openair1/SIMULATION/LTE_PHY/unitary_defs.h +++ b/openair1/SIMULATION/LTE_PHY/unitary_defs.h @@ -22,7 +22,11 @@ openair0_device openair0; volatile int oai_exit=0; -void exit_fun(const char *s) { exit(-1); } +void exit_function(const char* file, const char* function, const int line,const char *s) { + const char * msg= s==NULL ? "no comment": s; + printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); + exit(-1); +} extern unsigned int dlsch_tbs25[27][25],TBStable[27][110]; extern unsigned char offset_mumimo_llr_drange_fix; diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 3f736e5b3cf5406c1b22d930142320aa393282dc..0f9fc34f836f0241dcf3e07ed9ab74114d23ee93 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -34,9 +34,6 @@ #include <stdint.h> #endif -#if defined(ENABLE_ITTI) -#include "itti_types.h" -#endif //----------------------------------------------------------------------------- // GENERIC TYPES //----------------------------------------------------------------------------- @@ -288,4 +285,7 @@ typedef struct protocol_ctxt_s { (CTXT_Pp)->rnti #define CHECK_CTXT_ARGS(CTXT_Pp) + +#define exit_fun(msg) exit_function(__FILE__,__FUNCTION__,__LINE__,msg) +void exit_function(const char* file, const char* function, const int line, const char* s); #endif diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index f95fdd7e5ae8c7dfbecef187b1e2800320387284..ad3f5fd6ed7d063f0ddb36a8cb7e5709d3ac216a 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -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" diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index c6359f156347533af24dee549e64b798cb13092f..ed1b4aeaa2924dd08f49be84d5f20337b307a044 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -46,8 +46,8 @@ #else #include "RRC/LTE/MESSAGES/SystemInformationBlockType2.h" #endif -#include "intertask_interface_types.h" #include "RRC/LTE/rrc_defs.h" +#include <intertask_interface.h> #define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\ struct in_addr inp;\ diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index 057c5b9489a7332a9cdb8923f3abeb58a44f7d46..a43476fe4f08d1342011c92228dfdfed3793e419 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -46,7 +46,6 @@ # include "tree.h" # include "intertask_interface.h" -# include "timer.h" #define FLEXRAN_VERSION 0 diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index 8874a0f64852f06ac619ba4eed39e7d02fe292ec..e9fc39044d11dbdbd79974f4d5a52d7f56891af6 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -68,7 +68,7 @@ void handle_reconfiguration(mid_t mod_id) if (restart_L1L2(mod_id) < 0) { LOG_F(ENB_APP, "can not restart, killing lte-softmodem\n"); - itti_terminate_tasks(TASK_PHY_ENB); + exit_fun("can not restart L1L2, killing lte-softmodem"); return; } diff --git a/openair2/ENB_APP/flexran_agent_timer.h b/openair2/ENB_APP/flexran_agent_timer.h index 98d83c78a950d7db533316f297e3f3e4ac4c9704..06443c14d1f399aaf836a5469d9bee97abfe05da 100644 --- a/openair2/ENB_APP/flexran_agent_timer.h +++ b/openair2/ENB_APP/flexran_agent_timer.h @@ -37,7 +37,6 @@ # include "tree.h" # include "intertask_interface.h" -# include "timer.h" diff --git a/openair2/UTIL/MEM/mem_block.h b/openair2/UTIL/MEM/mem_block.h index a0455899e3a3cfeb23f936c8fb03c2a289c5fa72..861e4a8ea469598c034913959c7f6922a9ebef98 100644 --- a/openair2/UTIL/MEM/mem_block.h +++ b/openair2/UTIL/MEM/mem_block.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 diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index b9d81602c267bf6caff08d6d1362ce1812a80b0e..20c104ad1fa33a0ac7d2d43348d3e90e3debb69d 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -33,7 +33,6 @@ #include "assertions.h" #include "intertask_interface.h" -#include "timer.h" #include "msc.h" #include "gtpv1u.h" diff --git a/openair3/GTPV1-U/gtpv1u_eNB_task.h b/openair3/GTPV1-U/gtpv1u_eNB_task.h index 5a7822fe8c7322e12a6a32d231cec8c6af1d1df6..6afea103ef4892e158815779fd747f06bfe24a64 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB_task.h +++ b/openair3/GTPV1-U/gtpv1u_eNB_task.h @@ -29,7 +29,6 @@ #ifndef GTPV1U_ENB_TASK_H_ #define GTPV1U_ENB_TASK_H_ -#include "messages_types.h" /* int diff --git a/openair3/GTPV1-U/gtpv1u_task.c b/openair3/GTPV1-U/gtpv1u_task.c index 287c22b7e7ab28d162f6b36815b11eb14b629588..e821885ab5198055484b183f12eef1411b243b9a 100644 --- a/openair3/GTPV1-U/gtpv1u_task.c +++ b/openair3/GTPV1-U/gtpv1u_task.c @@ -35,7 +35,6 @@ #include "assertions.h" #include "intertask_interface.h" -#include "timer.h" #include "gtpv1u.h" #include "NwGtpv1u.h" diff --git a/openair3/NAS/COMMON/UTIL/nas_timer.c b/openair3/NAS/COMMON/UTIL/nas_timer.c index 0b92ac4d9d55c6b376558f99efbc028ae3effaa5..d92c48f483c25366334ac4a654aa23890056c7e8 100644 --- a/openair3/NAS/COMMON/UTIL/nas_timer.c +++ b/openair3/NAS/COMMON/UTIL/nas_timer.c @@ -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 diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index 9f922d8516d49933a3ae2f3b653f70bc1fd3efbf..546878e57692061c502ac17d56f08fd7a5f336d1 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -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" diff --git a/openair3/TEST/EPC_TEST/play_scenario_fsm.c b/openair3/TEST/EPC_TEST/play_scenario_fsm.c index 1589b83cae6b58bc651f4b0debaed2e59b5a3505..a3963951dce3d41a0fd865a1da1e1cc181fd4ac0 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_fsm.c +++ b/openair3/TEST/EPC_TEST/play_scenario_fsm.c @@ -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; diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index 361b56100c0cee37a8a987dc649b797df5420b8f..d2bf05c0862f8eddd958621744d08f439b836baa 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -38,7 +38,6 @@ #include "intertask_interface.h" -#include "timer.h" #include "platform_types.h" #include "assertions.h" #include "conversions.h" diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c index e0afbeb83875721c061b961908560791c325def3..001834fcab229ac60d4209bfeb215494e524540f 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -43,7 +43,6 @@ #include "intertask_interface.h" -#include "timer.h" #include "platform_types.h" #include "assertions.h" #include "conversions.h" diff --git a/openair3/TEST/oaisim_mme_itti_test.c b/openair3/TEST/oaisim_mme_itti_test.c index bf8ad4471417abe7ceb95411ec3e345847edffea..57cfd412ef12c7b607c011c8125f99675be5c3b6 100644 --- a/openair3/TEST/oaisim_mme_itti_test.c +++ b/openair3/TEST/oaisim_mme_itti_test.c @@ -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" diff --git a/openair3/TEST/oaisim_mme_test_s1c.c b/openair3/TEST/oaisim_mme_test_s1c.c index f006434b9013ca093e592d511f498c5af13b49ee..52623463c6bc4f83091311e3bb5969b5338a8cb1 100644 --- a/openair3/TEST/oaisim_mme_test_s1c.c +++ b/openair3/TEST/oaisim_mme_test_s1c.c @@ -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" diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index f61f614a143464d04b255d2980d7cefc701ebfb7..fdcdeb037af62ebddb912651d620f7954e2149b5 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -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); diff --git a/openair3/UDP/udp_eNB_task.h b/openair3/UDP/udp_eNB_task.h index 658516212574efbfb5115444d350c47e0c42828d..8b783f7455c08f6aec5a0d80788b51746a9feb51 100644 --- a/openair3/UDP/udp_eNB_task.h +++ b/openair3/UDP/udp_eNB_task.h @@ -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 diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index c8c35cf2e88d57cf20f61182df6fc4b492405fdd..a2f255d4d890fd295552016c55469afac7b7b6d0 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -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 @@ -142,7 +141,6 @@ static struct { extern double cpuf; -void exit_fun(const char* s); void init_eNB(int,int); void stop_eNB(int nb_inst); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index a1130ce387f4d9b5db5c7f9ba5b58d97a96d0420..2d5f04d38680846c0b252373dbe74e6174644d16 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -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 @@ -324,13 +323,13 @@ void signal_handler(int sig) { -void exit_fun(const char* s) +void exit_function(const char* file, const char* function, const int line, const char* s) { int ru_id; if (s != NULL) { - printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); + printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); } oai_exit = 1; @@ -350,11 +349,11 @@ void exit_fun(const char* s) } -#if defined(ENABLE_ITTI) sleep(1); //allow lte-softmodem threads to exit first +#if defined(ENABLE_ITTI) itti_terminate_tasks (TASK_UNKNOWN); #endif - + exit(1); } diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 2eb4b0d60d4bbaade10d08a9e08c036b3e6a09ed..4728dce18ac6a1eb1ad05d9bd0116b6a1b2964d7 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -242,7 +242,6 @@ extern volatile int start_UE; #include "threads_t.h" extern threads_t threads; -extern void exit_fun(const char* s); // In lte-enb.c extern void init_eNB(int single_thread_flag,int wait_for_sync); extern void stop_eNB(int); diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 422f4347101cfce6276aba6c41cb70b841742218..2efcb496ac1ba8d399971bea9ff8486715885284 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -84,7 +84,6 @@ #endif #if defined(ENABLE_ITTI) -#include "intertask_interface_init.h" #include "create_tasks.h" #endif @@ -323,13 +322,13 @@ void signal_handler(int sig) { -void exit_fun(const char* s) +void exit_function(const char* file, const char* function, const int line, const char* s) { int CC_id; logClean(); if (s != NULL) { - printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); + printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); } oai_exit = 1; @@ -342,10 +341,11 @@ void exit_fun(const char* s) PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); } -#if defined(ENABLE_ITTI) sleep(1); //allow lte-softmodem threads to exit first +#if defined(ENABLE_ITTI) itti_terminate_tasks (TASK_UNKNOWN); #endif + exit(1); } #ifdef XFORMS