From 1f213b0b8e24bcc7498534b965b952173a5e8e3e Mon Sep 17 00:00:00 2001 From: Navid Nikaein <navid.nikaein@eurecom.fr> Date: Tue, 5 Jan 2016 11:33:40 +0100 Subject: [PATCH] * add options to enb configuration file for the enb agent * add timer api for the periodic and oneshot operations * create enb agent task --- common/utils/itti/timer.c | 16 +- openair2/COMMON/tasks_def.h | 2 + openair2/ENB_APP/MESSAGES/V2/progran.proto | 2 +- openair2/ENB_APP/enb_agent.c | 247 +++++++++++---- openair2/ENB_APP/enb_agent.h | 13 +- openair2/ENB_APP/enb_agent_common.c | 284 +++++++++++++++++- openair2/ENB_APP/enb_agent_common.h | 165 +++++++++- openair2/ENB_APP/enb_agent_defs.h | 142 +++++++++ openair2/ENB_APP/enb_agent_handler.c | 58 ++-- openair2/ENB_APP/enb_agent_mac.c | 45 ++- openair2/ENB_APP/enb_agent_mac.h | 12 +- openair2/ENB_APP/enb_app.c | 7 +- openair2/ENB_APP/enb_config.c | 43 +++ openair2/ENB_APP/enb_config.h | 3 + openair2/UTIL/LOG/log.c | 8 + openair2/UTIL/LOG/log.h | 1 + .../enb.band7.agent.oaisim.local_no_mme.conf | 153 ++++++++++ 17 files changed, 1059 insertions(+), 142 deletions(-) create mode 100644 openair2/ENB_APP/enb_agent_defs.h create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.agent.oaisim.local_no_mme.conf diff --git a/common/utils/itti/timer.c b/common/utils/itti/timer.c index 864ab16746..683efd1279 100644 --- a/common/utils/itti/timer.c +++ b/common/utils/itti/timer.c @@ -94,9 +94,8 @@ int timer_handle_signal(siginfo_t *info) 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); - -#if defined(ENABLE_ITTI) + TMR_DEBUG("Timer with id 0x%lx has expired\n", (long)timer_p->timer); + printf("Timer with id 0x%lx has expired\n", (long)timer_p->timer); task_id = timer_p->task_id; instance = timer_p->instance; @@ -106,7 +105,6 @@ int timer_handle_signal(siginfo_t *info) timer_expired_p->timer_id = (long)timer_p->timer; timer_expired_p->arg = timer_p->timer_arg; -#endif /* Timer is a one shot timer, remove it */ if (timer_p->type == TIMER_ONE_SHOT) { @@ -123,13 +121,16 @@ int timer_handle_signal(siginfo_t *info) TMR_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer); } } -#ifdefined ENABLE_ITTI + /* 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; @@ -209,6 +210,11 @@ int timer_setup( type == TIMER_PERIODIC ? "periodic" : "single shot", *timer_id, interval_sec, interval_us); + printf("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 */ diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h index 5e0f8bd211..6cd74c3aed 100644 --- a/openair2/COMMON/tasks_def.h +++ b/openair2/COMMON/tasks_def.h @@ -63,6 +63,8 @@ TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200) TASK_DEF(TASK_SCTP, TASK_PRIORITY_MED, 200) /// eNB APP task TASK_DEF(TASK_ENB_APP, TASK_PRIORITY_MED, 200) +/// eNB Agent task +TASK_DEF(TASK_ENB_AGENT, TASK_PRIORITY_MED, 200) // UE tasks and sub-tasks: //// Layer 2 and Layer 1 sub-tasks diff --git a/openair2/ENB_APP/MESSAGES/V2/progran.proto b/openair2/ENB_APP/MESSAGES/V2/progran.proto index 4f989361a9..995cd6861b 100644 --- a/openair2/ENB_APP/MESSAGES/V2/progran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/progran.proto @@ -37,7 +37,7 @@ enum progran_err { MSG_NOT_VALIDATED = -8; MSG_OUT_DATED = -9; - + // other erros UNEXPECTED = -100; } diff --git a/openair2/ENB_APP/enb_agent.c b/openair2/ENB_APP/enb_agent.c index c9a00ae9ce..7003a2c638 100644 --- a/openair2/ENB_APP/enb_agent.c +++ b/openair2/ENB_APP/enb_agent.c @@ -27,43 +27,82 @@ *******************************************************************************/ -/*! \file - * \brief - * \author +/*! \file enb_agent.h + * \brief top level enb agent receive thread and itti task + * \author Navid Nikaein and Xenofon Foukas * \date 2016 * \version 0.1 */ - -#include <stdio.h> -#include <stdlib.h> -#include <pthread.h> -#include <string.h> -#include <unistd.h> - #include "enb_agent_common.h" -#include "link_manager.h" #include "log.h" #include "enb_agent.h" -typedef uint8_t xid_t; +#include "assertions.h" + + +enb_agent_instance_t enb_agent[NUM_MAX_ENB_AGENT]; +msg_context_t shared_ctxt[NUM_MAX_ENB_AGENT]; +/* this could also go into enb_agent struct*/ +enb_agent_info_t enb_agent_info; -// tx and rx shared context -typedef struct { - message_queue_t *tx_mq; - message_queue_t *rx_mq; - xid_t tx_xid; - xid_t rx_xid; -} msg_context_t; -msg_context_t shared_ctxt; +char in_ip[40]; +static uint16_t in_port; -void *send_thread(void *arg); -void *receive_thread(void *arg); +//void *send_thread(void *args); +void *receive_thread(void *args); pthread_t new_thread(void *(*f)(void *), void *b); +err_code_t enb_agent_timeout(void* args); + +/* + * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller + * and can interact with other itti tasks +*/ +void *enb_agent_task(void *args){ + + MessageDef *msg_p = NULL; + const char *msg_name = NULL; + instance_t instance; + int result; + + + itti_mark_task_ready(TASK_ENB_AGENT); + + do { + // Wait for a message + itti_receive_msg (TASK_ENB_AGENT, &msg_p); + DevAssert(msg_p != NULL); + msg_name = ITTI_MSG_NAME (msg_p); + instance = ITTI_MSG_INSTANCE (msg_p); + + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + itti_exit_task (); + break; + + case MESSAGE_TEST: + LOG_I(ENB_AGENT, "Received %s\n", ITTI_MSG_NAME(msg_p)); + break; + + case TIMER_HAS_EXPIRED: + enb_agent_process_timeout(msg_p->ittiMsg.timer_has_expired.timer_id, &msg_p->ittiMsg.timer_has_expired.arg); + break; + + default: + LOG_E(ENB_AGENT, "Received unexpected message %s\n", msg_name); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } while (1); -void *send_thread(void *arg) { + return NULL; +} +/* +void *send_thread(void *args) { - msg_context_t *d = arg; + msg_context_t *d = args; void *data; int size; int priority; @@ -81,10 +120,10 @@ error: printf("receive_thread: there was an error\n"); return NULL; } +*/ +void *receive_thread(void *args) { -void *receive_thread(void *arg) { - - msg_context_t *d = arg; + msg_context_t *d = args; void *data; int size; int priority; @@ -97,10 +136,10 @@ void *receive_thread(void *arg) { err_code = PROTOCOL__PROGRAN_ERR__MSG_DEQUEUING; goto error; } - LOG_D(ENB_APP,"received message with size %d\n", size); + LOG_D(ENB_AGENT,"received message with size %d\n", size); - msg=enb_agent_handle_message(d->rx_xid, data, size); + msg=enb_agent_handle_message(d->mod_id, d->rx_xid, data, size); free(data); @@ -115,7 +154,7 @@ void *receive_thread(void *arg) { err_code = PROTOCOL__PROGRAN_ERR__MSG_ENQUEUING; goto error; } - LOG_D(ENB_APP,"sent message with size %d\n", size); + LOG_D(ENB_AGENT,"sent message with size %d\n", size); } } @@ -123,7 +162,7 @@ void *receive_thread(void *arg) { return NULL; error: - printf("receive_thread: error %d occured\n",err_code); + LOG_E(ENB_AGENT,"receive_thread: error %d occured\n",err_code); return NULL; } @@ -153,50 +192,146 @@ pthread_t new_thread(void *(*f)(void *), void *b) { return t; } -int enb_agent_start(){ - - socket_link_t *link; - message_queue_t *send_queue; - message_queue_t *receive_queue; - link_manager_t *manager; +int enb_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties){ - LOG_I(ENB_APP,"starting enb agent client\n"); + // + set_enb_vars(mod_id, RAN_LTE_OAI); + enb_agent[mod_id].mod_id = mod_id; + enb_agent_info.nb_modules+=1; + + /* + * check the configuration + */ + if (enb_properties->properties[mod_id]->enb_agent_ipv4_address != NULL) { + strncpy(in_ip, enb_properties->properties[mod_id]->enb_agent_ipv4_address, sizeof(in_ip) ); + in_ip[sizeof(in_ip) - 1] = 0; // terminate string + } else { + strcpy(in_ip, DEFAULT_ENB_AGENT_IPv4_ADDRESS ); + } + + if (enb_properties->properties[mod_id]->enb_agent_port != 0 ) { + in_port = enb_properties->properties[mod_id]->enb_agent_port; + } else { + in_port = DEFAULT_ENB_AGENT_PORT ; + } + LOG_I(ENB_AGENT,"starting enb agent client for module id %d on ipv4 %s, port %d\n", + enb_agent[mod_id].mod_id, + in_ip, + in_port); + + //#define TEST_TIMER 0 +#if !defined TEST_TIMER + + /* + * create a socket + */ + enb_agent[mod_id].link = new_link_client(in_ip, in_port); + if (enb_agent[mod_id].link == NULL) goto error; + + LOG_I(ENB_AGENT,"starting enb agent client for module id %d on ipv4 %s, port %d\n", + enb_agent[mod_id].mod_id, + in_ip, + in_port); + /* + * create a message queue + */ + + enb_agent[mod_id].send_queue = new_message_queue(); + if (enb_agent[mod_id].send_queue == NULL) goto error; + enb_agent[mod_id].receive_queue = new_message_queue(); + if (enb_agent[mod_id].receive_queue == NULL) goto error; + + /* + * create a link manager + */ + + enb_agent[mod_id].manager = create_link_manager(enb_agent[mod_id].send_queue, enb_agent[mod_id].receive_queue, enb_agent[mod_id].link); + if (enb_agent[mod_id].manager == NULL) goto error; - link = new_link_client("127.0.0.1", 2210); - if (link == NULL) goto error; + memset(&shared_ctxt, 0, sizeof(msg_context_t)); + + shared_ctxt[mod_id].mod_id = mod_id; + shared_ctxt[mod_id].tx_mq = enb_agent[mod_id].send_queue; + shared_ctxt[mod_id].rx_mq = enb_agent[mod_id].receive_queue; - send_queue = new_message_queue(); - if (send_queue == NULL) goto error; - receive_queue = new_message_queue(); - if (receive_queue == NULL) goto error; + /* + * start the enb agent rx thread + */ + + new_thread(receive_thread, &shared_ctxt[mod_id]); - manager = create_link_manager(send_queue, receive_queue, link); - if (manager == NULL) goto error; +#endif + + /* + * initilize a timer + */ + + enb_agent_init_timer(); + + + + /* + * start the enb agent task for tx and interaction with the underlying network function + */ + + if (itti_create_task (TASK_ENB_AGENT, enb_agent_task, NULL) < 0) { + LOG_E(ENB_AGENT, "Create task for eNB Agent failed\n"); + return -1; + } - memset(&shared_ctxt, 0, sizeof(msg_context_t)); - - shared_ctxt.tx_mq = send_queue; - shared_ctxt.rx_mq = receive_queue; +#ifdef TEST_TIMER + long timer_id=0; + enb_agent_timer_args_t timer_args; + memset (&timer_args, 0, sizeof(enb_agent_timer_args_t)); + timer_args.mod_id = mod_id; + timer_args.cc_actions= ENB_AGENT_ACTION_APPLY; + timer_args.cc_report_flags = PROTOCOL__PRP_CELL_STATS_TYPE__PRCST_NOISE_INTERFERENCE; + timer_args.ue_actions = ENB_AGENT_ACTION_SEND; + timer_args.ue_report_flags = PROTOCOL__PRP_UE_STATS_TYPE__PRUST_BSR | PROTOCOL__PRP_UE_STATS_TYPE__PRUST_DL_CQI; + enb_agent_create_timer(1, 0, ENB_AGENT_DEFAULT, mod_id, ENB_AGENT_TIMER_TYPE_PERIODIC, enb_agent_timeout,(void*)&timer_args, &timer_id); +#endif - new_thread(receive_thread, &shared_ctxt); - // new_thread(send_thread, &shared_ctxt); - // while (1) pause(); + //while (1) pause(); - printf("client ends\n"); + LOG_I(ENB_AGENT,"client ends\n"); return 0; error: - printf("there was an error\n"); + LOG_I(ENB_AGENT,"there was an error\n"); return 1; } -int enb_agent_stop(){ +int enb_agent_stop(mid_t mod_id){ + + int i=0; + enb_agent_destroy_timers(); + for ( i =0; i < enb_agent_info.nb_modules; i++) { + + destroy_link_manager(enb_agent[i].manager); + + destroy_message_queue(enb_agent[i].send_queue); + destroy_message_queue(enb_agent[i].receive_queue); + + close_link(enb_agent[i].link); + } +} + + +err_code_t enb_agent_timeout(void* args){ + + enb_agent_timer_args_t *timer_args = (enb_agent_timer_args_t *) args; + + LOG_I(ENB_AGENT, "enb_agent %d timeout\n", timer_args->mod_id); + LOG_I(ENB_AGENT, "eNB action %d ENB flags %d \n", timer_args->cc_actions,timer_args->cc_report_flags); + LOG_I(ENB_AGENT, "UE action %d UE flags %d \n", timer_args->ue_actions,timer_args->ue_report_flags); + + return 0; } diff --git a/openair2/ENB_APP/enb_agent.h b/openair2/ENB_APP/enb_agent.h index 89d1d9e0c2..1a53841d45 100644 --- a/openair2/ENB_APP/enb_agent.h +++ b/openair2/ENB_APP/enb_agent.h @@ -28,9 +28,9 @@ *******************************************************************************/ -/*! \file - * \brief - * \author +/*! \file enb_agent.h + * \brief top level enb agent + * \author Navid Nikaein and Xenofon Foukas * \date 2016 * \version 0.1 */ @@ -38,10 +38,13 @@ #ifndef ENB_AGENT_H_ #define ENB_AGENT_H_ +#include "enb_config.h" // for enb properties +#include "enb_agent_common.h" -int enb_agent_start(); +int enb_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties); -int enb_agent_stop(); +int enb_agent_stop(mid_t mod_id); +void *enb_agent_task(void *args); #endif diff --git a/openair2/ENB_APP/enb_agent_common.c b/openair2/ENB_APP/enb_agent_common.c index 848c10b6fa..c2653f4c85 100644 --- a/openair2/ENB_APP/enb_agent_common.c +++ b/openair2/ENB_APP/enb_agent_common.c @@ -27,9 +27,9 @@ *******************************************************************************/ -/*! \file - * \brief - * \author +/*! \file enb_agent_common.c + * \brief common primitives for all agents + * \author Navid Nikaein and Xenofon Foukas * \date 2016 * \version 0.1 */ @@ -39,6 +39,12 @@ #include "log.h" +void * enb[NUM_MAX_ENB_AGENT]; +void * enb_ue[NUM_MAX_ENB_AGENT]; +/* + * message primitives + */ + int enb_agent_serialize_message(Protocol__ProgranMessage *msg, void **buf, int *size) { *size = protocol__progran_message__get_packed_size(msg); @@ -52,7 +58,7 @@ int enb_agent_serialize_message(Protocol__ProgranMessage *msg, void **buf, int * return 0; error: - LOG_E(ENB_APP, "an error occured\n"); // change the com + LOG_E(ENB_AGENT, "an error occured\n"); // change the com return -1; } @@ -74,9 +80,7 @@ int enb_agent_deserialize_message(void *data, int size, Protocol__ProgranMessage - - -int prp_create_header(uint32_t xid, Protocol__PrpType type, Protocol__PrpHeader **header) { +int prp_create_header(xid_t xid, Protocol__PrpType type, Protocol__PrpHeader **header) { *header = malloc(sizeof(Protocol__PrpHeader)); if(*header == NULL) @@ -98,7 +102,7 @@ int prp_create_header(uint32_t xid, Protocol__PrpType type, Protocol__PrpHeader } -int enb_agent_hello(uint32_t xid, const void *params, Protocol__ProgranMessage **msg) { +int enb_agent_hello(mid_t mod_id, xid_t xid, const void *params, Protocol__ProgranMessage **msg) { Protocol__PrpHeader *header; if (prp_create_header(xid, PROTOCOL__PRP_TYPE__PRPT_HELLO, &header) != 0) @@ -150,7 +154,7 @@ int enb_agent_destroy_hello(Protocol__ProgranMessage *msg) { } -int enb_agent_echo_request(uint32_t xid, const void* params, Protocol__ProgranMessage **msg) { +int enb_agent_echo_request(mid_t mod_id, xid_t xid, const void* params, Protocol__ProgranMessage **msg) { Protocol__PrpHeader *header; if (prp_create_header(xid, PROTOCOL__PRP_TYPE__PRPT_ECHO_REQUEST, &header) != 0) goto error; @@ -199,7 +203,7 @@ int enb_agent_destroy_echo_request(Protocol__ProgranMessage *msg) { -int enb_agent_echo_reply(uint32_t xid, const void *params, Protocol__ProgranMessage **msg) { +int enb_agent_echo_reply(mid_t mod_id, xid_t xid, const void *params, Protocol__ProgranMessage **msg) { Protocol__PrpHeader *header; if (prp_create_header(xid, PROTOCOL__PRP_TYPE__PRPT_ECHO_REPLY, &header) != 0) goto error; @@ -246,3 +250,263 @@ int enb_agent_destroy_echo_reply(Protocol__ProgranMessage *msg) { LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); return -1; } + +/* + * get generic info from RAN + */ + +void set_enb_vars(mid_t mod_id, ran_name_t ran){ + + switch (ran){ + case RAN_LTE_OAI : + enb[mod_id] = (void *)&eNB_mac_inst[mod_id]; + enb_ue[mod_id] = (void *)&eNB_mac_inst[mod_id].UE_list; + break; + default : + goto error; + } + + return; + + error: + LOG_E(ENB_AGENT, "unknown RAN name %d\n", ran); +} + +int get_current_time_ms (mid_t mod_id, int subframe_flag){ + + if (subframe_flag == 1){ + return ((eNB_MAC_INST *)enb[mod_id])->frame*10 + ((eNB_MAC_INST *)enb[mod_id])->subframe; + }else { + return ((eNB_MAC_INST *)enb[mod_id])->frame*10; + } + +} + +int get_num_ues (mid_t mod_id){ + + return ((UE_list_t *)enb_ue[mod_id])->num_UEs; +} + +int get_ue_crnti (mid_t mod_id, mid_t ue_id){ + + return ((UE_list_t *)enb_ue[mod_id])->eNB_UE_stats[UE_PCCID(mod_id,ue_id)][ue_id].crnti; +} + +int get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid) { + + return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].bsr_info[lcid]; +} + +int get_ue_phr (mid_t mod_id, mid_t ue_id) { + + return ((UE_list_t *)enb_ue[mod_id])->UE_template[UE_PCCID(mod_id,ue_id)][ue_id].phr_info; +} + +int get_ue_wcqi (mid_t mod_id, mid_t ue_id) { + + return ((UE_list_t *)enb_ue[mod_id])->eNB_UE_stats[UE_PCCID(mod_id,ue_id)][ue_id].dl_cqi; +} +/* + * timer primitives + */ + + +//struct enb_agent_map agent_map; + +/* The timer_id might not be the best choice for the comparison */ +int enb_agent_compare_timer(struct enb_agent_timer_element_s *a, struct enb_agent_timer_element_s *b){ + + //if (a->timer_id) return 0; + //if (b->timer_id) return 0; + + if (a->timer_id < b->timer_id) return -1; + if (a->timer_id > b->timer_id) return 1; + + // equal timers + return 0; +} + +RB_GENERATE(enb_agent_map,enb_agent_timer_element_s, entry, enb_agent_compare_timer); + +err_code_t enb_agent_init_timer(void){ + + RB_INIT(&enb_agent_head); + + /* + struct enb_agent_timer_element_s e; + memset(&e, 0, sizeof(enb_agent_timer_element_t)); + RB_INSERT(enb_agent_map, &agent_map, &e); + */ + return PROTOCOL__PROGRAN_ERR__NO_ERR; +} + +err_code_t enb_agent_create_timer(uint32_t interval_sec, + uint32_t interval_usec, + agent_id_t agent_id, + instance_t instance, + uint32_t timer_type, + enb_agent_timer_callback_t cb, + void* timer_args, + long *timer_id){ + + struct enb_agent_timer_element_s e; +//uint32_t timer_id; + int ret=-1; + + if ((interval_sec == 0) && (interval_usec == 0 )) + return TIMER_NULL; + + if (timer_type >= ENB_AGENT_TIMER_TYPE_MAX) + return TIMER_TYPE_INVALIDE; + + if (timer_type == ENB_AGENT_TIMER_TYPE_ONESHOT){ + ret = timer_setup(interval_sec, + interval_usec, + TASK_ENB_AGENT, + instance, + TIMER_ONE_SHOT, + timer_args, + timer_id); + + e.type = TIMER_ONE_SHOT; + } + else if (timer_type == ENB_AGENT_TIMER_TYPE_PERIODIC ){ + ret = timer_setup(interval_sec, + interval_usec, + TASK_ENB_AGENT, + instance, + TIMER_PERIODIC, + timer_args, + timer_id); + + e.type = TIMER_PERIODIC; + } + + if (ret < 0 ) { + return TIMER_SETUP_FAILED; + } + + e.agent_id = agent_id; + e.instance = instance; + e.state = ENB_AGENT_TIMER_STATE_ACTIVE; + e.timer_id = *timer_id; + e.timer_args = timer_args; + e.cb = cb; + + LOG_I(ENB_AGENT,"created a timer with id 0x%lx for agent %d, instance %d \n", + e.timer_id, e.agent_id, e.instance); + + RB_INSERT(enb_agent_map, &enb_agent_head, &e); + + + /* + struct enb_agent_timer_element_s search; + search.timer_id = *timer_id; + printf("search 1: %p (expected %p)\n", RB_FIND(enb_agent_map, &enb_agent_head, &search), &e); + printf("search 1: %p (expected %p)\n", get_timer_entry(e.timer_id), &e); + */ + return 0; +} + +err_code_t enb_agent_destroy_timer(long timer_id){ + + struct enb_agent_timer_element_s *e = get_timer_entry(timer_id); + + if (e != NULL ) { + RB_REMOVE(enb_agent_map, &enb_agent_head, &e); + free(e); + } + + if (timer_remove(timer_id) < 0 ) + goto error; + + return 0; + + error: + LOG_E(ENB_AGENT, "timer can't be removed\n"); + return TIMER_REMOVED_FAILED ; +} + +err_code_t enb_agent_destroy_timers(void){ + + struct enb_agent_timer_element_s *e = NULL; + + RB_FOREACH(e, enb_agent_map, &enb_agent_head) { + RB_REMOVE(enb_agent_map, &enb_agent_head, e); + timer_remove(e->timer_id); + free(e); + } + + return 0; + +} + +struct enb_agent_timer_element_s * get_timer_entry(long timer_id) { + + struct enb_agent_timer_element_s search, *e; + memset(&search, 0, sizeof(struct enb_agent_timer_element_s)); + search.timer_id = timer_id; + + return RB_FIND(enb_agent_map, &enb_agent_head, &search); +} + +/* + int i =0; + RB_FOREACH(e, enb_agent_map, &enb_agent_head) { + printf("%d: %p\n", i, e); i++; + } +*/ + +/* +err_code_t enb_agent_stop_timer(uint32_t timer_id){ + + struct enb_agent_timer_element_s *e=NULL; + + RB_FOREACH(e, enb_agent_map, &enb_agent_head) { + if (e->timer_id == timer_id) + break; + } + + if (e != NULL ) { + e->state = ENB_AGENT_TIMER_STATE_STOPPED; + } + + timer_remove(timer_id); + + return 0; + +} + +// this will change the timer_id +err_code_t enb_agent_restart_timer(uint32_t *timer_id){ + + struct enb_agent_timer_element_s *e=NULL; + + RB_FOREACH(e, enb_agent_map, &enb_agent_head) { + if (e->timer_id == timer_id) + break; + } + + if (e != NULL ) { + e->state = ENB_AGENT_TIMER_STATE_ACTIVE; + } + + ret = timer_setup(e->interval_sec, + e->interval_usec, + e->agent_id, + e->instance, + e->type, + e->timer_args, + &timer_id); + + } + + if (ret < 0 ) { + return PROTOCOL__PROGRAN_ERR__TIMER_SETUP_FAILED; + } + + return 0; + +} + +*/ diff --git a/openair2/ENB_APP/enb_agent_common.h b/openair2/ENB_APP/enb_agent_common.h index 3bb6596f2e..eb3de96145 100644 --- a/openair2/ENB_APP/enb_agent_common.h +++ b/openair2/ENB_APP/enb_agent_common.h @@ -27,9 +27,9 @@ *******************************************************************************/ -/*! \file - * \brief - * \author +/*! \file enb_agent_common.h + * \brief common message primitves and utilities + * \author Navid Nikaein and Xenofon Foukas * \date 2016 * \version 0.1 */ @@ -45,10 +45,20 @@ #include "stats_messages.pb-c.h" #include "stats_common.pb-c.h" +# include "enb_agent_defs.h" + +#include "LAYER2/MAC/extern.h" +#include "LAYER2/RLC/rlc.h" + +# include "tree.h" +# include "intertask_interface.h" +# include "timer.h" + #define PROGRAN_VERSION 0 typedef int (*enb_agent_message_decoded_callback)( - uint32_t xid, + mid_t mod_id, + xid_t xid, const void *params, Protocol__ProgranMessage **msg ); @@ -57,32 +67,163 @@ typedef int (*enb_agent_message_destruction_callback)( Protocol__ProgranMessage *msg ); -typedef int32_t err_code_t; - int enb_agent_serialize_message(Protocol__ProgranMessage *msg, void **buf, int *size); int enb_agent_deserialize_message(void *data, int size, Protocol__ProgranMessage **msg); -int prp_create_header(uint32_t xid, Protocol__PrpType type, Protocol__PrpHeader **header); +int prp_create_header(xid_t xid, Protocol__PrpType type, Protocol__PrpHeader **header); -int enb_agent_hello(uint32_t xid, const void *params, Protocol__ProgranMessage **msg); +int enb_agent_hello(mid_t mod_id, xid_t xid, const void *params, Protocol__ProgranMessage **msg); int enb_agent_destroy_hello(Protocol__ProgranMessage *msg); -int enb_agent_echo_request(uint32_t xid, const void *params, Protocol__ProgranMessage **msg); +int enb_agent_echo_request(mid_t mod_id, xid_t xid, const void *params, Protocol__ProgranMessage **msg); int enb_agent_destroy_echo_request(Protocol__ProgranMessage *msg); -int enb_agent_echo_reply(uint32_t xid, const void *params, Protocol__ProgranMessage **msg); +int enb_agent_echo_reply(mid_t mod_id, xid_t xid, const void *params, Protocol__ProgranMessage **msg); int enb_agent_destroy_echo_reply(Protocol__ProgranMessage *msg); -Protocol__ProgranMessage* enb_agent_handle_message (uint32_t xid, +Protocol__ProgranMessage* enb_agent_handle_message (mid_t mod_id, + xid_t xid, uint8_t *data, uint32_t size); -void * enb_agent_send_message(uint32_t xid, +void * enb_agent_send_message(xid_t xid, Protocol__ProgranMessage *msg, uint32_t * size); + + + + +/**************************** + * get generic info from RAN + ****************************/ + +void set_enb_vars(mid_t mod_id, ran_name_t ran); + +int get_current_time_ms (mid_t mod_id, int subframe_flag); + +int get_num_ues(mid_t mod_id); + +int get_ue_crnti (mid_t mod_id, mid_t ue_id); + +int get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid); + +int get_ue_phr (mid_t mod_id, mid_t ue_id); + +int get_ue_wcqi (mid_t mod_id, mid_t ue_id); + + + + + + +/******************* + * timer primitves + *******************/ + +#define TIMER_NULL -1 +#define TIMER_TYPE_INVALIDE -2 +#define TIMER_SETUP_FAILED -3 +#define TIMER_REMOVED_FAILED -4 +#define TIMER_ELEMENT_NOT_FOUND -5 + + +/* Type of the callback executed when the timer expired */ +typedef err_code_t (*enb_agent_timer_callback_t)(void*); + +typedef enum { + /* oneshot timer: */ + ENB_AGENT_TIMER_TYPE_ONESHOT = 0x0, + + /* periodic timer */ + ENB_AGENT_TIMER_TYPE_PERIODIC = 0x1, + + /* Inactive state: initial state for any timer. */ + ENB_AGENT_TIMER_TYPE_EVENT_DRIVEN = 0x2, + + /* Max number of states available */ + ENB_AGENT_TIMER_TYPE_MAX, +} eNB_agent_timer_type_t; + +typedef enum { + /* Inactive state: initial state for any timer. */ + ENB_AGENT_TIMER_STATE_INACTIVE = 0x0, + + /* Inactive state: initial state for any timer. */ + ENB_AGENT_TIMER_STATE_ACTIVE = 0x1, + + /* Inactive state: initial state for any timer. */ + ENB_AGENT_TIMER_STATE_STOPPED = 0x2, + + /* Max number of states available */ + ENB_AGENT_TIMER_STATE_MAX, +} eNB_agent_timer_state_t; + +typedef struct enb_agent_timer_args_s{ + mid_t mod_id; + + agent_action_t cc_actions; + uint32_t cc_report_flags; + + agent_action_t ue_actions; + uint32_t ue_report_flags; + +} enb_agent_timer_args_t; + + + +typedef struct enb_agent_timer_element_s{ + RB_ENTRY(enb_agent_timer_element_s) entry; + + agent_id_t agent_id; + instance_t instance; + + eNB_agent_timer_type_t type; + eNB_agent_timer_state_t state; + + uint32_t interval_sec; + uint32_t interval_usec; + + long timer_id; /* Timer id returned by the timer API*/ + + enb_agent_timer_callback_t cb; + void* timer_args; + +} enb_agent_timer_element_t; + + +err_code_t enb_agent_init_timer(void); + +err_code_t enb_agent_create_timer(uint32_t interval_sec, + uint32_t interval_usec, + agent_id_t agent_id, + instance_t instance, + uint32_t timer_type, + enb_agent_timer_callback_t cb, + void* timer_args, + long *timer_id); + +err_code_t enb_agent_destroy_timers(void); +err_code_t enb_agent_destroy_timer(long timer_id); + +err_code_t enb_agent_stop_timer(long timer_id); + +err_code_t enb_agent_restart_timer(long *timer_id); + +struct enb_agent_timer_element_s * get_timer_entry(long timer_id); + +int enb_agent_compare_timer(struct enb_agent_timer_element_s *a, struct enb_agent_timer_element_s *b); + +err_code_t enb_agent_process_timeout(long timer_id, void* timer_args); + +RB_HEAD(enb_agent_map, enb_agent_timer_element_s) enb_agent_head; + +/* RB_PROTOTYPE is for .h files */ +RB_PROTOTYPE(enb_agent_map, enb_agent_timer_element_s, entry, enb_agent_compare_timer); + + #endif diff --git a/openair2/ENB_APP/enb_agent_defs.h b/openair2/ENB_APP/enb_agent_defs.h new file mode 100644 index 0000000000..416e61a431 --- /dev/null +++ b/openair2/ENB_APP/enb_agent_defs.h @@ -0,0 +1,142 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2016 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file enb_agent_defs.h + * \brief enb agent common definitions + * \author Navid Nikaein and Xenofon Foukas + * \date 2016 + * \version 0.1 + */ +#ifndef ENB_AGENT_DEFS_H_ +#define ENB_AGENT_DEFS_H_ + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <string.h> + +#include "link_manager.h" + +#define NUM_MAX_ENB_AGENT 2 +#define DEFAULT_ENB_AGENT_IPv4_ADDRESS "127.0.0.1" +#define DEFAULT_ENB_AGENT_PORT 2210 + +typedef enum { + + ENB_AGENT_DEFAULT=0, + + ENB_AGENT_PHY=1, + ENB_AGENT_MAC=2, + ENB_AGENT_RLC=3, + ENB_AGENT_PDCP=4, + ENB_AGENT_RRC=5, + ENB_AGENT_S1AP=6, + ENB_AGENT_GTP=7, + ENB_AGENT_X2AP=8, + + ENB_AGENT_MAX=9, + +} agent_id_t; + +typedef enum { + /* no action */ + ENB_AGENT_ACTION_NONE = 0x0, + + /* send action */ + ENB_AGENT_ACTION_SEND = 0x1, + + /* apply action */ + ENB_AGENT_ACTION_APPLY = 0x2, + + /* clear action */ + ENB_AGENT_ACTION_CLEAR = 0x4, + + /* write action */ + ENB_AGENT_ACTION_WRITE = 0x8, + + /* filter action */ + ENB_AGENT_ACTION_FILTER = 0x10, + + /* preprocess action */ + ENB_AGENT_ACTION_PREPROCESS = 0x20, + + /* meter action */ + ENB_AGENT_ACTION_METER = 0x40, + + /* Max number of states available */ + ENB_AGENT_ACTION_MAX = 0x7f, +} agent_action_t; + + +typedef enum { + + RAN_LTE_OAI= 0, + + /* Max number of states available */ + RAN_NAME_MAX = 0x7f, +} ran_name_t; + +typedef uint8_t xid_t; +typedef uint8_t mid_t; // module or enb id +typedef uint8_t lcid_t; +typedef int32_t err_code_t; + +// tx and rx shared context +typedef struct { + mid_t mod_id; + socket_link_t *link; + message_queue_t *send_queue; + message_queue_t *receive_queue; + link_manager_t *manager; +}enb_agent_instance_t; + +typedef struct { + /* general info */ + uint32_t nb_modules; + + + /* stats */ + + uint32_t total_rx_msg; + uint32_t total_tx_msg; + + uint32_t rx_msg[NUM_MAX_ENB_AGENT]; + uint32_t tx_msg[NUM_MAX_ENB_AGENT]; + +}enb_agent_info_t; + +typedef struct { + mid_t mod_id; + message_queue_t *tx_mq; + message_queue_t *rx_mq; + xid_t tx_xid; + xid_t rx_xid; +} msg_context_t; + +#endif diff --git a/openair2/ENB_APP/enb_agent_handler.c b/openair2/ENB_APP/enb_agent_handler.c index 5049e669e9..27536c8b7f 100644 --- a/openair2/ENB_APP/enb_agent_handler.c +++ b/openair2/ENB_APP/enb_agent_handler.c @@ -27,9 +27,9 @@ *******************************************************************************/ -/*! \file - * \brief - * \author +/*! \file enb_agent_handler.c + * \brief enb agent tx and rx message handler + * \author Navid Nikaein and Xenofon Foukas * \date 2016 * \version 0.1 */ @@ -67,7 +67,8 @@ static const char *enb_agent_direction2String[] = { }; -Protocol__ProgranMessage* enb_agent_handle_message (uint32_t xid, +Protocol__ProgranMessage* enb_agent_handle_message (mid_t mod_id, + xid_t xid, uint8_t *data, uint32_t size){ @@ -92,7 +93,7 @@ Protocol__ProgranMessage* enb_agent_handle_message (uint32_t xid, } - err_code= ((*messages_callback[decoded_message->msg_case-1][decoded_message->msg_dir-1])(xid, (void *) decoded_message, &reply_message)); + err_code = ((*messages_callback[decoded_message->msg_case-1][decoded_message->msg_dir-1])(mod_id, xid, (void *) decoded_message, &reply_message)); if ( err_code < 0 ){ goto error; } @@ -102,16 +103,16 @@ Protocol__ProgranMessage* enb_agent_handle_message (uint32_t xid, return reply_message; error: - LOG_E(ENB_APP,"errno %d occured\n",err_code); - return err_code; + LOG_E(ENB_AGENT,"errno %d occured\n",err_code); + return NULL; } -void * enb_agent_send_message(uint32_t xid, - Protocol__ProgranMessage *msg, - uint32_t * size){ +void * enb_agent_send_message(xid_t xid, + Protocol__ProgranMessage *msg, + uint32_t * size){ void * buffer; err_code_t err_code = PROTOCOL__PROGRAN_ERR__NO_ERR; @@ -126,21 +127,32 @@ void * enb_agent_send_message(uint32_t xid, err_code = ((*message_destruction_callback[msg->msg_case-1])(msg)); DevAssert(buffer !=NULL); - - LOG_D(ENB_APP,"Serilized the enb mac stats reply (size %d)\n", *size); - + + LOG_D(ENB_AGENT,"Serilized the enb mac stats reply (size %d)\n", *size); + return buffer; - -error : -LOG_E(ENB_APP,"errno %d occured\n",err_code); -return NULL; + + error : + LOG_E(ENB_AGENT,"errno %d occured\n",err_code); + + return NULL; } +err_code_t enb_agent_process_timeout(long timer_id, void* timer_args){ + + struct enb_agent_timer_element_s *e = get_timer_entry(timer_id); + + LOG_I(ENB_AGENT, "element %p: timer_id is 0x%lx 0x%lx\n", e, timer_id, e->timer_id); + + if (e == NULL ) goto error; + if (timer_args == NULL) + LOG_W(ENB_AGENT,"null timer args\n"); + + return e->cb(timer_args); + - - - - - - + error: + LOG_E(ENB_AGENT, "can't get the timer element\n"); + return TIMER_ELEMENT_NOT_FOUND; +} diff --git a/openair2/ENB_APP/enb_agent_mac.c b/openair2/ENB_APP/enb_agent_mac.c index 3c188881fb..edf1406296 100644 --- a/openair2/ENB_APP/enb_agent_mac.c +++ b/openair2/ENB_APP/enb_agent_mac.c @@ -27,20 +27,18 @@ *******************************************************************************/ -/*! \file - * \brief - * \author +/*! \file enb_agent_mac.c + * \brief enb agent message handler for MAC layer + * \author Navid Nikaein and Xenofon Foukas * \date 2016 * \version 0.1 */ #include "enb_agent_mac.h" -#include "enb_agent_common.h" -#include "LAYER2/MAC/extern.h" -#include "LAYER2/RLC/rlc.h" + #include "log.h" -int enb_agent_mac_handle_stats(uint32_t xid, const void *params, Protocol__ProgranMessage **msg){ +int enb_agent_mac_handle_stats(mid_t mod_id, xid_t xid, const void *params, Protocol__ProgranMessage **msg){ // TODO: Must deal with sanitization of input // TODO: Must check if RNTIs and cell ids of the request actually exist @@ -52,11 +50,11 @@ int enb_agent_mac_handle_stats(uint32_t xid, const void *params, Protocol__Progr //TODO: We do not deal with multiple CCs at the moment and eNB id is 0 int cc_id = 0; - int enb_id = 0; - - eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; - UE_list_t *eNB_UE_list= &eNB->UE_list; + int enb_id = mod_id; + //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; + //UE_list_t *eNB_UE_list= &eNB->UE_list; + report_config_t report_config; uint32_t ue_flags = 0; @@ -90,7 +88,7 @@ int enb_agent_mac_handle_stats(uint32_t xid, const void *params, Protocol__Progr //Create a list of all eNB RNTIs and cells //Set the number of UEs and create list with their RNTIs stats configs - report_config.nr_ue = eNB_UE_list->num_UEs; + report_config.nr_ue = get_num_ues(mod_id); //eNB_UE_list->num_UEs report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue); if (report_config.ue_report_type == NULL) { // TODO: Add appropriate error code @@ -98,7 +96,7 @@ int enb_agent_mac_handle_stats(uint32_t xid, const void *params, Protocol__Progr goto error; } for (i = 0; i < report_config.nr_ue; i++) { - report_config.ue_report_type[i].ue_rnti = eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti; + report_config.ue_report_type[i].ue_rnti = get_ue_crnti(enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti; report_config.ue_report_type[i].ue_report_flags = ue_flags; } //Set the number of CCs and create a list with the cell stats configs @@ -157,7 +155,7 @@ int enb_agent_mac_handle_stats(uint32_t xid, const void *params, Protocol__Progr goto error; } - if (enb_agent_mac_stats_reply(xid, &report_config, msg) < 0 ){ + if (enb_agent_mac_stats_reply(enb_id, xid, &report_config, msg) < 0 ){ err_code = PROTOCOL__PROGRAN_ERR__MSG_BUILD; goto error; } @@ -168,19 +166,20 @@ int enb_agent_mac_handle_stats(uint32_t xid, const void *params, Protocol__Progr return 0; error : - LOG_E(ENB_APP, "errno %d occured\n", err_code); + LOG_E(ENB_AGENT, "errno %d occured\n", err_code); return err_code; } -int enb_agent_mac_stats_reply(uint32_t xid, +int enb_agent_mac_stats_reply(mid_t mod_id, + xid_t xid, const report_config_t *report_config, Protocol__ProgranMessage **msg) { Protocol__PrpHeader *header; int i, j, k; int cc_id = 0; - int enb_id = 0; - eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; - UE_list_t *eNB_UE_list= &eNB->UE_list; + int enb_id = mod_id; + //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; + //UE_list_t *eNB_UE_list= &eNB->UE_list; if (prp_create_header(xid, PROTOCOL__PRP_TYPE__PRPT_STATS_REPLY, &header) != 0) @@ -226,7 +225,7 @@ int enb_agent_mac_stats_reply(uint32_t xid, for (j = 0; j++; j < ue_report[i]->n_bsr) { // Set the actual BSR for LCG j of the current UE // NN: we need to know the cc_id here, consider the first one - elem[j] = eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].bsr_info[j]; + elem[j] = get_ue_bsr (enb_id, i, j); //eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].bsr_info[j]; } ue_report[i]->bsr = elem; } @@ -234,7 +233,7 @@ int enb_agent_mac_stats_reply(uint32_t xid, /* Check flag for creation of PRH report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__PRP_UE_STATS_TYPE__PRUST_PRH) { // TODO: Fill in the actual power headroom value for the RNTI - ue_report[i]->phr = eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].phr_info; + ue_report[i]->phr = get_ue_phr (enb_id, i); // eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].phr_info; ue_report[i]->has_phr = 1; } @@ -297,7 +296,7 @@ int enb_agent_mac_stats_reply(uint32_t xid, goto error; protocol__prp_dl_cqi_report__init(dl_report); //TODO:Set the SFN and SF of the last report held in the agent. - dl_report->sfn_sn = eNB->frame*10 + eNB->subframe; + dl_report->sfn_sn = get_current_time_ms(enb_id, 1); dl_report->has_sfn_sn = 1; //TODO:Set the number of DL CQI reports for this UE. One for each CC dl_report->n_csi_report = 1; @@ -331,7 +330,7 @@ int enb_agent_mac_stats_reply(uint32_t xid, protocol__prp_csi_p10__init(csi10); //TODO: set the wideband value // NN: this is also depends on cc_id - csi10->wb_cqi = eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].dl_cqi; + csi10->wb_cqi = get_ue_wcqi (enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].dl_cqi; csi10->has_wb_cqi = 1; //Add the type of measurements to the csi report in the proper union type csi_reports[j]->p10csi = csi10; diff --git a/openair2/ENB_APP/enb_agent_mac.h b/openair2/ENB_APP/enb_agent_mac.h index e22253cf27..6584111825 100644 --- a/openair2/ENB_APP/enb_agent_mac.h +++ b/openair2/ENB_APP/enb_agent_mac.h @@ -27,9 +27,9 @@ *******************************************************************************/ -/*! \file - * \brief - * \author +/*! \file enb_agent_mac.h + * \brief enb agent message handler APIs for MAC layer + * \author Navid Nikaein and Xenofon Foukas * \date 2016 * \version 0.1 */ @@ -42,6 +42,8 @@ #include "stats_messages.pb-c.h" #include "stats_common.pb-c.h" +#include "enb_agent_common.h" + /* These types will be used to give instructions for the type of stats reports @@ -68,9 +70,9 @@ typedef struct { } report_config_t; -int enb_agent_mac_handle_stats(uint32_t xid, const void *params, Protocol__ProgranMessage **msg); +int enb_agent_mac_handle_stats(mid_t mod_id, xid_t xid, const void *params, Protocol__ProgranMessage **msg); -int enb_agent_mac_stats_reply(uint32_t xid, const report_config_t *report_config, Protocol__ProgranMessage **msg); +int enb_agent_mac_stats_reply(mid_t mod_id, xid_t xid, const report_config_t *report_config, Protocol__ProgranMessage **msg); int enb_agent_mac_destroy_stats_reply(Protocol__ProgranMessage *msg); diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index d63d895711..b20d0912d8 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -315,8 +315,11 @@ void *eNB_app_task(void *args_p) } #if defined (ENB_AGENT_SB_IF) - printf("\n start enb agent\n"); - enb_agent_start(); + + for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { + printf("\n start enb agent %d\n", enb_id); + enb_agent_start(enb_id, enb_properties_p); + } #endif # if defined(ENABLE_USE_MME) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 07e0ffa640..39bd5028d8 100755 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -170,6 +170,11 @@ #define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U "ENB_IPV4_ADDRESS_FOR_S1U" #define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U" +#define ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG "NETWORK_CONTROLLER" +#define ENB_CONFIG_STRING_ENB_AGENT_INTERFACE_NAME "ENB_AGENT_INTERFACE_NAME" +#define ENB_CONFIG_STRING_ENB_AGENT_IPV4_ADDRESS "ENB_AGENT_IPV4_ADDRESS" +#define ENB_CONFIG_STRING_ENB_AGENT_PORT "ENB_AGENT_PORT" + #define ENB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity" #define ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE "none" @@ -275,6 +280,14 @@ static void enb_config_display(void) printf( "\tMNC: \t%02"PRIu16":\n",enb_properties.properties[i]->mnc); } +#if defined(ENB_AGENT_SB_IF) + printf( "\nENB AGENT CONFIG : \n\n"); + printf( "\tInterface name: \t%s:\n",enb_properties.properties[i]->enb_agent_interface_name); + printf( "\tInterface IP Address: \t%s:\n",enb_properties.properties[i]->enb_agent_ipv4_address); + printf( "\tInterface PORT: \t%d:\n\n",enb_properties.properties[i]->enb_agent_port); + +#endif + for (j=0; j< enb_properties.properties[i]->nb_cc; j++) { printf( "\teutra band for CC %d: \t%"PRId16":\n",j,enb_properties.properties[i]->eutra_band[j]); printf( "\tdownlink freq for CC %d: \t%"PRIu64":\n",j,enb_properties.properties[i]->downlink_frequency[j]); @@ -571,6 +584,9 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) char *address = NULL; char *cidr = NULL; char *astring = NULL; + char* enb_agent_interface_name = NULL; + char* enb_agent_ipv4_address = NULL; + libconfig_int enb_agent_port = 0; libconfig_int otg_ue_id = 0; char* otg_app_type = NULL; char* otg_bg_traffic = NULL; @@ -2190,6 +2206,33 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) } } } + + // Network Controller + subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG); + + if (subsetting != NULL) { + if ( ( + config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_AGENT_INTERFACE_NAME, + (const char **)&enb_agent_interface_name) + && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_AGENT_IPV4_ADDRESS, + (const char **)&enb_agent_ipv4_address) + && config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_ENB_AGENT_PORT, + &enb_agent_port) + ) + ) { + enb_properties.properties[enb_properties_index]->enb_agent_interface_name = strdup(enb_agent_interface_name); + cidr = enb_agent_ipv4_address; + address = strtok(cidr, "/"); + enb_properties.properties[enb_properties_index]->enb_agent_ipv4_address = strdup(address); + /* if (address) { + IPV4_STR_ADDR_TO_INT_NWBO (address, enb_properties.properties[enb_properties_index]->enb_agent_ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB Agent !\n" ); + }*/ + + enb_properties.properties[enb_properties_index]->enb_agent_port = enb_agent_port; + + } + } + // OTG _CONFIG setting_otg = config_setting_get_member (setting_enb, ENB_CONF_STRING_OTG_CONFIG); diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index 113681dafe..7182628de0 100755 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -203,6 +203,9 @@ typedef struct Enb_properties_s { char *enb_interface_name_for_S1_MME; in_addr_t enb_ipv4_address_for_S1_MME; + char *enb_agent_interface_name; + in_addr_t enb_agent_ipv4_address; + tcp_udp_port_t enb_agent_port; // otg config /* Nb of OTG elements */ uint8_t num_otg_elements; diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c index abbdbc01ab..f8326be820 100755 --- a/openair2/UTIL/LOG/log.c +++ b/openair2/UTIL/LOG/log.c @@ -333,6 +333,14 @@ int logInit (void) g_log->log_component[ENB_APP].filelog = 0; g_log->log_component[ENB_APP].filelog_name = ""; + g_log->log_component[ENB_AGENT].name = "ENB_AGENT"; + g_log->log_component[ENB_AGENT].level = LOG_DEBUG; + g_log->log_component[ENB_AGENT].flag = LOG_MED; + g_log->log_component[ENB_AGENT].interval = 1; + g_log->log_component[ENB_AGENT].fd = 0; + g_log->log_component[ENB_AGENT].filelog = 0; + g_log->log_component[ENB_AGENT].filelog_name = ""; + g_log->log_component[TMR].name = "TMR"; g_log->log_component[TMR].level = LOG_EMERG; g_log->log_component[TMR].flag = LOG_MED; diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index c6abbfa001..1eb68f6e44 100755 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -264,6 +264,7 @@ typedef enum { RAL_ENB, RAL_UE, ENB_APP, + ENB_AGENT, TMR, USIM, LOCALIZE, diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.agent.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.agent.oaisim.local_no_mme.conf new file mode 100644 index 0000000000..045a2855a0 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.agent.oaisim.local_no_mme.conf @@ -0,0 +1,153 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "10"; + + ////////// Physical parameters: + + component_carriers = ( + { + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 25; + rx_gain = 20; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = 0; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 0; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -108; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -108; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 2; + rach_preambleInitialReceivedTargetPower = -100; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + } + ); + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "0.0.0.0"; + ipv6 = "0::0"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "none"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "0.0.0.0/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "none"; + ENB_IPV4_ADDRESS_FOR_S1U = "0.0.0.0/24"; + ENB_PORT_FOR_S1U = 2153; # Spec 2152 + }; + + NETWORK_CONTROLLER : + { + ENB_AGENT_INTERFACE_NAME = "eth0"; + ENB_AGENT_IPV4_ADDRESS = "127.0.0.1/24"; + ENB_AGENT_PORT = 2210; + }; + + log_config : + { + global_log_level ="trace"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="trace"; + phy_log_verbosity ="medium"; + mac_log_level ="trace"; + mac_log_verbosity ="medium"; + rlc_log_level ="trace"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="trace"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="trace"; + rrc_log_verbosity ="medium"; + gtpu_log_level ="debug"; + gtpu_log_verbosity ="medium"; + udp_log_level ="debug"; + udp_log_verbosity ="medium"; + osa_log_level ="debug"; + osa_log_verbosity ="low"; + }; + + } +); -- 2.26.2