From 9f3b8cb9f8b3b32b70807287608fc7bce25f9c8b Mon Sep 17 00:00:00 2001 From: Nikos Makris Date: Thu, 15 Sep 2016 18:38:31 +0300 Subject: [PATCH] Added support for the UL split: TODO: 1) connection to UEs is broken (tested for oaisim) 2) Memory management problems, oaisim is exiting for large rates of traffic --- openair2/LAYER2/PROTO_AGENT/proto_agent.c | 297 ++++++++++-------- openair2/LAYER2/PROTO_AGENT/proto_agent.h | 1 + .../LAYER2/PROTO_AGENT/proto_agent_common.c | 267 ++++++++++++++-- .../LAYER2/PROTO_AGENT/proto_agent_common.h | 250 +-------------- .../LAYER2/PROTO_AGENT/proto_agent_handler.c | 29 +- openair2/LAYER2/RLC/rlc.c | 15 +- targets/COMMON/MESSAGES/V2/flexsplit.proto | 6 + targets/COMMON/MESSAGES/V2/header.proto | 1 + 8 files changed, 435 insertions(+), 431 deletions(-) diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent.c b/openair2/LAYER2/PROTO_AGENT/proto_agent.c index 0a1549afcd..069dab1c95 100644 --- a/openair2/LAYER2/PROTO_AGENT/proto_agent.c +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent.c @@ -216,10 +216,12 @@ int proto_server_start(mid_t mod_id, const Enb_properties_array_t* enb_propertie msg_flag = proto_agent_hello(mod_id, NULL, &init_msg); #endif + if (msg_flag != 0) + goto error; + int msgsize = 0; int err_code; msg = proto_agent_pack_message(init_msg, &msgsize); - //proto_agent_serialize_message(init_msg, &msg, &msgsize); LOG_I(PROTO_AGENT,"Server sending the message over the async channel\n"); proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, (void *) channel_info); @@ -231,36 +233,7 @@ int proto_server_start(mid_t mod_id, const Enb_properties_array_t* enb_propertie LOG_I(PROTO_AGENT, "Server reading any message over the async channel.\n"); - while (1) { - LOG_I(PROTO_AGENT, "Server reading any message over the async channel.\n"); - if (proto_agent_async_msg_recv(&rep_msg, &size, &priority, channel_info)){ - //(mod_id, PROTO_AGENT_DEFAULT, &rep_msg, &size, &priority)) { - err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING; - goto error; - } - - LOG_I(PROTO_AGENT,"Server received reply message with size %d and priority %d, calling message handler\n", size, priority); - - msg=proto_agent_handle_message(mod_id, rep_msg, size); - - if (msg == NULL) - { - LOG_I(PROTO_AGENT,"Server msg to send back is NULL\n"); - } - else - { //(msg != NULL){ - ser_msg = proto_agent_pack_message(msg, &size); - //proto_agent_serialize_message(msg, &ser_msg, &size); - -// if (proto_agent_msg_send(mod_id, PROTO_AGENT_DEFAULT, msg, size, priority)) { - if (proto_agent_async_msg_send((void *)ser_msg, (int) size, 1, (void *) channel_info)) { - - err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING; - goto error; - } - LOG_I(PROTO_AGENT,"sent message with size %d\n", size); - } - } + new_thread(proto_server_receive, &proto_server[mod_id]); LOG_I(PROTO_AGENT,"server ends\n"); return 0; @@ -316,13 +289,6 @@ int proto_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties /*Register the channel for all underlying agents (use ENB_AGENT_MAX)*/ proto_agent_register_channel(mod_id, channel, ENB_AGENT_MAX); - - /*Example of registration for a specific agent(MAC): - *enb_agent_register_channel(mod_id, channel, ENB_AGENT_MAC); - */ - - // Do not call a new thread, but do the msg exchange without threads - //new_thread(receive_thread, &proto_agent[mod_id]); void *data; int size; @@ -331,34 +297,8 @@ int proto_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties Protocol__FlexsplitMessage *msg; Protocol__FlexsplitMessage *ser_msg; - if (proto_agent_async_msg_recv(&data, &size, &priority, channel_info)) { - err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING; - goto error; - } - LOG_I(PROTO_AGENT,"Received message with size %d and priority %d, calling message handle\n", size, priority); - - msg=proto_agent_handle_message(proto_agent[mod_id].enb_id, data, size); - - if (msg == NULL) - { - LOG_I(PROTO_AGENT," CLIENT msg to send back is NULL\n"); - } - - //free(data); - - if (msg != NULL){ - ser_msg = proto_agent_pack_message(msg, &size); - //proto_agent_serialize_message(msg, &ser_msg, &size); - if( proto_agent_async_msg_send((void *)ser_msg, (int) size, 1, (void *) channel_info)){ - err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING; - goto error; - } - LOG_I(PROTO_AGENT,"CLIENT sent message with size %d\n", size); - } - - - //LOG_D(PROTO_AGENT, "Client launched the the receive thread for mod_id %d\n", proto_agent[mod_id]); + new_thread(proto_client_receive, &proto_agent[mod_id]); return 0; @@ -368,23 +308,20 @@ error: } - void proto_agent_send_hello(void) { Protocol__FlexsplitMessage *msg = NULL; Protocol__FlexsplitMessage *init_msg=NULL; - //Protocol__FlexsplitMessage *rep_msg=NULL; int msg_flag = 0; - //int priority; - //int size; + LOG_D(PROTO_AGENT, "PDCP agent Server: Calling the hello packet constructor\n"); msg_flag = proto_agent_hello(proto_agent[client_mod].enb_id, NULL, &init_msg); int msgsize = 0; //int err_code; - if (msg_flag > 0) + if (msg_flag == 0) { proto_agent_serialize_message(init_msg, &msg, &msgsize); } @@ -416,8 +353,6 @@ proto_agent_send_rlc_data_req(const protocol_ctxt_t* const ctxt_pP, const srb_fl LOG_D(PROTO_AGENT, "PDCP agent Server: Calling the hello packet constructor\n"); - //EDW - printf("instance is %u, %u\n", ctxt_pP->instance, ctxt_pP->frame); data_req_args *args = malloc(sizeof(data_req_args)); args->ctxt = malloc(sizeof(protocol_ctxt_t)); @@ -432,59 +367,93 @@ proto_agent_send_rlc_data_req(const protocol_ctxt_t* const ctxt_pP, const srb_fl memcpy(args->sdu_p, sdu_pP->data, sdu_sizeP); msg_flag = proto_agent_pdcp_data_req(proto_agent[client_mod].enb_id, (void *) args, &init_msg); + if (msg_flag != 0) + goto error; - printf("PROTO_AGENT msg flag is %d", msg_flag); int msgsize = 0; - //int err_code; - msg = proto_agent_pack_message(init_msg, &msgsize); + if (init_msg != NULL) + { + printf("Will pack the message\n"); + msg = proto_agent_pack_message(init_msg, &msgsize); - free(init_msg); + printf("Will free the message\n"); + free(init_msg); - LOG_I(PROTO_AGENT,"Server sending the pdcp data_req message over the async channel\n"); + LOG_I(PROTO_AGENT,"Server sending the pdcp data_req message over the async channel\n"); - proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, (void *) client_channel); + if (msg!=NULL) + proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, (void *) client_channel); - // Block until you receive the ACK with the op code - // while (1) { - /* - msg = NULL; - rep = NULL;*/ - //data = NULL; - msgsize = 0; - priority = 0; - msg = NULL; - - while (rep == NULL) + } + else + { + goto error; + } + + return; +error: + LOG_E(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) +{ + printf("PROTOPDCP: Sending Data Indication over the async channel\n"); + + Protocol__FlexsplitMessage *msg = NULL; + Protocol__FlexsplitMessage *init_msg = NULL; + Protocol__FlexsplitMessage *rep = NULL; + Protocol__FlexsplitMessage *srep = NULL; + + //Protocol__FlexsplitMessage *rep_msg=NULL; + int msg_flag = 0; + void *data=NULL; + int priority; + int size; + int ret; + int err_code; + + LOG_D(PROTO_AGENT, "PDCP agent Server: Calling the hello packet constructor\n"); + + data_req_args *args = malloc(sizeof(data_req_args)); + + args->ctxt = malloc(sizeof(protocol_ctxt_t)); + memcpy(args->ctxt, ctxt_pP, sizeof(protocol_ctxt_t)); + args->srb_flag = srb_flagP; + args->MBMS_flag = MBMS_flagP; + args->rb_id = rb_idP; + args->sdu_size = sdu_sizeP; + args->sdu_p = malloc(sdu_sizeP); + memcpy(args->sdu_p, sdu_pP->data, sdu_sizeP); + + msg_flag = proto_agent_pdcp_data_ind(proto_server[server_mod].enb_id, (void *) args, &init_msg); + if (msg_flag != 0) + goto error; + + int msgsize = 0; + + if (init_msg != NULL) + { + printf("Will pack the message \n"); + msg = proto_agent_pack_message(init_msg, &msgsize); + printf("packed the message \n"); + free(init_msg); + + if (msg!=NULL) { - if (proto_agent_async_msg_recv(&rep, &msgsize, &priority, client_channel)) { - err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING; - goto error; - } + LOG_I(PROTO_AGENT,"Server sending the pdcp data_ind message over the async channel\n"); + proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, (void *) server_channel); } - LOG_D(PROTO_AGENT,"Received message with size %d and priority %d, calling message handle\n", size, priority); - - msg = proto_agent_handle_message(proto_agent[client_mod].enb_id, rep, msgsize); - - if (msg == NULL) - { - LOG_E(PROTO_AGENT,"msg to send back is NULL\n"); - } - else - { - srep = proto_agent_pack_message(rep, &size); - - //free(data); - - - if (proto_agent_async_msg_send((void *)msg, (int) size, 1, (void *) client_channel)){ - //if (proto_agent_msg_send(proto_agent[client_mod].enb_id, PROTO_AGENT_DEFAULT, msg, size, priority)) { - err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING; - goto error; - } - LOG_D(PROTO_AGENT,"sent message with size %d\n", size); - } - - //} + } + else + { + goto error; + } + return; error: LOG_E(PROTO_AGENT,"there was an error\n"); @@ -495,25 +464,29 @@ error: - void * proto_server_receive(void) { proto_agent_instance_t *d = &proto_server[server_mod]; - void *data; + void *data = NULL; int size; int priority; err_code_t err_code; Protocol__FlexsplitMessage *msg; - - //while (1) { - if (proto_agent_msg_recv(d->enb_id, PROTO_AGENT_DEFAULT, &data, &size, &priority)) { + Protocol__FlexsplitMessage *ser_msg; + + while (1) { + + msg = NULL; + ser_msg = NULL; + + if (proto_agent_async_msg_recv(&data, &size, &priority, server_channel)){ err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING; goto error; } - LOG_I(PROTO_AGENT,"Server Received message with size %d and priority %d, calling message handle\n", size, priority); + LOG_I(PROTO_AGENT,"Client Received message with size %d and priority %d, calling message handle\n", size, priority); msg=proto_agent_handle_message(d->enb_id, data, size); @@ -521,22 +494,86 @@ proto_server_receive(void) { LOG_E(PROTO_AGENT,"msg to send back is NULL\n"); } + else + { + free(data); - //free(data); - - if (msg != NULL){ - if (proto_agent_msg_send(d->enb_id, PROTO_AGENT_DEFAULT, msg, size, priority)) { + ser_msg = proto_agent_pack_message(msg, &size); + } + + LOG_I(PROTO_AGENT,"Server sending the pdcp data_req message over the async channel\n"); + if (ser_msg != NULL){ + if (proto_agent_async_msg_send((void *)ser_msg, (int) size, 1, (void *) server_channel)){ 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,"receive_thread: error %d occured\n",err_code); + LOG_E(PROTO_AGENT,"server_receive_thread: error %d occured\n",err_code); return NULL; -} \ No newline at end of file +} + +void * +proto_client_receive(void) +{ + proto_agent_instance_t *d = &proto_agent[client_mod]; + void *data = NULL; + int size; + int priority; + err_code_t err_code; + + Protocol__FlexsplitMessage *msg; + Protocol__FlexsplitMessage *ser_msg; + + + while (1) { + + msg = NULL; + ser_msg = NULL; + + if (proto_agent_async_msg_recv(&data, &size, &priority, client_channel)){ + //proto_agent_msg_recv(d->enb_id, PROTO_AGENT_DEFAULT, &data, &size, &priority)) { + err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING; + goto error; + } + + LOG_I(PROTO_AGENT,"Client Received message with size %d and priority %d, calling message handle\n", size, priority); + + msg=proto_agent_handle_message(d->enb_id, data, size); + + if (msg == NULL) + { + LOG_E(PROTO_AGENT,"msg to send back is NULL\n"); + } + else + { + free(data); + + ser_msg = proto_agent_pack_message(msg, &size); + } + + if (ser_msg != NULL){ + if (proto_agent_async_msg_send((void *)ser_msg, (int) size, 1, (void *) client_channel)){ + //proto_agent_msg_send(d->enb_id, PROTO_AGENT_DEFAULT, msg, size, priority)) { + 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,"client_receive_thread: error %d occured\n",err_code); + return NULL; + +} diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent.h b/openair2/LAYER2/PROTO_AGENT/proto_agent.h index 1815ee5374..1ce8cbef45 100644 --- a/openair2/LAYER2/PROTO_AGENT/proto_agent.h +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent.h @@ -43,6 +43,7 @@ void * proto_server_init(void *args); void * proto_server_receive(void); +void * proto_client_receive(void); int proto_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties); int proto_server_start(mid_t mod_id, const Enb_properties_array_t* enb_properties); diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c index 98d77fb36f..d16b9ef9ad 100644 --- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c @@ -324,29 +324,14 @@ int proto_agent_pdcp_data_req_ack(mid_t mod_id, const void *params, Protocol__Fl rb_idP = rlc_data->fsp_rb_id; muiP = rlc_data->fsp_muip; confirmP = rlc_data->fsp_confirm; - pdcp_pdu_size = rlc_data->fsp_pdu->fsp_pdu_data.len; - //fsp_sdu_buffer_size; // Same as rlc_data->fsp_pdu_data.len - + pdcp_pdu_size = rlc_data->fsp_pdu->fsp_pdu_data.len; pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size); - //malloc(pdcp_pdu_size); memcpy(pdcp_pdu_p->data, rlc_data->fsp_pdu->fsp_pdu_data.data, pdcp_pdu_size); - //memset(pdcp_pdu_p, 0, pdcp_pdu_size); - // Ready to call the rlc_data_req result = rlc_data_req((const protocol_ctxt_t*) ctxt_pP, (const srb_flag_t) srb_flagP, (const MBMS_flag_t) flag_MBMS, (const rb_id_t) rb_idP, (const mui_t) muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p); -// printf("subframe is %u\n", ctxt_pP->subframe); -// printf("srb is %u\n", srb_flagP); -// printf("MBMS is %u\n", flag_MBMS); -// printf("rb_id is %u\n", rb_idP); -// printf("muiP is %u\n", muiP); -// printf("confirm is %u\n", confirmP); -// printf("Size is %u\n", pdcp_pdu_size); - //result = rlc_data_req(ctxt_pP, srb_flagP, flag_MBMS, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p); - - printf("result is %u\n", result); - + if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_RLC_DATA_REQ_ACK, &header) != 0) goto error; @@ -395,6 +380,237 @@ int proto_agent_destroy_pdcp_data_req_ack(Protocol__FlexsplitMessage *msg) { return -1; } + +int proto_agent_destroy_pdcp_data_ind(Protocol__FlexsplitMessage *msg) { + if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG) + goto error; + + //free(msg->data_req_ack->header); + //free(msg->data_req_ack); + //free(msg); + return 0; + + error: + LOG_E(PROTO_AGENT, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int proto_agent_pdcp_data_ind(mid_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) +{ + + // Initialize the PDCP params + data_req_args *args = (data_req_args *)params; + + // Create the protobuf header + Protocol__FspHeader *header; + xid_t xid = 1; + LOG_I(PROTO_AGENT, "creating the data_ind message\n"); + + if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_PDCP_DATA_IND, &header) != 0) + goto error; + + /* Begin constructing the messages. They are defined as follows: + * 1) fspRlcPdu is storing the bytes of the packet + * 2) Message fspRlcData is packing the packet + the context of the PDCP (separate message) + * 3) Messge fspRlcDataReq is packing the header, enb_id and fspRlcData + */ + + Protocol__FspCtxt *ctxt = NULL; + Protocol__FspRlcPdu *pdu = NULL; + Protocol__FspRlcData *rlc_data = NULL; + Protocol__FspPdcpDataInd *data_ind = NULL; + + + ctxt = malloc(sizeof(Protocol__FspCtxt)); + pdu = malloc(sizeof(Protocol__FspRlcPdu)); + rlc_data = malloc(sizeof(Protocol__FspRlcData)); + data_ind = malloc(sizeof(Protocol__FspPdcpDataInd)); + + protocol__fsp_ctxt__init(ctxt); + protocol__fsp_rlc_pdu__init(pdu); + protocol__fsp_rlc_data__init(rlc_data); + protocol__fsp_pdcp_data_ind__init(data_ind); + + // Copy data to the RlcPdu structure + pdu->fsp_pdu_data.data = malloc(args->sdu_size); + pdu->fsp_pdu_data.len = args->sdu_size; + + printf("MSG payload is %u", args->sdu_size); + + //memcpy(pdu->fsp_pdu_data.data, args->sdu_p, args->sdu_size); + pdu->has_fsp_pdu_data = 1; + + // Copy data to the ctxt structure + ctxt->fsp_mod_id = args->ctxt->module_id; + ctxt->fsp_enb_flag = args->ctxt->enb_flag; + ctxt->fsp_instance = args->ctxt->instance; + ctxt->fsp_rnti = args->ctxt->rnti; + ctxt->fsp_frame = args->ctxt->frame; + ctxt->fsp_subframe = args->ctxt->subframe; + ctxt->fsp_enb_index = args->ctxt->eNB_index; + + ctxt->has_fsp_mod_id = 1; + ctxt->has_fsp_enb_flag = 1; + ctxt->has_fsp_instance = 1; + ctxt->has_fsp_rnti = 1; + ctxt->has_fsp_frame = 1; + ctxt->has_fsp_subframe = 1; + ctxt->has_fsp_enb_index = 1; + + rlc_data->fsp_ctxt = ctxt; + rlc_data->fsp_srb_flag = args->srb_flag; + rlc_data->fsp_mbms_flag = args->MBMS_flag; + rlc_data->fsp_rb_id = args->rb_id; + + rlc_data->fsp_sdu_buffer_size = args->sdu_size; + rlc_data->fsp_pdu = pdu; + rlc_data->has_fsp_srb_flag = 1; + rlc_data->has_fsp_mbms_flag = 1; + rlc_data->has_fsp_rb_id = 1; + rlc_data->has_fsp_sdu_buffer_size = 1; + + // Up to here, everything is a signle message that is packed inside another. The final data_req + // will be created later, after the setting of all variables + + data_ind->header = header; + data_ind->enb_id = mod_id; + data_ind->has_enb_id = 1; + data_ind->rlc_data = rlc_data; + + + *msg = malloc(sizeof(Protocol__FlexsplitMessage)); + + if(*msg == NULL) + goto error; + + protocol__flexsplit_message__init(*msg); + LOG_I(PROTO_AGENT,"setting the message case to %d\n", PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG); + + (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__INITIATING_MESSAGE; //we will be waiting for the ACK + (*msg)->has_msg_dir = 1; + (*msg)->data_ind_msg = data_ind; //data_req; + + return 0; + + error: + if(header != NULL) + free(header); + if(pdu!=NULL) + free(pdu); + if(rlc_data!=NULL) + free(rlc_data); + if(data_ind!= NULL) + free(data_ind); + if(*msg != NULL) + free(*msg); + LOG_E(PROTO_AGENT, "%s: an error occured\n", __FUNCTION__); + return -1; + +} + + +int proto_agent_pdcp_data_ind_ack(mid_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) +{ + Protocol__FspHeader *header; + xid_t xid; + rlc_op_status_t result = 0; + + LOG_I(PROTO_AGENT, "creating the data_ind_ack message\n"); + + Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params; + Protocol__FspPdcpDataInd *data_ind = input->data_ind_msg; + + xid = data_ind->header->xid; + Protocol__FspRlcPdu *pdu = NULL; + Protocol__FspCtxt *ctxt = NULL; + Protocol__FspRlcData *rlc_data = NULL; + + + rlc_data = data_ind->rlc_data; + + pdu = rlc_data->fsp_pdu; + + ctxt = rlc_data->fsp_ctxt; + + protocol_ctxt_t *ctxt_pP; + srb_flag_t srb_flagP = 0; + rb_id_t rb_idP = 0; + sdu_size_t pdcp_pdu_size = 0; + MBMS_flag_t flag_MBMS = 0; + mem_block_t *pdcp_pdu_p = NULL; + + + // Create a new protocol context for handling the packet + + ctxt_pP = malloc(sizeof(protocol_ctxt_t)); + ctxt_pP->module_id = ctxt->fsp_mod_id; + ctxt_pP->enb_flag = ctxt->fsp_enb_flag; + ctxt_pP->instance = ctxt->fsp_instance; + ctxt_pP->rnti = ctxt->fsp_rnti; + ctxt_pP->frame = ctxt->fsp_frame; + ctxt_pP->subframe = ctxt->fsp_subframe; + ctxt_pP->eNB_index = ctxt->fsp_enb_index; + + srb_flagP = rlc_data->fsp_srb_flag; + flag_MBMS = rlc_data->fsp_mbms_flag; + rb_idP = rlc_data->fsp_rb_id; + pdcp_pdu_size = rlc_data->fsp_pdu->fsp_pdu_data.len; + pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size); + + memcpy(pdcp_pdu_p->data, rlc_data->fsp_pdu->fsp_pdu_data.data, pdcp_pdu_size); + + pdcp_data_ind((const protocol_ctxt_t*) ctxt_pP, (const srb_flag_t) srb_flagP, (const MBMS_flag_t) flag_MBMS, (const rb_id_t) rb_idP, pdcp_pdu_size, pdcp_pdu_p); + + if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_PDCP_DATA_IND_ACK, &header) != 0) + goto error; + + Protocol__FspPdcpDataIndAck *ack = NULL; + ack = malloc(sizeof(Protocol__FspPdcpDataIndAck)); + protocol__fsp_pdcp_data_ind_ack__init(ack); + + ack->header = header; + ack->result = result; + ack->has_result = 1; + + *msg = malloc(sizeof(Protocol__FlexsplitMessage)); + if(*msg == NULL) + goto error; + + protocol__flexsplit_message__init(*msg); + (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_ACK; + (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__SUCCESSFUL_OUTCOME; + (*msg)->has_msg_dir = 1; + (*msg)->data_req_ack = ack; + return 0; + + error: + if(header != NULL) + free(header); + if(ack!=NULL) + free(ack); + if(*msg != NULL) + free(*msg); + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; + +} + + +int proto_agent_destroy_pdcp_data_ind_ack(Protocol__FlexsplitMessage *msg) { + if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_ACK) + goto error; + + //free(msg->data_req_ack->header); + //free(msg->data_req_ack); + //free(msg); + return 0; + + error: + LOG_E(PROTO_AGENT, "%s: an error occured\n", __FUNCTION__); + return -1; +} + int proto_agent_hello(mid_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) { Protocol__FspHeader *header; @@ -557,23 +773,6 @@ int proto_agent_destroy_echo_reply(Protocol__FlexsplitMessage *msg) { LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); return -1; } -/* -// call this function to start a nanosecond-resolution timer -struct timespec timer_start(){ - struct timespec start_time; - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time); - return start_time; -} - -// call this function to end a timer, returning nanoseconds elapsed as a long -long timer_end(struct timespec start_time){ - struct timespec end_time; - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time); - long diffInNanos = end_time.tv_nsec - start_time.tv_nsec; - return diffInNanos; -} -*/ - /* * get generic info from RAN */ diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h index 4622b0718b..159ed036e0 100644 --- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h @@ -102,6 +102,8 @@ int proto_agent_destroy_pdcp_data_req(Protocol__FlexsplitMessage *msg); int proto_agent_destroy_pdcp_data_req_ack(Protocol__FlexsplitMessage *msg); int proto_agent_pdcp_data_ind(mid_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); int proto_agent_destroy_pdcp_data_ind(Protocol__FlexsplitMessage *msg); +int proto_agent_pdcp_data_ind_ack(mid_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); +int proto_agent_destroy_pdcp_data_ind_ack(Protocol__FlexsplitMessage *msg); int just_print(mid_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); @@ -135,254 +137,6 @@ struct _data_req_args{ void set_enb_vars(mid_t mod_id, ran_name_t ran); -// int get_current_time_ms (mid_t mod_id, int subframe_flag); - -/*Return the current frame number - *Could be using implementation specific numbering of frames - */ -// unsigned int get_current_frame(mid_t mod_id); - -/* Do not need these */ - -///*Return the current SFN (0-1023)*/ -//unsigned int get_current_system_frame_num(mid_t mod_id); -// -//unsigned int get_current_subframe(mid_t mod_id); - -///*Return the frame and subframe number in compact 16-bit format. -// Bits 0-3 subframe, rest for frame. Required by progRAN protocol*/ -// uint16_t get_sfn_sf (mid_t mod_id); -// -// 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); -// -// int get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id); -// -// int get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id); -// -// int get_active_CC(mid_t mod_id, mid_t ue_id); -// -// int get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id); -// -// int get_n1pucch_an(mid_t mod_id, int CC_id); -// -// int get_nRB_CQI(mid_t mod_id, int CC_id); -// -// int get_deltaPUCCH_Shift(mid_t mod_id, int CC_id); -// -// int get_prach_ConfigIndex(mid_t mod_id, int CC_id); -// -// int get_prach_FreqOffset(mid_t mod_id, int CC_id); -// -// int get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id); -// -// int get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id); -// -// int get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id); -// -// int get_cell_id(mid_t mod_id, int CC_id); -// -// int get_srs_BandwidthConfig(mid_t mod_id, int CC_id); -// -// int get_srs_SubframeConfig(mid_t mod_id, int CC_id); -// -// int get_srs_MaxUpPts(mid_t mod_id, int CC_id); -// -// int get_N_RB_DL(mid_t mod_id, int CC_id); -// -// int get_N_RB_UL(mid_t mod_id, int CC_id); -// -// int get_subframe_assignment(mid_t mod_id, int CC_id); -// -// int get_special_subframe_assignment(mid_t mod_id, int CC_id); -// -// int get_ra_ResponseWindowSize(mid_t mod_id, int CC_id); -// -// int get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id); -// -// int get_duplex_mode(mid_t mod_id, int CC_id); -// -// long get_si_window_length(mid_t mod_id, int CC_id); -// -// int get_num_pdcch_symb(mid_t mod_id, int CC_id); -// -// int get_tpc(mid_t mod_id, mid_t ue_id); -// -// int get_harq(const mid_t mod_id, const uint8_t CC_id, const mid_t ue_id, -// const int frame, const uint8_t subframe, int *id, int *status); - -/* - * ************************************ - * Get Messages for UE Configuration Reply - * ************************************ - */ - -// int get_time_alignment_timer(mid_t mod_id, mid_t ue_id); -// -// int get_meas_gap_config(mid_t mod_id, mid_t ue_id); -// -// int get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id); -// -// int get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id); -// -// int get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id); -// -// int get_half_duplex(mid_t ue_id); -// -// int get_intra_sf_hopping(mid_t ue_id); -// -// int get_type2_sb_1(mid_t ue_id); -// -// int get_ue_category(mid_t ue_id); -// -// int get_res_alloc_type1(mid_t ue_id); -// -// int get_ue_transmission_mode(mid_t mod_id, mid_t ue_id); -// -// int get_tti_bundling(mid_t mod_id, mid_t ue_id); -// -// int get_maxHARQ_TX(mid_t mod_id, mid_t ue_id); -// -// int get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id); -// -// int get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id); -// -// int get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id); -// -// int get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id); -// -// int get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id); -// -// int get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id); -// -// int get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id); -// -// int get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id); -// -// int get_extended_bsr_size(mid_t mod_id, mid_t ue_id); -// -// int get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id); -// -// int get_lcg(mid_t ue_id, mid_t lc_id); -// -// int get_direction(mid_t ue_id, mid_t lc_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 Protocol__FlexsplitMessage *(*proto_agent_timer_callback_t)(void*); - -typedef enum { - /* oneshot timer: */ - PROTO_AGENT_TIMER_TYPE_ONESHOT = 0x0, - - /* periodic timer */ - PROTO_AGENT_TIMER_TYPE_PERIODIC = 0x1, - - /* Inactive state: initial state for any timer. */ - PROTO_AGENT_TIMER_TYPE_EVENT_DRIVEN = 0x2, - - /* Max number of states available */ - PROTO_AGENT_TIMER_TYPE_MAX, -} proto_agent_timer_type_t; - -typedef enum { - /* Inactive state: initial state for any timer. */ - PROTO_AGENT_TIMER_STATE_INACTIVE = 0x0, - - /* Inactive state: initial state for any timer. */ - PROTO_AGENT_TIMER_STATE_ACTIVE = 0x1, - - /* Inactive state: initial state for any timer. */ - PROTO_AGENT_TIMER_STATE_STOPPED = 0x2, - - /* Max number of states available */ - PROTO_AGENT_TIMER_STATE_MAX, -} proto_agent_timer_state_t; - -typedef struct proto_agent_timer_args_s{ - mid_t mod_id; - Protocol__FlexsplitMessage *msg; -} proto_agent_timer_args_t; - - -// Do we need this?? Probably not.. -typedef struct proto_agent_timer_element_s{ - RB_ENTRY(proto_agent_timer_element_s) entry; - - agent_id_t agent_id; - instance_t instance; - - proto_agent_timer_type_t type; - proto_agent_timer_state_t state; - - uint32_t interval_sec; - uint32_t interval_usec; - - long timer_id; /* Timer id returned by the timer API*/ - xid_t xid; /*The id of the task as received by the controller - message*/ - - proto_agent_timer_callback_t cb; - proto_agent_timer_args_t *timer_args; - -} proto_agent_timer_element_t; - -typedef struct proto_agent_timer_instance_s{ - RB_HEAD(proto_agent_map, proto_agent_timer_element_s) proto_agent_head; -}proto_agent_timer_instance_t; - -err_code_t proto_agent_init_timer(void); - -err_code_t proto_agent_create_timer(uint32_t interval_sec, - uint32_t interval_usec, - agent_id_t agent_id, - instance_t instance, - uint32_t timer_type, - xid_t xid, - proto_agent_timer_callback_t cb, - void* timer_args, - long *timer_id); - -err_code_t proto_agent_destroy_timers(void); -err_code_t proto_agent_destroy_timer(long timer_id); -err_code_t proto_agent_destroy_timer_by_task_id(xid_t xid); - -err_code_t proto_agent_stop_timer(long timer_id); - -err_code_t proto_agent_restart_timer(long *timer_id); - -struct proto_agent_timer_element_s * get_timer_entry(long timer_id); - -Protocol__FlexsplitMessage * proto_agent_process_timeout(long timer_id, void* timer_args); - -int proto_agent_compare_timer(struct proto_agent_timer_element_s *a, struct proto_agent_timer_element_s *b); - -/*Specify a delay in nanoseconds to timespec and sleep until then*/ -void proto_agent_sleep_until(struct timespec *ts, int delay); - -/* RB_PROTOTYPE is for .h files */ -RB_PROTOTYPE(proto_agent_map, proto_agent_timer_element_s, entry, proto_agent_compare_timer); - - #endif diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c index fd307dfb9c..b2b085c999 100644 --- a/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c @@ -45,8 +45,8 @@ proto_agent_message_decoded_callback agent_messages_callback[][3] = { {0, just_print, 0}, {proto_agent_pdcp_data_req_ack, 0, 0}, {0, proto_agent_get_ack_result, 0}, - {0, 0, 0}, -// {proto_agent_pdcp_data_ind, proto_agent_pdcp_data_ind_ack, proto_agent_rlc_data_ind_nack}, + {proto_agent_pdcp_data_ind_ack, 0, 0}, + {0, just_print, 0}, }; proto_agent_message_destruction_callback message_destruction_callback[] = { @@ -55,10 +55,9 @@ proto_agent_message_destruction_callback message_destruction_callback[] = { proto_agent_destroy_echo_reply, proto_agent_destroy_pdcp_data_req, proto_agent_destroy_pdcp_data_req_ack, -// proto_agent_destroy_rlc_data_req_nack, -// proto_agent_destroy_pdcp_data_ind, -// proto_agent_destroy_pdcp_data_ind_ack, -// proto_agent_destroy_rlc_data_ind_nack, + proto_agent_destroy_pdcp_data_ind, + proto_agent_destroy_pdcp_data_ind_ack, + }; static const char *proto_agent_direction2String[] = { @@ -91,21 +90,14 @@ Protocol__FlexsplitMessage* proto_agent_handle_message (mid_t mod_id, //printf("HANDLER: msg_case %u msg_dir %u\n\n", decoded_message->msg_case, decoded_message->msg_dir); if ((decoded_message->msg_case > sizeof(agent_messages_callback) / (3*sizeof(proto_agent_message_decoded_callback))) || - (decoded_message->msg_dir > PROTOCOL__FLEXSPLIT_DIRECTION__UNSUCCESSFUL_OUTCOME)){ - err_code= PROTOCOL__FLEXSPLIT_ERR__MSG_NOT_HANDLED; + (decoded_message->msg_dir > PROTOCOL__FLEXSPLIT_DIRECTION__UNSUCCESSFUL_OUTCOME)) + { + err_code= PROTOCOL__FLEXSPLIT_ERR__MSG_NOT_HANDLED; LOG_I(PROTO_AGENT,"Handling message: MSG NOT handled, going to error\n"); goto error; } - -// if ((decoded_message->msg_case != 5)&&(decoded_message->msg_dir!=2)){ - err_code = ((*agent_messages_callback[decoded_message->msg_case-1][decoded_message->msg_dir-1])(mod_id, (void *) decoded_message, &reply_message)); - printf("Err code is %u\n", err_code); -// } -// else{ -// err_code = 0; -// } if ( err_code < 0 ) { @@ -118,7 +110,7 @@ Protocol__FlexsplitMessage* proto_agent_handle_message (mid_t mod_id, LOG_D(PROTO_AGENT,"Returning REPLY message after the callback\n"); return reply_message; -error: + error: LOG_E(PROTO_AGENT,"errno %d occured\n",err_code); return NULL; } @@ -130,6 +122,7 @@ void * proto_agent_pack_message(Protocol__FlexsplitMessage *msg, void * buffer; err_code_t err_code = PROTOCOL__FLEXSPLIT_ERR__NO_ERR; + printf("serializing message\n"); if (proto_agent_serialize_message(msg, &buffer, size) < 0 ) { err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENCODING; goto error; @@ -137,8 +130,10 @@ void * proto_agent_pack_message(Protocol__FlexsplitMessage *msg, // free the msg --> later keep this in the data struct and just update the values //TODO call proper destroy function + printf("destruction callback\n"); err_code = ((*message_destruction_callback[msg->msg_case-1])(msg)); + printf("asserion"); DevAssert(buffer !=NULL); LOG_D(PROTO_AGENT,"Serialized the enb mac stats reply (size %d)\n", *size); diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index dc5cf82ce8..775f83654e 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -653,14 +653,25 @@ void rlc_data_ind ( T(T_ENB_RLC_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP)); #endif - - pdcp_data_ind ( + if (!srb_flagP) + { + proto_agent_send_pdcp_data_ind(ctxt_pP, + srb_flagP, + MBMS_flagP, + rb_idP, + sdu_sizeP, + sdu_pP); + } + else + { + pdcp_data_ind ( ctxt_pP, srb_flagP, MBMS_flagP, rb_idP, sdu_sizeP, sdu_pP); + } } //----------------------------------------------------------------------------- void rlc_data_conf (const protocol_ctxt_t* const ctxt_pP, diff --git a/targets/COMMON/MESSAGES/V2/flexsplit.proto b/targets/COMMON/MESSAGES/V2/flexsplit.proto index b743ebe2c0..c4a8b70a4e 100644 --- a/targets/COMMON/MESSAGES/V2/flexsplit.proto +++ b/targets/COMMON/MESSAGES/V2/flexsplit.proto @@ -12,6 +12,7 @@ message flexsplit_message { fspRlcDataReq data_req_msg = 4; fspRlcDataReqAck data_req_ack = 5; fspPdcpDataInd data_ind_msg = 6; + fspPdcpDataIndAck data_ind_ack = 7; } } @@ -77,3 +78,8 @@ message fspPdcpDataInd { optional uint32 eNB_id = 2; optional fspRlcData rlc_data = 3; } + +message fspPdcpDataIndAck { + optional fsp_header header = 1; + optional uint32 result = 2; +} diff --git a/targets/COMMON/MESSAGES/V2/header.proto b/targets/COMMON/MESSAGES/V2/header.proto index 01257cf187..44d52f777c 100644 --- a/targets/COMMON/MESSAGES/V2/header.proto +++ b/targets/COMMON/MESSAGES/V2/header.proto @@ -14,5 +14,6 @@ enum fsp_type { FSPT_RLC_DATA_REQ = 3; FSPT_RLC_DATA_REQ_ACK = 4; FSPT_PDCP_DATA_IND = 5; + FSPT_PDCP_DATA_IND_ACK = 6; }