flexran_agent_common.c 26 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19
 * 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
frtabu's avatar
frtabu committed
20
 */
21

22
/*! \file flexran_agent_common.c
frtabu's avatar
frtabu committed
23
 * \brief common primitives for all agents
24 25
 * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein, shahab SHARIAT BAGHERI
 * \date 2017
26 27 28
 * \version 0.1
 */

shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
29
#include <stdio.h>
30
#include <time.h>
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
31
#include <sys/stat.h>
32

33 34 35
#include "flexran_agent_common.h"
#include "flexran_agent_common_internal.h"
#include "flexran_agent_extern.h"
36
#include "flexran_agent_net_comm.h"
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI committed
37
#include "flexran_agent_ran_api.h"
38 39 40
#include "flexran_agent_phy.h"
#include "flexran_agent_mac.h"
#include "flexran_agent_rrc.h"
41
//#include "PHY/extern.h"
42
#include "common/utils/LOG/log.h"
43
#include "flexran_agent_mac_internal.h"
44

45 46
//#include "SCHED/defs.h"
#include "RRC/LTE/rrc_extern.h"
47
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
48
#include "rrc_eNB_UE_context.h"
49

50 51 52 53
/*
 * message primitives
 */

54
int flexran_agent_serialize_message(Protocol__FlexranMessage *msg, void **buf, int *size) {
55
  *size = protocol__flexran_message__get_packed_size(msg);
frtabu's avatar
frtabu committed
56

57 58
  if (buf == NULL)
    goto error;
frtabu's avatar
frtabu committed
59 60 61 62 63 64

  *buf = malloc(*size);

  if (*buf == NULL)
    goto error;

65
  protocol__flexran_message__pack(msg, *buf);
66
  return 0;
frtabu's avatar
frtabu committed
67
error:
68
  LOG_E(FLEXRAN_AGENT, "an error occured\n"); // change the com
69 70 71 72 73 74 75
  return -1;
}



/* We assume that the buffer size is equal to the message size.
   Should be chekced durint Tx/Rx */
76
int flexran_agent_deserialize_message(void *data, int size, Protocol__FlexranMessage **msg) {
77
  *msg = protocol__flexran_message__unpack(NULL, size, data);
frtabu's avatar
frtabu committed
78

79 80
  if (*msg == NULL)
    goto error;
81

82
  return 0;
frtabu's avatar
frtabu committed
83
error:
84 85 86 87 88 89
  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}



90
int flexran_create_header(xid_t xid, Protocol__FlexType type,  Protocol__FlexHeader **header) {
91
  *header = malloc(sizeof(Protocol__FlexHeader));
frtabu's avatar
frtabu committed
92

93 94
  if(*header == NULL)
    goto error;
frtabu's avatar
frtabu committed
95

96 97
  protocol__flex_header__init(*header);
  (*header)->version = FLEXRAN_VERSION;
frtabu's avatar
frtabu committed
98
  (*header)->has_version = 1;
99 100 101 102 103 104
  // check if the type is set
  (*header)->type = type;
  (*header)->has_type = 1;
  (*header)->xid = xid;
  (*header)->has_xid = 1;
  return 0;
frtabu's avatar
frtabu committed
105
error:
106
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
107 108 109 110
  return -1;
}


111
int flexran_agent_hello(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
112
  Protocol__FlexHeader *header = NULL;
113 114
  /*TODO: Need to set random xid or xid from received hello message*/
  xid_t xid = 1;
115 116
  Protocol__FlexHello *hello_msg;
  hello_msg = malloc(sizeof(Protocol__FlexHello));
frtabu's avatar
frtabu committed
117

118 119
  if(hello_msg == NULL)
    goto error;
frtabu's avatar
frtabu committed
120

121
  protocol__flex_hello__init(hello_msg);
122 123 124 125

  if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_HELLO, &header) != 0)
    goto error;

126
  hello_msg->header = header;
127 128 129
  hello_msg->bs_id  = flexran_get_bs_id(mod_id);
  hello_msg->has_bs_id = 1;
  hello_msg->n_capabilities = flexran_get_capabilities(mod_id, &hello_msg->capabilities);
