proto_agent_common.c 22.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
21 22

/*! \file proto_agent_common.c
23
 * \brief common primitives for all agents
24 25 26 27 28 29 30 31 32
 * \author Navid Nikaein and Xenofon Foukas
 * \date 2016
 * \version 0.1
 */

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

33
#include "PHY/phy_extern.h"
34
#include "proto_agent_common.h"
35
#include "common/utils/LOG/log.h"
36

37
#include "RRC/LTE/rrc_extern.h"
38 39
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "rrc_eNB_UE_context.h"
40

41 42 43 44
/*
 * message primitives
 */

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
// 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;
}

73 74
int f1u_serialize_message(Protocol__F1uMessage *msg, void **buf,int *size)
{
75 76 77
  *size = protocol__f1u_message__get_packed_size(msg);

  *buf = malloc(*size);
78
  if (!(*buf))
79 80 81 82 83 84 85
    goto error;

  protocol__f1u_message__pack(msg, *buf);

  return 0;

 error:
86
  LOG_E(F1U, "an error occured\n");
87 88 89 90
  return -1;

}

91 92
int f1u_deserialize_message(void *data, int size, Protocol__F1uMessage **msg)
{
93 94 95 96 97 98 99 100 101 102 103
  *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;
}

104 105
int f1u_dl_data_create_header(uint32_t pdu_type, uint32_t f1u_sn, Protocol__DlDataHeader **header)
{
106 107 108 109 110 111 112
  *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");

113
  fill_dl_data_header(pdu_type, 0, f1u_sn, &(*header)->fields);
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
  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;


140 141 142
  // FIXME: Is the following used? It seems to be overwritten by the function
  // protocol__dl_user_data__init() anyway
  //dl_data = *msg;
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158

  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;
159

160 161 162 163 164 165 166 167 168
  error:
    if(header != NULL)
      free(header);
    if(*msg != NULL)
      free(*msg);
    LOG_E(F1U, "%s: an error occured\n", __FUNCTION__);
    return -1;
}

169 170
int proto_agent_serialize_message(Protocol__FlexsplitMessage *msg, uint8_t **buf, int *size)
{
171
  *size = protocol__flexsplit_message__get_packed_size(msg);
172

173
  *buf = malloc(*size);
174
  if (!(*buf))
175
    goto error;
176

177
  protocol__flexsplit_message__pack(msg, *buf);
178

179
  return 0;
180

181
 error:
182
  LOG_E(MAC, "an error occured\n");
183 184 185 186 187
  return -1;
}

/* We assume that the buffer size is equal to the message size.
   Should be chekced durint Tx/Rx */
