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_*/