130
  *msg = malloc(sizeof(Protocol__FlexranMessage));
frtabu's avatar
frtabu committed
131

132 133
  if(*msg == NULL)
    goto error;
frtabu's avatar
frtabu committed
134

135 136 137
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
138
  (*msg)->has_msg_dir = 1;
139 140
  (*msg)->hello_msg = hello_msg;
  return 0;
frtabu's avatar
frtabu committed
141 142
error:

143 144
  if(header != NULL)
    free(header);
frtabu's avatar
frtabu committed
145

146 147
  if(hello_msg != NULL)
    free(hello_msg);
frtabu's avatar
frtabu committed
148

149 150
  if(*msg != NULL)
    free(*msg);
frtabu's avatar
frtabu committed
151

152
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
153 154 155 156
  return -1;
}


157
int flexran_agent_destroy_hello(Protocol__FlexranMessage *msg) {
158
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG)
159
    goto error;
frtabu's avatar
frtabu committed
160

161
  free(msg->hello_msg->header);
162
  free(msg->hello_msg->capabilities);
163 164 165
  free(msg->hello_msg);
  free(msg);
  return 0;
frtabu's avatar
frtabu committed
166
error:
167
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
168 169 170 171
  return -1;
}


frtabu's avatar
frtabu committed
172
int flexran_agent_echo_request(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
173
  Protocol__FlexHeader *header = NULL;
174 175
  /*TODO: Need to set a random xid*/
  xid_t xid = 1;
176
  Protocol__FlexEchoRequest *echo_request_msg = NULL;
177
  echo_request_msg = malloc(sizeof(Protocol__FlexEchoRequest));
frtabu's avatar
frtabu committed
178

179 180
  if(echo_request_msg == NULL)
    goto error;
frtabu's avatar
frtabu committed
181

182
  protocol__flex_echo_request__init(echo_request_msg);
183 184 185 186

  if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_ECHO_REQUEST, &header) != 0)
    goto error;

187
  echo_request_msg->header = header;
188
  *msg = malloc(sizeof(Protocol__FlexranMessage));
frtabu's avatar
frtabu committed
189

190 191
  if(*msg == NULL)
    goto error;
frtabu's avatar
frtabu committed
192

193 194 195
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
196 197
  (*msg)->echo_request_msg = echo_request_msg;
  return 0;
frtabu's avatar
frtabu committed
198
error:
199 200 201

  if(header != NULL)
    free(header);
frtabu's avatar
frtabu committed
202

203 204
  if(echo_request_msg != NULL)
    free(echo_request_msg);
frtabu's avatar
frtabu committed
205

206 207
  if(*msg != NULL)
    free(*msg);
frtabu's avatar
frtabu committed
208

209 210 211 212 213
  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}


214
int flexran_agent_destroy_echo_request(Protocol__FlexranMessage *msg) {
215
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG)
216
    goto error;
frtabu's avatar
frtabu committed
217

218 219 220 221
  free(msg->echo_request_msg->header);
  free(msg->echo_request_msg);
  free(msg);
  return 0;
frtabu's avatar
frtabu committed
222
error:
223
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
224 225 226 227 228
  return -1;
}



229
int flexran_agent_echo_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
230
  xid_t xid;
231
  Protocol__FlexHeader *header = NULL;
232 233
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexEchoRequest *echo_req = input->echo_request_msg;
234
  xid = (echo_req->header)->xid;
235
  Protocol__FlexEchoReply *echo_reply_msg = NULL;
236
  echo_reply_msg = malloc(sizeof(Protocol__FlexEchoReply));
frtabu's avatar
frtabu committed
237

238 239
  if(echo_reply_msg == NULL)
    goto error;
frtabu's avatar
frtabu committed
240

241
  protocol__flex_echo_reply__init(echo_reply_msg);
242 243 244 245

  if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_ECHO_REPLY, &header) != 0)
    goto error;

246
  echo_reply_msg->header = header;
247
  *msg = malloc(sizeof(Protocol__FlexranMessage));
frtabu's avatar
frtabu committed
248