188 189
int proto_agent_deserialize_message(void *data, int size, Protocol__FlexsplitMessage **msg)
{
190 191
  *msg = protocol__flexsplit_message__unpack(NULL, size, data);
  if (*msg == NULL)
192
    goto error;
193 194

  return 0;
195

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

201 202
int fsp_create_header(xid_t xid, Protocol__FspType type,  Protocol__FspHeader **header)
{
203 204 205
  *header = malloc(sizeof(Protocol__FspHeader));
  if(*header == NULL)
    goto error;
206

207
  protocol__fsp_header__init(*header);
208
  LOG_D(PROTO_AGENT, "Initialized the PROTOBUF message header\n");
209
  (*header)->version = FLEXSPLIT_VERSION;
210 211
  LOG_D(PROTO_AGENT, "Set the vversion to FLEXSPLIT_VERSION\n");

212
  (*header)->has_version = 1;
213 214 215 216 217 218 219 220 221 222 223
  (*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;
}

224
int just_print(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
225 226 227 228
{
    return 1;
}

229
int proto_agent_pdcp_data_req(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
230
{
231 232 233 234 235
  Protocol__FspCtxt *ctxt = NULL;
  Protocol__FspRlcPdu *pdu = NULL;
  Protocol__FspRlcData *rlc_data = NULL;
  Protocol__FspRlcDataReq *data_req = NULL;

236 237
  // Initialize the PDCP params
  data_req_args *args = (data_req_args *)params;
238

239 240
  // Create the protobuf header
  Protocol__FspHeader *header;
241
  xid_t xid = mod_id;
242
  LOG_D(PROTO_AGENT, "creating the data_req message\n");
243

244 245
  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_RLC_DATA_REQ, &header) != 0)
     goto error;
246

247 248 249 250 251
  /* 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
  */
252

253
  ctxt = malloc(sizeof(Protocol__FspCtxt));
254
  pdu = malloc(sizeof(Protocol__FspRlcPdu));
255 256
  rlc_data = malloc(sizeof(Protocol__FspRlcData));
  data_req = malloc(sizeof(Protocol__FspRlcDataReq));
257

258
  protocol__fsp_ctxt__init(ctxt);
259
  protocol__fsp_rlc_pdu__init(pdu);
260 261
  protocol__fsp_rlc_data__init(rlc_data);
  protocol__fsp_rlc_data_req__init(data_req);
262

263 264 265
  // Copy data to the RlcPdu structure
  pdu->fsp_pdu_data.data =  malloc(args->sdu_size);
  pdu->fsp_pdu_data.len = args->sdu_size;
266 267

  memcpy(pdu->fsp_pdu_data.data, args->sdu_p->data, args->sdu_size);
268
  pdu->has_fsp_pdu_data = 1;
269

270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
  // 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;

287
  rlc_data->fsp_ctxt = ctxt;
288 289 290 291 292 293 294
  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;
295

296 297 298 299 300 301 302
  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;

303
  // Up to here, everything is a signle message that is packed inside another. The final data_req
304
  // will be created later, after the setting of all variables
305

306 307 308 309
  data_req->header = header;
  data_req->enb_id = mod_id;
  data_req->has_enb_id = 1;
  data_req->pdcp_data = rlc_data;
310

311 312 313 314
  *msg = malloc(sizeof(Protocol__FlexsplitMessage));

  if(*msg == NULL)
    goto error;
315

316
  protocol__flexsplit_message__init(*msg);
317

318 319 320
  (*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;
321
  (*msg)->data_req_msg = data_req;
322

323
  return 0;
324

325 326 327 328 329 330 331 332 333 334 335
  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);
336
    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
337 338 339 340 341 342
    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;
343

344 345 346 347 348 349 350
  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);
351
  return 0;
352

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

358
int proto_agent_get_ack_result(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
359 360
{
  rlc_op_status_t result = 0;
361
  //printf("PROTO_AGENT: handling the data_req_ack message\n");
362 363 364
  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
  Protocol__FspRlcDataReqAck *data_ack = input->data_req_ack;
  result = data_ack->result;
365
  //printf("PROTO_AGENT: ACK RESULT IS %u\n", result);
366
  ack_result = result;
367
  return 0;
368 369 370

}

371

372
int proto_agent_pdcp_data_req_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
373
{
374
  rlc_op_status_t result = 0;
375

376 377
  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
  Protocol__FspRlcDataReq *data_req = input->data_req_msg;
378

379 380
  Protocol__FspCtxt *ctxt = NULL;
  Protocol__FspRlcData *rlc_data = NULL;
381

382 383
  rlc_data = data_req->pdcp_data;
  ctxt = rlc_data->fsp_ctxt;
384

385
  protocol_ctxt_t  ctxt_pP;
386 387 388 389 390 391 392
  srb_flag_t       srb_flagP = 0;
  rb_id_t          rb_idP = 0;
  mui_t            muiP = 0;
  confirm_t        confirmP = 0;
  MBMS_flag_t      flag_MBMS = 0;
  sdu_size_t       pdcp_pdu_size = 0;
  mem_block_t     *pdcp_pdu_p = NULL;
393 394

  // Create a new protocol context for handling the packet
395 396 397 398 399 400 401
  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;
402

403 404 405 406 407
  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;
408
  pdcp_pdu_size = rlc_data->fsp_pdu->fsp_pdu_data.len;
409
  pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size, __func__);
410
  if (!pdcp_pdu_p) goto error;
411 412
  memcpy(pdcp_pdu_p->data, rlc_data->fsp_pdu->fsp_pdu_data.data, pdcp_pdu_size);

413 414 415 416 417
  result = rlc_data_req(&ctxt_pP
                        ,srb_flagP
                        ,flag_MBMS
                        ,rb_idP
                        ,muiP
418 419 420 421 422 423
                        ,confirmP
                        ,pdcp_pdu_size
                        ,pdcp_pdu_p
  #ifdef Rel14
                        ,NULL
                        ,NULL
424
  #endif
425
                        );
426

427
  return result;
428 429

  error:
430
    if (pdcp_pdu_p)
431
      free_mem_block(pdcp_pdu_p, __func__);
432
    LOG_E(PROTO_AGENT, "%s: an error occured\n", __FUNCTION__);
433 434 435 436
    return -1;

}

437 438
int proto_agent_destroy_pdcp_data_ind(Protocol__FlexsplitMessage *msg)
{
439 440
  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG)
    goto error;
441

442 443 444 445 446 447
  free(msg->data_ind_msg->header);
  free(msg->data_ind_msg->rlc_data->fsp_pdu->fsp_pdu_data.data);
  free(msg->data_ind_msg->rlc_data->fsp_pdu);
  free(msg->data_ind_msg->rlc_data->fsp_ctxt);
  free(msg->data_ind_msg->rlc_data);
  free(msg->data_ind_msg);
448
  free(msg);
449
  return 0;
450

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

456
int proto_agent_pdcp_data_ind(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
457
{
458 459 460 461 462
  Protocol__FspCtxt *ctxt = NULL;
  Protocol__FspRlcPdu *pdu = NULL;
  Protocol__FspRlcData *rlc_data = NULL;
  Protocol__FspPdcpDataInd *data_ind = NULL;

463 464
  // Initialize the PDCP params
  data_req_args *args = (data_req_args *)params;
465

466 467
  // Create the protobuf header
  Protocol__FspHeader *header;
468
  xid_t xid = mod_id;
469
  LOG_D(PROTO_AGENT, "creating the data_ind message\n");
470

471 472
  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_PDCP_DATA_IND, &header) != 0)
     goto error;
473

474 475 476 477 478 479 480 481 482 483
  /* 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));
484

485 486 487 488
  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);
489

490 491 492
  // Copy data to the RlcPdu structure
  pdu->fsp_pdu_data.data =  malloc(args->sdu_size);
  pdu->fsp_pdu_data.len = args->sdu_size;
493 494

  memcpy(pdu->fsp_pdu_data.data, args->sdu_p->data, args->sdu_size);
495
  pdu->has_fsp_pdu_data = 1;
496

497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
  // 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;

514
  rlc_data->fsp_ctxt = ctxt;
515 516 517 518 519 520 521 522 523 524 525
  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;

526
  // Up to here, everything is a signle message that is packed inside another. The final data_req
527
  // will be created later, after the setting of all variables
528

529 530 531 532
  data_ind->header = header;
  data_ind->enb_id = mod_id;
  data_ind->has_enb_id = 1;
  data_ind->rlc_data = rlc_data;
533 534


535 536 537 538
  *msg = malloc(sizeof(Protocol__FlexsplitMessage));

  if(*msg == NULL)
    goto error;
539

540
  protocol__flexsplit_message__init(*msg);
541
  LOG_D(PROTO_AGENT,"setting the message case to %d\n", PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG);
542 543 544 545 546

  (*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;
547

548
  return 0;
549

550 551 552 553 554 555 556 557 558 559 560
  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);
561
    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
562 563 564 565
    return -1;
}


566
int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
567
{
568
  boolean_t result = 0;
569

570 571 572 573
  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
  Protocol__FspPdcpDataInd *data_ind = input->data_ind_msg;
  Protocol__FspCtxt *ctxt = NULL;
  Protocol__FspRlcData *rlc_data = NULL;
574

575 576
  rlc_data = data_ind->rlc_data;
  ctxt = rlc_data->fsp_ctxt;
577

578
  protocol_ctxt_t  ctxt_pP;
579 580 581 582 583
  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;
584 585

  // Create a new protocol context for handling the packet
586 587 588 589 590 591 592
  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;
593

594 595 596
  srb_flagP = rlc_data->fsp_srb_flag;
  flag_MBMS = rlc_data->fsp_mbms_flag;
  rb_idP = rlc_data->fsp_rb_id;
597
  pdcp_pdu_size = rlc_data->fsp_pdu->fsp_pdu_data.len;
598
  pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size, __func__);
599 600
  if (!pdcp_pdu_p) goto error;

601
  memcpy(pdcp_pdu_p->data, rlc_data->fsp_pdu->fsp_pdu_data.data, pdcp_pdu_size);
602

603 604 605
//   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
606 607
  LOG_D(PROTO_AGENT, "[inst %d] Received PDCP PDU with size %d for UE RNTI %x RB %d, Calling pdcp_data_ind\n", ctxt_pP.instance, pdcp_pdu_size,ctxt_pP.rnti,rb_idP);
  result = pdcp_data_ind(&ctxt_pP,
608 609 610 611 612
                         srb_flagP,
                         flag_MBMS,
                         rb_idP,
                         pdcp_pdu_size,
                         pdcp_pdu_p);
613

614
  return result;
615 616

  error:
617
    if (pdcp_pdu_p)
618
      free_mem_block(pdcp_pdu_p, __func__);
619 620 621 622
    LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
    return -1;
}

623 624
int proto_agent_hello(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
{
625
  Protocol__FspHeader *header;
626 627
  Protocol__FspHello *hello_msg = NULL;

628
  /*TODO: Need to set random xid or xid from received hello message*/
629
  xid_t xid = mod_id;
630 631 632
  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_HELLO, &header) != 0)
    goto error;

