proto_agent_common.c 25.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
/*******************************************************************************
    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 proto_agent_common.c
 * \brief common primitives for all agents 
 * \author Navid Nikaein and Xenofon Foukas
 * \date 2016
 * \version 0.1
 */

#include<stdio.h>
#include <dlfcn.h>
#include <time.h>

#include "proto_agent_common.h"
42
#include "PHY/phy_extern.h"
43
#include "common/utils/LOG/log.h"
44

45
#include "RRC/LTE/rrc_extern.h"
46 47
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "rrc_eNB_UE_context.h"
48
//#include "LAYER2/PDCP_v10.1.0/pdcp_primitives.h"
49 50 51 52

void * enb[NUM_MAX_ENB];
void * enb_ue[NUM_MAX_ENB];
void * enb_rrc[NUM_MAX_ENB];
53

54 55 56 57
/*
 * message primitives
 */

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
// Function to fill in the dl_data header (32bits) with the appropriate fields (doing bitwise operations)
void fill_dl_data_header(int pdu_type, int spare, int seq_no, uint32_t *header)
{
  uint32_t type = pdu_type;
  uint32_t spare_ = spare;
  uint32_t seq = seq_no;
  type = type << 28;
  spare_ = spare_ << 24;
  *header = (type | spare_);
  *header = (*header | seq);
  return;
}


// Function to retrieve data from the dl_data header (32bits) (doing bitwise operations)
void read_dl_data_header(int *pdu_type, int *spare, int *seqno, uint32_t header)
{
  *pdu_type = header;
  *spare = header;
  *seqno = header;
  *pdu_type = *pdu_type >> 28;
  *spare = *spare << 4;
  *spare = *spare >> 28;
  *seqno = *seqno << 8;
  *seqno = *seqno >> 8;
  return;
}

int f1u_serialize_message(Protocol__F1uMessage *msg, void **buf,int *size){
  *size = protocol__f1u_message__get_packed_size(msg);

  *buf = malloc(*size);
  if (buf == NULL)
    goto error;

  protocol__f1u_message__pack(msg, *buf);

  return 0;

 error:
  LOG_E(F1U, "an error occured\n"); 
  return -1;

}

int f1u_deserialize_message(void *data, int size, Protocol__F1uMessage **msg) {
  *msg = protocol__f1u_message__unpack(NULL, size, data);
  if (*msg == NULL)
    goto error;

  return 0;

 error:
  LOG_E(F1U, "%s: an error occured\n", __FUNCTION__);
  return -1;
}

int f1u_dl_data_create_header(uint32_t pdu_type, uint32_t f1u_sn, Protocol__DlDataHeader **header) {

  *header = malloc(sizeof(Protocol__DlDataHeader));
  if(*header == NULL)
    goto error;

  protocol__dl_data_header__init(*header);
  LOG_D(F1U, "Initialized the DL Data User header\n");

124
  fill_dl_data_header(pdu_type, 0, f1u_sn, &(*header)->fields);
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
  return 0;

 error:
  LOG_E(F1U, "%s: an error occured\n", __FUNCTION__);
  return -1;
}

int f1u_dl_data(const void *params, Protocol__F1uMessage **msg)
{

  // Initialize the PDCP params
  dl_data_args *args = (dl_data_args *)params;

  Protocol__DlDataHeader *header;

  if (f1u_dl_data_create_header(args->pdu_type, args->sn, &header) != 0)
     goto error;


  Protocol__DlUserData *dl_data = NULL;

  *msg = malloc(sizeof(Protocol__DlUserData));

  if(*msg == NULL)
    goto error;


152 153 154
  // FIXME: Is the following used? It seems to be overwritten by the function
  // protocol__dl_user_data__init() anyway
  //dl_data = *msg;
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181

  protocol__dl_user_data__init(dl_data);


  // Copy data to the bytes structure
  dl_data->pdu.data = malloc(args->sdu_size);
  dl_data->pdu.len = args->sdu_size;
  memcpy(dl_data->pdu.data, args->sdu_p, args->sdu_size);

  dl_data->frame = args->frame;
  dl_data->subframe = args->subframe;
  dl_data->rnti = args->rnti;

  dl_data->header = header;

  return 0;
  
  error:
    if(header != NULL)
      free(header);
    if(*msg != NULL)
      free(*msg);
    LOG_E(F1U, "%s: an error occured\n", __FUNCTION__);
    return -1;
  
}