249 250
  if(*msg == NULL)
    goto error;
frtabu's avatar
frtabu committed
251

252 253 254
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
255
  (*msg)->has_msg_dir = 1;
256 257
  (*msg)->echo_reply_msg = echo_reply_msg;
  return 0;
frtabu's avatar
frtabu committed
258
error:
259 260 261

  if(header != NULL)
    free(header);
frtabu's avatar
frtabu committed
262

263 264
  if(echo_reply_msg != NULL)
    free(echo_reply_msg);
frtabu's avatar
frtabu committed
265

266 267
  if(*msg != NULL)
    free(*msg);
frtabu's avatar
frtabu committed
268

269
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
270 271 272 273
  return -1;
}


274
int flexran_agent_destroy_echo_reply(Protocol__FlexranMessage *msg) {
275
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG)
276
    goto error;
frtabu's avatar
frtabu committed
277

278 279 280 281
  free(msg->echo_reply_msg->header);
  free(msg->echo_reply_msg);
  free(msg);
  return 0;
frtabu's avatar
frtabu committed
282
error:
283
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
284 285
  return -1;
}
286

287

288
int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
289
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG)
290
    goto error;
frtabu's avatar
frtabu committed
291

292
  free(msg->enb_config_reply_msg->header);
293
  Protocol__FlexEnbConfigReply *reply = msg->enb_config_reply_msg;
frtabu's avatar
frtabu committed
294

295
  for (int i = 0; i < reply->n_cell_config; i++) {
296 297
    if (reply->cell_config[i]->mbsfn_subframe_config_rfoffset)
      free(reply->cell_config[i]->mbsfn_subframe_config_rfoffset);
298

299 300
    if (reply->cell_config[i]->mbsfn_subframe_config_rfperiod)
      free(reply->cell_config[i]->mbsfn_subframe_config_rfperiod);
301 302

    if (reply->cell_config[i]->mbsfn_subframe_config_sfalloc)
303
      free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc);
frtabu's avatar
frtabu committed
304

305 306
    if (reply->cell_config[i]->si_config) {
      for(int j = 0; j < reply->cell_config[i]->si_config->n_si_message; j++) {
frtabu's avatar
frtabu committed
307
        free(reply->cell_config[i]->si_config->si_message[j]);
308
      }
309

310 311 312
      free(reply->cell_config[i]->si_config->si_message);
      free(reply->cell_config[i]->si_config);
    }
frtabu's avatar
frtabu committed
313

314
    if (reply->cell_config[i]->slice_config) {
315
      for (int j = 0; j < reply->cell_config[i]->slice_config->n_dl; ++j) {
316 317
        if (reply->cell_config[i]->slice_config->dl[j]->n_sorting > 0)
          free(reply->cell_config[i]->slice_config->dl[j]->sorting);
frtabu's avatar
frtabu committed
318

319 320 321
        free(reply->cell_config[i]->slice_config->dl[j]->scheduler_name);
        free(reply->cell_config[i]->slice_config->dl[j]);
      }
frtabu's avatar
frtabu committed
322

323
      free(reply->cell_config[i]->slice_config->dl);
324

325
      for (int j = 0; j < reply->cell_config[i]->slice_config->n_ul; ++j) {
326 327
        if (reply->cell_config[i]->slice_config->ul[j]->n_sorting > 0)
          free(reply->cell_config[i]->slice_config->ul[j]->sorting);
frtabu's avatar
frtabu committed
328

329 330 331
        free(reply->cell_config[i]->slice_config->ul[j]->scheduler_name);
        free(reply->cell_config[i]->slice_config->ul[j]);
      }
frtabu's avatar
frtabu committed
332

333 334 335
      free(reply->cell_config[i]->slice_config->ul);
      free(reply->cell_config[i]->slice_config);
    }
frtabu's avatar
frtabu committed
336

337 338
    free(reply->cell_config[i]);
  }
frtabu's avatar
frtabu committed
339

340 341 342 343
  free(reply->cell_config);
  free(reply);
  free(msg);
  return 0;
frtabu's avatar
frtabu committed
344
error:
345
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
346
  return -1;