633
  LOG_D(PROTO_AGENT, "creating the HELLO message\n");
634 635 636 637 638 639 640 641 642
  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;
643

644 645 646 647 648 649
  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;
650

651 652 653
 error:
  if(header != NULL)
    free(header);
654
  if(hello_msg!=NULL)
655 656 657 658 659 660 661 662
    free(hello_msg);
  if(*msg != NULL)
    free(*msg);
  LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}


663 664
int proto_agent_destroy_hello(Protocol__FlexsplitMessage *msg)
{
665 666
  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_HELLO_MSG)
    goto error;
667

668 669 670 671 672 673 674 675 676 677
  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;
}

678 679
int proto_agent_echo_request(mod_id_t mod_id, const void* params, Protocol__FlexsplitMessage **msg)
{
680
  Protocol__FspHeader *header;
681
  Protocol__FspEchoRequest *echo_request_msg = NULL;
682

683
  xid_t xid = mod_id;
684 685
  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_ECHO_REQUEST, &header) != 0)
    goto error;
686
  LOG_D(PROTO_AGENT, "creating the echo request message\n");
687

688 689 690
  echo_request_msg = malloc(sizeof(Protocol__FspEchoRequest));
  if(echo_request_msg == NULL)
    goto error;
691

692 693
  protocol__fsp_echo_request__init(echo_request_msg);
  echo_request_msg->header = header;