182
int proto_agent_serialize_message(Protocol__FlexsplitMessage *msg, uint8_t **buf, int *size) {
183 184

  *size = protocol__flexsplit_message__get_packed_size(msg);
185

186 187 188
  *buf = malloc(*size);
  if (buf == NULL)
    goto error;
189

190
  protocol__flexsplit_message__pack(msg, *buf);
191

192
  return 0;
193

194
 error:
195
  LOG_E(MAC, "an error occured\n"); 
196 197 198 199 200 201 202 203
  return -1;
}

/* We assume that the buffer size is equal to the message size.
   Should be chekced durint Tx/Rx */
int proto_agent_deserialize_message(void *data, int size, Protocol__FlexsplitMessage **msg) {
  *msg = protocol__flexsplit_message__unpack(NULL, size, data);
  if (*msg == NULL)
204
    goto error;  
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219

  return 0;
  
 error:
  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}

int fsp_create_header(xid_t xid, Protocol__FspType type,  Protocol__FspHeader **header) {
  
  *header = malloc(sizeof(Protocol__FspHeader));
  if(*header == NULL)
    goto error;
  
  protocol__fsp_header__init(*header);
220
  LOG_D(PROTO_AGENT, "Initialized the PROTOBUF message header\n");
221
  (*header)->version = FLEXSPLIT_VERSION;
222 223
  LOG_D(PROTO_AGENT, "Set the vversion to FLEXSPLIT_VERSION\n");

224 225 226 227 228 229 230 231 232 233 234 235
  (*header)->has_version = 1; 
  (*header)->type = type;
  (*header)->has_type = 1;
  (*header)->xid = xid;
  (*header)->has_xid = 1;
  return 0;

 error:
  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}