347 348
}

349
int flexran_agent_destroy_ue_config_reply(Protocol__FlexranMessage *msg) {
350
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG)
351
    goto error;
frtabu's avatar
frtabu committed
352

353
  free(msg->ue_config_reply_msg->header);
354
  int i;
355
  Protocol__FlexUeConfigReply *reply = msg->ue_config_reply_msg;
frtabu's avatar
frtabu committed
356 357

  for(i = 0; i < reply->n_ue_config; i++) {
358 359 360
    free(reply->ue_config[i]->capabilities);
    free(reply->ue_config[i]);
  }
frtabu's avatar
frtabu committed
361

362 363 364
  free(reply->ue_config);
  free(reply);
  free(msg);
365
  return 0;
frtabu's avatar
frtabu committed
366
error:
367
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
368
  return -1;
369 370
}

371
int flexran_agent_destroy_lc_config_reply(Protocol__FlexranMessage *msg) {
372
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REPLY_MSG)
373 374 375 376
    goto error;

  int i, j;
  free(msg->lc_config_reply_msg->header);
frtabu's avatar
frtabu committed
377

378 379 380 381
  for (i = 0; i < msg->lc_config_reply_msg->n_lc_ue_config; i++) {
    for (j = 0; j < msg->lc_config_reply_msg->lc_ue_config[i]->n_lc_config; j++) {
      free(msg->lc_config_reply_msg->lc_ue_config[i]->lc_config[j]);
    }
frtabu's avatar
frtabu committed
382

383 384 385
    free(msg->lc_config_reply_msg->lc_ue_config[i]->lc_config);
    free(msg->lc_config_reply_msg->lc_ue_config[i]);
  }
frtabu's avatar
frtabu committed
386

387 388 389
  free(msg->lc_config_reply_msg->lc_ue_config);
  free(msg->lc_config_reply_msg);
  free(msg);
390
  return 0;
frtabu's avatar
frtabu committed
391
error:
392
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
393
  return -1;
394 395
}

396

397
int flexran_agent_destroy_enb_config_request(Protocol__FlexranMessage *msg) {
398
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG)
399
    goto error;
frtabu's avatar
frtabu committed
400

401 402 403 404
  free(msg->enb_config_request_msg->header);
  free(msg->enb_config_request_msg);
  free(msg);
  return 0;
frtabu's avatar
frtabu committed
405
error:
406
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
407
  return -1;
408 409
}

410
int flexran_agent_destroy_ue_config_request(Protocol__FlexranMessage *msg) {
411 412 413 414
  /* TODO: Deallocate memory for a dynamically allocated UE config message */
  return 0;
}

415
int flexran_agent_destroy_lc_config_request(Protocol__FlexranMessage *msg) {
416 417 418 419
  /* TODO: Deallocate memory for a dynamically allocated LC config message */
  return 0;
}

420
// call this function to start a nanosecond-resolution timer
421
struct timespec timer_start(void) {
frtabu's avatar
frtabu committed
422 423 424
  struct timespec start_time;
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time);
  return start_time;
425 426 427
}

// call this function to end a timer, returning nanoseconds elapsed as a long
frtabu's avatar
frtabu committed
428 429 430 431 432
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;
433 434
}

435
int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
436 437
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexControlDelegation *control_delegation_msg = input->control_delegation_msg;
438
  //  struct timespec vartime = timer_start();
439 440 441
  //Write the payload lib into a file in the cache and load the lib
  char lib_name[120];
  char target[512];
442
  snprintf(lib_name, sizeof(lib_name), "/%s.so", control_delegation_msg->name);
443
  strcpy(target, RC.flexran[mod_id]->cache_name);
444 445 446
  strcat(target, lib_name);
  FILE *f;
  f = fopen(target, "wb");
frtabu's avatar
frtabu committed
447

448 449 450
  if (f) {
    fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f);
    fclose(f);
frtabu's avatar
frtabu committed
451
  } else {
452 453 454
    LOG_W(FLEXRAN_AGENT, "[%d] can not write control delegation data to %s\n",
          mod_id, target);
  }
