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