290 lines
8.5 KiB
C
290 lines
8.5 KiB
C
/*******************************************************************************
|
|
OpenAirInterface
|
|
Copyright(c) 1999 - 2014 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.h
|
|
* \brief top level enb agent receive thread and itti task
|
|
* \author Navid Nikaein and Xenofon Foukas
|
|
* \date 2016
|
|
* \version 0.1
|
|
*/
|
|
#include "proto_agent_common.h"
|
|
#include "common/utils/LOG/log.h"
|
|
#include "proto_agent.h"
|
|
#include "assertions.h"
|
|
#include "proto_agent_net_comm.h"
|
|
#include "proto_agent_async.h"
|
|
|
|
#define ENB_AGENT_MAX 9
|
|
|
|
proto_agent_instance_t proto_agent[MAX_DU];
|
|
|
|
pthread_t new_thread(void *(*f)(void *), void *b);
|
|
|
|
Protocol__FlexsplitMessage *proto_agent_timeout_fsp(void* args);
|
|
|
|
#define TEST_MOD 0
|
|
|
|
#define ECHO
|
|
|
|
/* Server side function; upon a new connection
|
|
reception, sends the hello packets
|
|
*/
|
|
int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p)
|
|
{
|
|
int channel_id;
|
|
|
|
// RS: CUDU does not work!
|
|
//DevAssert(p->local_interface);
|
|
//DevAssert(p->local_ipv4_address);
|
|
//DevAssert(p->local_port > 1024); // "unprivileged" port
|
|
//DevAssert(p->remote_ipv4_address);
|
|
//DevAssert(p->remote_port > 1024); // "unprivileged" port
|
|
|
|
proto_agent[mod_id].mod_id = mod_id;
|
|
|
|
/* Initialize the channel container */
|
|
|
|
/* TODO only initialize the first time */
|
|
proto_agent_init_channel_container();
|
|
|
|
/*Create the async channel info*/
|
|
proto_agent_async_channel_t *channel_info;
|
|
channel_info = proto_agent_async_channel_info(mod_id, p->local_ipv4_address, p->local_port,
|
|
p->remote_ipv4_address, p->remote_port);
|
|
if (!channel_info) goto error;
|
|
|
|
/* Create a channel using the async channel info */
|
|
channel_id = proto_agent_create_channel((void *) channel_info,
|
|
proto_agent_async_msg_send,
|
|
proto_agent_async_msg_recv,
|
|
proto_agent_async_release);
|
|
if (channel_id <= 0) goto error;
|
|
|
|
proto_agent_channel_t *channel = proto_agent_get_channel(channel_id);
|
|
if (!channel) goto error;
|
|
proto_agent[mod_id].channel = channel;
|
|
|
|
/* Register the channel for all underlying agents (use ENB_AGENT_MAX) */
|
|
proto_agent_register_channel(mod_id, channel, ENB_AGENT_MAX);
|
|
|
|
// Code for sending the HELLO/ECHO_REQ message once a connection is established
|
|
//uint8_t *msg = NULL;
|
|
//Protocol__FlexsplitMessage *init_msg=NULL;
|
|
|
|
//if (udp == 0)
|
|
//{
|
|
// // If the comm is not UDP, allow the server to send the first packet over the channel
|
|
// //printf( "Proto agent Server: Calling the echo_request packet constructor\n");
|
|
// msg_flag = proto_agent_echo_request(mod_id, NULL, &init_msg);
|
|
// if (msg_flag != 0)
|
|
// goto error;
|
|
//
|
|
// int msgsize = 0;
|
|
// if (init_msg != NULL)
|
|
// msg = proto_agent_pack_message(init_msg, &msgsize);
|
|
|
|
// if (msg!= NULL)
|
|
// {
|
|
// LOG_D(PROTO_AGENT, "Server sending the message over the async channel\n");
|
|
// proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, (void *) channel_info);
|
|
// }
|
|
// /* After sending the message, wait for any replies;
|
|
// the server thread blocks until it reads any data
|
|
// over the channel
|
|
// */
|
|
|
|
//}
|
|
|
|
proto_agent[mod_id].recv_thread = new_thread(proto_agent_receive, &proto_agent[mod_id]);
|
|
|
|
fprintf(stderr, "[PROTO_AGENT] server started at port %s:%d\n", p->local_ipv4_address, p->local_port);
|
|
return 0;
|
|
|
|
error:
|
|
LOG_E(PROTO_AGENT, "there was an error\n");
|
|
return 1;
|
|
|
|
}
|
|
|
|
void proto_agent_stop(mod_id_t mod_id)
|
|
{
|
|
proto_agent_destroy_channel(proto_agent[mod_id].channel->channel_id);
|
|
}
|
|
|
|
//void
|
|
//proto_agent_send_hello(void)
|
|
//{
|
|
// uint8_t *msg = NULL;
|
|
// Protocol__FlexsplitMessage *init_msg=NULL;
|
|
// int msg_flag = 0;
|
|
//
|
|
//
|
|
// //printf( "PDCP agent: Calling the HELLO packet constructor\n");
|
|
// msg_flag = proto_agent_hello(proto_agent[TEST_MOD].mod_id, NULL, &init_msg);
|
|
//
|
|
// int msgsize = 0;
|
|
// if (msg_flag == 0)
|
|
// {
|
|
// proto_agent_serialize_message(init_msg, &msg, &msgsize);
|
|
// }
|
|
//
|
|
// LOG_D(PROTO_AGENT, "Agent sending the message over the async channel\n");
|
|
// proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, (void *) client_channel[TEST_MOD]);
|
|
//}
|
|
|
|
|
|
void
|
|
proto_agent_send_rlc_data_req(const protocol_ctxt_t* const ctxt_pP,
|
|
const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP,
|
|
const rb_id_t rb_idP, const mui_t muiP,
|
|
confirm_t confirmP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP)
|
|
{
|
|
uint8_t *msg = NULL;
|
|
Protocol__FlexsplitMessage *init_msg=NULL;
|
|
int msg_flag = 0;
|
|
int msgsize = 0;
|
|
mod_id_t mod_id = ctxt_pP->module_id;
|
|
data_req_args args;
|
|
|
|
DevAssert(proto_agent[mod_id].channel);
|
|
DevAssert(proto_agent[mod_id].channel->channel_info);
|
|
|
|
args.ctxt = ctxt_pP;
|
|
args.srb_flag = srb_flagP;
|
|
args.MBMS_flag = MBMS_flagP;
|
|
args.rb_id = rb_idP;
|
|
args.mui = muiP;
|
|
args.confirm = confirmP;
|
|
args.sdu_size = sdu_sizeP;
|
|
args.sdu_p = sdu_pP;
|
|
|
|
msg_flag = proto_agent_pdcp_data_req(mod_id, (void *) &args, &init_msg);
|
|
if (msg_flag != 0 || !init_msg) goto error;
|
|
|
|
msg = proto_agent_pack_message(init_msg, &msgsize);
|
|
if (!msg) goto error;
|
|
|
|
proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, proto_agent[mod_id].channel->channel_info);
|
|
|
|
return;
|
|
error:
|
|
LOG_E(PROTO_AGENT, "PROTO_AGENT there was an error\n");
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
void
|
|
proto_agent_send_pdcp_data_ind(const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP,
|
|
const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP)
|
|
{
|
|
uint8_t *msg = NULL;
|
|
Protocol__FlexsplitMessage *init_msg = NULL;
|
|
int msg_flag = 0;
|
|
int msgsize = 0;
|
|
mod_id_t mod_id = ctxt_pP->module_id;
|
|
data_req_args args;
|
|
|
|
DevAssert(proto_agent[mod_id].channel);
|
|
DevAssert(proto_agent[mod_id].channel->channel_info);
|
|
|
|
args.ctxt = ctxt_pP;
|
|
args.srb_flag = srb_flagP;
|
|
args.MBMS_flag = MBMS_flagP;
|
|
args.rb_id = rb_idP;
|
|
args.sdu_size = sdu_sizeP;
|
|
args.sdu_p = sdu_pP;
|
|
|
|
msg_flag = proto_agent_pdcp_data_ind(mod_id, (void *) &args, &init_msg);
|
|
if (msg_flag != 0 || !init_msg) goto error;
|
|
|
|
msg = proto_agent_pack_message(init_msg, &msgsize);
|
|
if (!msg) goto error;
|
|
|
|
proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, proto_agent[mod_id].channel->channel_info);
|
|
|
|
return;
|
|
|
|
error:
|
|
LOG_E(PROTO_AGENT, "there was an error in %s\n", __func__);
|
|
return;
|
|
|
|
}
|
|
|
|
void *
|
|
proto_agent_receive(void *args)
|
|
{
|
|
proto_agent_instance_t *inst = args;
|
|
void *data = NULL;
|
|
int size;
|
|
int priority;
|
|
err_code_t err_code;
|
|
|
|
Protocol__FlexsplitMessage *msg;
|
|
uint8_t *ser_msg;
|
|
|
|
while (1) {
|
|
|
|
msg = NULL;
|
|
ser_msg = NULL;
|
|
|
|
if (proto_agent_async_msg_recv(&data, &size, &priority, inst->channel->channel_info)){
|
|
err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING;
|
|
goto error;
|
|
}
|
|
|
|
LOG_D(PROTO_AGENT, "Server side Received message with size %d and priority %d, calling message handle\n", size, priority);
|
|
|
|
msg = proto_agent_handle_message(inst->mod_id, data, size);
|
|
if (!msg) {
|
|
LOG_D(PROTO_AGENT, "msg to send back is NULL\n");
|
|
continue;
|
|
}
|
|
|
|
ser_msg = proto_agent_pack_message(msg, &size);
|
|
if (!ser_msg) {
|
|
continue;
|
|
}
|
|
|
|
LOG_D(PROTO_AGENT, "Server sending the reply message over the async channel\n");
|
|
if (proto_agent_async_msg_send((void *)ser_msg, (int) size, 1, inst->channel->channel_info)){
|
|
err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING;
|
|
goto error;
|
|
LOG_D(PROTO_AGENT, "sent message with size %d\n", size);
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
error:
|
|
LOG_E(PROTO_AGENT, "proto_agent_receive(): error %d occured\n",err_code);
|
|
return NULL;
|
|
}
|