455

456
  //  long time_elapsed_nanos = timer_end(vartime);
457 458 459 460
  *msg = NULL;
  return 0;
}

461
int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg) {
462
  /*TODO: Dealocate memory for a dynamically allocated control delegation message*/
463
  return 0;
464 465
}

466
int flexran_agent_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
467 468
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexAgentReconfiguration *agent_reconfiguration_msg = input->agent_reconfiguration_msg;
469 470 471 472 473
  apply_reconfiguration_policy(mod_id, agent_reconfiguration_msg->policy, strlen(agent_reconfiguration_msg->policy));
  *msg = NULL;
  return 0;
}

474
int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg) {
475
  /*TODO: Dealocate memory for a dynamically allocated agent reconfiguration message*/
476
  return 0;
477 478
}

479

480
int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
481
  xid_t xid;
482
  Protocol__FlexHeader *header = NULL;
483 484
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexLcConfigRequest *lc_config_request_msg = input->lc_config_request_msg;
485
  xid = (lc_config_request_msg->header)->xid;
486 487
  Protocol__FlexLcConfigReply *lc_config_reply_msg;
  lc_config_reply_msg = malloc(sizeof(Protocol__FlexLcConfigReply));
frtabu's avatar
frtabu committed
488

489 490
  if(lc_config_reply_msg == NULL)
    goto error;
frtabu's avatar
frtabu committed
491

492
  protocol__flex_lc_config_reply__init(lc_config_reply_msg);
493 494 495 496

  if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_LC_CONFIG_REPLY, &header) != 0)
    goto error;

497
  lc_config_reply_msg->header = header;
498 499 500 501 502 503
  /* the lc_config_reply entirely depends on MAC except for the
   * mac_eNB_get_rrc_status() function (which in the current OAI implementation
   * is reachable if F1 is present). Therefore we check here wether MAC CM is
   * present and the message gets properly filled if it is or remains empty if
   * not */
  lc_config_reply_msg->n_lc_ue_config =
504
    flexran_agent_get_mac_xface(mod_id) ? flexran_get_mac_num_ues(mod_id) : 0;
505
  Protocol__FlexLcUeConfig **lc_ue_config = NULL;
506

507
  if (lc_config_reply_msg->n_lc_ue_config > 0) {
508
    lc_ue_config = malloc(sizeof(Protocol__FlexLcUeConfig *) * lc_config_reply_msg->n_lc_ue_config);
frtabu's avatar
frtabu committed
509

510 511 512
    if (lc_ue_config == NULL) {
      goto error;
    }
frtabu's avatar
frtabu committed
513

514
    // Fill the config for each UE
515
    for (int i = 0; i < lc_config_reply_msg->n_lc_ue_config; i++) {
516
      lc_ue_config[i] = malloc(sizeof(Protocol__FlexLcUeConfig));
517 518 519 520 521 522 523
      if (!lc_ue_config[i]){
        for (int j = 0; j < i; j++){
          free(lc_ue_config[j]);
        }
        free(lc_ue_config);
        goto error;
      }
524

525
      protocol__flex_lc_ue_config__init(lc_ue_config[i]);
526 527
      const int UE_id = flexran_get_mac_ue_id(mod_id, i);
      flexran_agent_fill_mac_lc_ue_config(mod_id, UE_id, lc_ue_config[i]);
528
    } // end for UE
frtabu's avatar
frtabu committed
529

530 531
    lc_config_reply_msg->lc_ue_config = lc_ue_config;
  } // lc_config_reply_msg->n_lc_ue_config > 0
frtabu's avatar
frtabu committed
532

533
  *msg = malloc(sizeof(Protocol__FlexranMessage));
frtabu's avatar
frtabu committed
534

535 536 537 538 539
  if (*msg == NULL){
    for (int k = 0; k < lc_config_reply_msg->n_lc_ue_config; k++){
      free(lc_ue_config[k]);
    }
    free(lc_ue_config);
540
    goto error;
541
  }
frtabu's avatar
frtabu committed
542

543 544 545
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REPLY_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
546 547
  (*msg)->lc_config_reply_msg = lc_config_reply_msg;
  return 0;