236
int just_print(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
237 238 239 240
{
    return 1;
}

241
int proto_agent_pdcp_data_req(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
242
{
243 244 245 246 247
  Protocol__FspCtxt *ctxt = NULL;
  Protocol__FspRlcPdu *pdu = NULL;
  Protocol__FspRlcData *rlc_data = NULL;
  Protocol__FspRlcDataReq *data_req = NULL;

248 249 250 251 252
  // Initialize the PDCP params
  data_req_args *args = (data_req_args *)params;
 
  // Create the protobuf header
  Protocol__FspHeader *header;
253
  xid_t xid = mod_id;
254
  LOG_D(PROTO_AGENT, "creating the data_req message\n");
255 256 257 258 259 260 261 262 263
  
  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_RLC_DATA_REQ, &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
  */
264

265
  ctxt = malloc(sizeof(Protocol__FspCtxt));
266
  pdu = malloc(sizeof(Protocol__FspRlcPdu));
267 268 269 270
  rlc_data = malloc(sizeof(Protocol__FspRlcData));
  data_req = malloc(sizeof(Protocol__FspRlcDataReq));
  
  protocol__fsp_ctxt__init(ctxt);
271
  protocol__fsp_rlc_pdu__init(pdu);
272 273 274 275 276 277
  protocol__fsp_rlc_data__init(rlc_data);
  protocol__fsp_rlc_data_req__init(data_req);
  
  // Copy data to the RlcPdu structure
  pdu->fsp_pdu_data.data =  malloc(args->sdu_size);
  pdu->fsp_pdu_data.len = args->sdu_size;
278
   
279
  memcpy(pdu->fsp_pdu_data.data, args->sdu_p, args->sdu_size); 
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
  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;

299
  rlc_data->fsp_ctxt = ctxt; 
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
  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_muip = args->mui;
  rlc_data->fsp_confirm = args->confirm;
  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_muip = 1;
  rlc_data->has_fsp_confirm = 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_req->header = header;
  data_req->enb_id = mod_id;
  data_req->has_enb_id = 1;
  data_req->pdcp_data = rlc_data;
  
  *msg = malloc(sizeof(Protocol__FlexsplitMessage));

  if(*msg == NULL)
    goto error;
  
  protocol__flexsplit_message__init(*msg);
  
  (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_REQ_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__INITIATING_MESSAGE; //we will be waiting for the ACK
  (*msg)->has_msg_dir = 1;
333
  (*msg)->data_req_msg = data_req;
334 335 336 337 338 339 340 341 342 343 344 345 346 347
  
  return 0;
  
  error:
    if(header != NULL)
      free(header);
    if(pdu!=NULL)
      free(pdu);
    if(rlc_data!=NULL)
      free(rlc_data);
    if(data_req!= NULL)
      free(data_req);
    if(*msg != NULL)
      free(*msg);
348
    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
349 350 351 352 353 354 355 356
    return -1;
  
}

int proto_agent_destroy_pdcp_data_req(Protocol__FlexsplitMessage *msg) {
  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_REQ_MSG)
    goto error;
  
357 358 359 360 361 362 363
  free(msg->data_req_msg->header);
  free(msg->data_req_msg->pdcp_data->fsp_pdu->fsp_pdu_data.data);
  free(msg->data_req_msg->pdcp_data->fsp_pdu);
  free(msg->data_req_msg->pdcp_data->fsp_ctxt);
  free(msg->data_req_msg->pdcp_data);
  free(msg->data_req_msg);
  free(msg);
364 365 366
  return 0;
  
  error:
367
    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
368 369 370
    return -1;
}

371
int proto_agent_get_ack_result(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
372 373
{
  rlc_op_status_t result = 0;
374
  //printf("PROTO_AGENT: handling the data_req_ack message\n");
375 376 377
  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
  Protocol__FspRlcDataReqAck *data_ack = input->data_req_ack;
  result = data_ack->result;
378
  //printf("PROTO_AGENT: ACK RESULT IS %u\n", result);
379
  ack_result = result;
380
  return 0;
381 382 383

}

384

385
int proto_agent_pdcp_data_req_ack(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
386 387 388
{
  Protocol__FspHeader *header;
  xid_t xid;
389 390
  rlc_op_status_t result = 0;
  
391
  LOG_D(PROTO_AGENT, "creating the data_req_ack message\n");
392 393 394 395
  
  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
  Protocol__FspRlcDataReq *data_req = input->data_req_msg;
  
396
  xid = data_req->header->xid;
397 398 399
  Protocol__FspCtxt *ctxt = NULL;
  Protocol__FspRlcData *rlc_data = NULL;
  
400
  
401
  rlc_data = data_req->pdcp_data;
402
  
403 404
  ctxt = rlc_data->fsp_ctxt;
  
405
  protocol_ctxt_t	 *ctxt_pP;
406 407 408 409
  srb_flag_t     	 srb_flagP = 0;
  rb_id_t        	 rb_idP = 0;
  mui_t         	 muiP = 0;
  confirm_t      	 confirmP = 0;
410 411
  sdu_size_t           	 pdcp_pdu_size = 0;
  MBMS_flag_t		 flag_MBMS = 0;
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
  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;
  muiP = rlc_data->fsp_muip;
  confirmP = rlc_data->fsp_confirm;
431
  pdcp_pdu_size = rlc_data->fsp_pdu->fsp_pdu_data.len; 
432
  pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size, __func__);
433
  
434 435
  memcpy(pdcp_pdu_p->data, rlc_data->fsp_pdu->fsp_pdu_data.data, pdcp_pdu_size);

436
  
437 438 439 440 441 442 443 444 445 446 447 448 449
  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
  #ifdef Rel14
                        ,NULL
                        ,NULL
  #endif                      
                        );
450 451

  Protocol__FspRlcDataReqAck *ack = NULL;
452
 
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_RLC_DATA_REQ_ACK, &header) != 0)
    goto error;

  ack = malloc(sizeof(Protocol__FspRlcDataReqAck));
  protocol__fsp_rlc_data_req_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_REQ_ACK;
  (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__SUCCESSFUL_OUTCOME;
  (*msg)->has_msg_dir = 1;
  (*msg)->data_req_ack = ack;
  return 0;
  
  error:
475
    if (pdcp_pdu_p != NULL)
476
      free_mem_block(pdcp_pdu_p, __func__);
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
    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_req_ack(Protocol__FlexsplitMessage *msg) {
  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_REQ_ACK)
    goto error;
  
492 493 494
  free(msg->data_req_ack->header);
  free(msg->data_req_ack);
  free(msg);
495 496 497
  return 0;
  
  error:
498
    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
499 500 501
    return -1;
}

502 503 504 505 506

int proto_agent_destroy_pdcp_data_ind(Protocol__FlexsplitMessage *msg) {
  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG)
    goto error;
  
507 508 509
  free(msg->data_req_ack->header);
  free(msg->data_req_ack);
  free(msg);
510 511 512
  return 0;
  
  error:
513
    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
514 515 516
    return -1;
}

