diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 0777e1f3a0..8cd37613fa 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -747,6 +747,7 @@ if (ENB_AGENT_SB_IF) ${OPENAIR2_DIR}/ENB_APP/enb_agent_mac.c ${OPENAIR2_DIR}/ENB_APP/enb_agent.c ${OPENAIR2_DIR}/ENB_APP/enb_agent_task_manager.c + ${OPENAIR2_DIR}/ENB_APP/enb_agent_net_comm.c ) set(ENB_AGENT_LIB ENB_AGENT) #include_directories(${OPENAIR2_DIR}/ENB_APP) diff --git a/openair2/ENB_APP/enb_agent_net_comm.c b/openair2/ENB_APP/enb_agent_net_comm.c new file mode 100644 index 0000000000..096779f261 --- /dev/null +++ b/openair2/ENB_APP/enb_agent_net_comm.c @@ -0,0 +1,196 @@ +/******************************************************************************* + 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 . + + 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_net_comm.c + * \brief enb agent network interface abstraction + * \author Xenofon Foukas + * \date 2016 + * \version 0.1 + */ + +#include "enb_agent_net_comm.h" +#include "log.h" + +enb_agent_channel_t *agent_channel[ENB_AGENT_MAX]; +enb_agent_channel_instance_t channel_instance; +int enb_agent_channel_id = 0; + +int enb_agent_msg_send(void *data, int size, int priority, agent_id_t agent_id) { + /*Check if agent id is valid*/ + if (agent_id >= ENB_AGENT_MAX || agent_id < 0) { + goto error; + } + enb_agent_channel_t *channel; + channel = agent_channel[agent_id]; + + /*Check if agent has a channel registered*/ + if (channel == NULL) { + goto error; + } + + return channel->msg_send(data, size, priority, channel->channel_info); + + error: + LOG_E(ENB_AGENT, "No channel registered for agent with id %d\n", agent_id); + return -1; +} + +int enb_agent_msg_recv(void **data, int *size, int *priority, agent_id_t agent_id) { + /*Check if agent id is valid*/ + if (agent_id >= ENB_AGENT_MAX || agent_id < 0) { + goto error; + } + enb_agent_channel_t *channel; + channel = agent_channel[agent_id]; + + /*Check if agent has a channel registered*/ + if (channel == NULL) { + goto error; + } + + return channel->msg_recv(data, size, priority, channel->channel_info); + + error: + LOG_E(ENB_AGENT, "No channel registered for agent with id %d\n", agent_id); + return -1; +} + +int enb_agent_register_channel(enb_agent_channel_t *channel, agent_id_t agent_id) { + int i; + + if (channel == NULL) { + return -1; + } + + if (agent_id == ENB_AGENT_MAX) { + for (i = 0; i < ENB_AGENT_MAX; i++) { + agent_channel[i] = channel; + } + } else { + agent_channel[agent_id] = channel; + } + return 0; +} + +void enb_agent_unregister_channel(agent_id_t agent_id) { + int i; + + if (agent_id == ENB_AGENT_MAX) { + for (i = 0; i < ENB_AGENT_MAX; i++) { + agent_channel[i] = NULL; + } + } else { + agent_channel[agent_id] = NULL; + } +} + +int enb_agent_create_channel(void *channel_info, + int (*msg_send)(void *data, int size, int priority, void *channel_info), + int (*msg_recv)(void **data, int *size, int *priority, void *channel_info), + void (*release)(enb_agent_channel_t *channel)) { + + int channel_id = ++enb_agent_channel_id; + enb_agent_channel_t *channel = (enb_agent_channel_t *) malloc(sizeof(enb_agent_channel_t)); + channel->channel_id = channel_id; + channel->channel_info = channel_info; + channel->msg_send = msg_send; + channel->msg_recv = msg_recv; + channel->release = release; + + /*element should be a real pointer*/ + RB_INSERT(enb_agent_channel_map, &channel_instance.enb_agent_head, channel); + + LOG_I(ENB_AGENT,"Created a new channel with id 0x%lx\n", channel->channel_id); + + return channel_id; +} + +int enb_agent_destroy_channel(int channel_id) { + int i; + + /*Check to see if channel exists*/ + struct enb_agent_channel_s *e = NULL; + struct enb_agent_channel_s search; + memset(&search, 0, sizeof(struct enb_agent_channel_s)); + + e = RB_FIND(enb_agent_channel_map, &channel_instance.enb_agent_head, &search); + + if (e == NULL) { + return -1; + } + + /*Unregister the channel from all agents*/ + for (i = 0; i < ENB_AGENT_MAX; i++) { + if (agent_channel[i] != NULL) { + if (agent_channel[i]->channel_id == e->channel_id) { + agent_channel[i] == NULL; + } + } + } + + /*Remove the channel from the tree and free memory*/ + RB_REMOVE(enb_agent_channel_map, &channel_instance.enb_agent_head, e); + e->release(e); + free(e); + + return 0; +} + +err_code_t enb_agent_init_channel_container(void) { + int i; + LOG_I(ENB_AGENT, "init RB tree for channel container\n"); + + RB_INIT(&channel_instance.enb_agent_head); + + for (i = 0; i < ENB_AGENT_MAX; i++) { + agent_channel[i] == NULL; + } + + return 0; +} + +RB_GENERATE(enb_agent_channel_map,enb_agent_channel_s, entry, enb_agent_compare_channel); + +int enb_agent_compare_channel(struct enb_agent_channel_s *a, struct enb_agent_channel_s *b) { + if (a->channel_id < b->channel_id) return -1; + if (a->channel_id > b->channel_id) return 1; + + // equal timers + return 0; +} + +enb_agent_channel_t * get_channel(int channel_id) { + + struct enb_agent_channel_s search; + memset(&search, 0, sizeof(struct enb_agent_channel_s)); + search.channel_id = channel_id; + + return RB_FIND(enb_agent_channel_map, &channel_instance.enb_agent_head, &search); + +} diff --git a/openair2/ENB_APP/enb_agent_net_comm.h b/openair2/ENB_APP/enb_agent_net_comm.h new file mode 100644 index 0000000000..50237379d4 --- /dev/null +++ b/openair2/ENB_APP/enb_agent_net_comm.h @@ -0,0 +1,90 @@ +/******************************************************************************* + 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 . + + 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_net_comm.h + * \brief enb agent network interface abstraction + * \autho Xenofon Foukas + * \date 2016 + * \version 0.1 + */ +#ifndef ENB_AGENT_NET_COMM_H_ +#define ENB_AGENT_NET_COMM_H_ + +#include "enb_agent_defs.h" + +#include "tree.h" + +/*Channel related information used for Tx/Rx of protocol messages*/ +typedef struct enb_agent_channel_s { + RB_ENTRY(enb_agent_channel_s) entry; +int channel_id; +void *channel_info; +/*Callbacks for channel message Tx and Rx*/ +int (*msg_send)(void *data, int size, int priority, void *channel_info); +int (*msg_recv)(void **data, int *size, int *priority, void *channel_info); +void (*release)(struct enb_agent_channel_s *channel); +} enb_agent_channel_t; + +typedef struct enb_agent_channel_instance_s{ + RB_HEAD(enb_agent_channel_map, enb_agent_channel_s) enb_agent_head; +} enb_agent_channel_instance_t; + +/*Send and receive messages using the channel registered for a specific agent*/ +int enb_agent_msg_send(void *data, int size, int priority, agent_id_t agent_id); + +int enb_agent_msg_recv(void **data, int *size, int *priority, agent_id_t agent_id); + +/*Register a channel to an agent. Use ENB_AGENT_MAX to register the + *same channel to all agents*/ +int enb_agent_register_channel(enb_agent_channel_t *channel, agent_id_t agent_id); + +/*Unregister the current channel of an agent. Use ENB_AGENT_MAX to unregister all channels*/ +void enb_agent_unregister_channel(agent_id_t agent_id); + +/*Create a new channel. Returns the id of the new channel or negative number otherwise*/ +int enb_agent_create_channel(void *channel_info, + int (*msg_send)(void *data, int size, int priority, void *channel_info), + int (*msg_recv)(void **data, int *size, int *priority, void *channel_info), + void (*release)(enb_agent_channel_t *channel)); + +/*Unregister a channel from all agents and destroy it. Returns 0 in case of success*/ +int enb_agent_destroy_channel(int channel_id); + +/*Return an agent communication channel based on its id*/ +enb_agent_channel_t * get_channel(int channel_id); + +/*Should be called before performing any channel operations*/ +err_code_t enb_agent_init_channel_container(void); + +int enb_agent_compare_channel(struct enb_agent_channel_s *a, struct enb_agent_channel_s *b); + +/* RB_PROTOTYPE is for .h files */ +RB_PROTOTYPE(enb_agent_channel_map, enb_agent_channel_s, entry, enb_agent_compare_channel); + +#endif /*ENB_AGENT_COMM_H_*/