frtabu's avatar
frtabu committed
548
error:
549 550 551 552

  // TODO: Need to make proper error handling
  if (header != NULL)
    free(header);
frtabu's avatar
frtabu committed
553

554 555
  if (lc_config_reply_msg != NULL)
    free(lc_config_reply_msg);
frtabu's avatar
frtabu committed
556

557 558
  if(*msg != NULL)
    free(*msg);
frtabu's avatar
frtabu committed
559

560
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
561 562 563 564 565 566 567 568 569
  return -1;
}

/*
 * ************************************
 * UE Configuration Reply
 * ************************************
 */

570
int sort_ue_config(const void *a, const void *b) {
571 572 573 574 575 576 577
  const Protocol__FlexUeConfig *fa = a;
  const Protocol__FlexUeConfig *fb = b;

  if (fa->rnti < fb->rnti)
    return -1;
  else if (fa->rnti < fb->rnti)
    return 1;
578

579 580 581
  return 0;
}

582
int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
583
  xid_t xid;
584
  Protocol__FlexHeader *header = NULL;
585 586
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexUeConfigRequest *ue_config_request_msg = input->ue_config_request_msg;
587
  xid = (ue_config_request_msg->header)->xid;
588 589
  Protocol__FlexUeConfigReply *ue_config_reply_msg;
  ue_config_reply_msg = malloc(sizeof(Protocol__FlexUeConfigReply));
frtabu's avatar
frtabu committed
590

591 592
  if(ue_config_reply_msg == NULL)
    goto error;
frtabu's avatar
frtabu committed
593

594
  protocol__flex_ue_config_reply__init(ue_config_reply_msg);
595 596 597 598

  if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_UE_CONFIG_REPLY, &header) != 0)
    goto error;

599
  ue_config_reply_msg->header = header;
600
  ue_config_reply_msg->n_ue_config = 0;
601

602 603 604 605 606 607 608
  if (flexran_agent_get_rrc_xface(mod_id))
    ue_config_reply_msg->n_ue_config = flexran_get_rrc_num_ues(mod_id);
  else if (flexran_agent_get_mac_xface(mod_id))
    ue_config_reply_msg->n_ue_config = flexran_get_mac_num_ues(mod_id);

  if (flexran_agent_get_rrc_xface(mod_id) && flexran_agent_get_mac_xface(mod_id)
      && flexran_get_rrc_num_ues(mod_id) != flexran_get_mac_num_ues(mod_id)) {
609 610 611 612
    const int nrrc = flexran_get_rrc_num_ues(mod_id);
    const int nmac = flexran_get_mac_num_ues(mod_id);
    ue_config_reply_msg->n_ue_config = nrrc < nmac ? nrrc : nmac;
    LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %lu UEs\n",
613
          __func__, nrrc, nmac, ue_config_reply_msg->n_ue_config);
614
  }
615

616
  Protocol__FlexUeConfig **ue_config;
frtabu's avatar
frtabu committed
617

618
  if (ue_config_reply_msg->n_ue_config > 0) {
619
    ue_config = malloc(sizeof(Protocol__FlexUeConfig *) * ue_config_reply_msg->n_ue_config);
frtabu's avatar
frtabu committed
620

621 622 623
    if (ue_config == NULL) {
      goto error;
    }
624

625 626
    rnti_t rntis[ue_config_reply_msg->n_ue_config];
    flexran_get_rrc_rnti_list(mod_id, rntis, ue_config_reply_msg->n_ue_config);
627

628
    for (int i = 0; i < ue_config_reply_msg->n_ue_config; i++) {
629
      const rnti_t rnti = rntis[i];
630 631
      ue_config[i] = malloc(sizeof(Protocol__FlexUeConfig));
      protocol__flex_ue_config__init(ue_config[i]);
632

633 634
      if (flexran_agent_get_rrc_xface(mod_id))
        flexran_agent_fill_rrc_ue_config(mod_id, rnti, ue_config[i]);
635

636
      if (flexran_agent_get_mac_xface(mod_id)) {
637
        const int UE_id = flexran_get_mac_ue_id_rnti(mod_id, rnti);
638
        flexran_agent_fill_mac_ue_config(mod_id, UE_id, ue_config[i]);
639 640
      }
    }
641

642 643
    ue_config_reply_msg->ue_config = ue_config;
  }