517
int proto_agent_pdcp_data_ind(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
518
{
519 520 521 522 523
  Protocol__FspCtxt *ctxt = NULL;
  Protocol__FspRlcPdu *pdu = NULL;
  Protocol__FspRlcData *rlc_data = NULL;
  Protocol__FspPdcpDataInd *data_ind = NULL;

524 525 526 527 528
  // Initialize the PDCP params
  data_req_args *args = (data_req_args *)params;
 
  // Create the protobuf header
  Protocol__FspHeader *header;
529
  xid_t xid = mod_id;
530
  LOG_D(PROTO_AGENT, "creating the data_ind message\n");
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
  
  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
  */

  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;
  
555
  memcpy(pdu->fsp_pdu_data.data, args->sdu_p, args->sdu_size); 
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
  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);
602
  LOG_D(PROTO_AGENT,"setting the message case to %d\n", PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG);
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621

  (*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);
622
    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
623 624 625 626 627
    return -1;
  
}


628
int proto_agent_pdcp_data_ind_ack(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
629 630
{
  Protocol__FspHeader *header;
631 632
  Protocol__FspPdcpDataIndAck *ack = NULL;

633 634 635
  xid_t xid;
  rlc_op_status_t result = 0;
  
636
  //printf("PROTO_AGENT: creating the data_ind_ack message\n");
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
  
  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
  Protocol__FspPdcpDataInd *data_ind = input->data_ind_msg;
  
  xid = data_ind->header->xid;
  Protocol__FspCtxt *ctxt = NULL;
  Protocol__FspRlcData *rlc_data = NULL;
  
  
  rlc_data = data_ind->rlc_data;
  
  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));
661 662 663
  //FIXME: 
  //ctxt_pP->module_id = ctxt->fsp_mod_id;
  ctxt_pP->module_id = 0;
664 665 666 667 668 669 670 671 672 673 674
  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; 
675
  pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size, __func__);
676 677 678
  
  memcpy(pdcp_pdu_p->data, rlc_data->fsp_pdu->fsp_pdu_data.data, pdcp_pdu_size);
  
679 680 681 682 683
//   if (xid == 1)
//     pdcp_data_ind_wifi((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);
//   else if (xid == 0)   // FIXME: USE a preprocessed definition
    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);

684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_PDCP_DATA_IND_ACK, &header) != 0)
    goto error;

  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;
702 703 704
  // FIXME: the following was (*msg)->data_req_ack = ack;
  // but this throws compiler warning. Probably we want the following instead
  (*msg)->data_ind_ack = ack;
705
  
706 707 708 709 710 711 712 713 714
  return 0;
  
  error:
    if(header != NULL)
      free(header);
    if(ack!=NULL)
      free(ack);
    if(*msg != NULL)
      free(*msg);
715
    if (pdcp_pdu_p != NULL)
716
      free_mem_block(pdcp_pdu_p, __func__);
717

718 719 720 721 722 723 724 725 726 727
    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;
  
728 729 730
  free(msg->data_req_ack->header);
  free(msg->data_req_ack);
  free(msg);
731 732 733
  return 0;
  
  error:
734
    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
735 736 737
    return -1;
}

738
int proto_agent_hello(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) {
739 740
 
  Protocol__FspHeader *header;
741 742
  Protocol__FspHello *hello_msg = NULL;

743
  /*TODO: Need to set random xid or xid from received hello message*/
744
  xid_t xid = mod_id;
745 746 747
  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_HELLO, &header) != 0)
    goto error;

748
  LOG_D(PROTO_AGENT, "creating the HELLO message\n");
749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
  hello_msg = malloc(sizeof(Protocol__FspHello));
  if(hello_msg == NULL)
    goto error;
  protocol__fsp_hello__init(hello_msg);
  hello_msg->header = header;

  *msg = malloc(sizeof(Protocol__FlexsplitMessage));
  if(*msg == NULL)
    goto error;
  
  protocol__flexsplit_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_HELLO_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__SUCCESSFUL_OUTCOME;
  (*msg)->has_msg_dir = 1;
  (*msg)->hello_msg = hello_msg;
  return 0;
  
 error:
  if(header != NULL)
    free(header);