694

695 696
  *msg = malloc(sizeof(Protocol__FlexsplitMessage));
  if(*msg == NULL)
697
    goto error;
698
  protocol__flexsplit_message__init(*msg);
699

700
  LOG_D(PROTO_AGENT,"setting the message direction to %d\n", PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REQUEST_MSG);
701 702 703 704 705
  (*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;
706 707

 error:
708 709 710 711 712 713 714
  if(header != NULL)
    free(header);
  if(echo_request_msg != NULL)
    free(echo_request_msg);
  if(*msg != NULL)
    free(*msg);
  return -1;
715 716
}

717 718
int proto_agent_destroy_echo_request(Protocol__FlexsplitMessage *msg)
{
719 720
  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REQUEST_MSG)
    goto error;
721

722 723 724
  free(msg->echo_request_msg->header);
  free(msg->echo_request_msg);
  free(msg);
725
  return 0;
726

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

732 733
int proto_agent_echo_reply(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg)
{
734 735 736
  xid_t xid;
  Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
  Protocol__FspEchoRequest *echo_req = input->echo_request_msg;
737
  Protocol__FspEchoReply *echo_reply_msg = NULL;
738
  xid = (echo_req->header)->xid;
739

740
  LOG_D(PROTO_AGENT, "creating the echo reply message\n");
741 742
  Protocol__FspHeader *header;
  if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_ECHO_REPLY, &header) != 0)
743 744
    goto error;

745 746 747 748 749
  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;
750

751 752 753 754 755 756 757 758
  *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;
759 760 761
  return 0;

 error:
762 763 764 765 766 767 768 769
  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;
770 771
}

772 773 774
int proto_agent_destroy_echo_reply(Protocol__FlexsplitMessage *msg) {
  if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REPLY_MSG)
    goto error;
775

776 777 778
  free(msg->echo_reply_msg->header);
  free(msg->echo_reply_msg);
  free(msg);
779
  return 0;
780

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