frtabu's avatar
frtabu committed
644

645
  *msg = malloc(sizeof(Protocol__FlexranMessage));
frtabu's avatar
frtabu committed
646

647 648
  if (*msg == NULL)
    goto error;
frtabu's avatar
frtabu committed
649

650 651 652
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
653 654
  (*msg)->ue_config_reply_msg = ue_config_reply_msg;
  return 0;
frtabu's avatar
frtabu committed
655
error:
656 657 658 659

  // TODO: Need to make proper error handling
  if (header != NULL)
    free(header);
frtabu's avatar
frtabu committed
660

661 662
  if (ue_config_reply_msg != NULL)
    free(ue_config_reply_msg);
frtabu's avatar
frtabu committed
663

664 665
  if(*msg != NULL)
    free(*msg);
frtabu's avatar
frtabu committed
666

667
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
668 669 670 671
  return -1;
}


MKassem's avatar
MKassem committed
672 673 674 675 676 677
/*
 * ************************************
 * eNB Configuration Request and Reply
 * ************************************
 */

frtabu's avatar
frtabu committed
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
int flexran_agent_enb_config_request(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
  Protocol__FlexHeader *header = NULL;
  xid_t xid = 1;
  Protocol__FlexEnbConfigRequest *enb_config_request_msg;
  enb_config_request_msg = malloc(sizeof(Protocol__FlexEnbConfigRequest));

  if(enb_config_request_msg == NULL)
    goto error;

  protocol__flex_enb_config_request__init(enb_config_request_msg);

  if(flexran_create_header(xid,PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REQUEST, &header) != 0)
    goto error;

  enb_config_request_msg->header = header;
  *msg = malloc(sizeof(Protocol__FlexranMessage));

  if(*msg == NULL)
    goto error;

  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
  (*msg)->enb_config_request_msg = enb_config_request_msg;
  return 0;
error:

  // TODO: Need to make proper error handling
  if (header != NULL)
    free(header);

  if (enb_config_request_msg != NULL)
    free(enb_config_request_msg);

  if(*msg != NULL)
    free(*msg);

  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
MKassem's avatar
MKassem committed
717 718
}

719
int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
720
  xid_t xid;
721
  Protocol__FlexHeader *header = NULL;
722 723
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexEnbConfigRequest *enb_config_req_msg = input->enb_config_request_msg;
724
  xid = (enb_config_req_msg->header)->xid;
725
  Protocol__FlexEnbConfigReply *enb_config_reply_msg;
726
  enb_config_reply_msg = malloc(sizeof(Protocol__FlexEnbConfigReply));
frtabu's avatar
frtabu committed
727

728 729
  if(enb_config_reply_msg == NULL)
    goto error;
frtabu's avatar
frtabu committed
730

731
  protocol__flex_enb_config_reply__init(enb_config_reply_msg);
732 733 734

  if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REPLY, &header) != 0)
    goto error;
735

frtabu's avatar
frtabu committed
736
  enb_config_reply_msg->header = header;
737
  enb_config_reply_msg->n_cell_config = MAX_NUM_CCs;
738
  Protocol__FlexCellConfig **cell_conf;