769
  if(hello_msg!=NULL)
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
    free(hello_msg);
  if(*msg != NULL)
    free(*msg);
  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}


int proto_agent_destroy_hello(Protocol__FlexsplitMessage *msg) {
  
  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_HELLO_MSG)
    goto error;
  
  free(msg->hello_msg->header);
  free(msg->hello_msg);
  free(msg);
  return 0;

 error:
  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}

793
int proto_agent_echo_request(mod_id_t mod_id, const void* params, Protocol__FlexsplitMessage **msg) {
794
  Protocol__FspHeader *header;
795
  Protocol__FspEchoRequest *echo_request_msg = NULL;
796

797
  xid_t xid = mod_id;
798 799
  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_ECHO_REQUEST, &header) != 0)
    goto error;
800
  LOG_D(PROTO_AGENT, "creating the echo request message\n");
801
  
802 803 804
  echo_request_msg = malloc(sizeof(Protocol__FspEchoRequest));
  if(echo_request_msg == NULL)
    goto error;
805

806 807
  protocol__fsp_echo_request__init(echo_request_msg);
  echo_request_msg->header = header;
808

809 810
  *msg = malloc(sizeof(Protocol__FlexsplitMessage));
  if(*msg == NULL)
811
    goto error;
812
  protocol__flexsplit_message__init(*msg);
813

814
  LOG_D(PROTO_AGENT,"setting the message direction to %d\n", PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REQUEST_MSG);
815 816 817 818 819
  (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REQUEST_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__INITIATING_MESSAGE;
  (*msg)->has_msg_dir = 1;
  (*msg)->echo_request_msg = echo_request_msg;
  return 0;
820 821

 error:
822 823 824 825 826 827 828
  if(header != NULL)
    free(header);
  if(echo_request_msg != NULL)
    free(echo_request_msg);
  if(*msg != NULL)
    free(*msg);
  return -1;
829 830
}

831 832 833
int proto_agent_destroy_echo_request(Protocol__FlexsplitMessage *msg) {
  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REQUEST_MSG)
    goto error;
834
  
835 836 837
  free(msg->echo_request_msg->header);
  free(msg->echo_request_msg);
  free(msg);
838 839
  return 0;
  
840 841 842
 error:
  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
843 844
}

845
int proto_agent_echo_reply(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) {
846
  
847 848 849
  xid_t xid;
  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
  Protocol__FspEchoRequest *echo_req = input->echo_request_msg;
850
  Protocol__FspEchoReply *echo_reply_msg = NULL;
851
  xid = (echo_req->header)->xid;
852

853 854
  
  
855
  LOG_D(PROTO_AGENT, "creating the echo reply message\n");
856 857
  Protocol__FspHeader *header;
  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_ECHO_REPLY, &header) != 0)
858 859
    goto error;

860 861 862 863 864
  echo_reply_msg = malloc(sizeof(Protocol__FspEchoReply));
  if(echo_reply_msg == NULL)
    goto error;
  protocol__fsp_echo_reply__init(echo_reply_msg);
  echo_reply_msg->header = header;
865

866 867 868 869 870 871 872 873
  *msg = malloc(sizeof(Protocol__FlexsplitMessage));
  if(*msg == NULL)
    goto error;
  protocol__flexsplit_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REPLY_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__SUCCESSFUL_OUTCOME;
  (*msg)->has_msg_dir = 1;
  (*msg)->echo_reply_msg = echo_reply_msg;
874 875 876
  return 0;

 error:
877 878 879 880 881 882 883 884
  if(header != NULL)
    free(header);
  if(echo_reply_msg != NULL)
    free(echo_reply_msg);
  if(*msg != NULL)
    free(*msg);
  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
885 886
}

887 888 889
int proto_agent_destroy_echo_reply(Protocol__FlexsplitMessage *msg) {
  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REPLY_MSG)
    goto error;
890
  
891 892 893
  free(msg->echo_reply_msg->header);
  free(msg->echo_reply_msg);
  free(msg);
894
  return 0;
895 896 897 898
  
 error:
  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
899
}