frtabu's avatar
frtabu committed
739 740

  if(enb_config_reply_msg->n_cell_config > 0) {
741
    cell_conf = malloc(sizeof(Protocol__FlexCellConfig *) * enb_config_reply_msg->n_cell_config);
frtabu's avatar
frtabu committed
742

743 744
    if(cell_conf == NULL)
      goto error;
745 746

    for(int i = 0; i < enb_config_reply_msg->n_cell_config; i++) {
747
      cell_conf[i] = malloc(sizeof(Protocol__FlexCellConfig));
748

749 750 751 752 753 754 755
      if (!cell_conf[i]) {
        for (int j = 0; j < i; j++) {
          free(cell_conf[j]);
        }
        free(cell_conf);
        goto error;
      }
756

757
      protocol__flex_cell_config__init(cell_conf[i]);
758

759 760
      if (flexran_agent_get_phy_xface(mod_id))
        flexran_agent_fill_phy_cell_config(mod_id, i, cell_conf[i]);
761

762 763
      if (flexran_agent_get_rrc_xface(mod_id))
        flexran_agent_fill_rrc_cell_config(mod_id, i, cell_conf[i]);
764

765 766
      if (flexran_agent_get_mac_xface(mod_id))
        flexran_agent_fill_mac_cell_config(mod_id, i, cell_conf[i]);
767

768 769 770
      cell_conf[i]->carrier_index = i;
      cell_conf[i]->has_carrier_index = 1;
    }
frtabu's avatar
frtabu committed
771

772 773
    enb_config_reply_msg->cell_config=cell_conf;
  }
frtabu's avatar
frtabu committed
774

775
  *msg = malloc(sizeof(Protocol__FlexranMessage));
frtabu's avatar
frtabu committed
776

777 778 779 780 781
  if(*msg == NULL) {
    for (int k = 0; k < enb_config_reply_msg->n_cell_config; k++) {
      free(cell_conf[k]);
    }
    free(cell_conf);
782
    goto error;
783
  }
frtabu's avatar
frtabu committed
784

785 786 787
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
788 789
  (*msg)->enb_config_reply_msg = enb_config_reply_msg;
  return 0;
frtabu's avatar
frtabu committed
790 791
error:

792 793 794
  // TODO: Need to make proper error handling
  if (header != NULL)
    free(header);
frtabu's avatar
frtabu committed
795

796 797
  if (enb_config_reply_msg != NULL)
    free(enb_config_reply_msg);
frtabu's avatar
frtabu committed
798

799 800
  if(*msg != NULL)
    free(*msg);
frtabu's avatar
frtabu committed
801

802
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
803
  return -1;
MKassem's avatar
MKassem committed
804 805
}

806

807 808 809 810 811 812 813
int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
  protocol_ctxt_t  ctxt;
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexRrcTriggering *triggering = input->rrc_triggering;
  agent_reconf_rrc *reconf_param = malloc(sizeof(agent_reconf_rrc));
  reconf_param->trigger_policy = triggering->rrc_trigger;
  struct rrc_eNB_ue_context_s   *ue_context_p = NULL;
frtabu's avatar
frtabu committed
814 815 816
  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[mod_id]->rrc_ue_head)) {
    PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id);
    flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, ue_context_p, 0, reconf_param);
817
  }
818
  *msg = NULL;
819
  return 0;
820 821
}

822

frtabu's avatar
frtabu committed
823
int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg) {
Xenofon Foukas's avatar
Xenofon Foukas committed
824
  // TODO
825 826 827
  return 0;
}

frtabu's avatar
frtabu committed
828
int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
829 830
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexEnbConfigReply *enb_config = input->enb_config_reply_msg;
831

832 833 834 835 836 837
  if (enb_config->n_cell_config == 0) {
    LOG_W(FLEXRAN_AGENT,
          "received enb_config_reply message does not contain a cell_config\n");
    *msg = NULL;
    return 0;
  }
838

839 840
  if (enb_config->n_cell_config > 1)
    LOG_W(FLEXRAN_AGENT, "ignoring slice configs for other cell except cell 0\n");
841

842
  if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) {
843
    prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config);
844 845
    //} else {
    //  initiate_soft_restart(mod_id, enb_config->cell_config[0]);
846
  }
847

848 849 850
  *msg = NULL;
  return 0;
}
851

frtabu's avatar
frtabu committed
852
int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
853 854 855 856
  int i;
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexUeConfigReply *ue_config_reply = input->ue_config_reply_msg;

857
  for (i = 0; flexran_agent_get_mac_xface(mod_id) && i < ue_config_reply->n_ue_config; i++)
858 859 860 861 862
    prepare_ue_slice_assoc_update(mod_id, ue_config_reply->ue_config[i]);

  *msg = NULL;
  return 0;
}