flexran_agent_common.c 37.5 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
Cedric Roux's avatar
Cedric Roux committed
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
20
 * 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
 */ 
nikaeinn's avatar
nikaeinn committed
21

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

shahab's avatar
shahab committed
29
#include <stdio.h>
30
#include <time.h>
shahab's avatar
shahab committed
31
#include <sys/stat.h>
nikaeinn's avatar
nikaeinn committed
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's avatar
shahab committed
37
#include "flexran_agent_ran_api.h"
MKassem's avatar
MKassem committed
38
#include "PHY/extern.h"
nikaeinn's avatar
nikaeinn committed
39
40
#include "log.h"

41
#include "SCHED/defs.h"
42
43
#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
44
#include "rrc_eNB_UE_context.h"
nikaeinn's avatar
nikaeinn committed
45

46
47
48
49
/*
 * message primitives
 */

50
int flexran_agent_serialize_message(Protocol__FlexranMessage *msg, void **buf, int *size) {
nikaeinn's avatar
nikaeinn committed
51

52
  *size = protocol__flexran_message__get_packed_size(msg);
nikaeinn's avatar
nikaeinn committed
53
54
55
56
57
  
  *buf = malloc(*size);
  if (buf == NULL)
    goto error;
  
58
  protocol__flexran_message__pack(msg, *buf);
nikaeinn's avatar
nikaeinn committed
59
60
61
62
  
  return 0;
  
 error:
63
  LOG_E(FLEXRAN_AGENT, "an error occured\n"); // change the com
nikaeinn's avatar
nikaeinn committed
64
65
66
67
68
69
70
  return -1;
}



/* We assume that the buffer size is equal to the message size.
   Should be chekced durint Tx/Rx */
71
int flexran_agent_deserialize_message(void *data, int size, Protocol__FlexranMessage **msg) {
72
  *msg = protocol__flexran_message__unpack(NULL, size, data);
nikaeinn's avatar
nikaeinn committed
73
74
  if (*msg == NULL)
    goto error;
75

nikaeinn's avatar
nikaeinn committed
76
77
78
79
80
81
82
83
84
  return 0;
  
 error:
  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}



85
int flexran_create_header(xid_t xid, Protocol__FlexType type,  Protocol__FlexHeader **header) {
nikaeinn's avatar
nikaeinn committed
86
  
87
  *header = malloc(sizeof(Protocol__FlexHeader));
nikaeinn's avatar
nikaeinn committed
88
89
90
  if(*header == NULL)
    goto error;
  
91
92
  protocol__flex_header__init(*header);
  (*header)->version = FLEXRAN_VERSION;
nikaeinn's avatar
nikaeinn committed
93
94
95
96
97
98
99
100
101
  (*header)->has_version = 1; 
  // check if the type is set
  (*header)->type = type;
  (*header)->has_type = 1;
  (*header)->xid = xid;
  (*header)->has_xid = 1;
  return 0;

 error:
102
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
nikaeinn's avatar
nikaeinn committed
103
104
105
106
  return -1;
}


107
int flexran_agent_hello(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
nikaeinn's avatar
nikaeinn committed
108
 
109
  Protocol__FlexHeader *header = NULL;
110
111
  /*TODO: Need to set random xid or xid from received hello message*/
  xid_t xid = 1;
nikaeinn's avatar
nikaeinn committed
112

113
114
  Protocol__FlexHello *hello_msg;
  hello_msg = malloc(sizeof(Protocol__FlexHello));
nikaeinn's avatar
nikaeinn committed
115
116
  if(hello_msg == NULL)
    goto error;
117
  protocol__flex_hello__init(hello_msg);
118
119
120
121

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

nikaeinn's avatar
nikaeinn committed
122
123
  hello_msg->header = header;

124
  *msg = malloc(sizeof(Protocol__FlexranMessage));
nikaeinn's avatar
nikaeinn committed
125
126
127
  if(*msg == NULL)
    goto error;
  
128
129
130
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
131
  (*msg)->has_msg_dir = 1;
nikaeinn's avatar
nikaeinn committed
132
133
134
135
136
137
138
139
140
141
  (*msg)->hello_msg = hello_msg;
  return 0;
  
 error:
  if(header != NULL)
    free(header);
  if(hello_msg != NULL)
    free(hello_msg);
  if(*msg != NULL)
    free(*msg);
142
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
nikaeinn's avatar
nikaeinn committed
143
144
145
146
  return -1;
}


147
int flexran_agent_destroy_hello(Protocol__FlexranMessage *msg) {
nikaeinn's avatar
nikaeinn committed
148
  
149
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG)
nikaeinn's avatar
nikaeinn committed
150
151
152
153
154
155
156
157
    goto error;
  
  free(msg->hello_msg->header);
  free(msg->hello_msg);
  free(msg);
  return 0;

 error:
158
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
nikaeinn's avatar
nikaeinn committed
159
160
161
162
  return -1;
}


163
int flexran_agent_echo_request(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg) {
164
  Protocol__FlexHeader *header = NULL;
165
166
  /*TODO: Need to set a random xid*/
  xid_t xid = 1;
nikaeinn's avatar
nikaeinn committed
167

168
  Protocol__FlexEchoRequest *echo_request_msg = NULL;
169
  echo_request_msg = malloc(sizeof(Protocol__FlexEchoRequest));
nikaeinn's avatar
nikaeinn committed
170
171
  if(echo_request_msg == NULL)
    goto error;
172
  protocol__flex_echo_request__init(echo_request_msg);
173
174
175
176

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

nikaeinn's avatar
nikaeinn committed
177
178
  echo_request_msg->header = header;

179
  *msg = malloc(sizeof(Protocol__FlexranMessage));
nikaeinn's avatar
nikaeinn committed
180
181
  if(*msg == NULL)
    goto error;
182
183
184
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
nikaeinn's avatar
nikaeinn committed
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
  (*msg)->echo_request_msg = echo_request_msg;
  return 0;

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


200
int flexran_agent_destroy_echo_request(Protocol__FlexranMessage *msg) {
201
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG)
nikaeinn's avatar
nikaeinn committed
202
203
204
205
206
207
208
209
    goto error;
  
  free(msg->echo_request_msg->header);
  free(msg->echo_request_msg);
  free(msg);
  return 0;
  
 error:
210
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
nikaeinn's avatar
nikaeinn committed
211
212
213
214
215
  return -1;
}



216
int flexran_agent_echo_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
217
218
  
  xid_t xid;
219
  Protocol__FlexHeader *header = NULL;
220
221
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexEchoRequest *echo_req = input->echo_request_msg;
222
223
  xid = (echo_req->header)->xid;

224
  Protocol__FlexEchoReply *echo_reply_msg = NULL;
225
  echo_reply_msg = malloc(sizeof(Protocol__FlexEchoReply));
nikaeinn's avatar
nikaeinn committed
226
227
  if(echo_reply_msg == NULL)
    goto error;
228
  protocol__flex_echo_reply__init(echo_reply_msg);
229
230
231
232

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

nikaeinn's avatar
nikaeinn committed
233
234
  echo_reply_msg->header = header;

235
  *msg = malloc(sizeof(Protocol__FlexranMessage));
nikaeinn's avatar
nikaeinn committed
236
237
  if(*msg == NULL)
    goto error;
238
239
240
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
241
  (*msg)->has_msg_dir = 1;
nikaeinn's avatar
nikaeinn committed
242
243
244
245
246
247
248
249
250
251
  (*msg)->echo_reply_msg = echo_reply_msg;
  return 0;

 error:
  if(header != NULL)
    free(header);
  if(echo_reply_msg != NULL)
    free(echo_reply_msg);
  if(*msg != NULL)
    free(*msg);
252
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
nikaeinn's avatar
nikaeinn committed
253
254
255
256
  return -1;
}


257
int flexran_agent_destroy_echo_reply(Protocol__FlexranMessage *msg) {
258
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG)
nikaeinn's avatar
nikaeinn committed
259
260
261
262
263
264
265
266
    goto error;
  
  free(msg->echo_reply_msg->header);
  free(msg->echo_reply_msg);
  free(msg);
  return 0;
  
 error:
267
  LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
nikaeinn's avatar
nikaeinn committed
268
269
  return -1;
}
270

271

272
int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) {
273
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG)
274
275
276
    goto error;
  free(msg->enb_config_reply_msg->header);
  int i, j;
277
  Protocol__FlexEnbConfigReply *reply = msg->enb_config_reply_msg;
278
  
279
  for(i = 0; i < reply->n_cell_config;i++) {
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
    free(reply->cell_config[i]->mbsfn_subframe_config_rfoffset);
    free(reply->cell_config[i]->mbsfn_subframe_config_rfperiod);
    free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc);
    if (reply->cell_config[i]->si_config != NULL) {
      for(j = 0; j < reply->cell_config[i]->si_config->n_si_message;j++){
	free(reply->cell_config[i]->si_config->si_message[j]);
      }
      free(reply->cell_config[i]->si_config->si_message);
      free(reply->cell_config[i]->si_config);
    }
    free(reply->cell_config[i]);
  }
  free(reply->cell_config);
  free(reply);
  free(msg);
  
  return 0;
 error:
298
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
299
  return -1;
300
301
}

302
int flexran_agent_destroy_ue_config_reply(Protocol__FlexranMessage *msg) {
303
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG)
304
305
    goto error;
  free(msg->ue_config_reply_msg->header);
306
  int i;
307
  Protocol__FlexUeConfigReply *reply = msg->ue_config_reply_msg;
308
309
310
311
312
313
314
315
316
  
  for(i = 0; i < reply->n_ue_config;i++){
    free(reply->ue_config[i]->capabilities);
    free(reply->ue_config[i]);
  }
  free(reply->ue_config);
  free(reply);
  free(msg);

317
  return 0;
318
 error:
319
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
320
  return -1;
321
322
}

323
int flexran_agent_destroy_lc_config_reply(Protocol__FlexranMessage *msg) {
324
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REPLY_MSG)
325
326
327
328
329
330
331
332
333
334
335
336
337
338
    goto error;

  int i, j;
  free(msg->lc_config_reply_msg->header);
  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]);
    }
    free(msg->lc_config_reply_msg->lc_ue_config[i]->lc_config);
    free(msg->lc_config_reply_msg->lc_ue_config[i]);
  }
  free(msg->lc_config_reply_msg->lc_ue_config);
  free(msg->lc_config_reply_msg);
  free(msg);
339
  return 0;
340
 error:
341
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
342
  return -1;
343
344
}

345

346
int flexran_agent_destroy_enb_config_request(Protocol__FlexranMessage *msg) {
347
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG)
348
349
350
351
352
353
354
    goto error;
  free(msg->enb_config_request_msg->header);
  free(msg->enb_config_request_msg);
  free(msg);
  return 0;
  
 error:
355
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
356
  return -1;
357
358
}

359
int flexran_agent_destroy_ue_config_request(Protocol__FlexranMessage *msg) {
360
361
362
363
  /* TODO: Deallocate memory for a dynamically allocated UE config message */
  return 0;
}

364
int flexran_agent_destroy_lc_config_request(Protocol__FlexranMessage *msg) {
365
366
367
368
  /* TODO: Deallocate memory for a dynamically allocated LC config message */
  return 0;
}

369
// call this function to start a nanosecond-resolution timer
370
struct timespec timer_start(void) {
371
372
373
374
375
376
377
378
379
380
381
382
383
    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;
}

384
int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
385

386
387
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexControlDelegation *control_delegation_msg = input->control_delegation_msg;
388

389
  //  struct timespec vartime = timer_start();
390
391
392
  //Write the payload lib into a file in the cache and load the lib
  char lib_name[120];
  char target[512];
393
  snprintf(lib_name, sizeof(lib_name), "/%s.so", control_delegation_msg->name);
394
  strcpy(target, RC.flexran[mod_id]->cache_name);
395
  strcat(target, lib_name);
shahab's avatar
shahab committed
396
  
397
398
399
400
401
  FILE *f;
  f = fopen(target, "wb");
  fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f);
  fclose(f);

402
  //  long time_elapsed_nanos = timer_end(vartime);
403
404
405
406
407
  *msg = NULL;
  return 0;

}

408
int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg) {
409
  /*TODO: Dealocate memory for a dynamically allocated control delegation message*/
410
  return 0;
411
412
}

413
int flexran_agent_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
414
415
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexAgentReconfiguration *agent_reconfiguration_msg = input->agent_reconfiguration_msg;
416
417
418
419
420
421
422

  apply_reconfiguration_policy(mod_id, agent_reconfiguration_msg->policy, strlen(agent_reconfiguration_msg->policy));

  *msg = NULL;
  return 0;
}

423
int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg) {
424
  /*TODO: Dealocate memory for a dynamically allocated agent reconfiguration message*/
425
  return 0;
426
427
}

428

429
int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
430
431

  xid_t xid;
432
  Protocol__FlexHeader *header = NULL;
433
434
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexLcConfigRequest *lc_config_request_msg = input->lc_config_request_msg;
435
436
437
438
  xid = (lc_config_request_msg->header)->xid;

  int i, j;

439
440
  Protocol__FlexLcConfigReply *lc_config_reply_msg;
  lc_config_reply_msg = malloc(sizeof(Protocol__FlexLcConfigReply));
441
442
  if(lc_config_reply_msg == NULL)
    goto error;
443
  protocol__flex_lc_config_reply__init(lc_config_reply_msg);
444
445
446
447

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

448
449
  lc_config_reply_msg->header = header;

450
  lc_config_reply_msg->n_lc_ue_config = flexran_get_num_ues(mod_id);
451

452
  Protocol__FlexLcUeConfig **lc_ue_config;
453
  if (lc_config_reply_msg->n_lc_ue_config > 0) {
454
    lc_ue_config = malloc(sizeof(Protocol__FlexLcUeConfig *) * lc_config_reply_msg->n_lc_ue_config);
455
456
457
458
459
    if (lc_ue_config == NULL) {
      goto error;
    }
    // Fill the config for each UE
    for (i = 0; i < lc_config_reply_msg->n_lc_ue_config; i++) {
460
461
      lc_ue_config[i] = malloc(sizeof(Protocol__FlexLcUeConfig));
      protocol__flex_lc_ue_config__init(lc_ue_config[i]);
462

463
      lc_ue_config[i]->has_rnti = 1;
464
      lc_ue_config[i]->rnti = flexran_get_ue_crnti(mod_id,i);
465

466
      //TODO: Set the number of LC configurations that will be reported for this UE
467
468
      //Set this according to the current state of the UE. This is only a temporary fix
      int status = 0;
469
      status = mac_eNB_get_rrc_status(mod_id, flexran_get_ue_crnti(mod_id, i));
Robert Schmidt's avatar
Robert Schmidt committed
470
      /* TODO needs to be revised and appropriate API to be implemented */
471
472
473
474
475
476
477
      if (status < RRC_CONNECTED) {
	lc_ue_config[i]->n_lc_config = 0;
      } else if (status == RRC_CONNECTED) {
	lc_ue_config[i]->n_lc_config = 1;
      } else {
	lc_ue_config[i]->n_lc_config = 3;
      }
478

479
      Protocol__FlexLcConfig **lc_config;
480
      if (lc_ue_config[i]->n_lc_config > 0) {
481
	lc_config = malloc(sizeof(Protocol__FlexLcConfig *) * lc_ue_config[i]->n_lc_config);
482
483
484
485
	if (lc_config == NULL) {
	  goto error;
	}
	for (j = 0; j < lc_ue_config[i]->n_lc_config; j++) {
486
487
	  lc_config[j] = malloc(sizeof(Protocol__FlexLcConfig));
	  protocol__flex_lc_config__init(lc_config[j]);
488
	 
489
490
	  lc_config[j]->has_lcid = 1;
	  lc_config[j]->lcid = j+1;
491
	 
492
	  int lcg = flexran_get_lcg(mod_id, i, j+1);
493
494
	  if (lcg >= 0 && lcg <= 3) {
	    lc_config[j]->has_lcg = 1;
495
	    lc_config[j]->lcg = flexran_get_lcg(mod_id, i,j+1);
496
	  }
497
	 
498
	  lc_config[j]->has_direction = 1;
499
	  lc_config[j]->direction = flexran_get_direction(i,j+1);
500
	  //TODO: Bearer type. One of FLQBT_* values. Currently only default bearer supported
501
	  lc_config[j]->has_qos_bearer_type = 1;
502
	  lc_config[j]->qos_bearer_type = PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_NON_GBR;
503

504
	  //TODO: Set the QCI defined in TS 23.203, coded as defined in TS 36.413
505
	  // One less than the actual QCI value. Needs to be generalized
506
507
	  lc_config[j]->has_qci = 1;
	  lc_config[j]->qci = 1;
508
	  if (lc_config[j]->direction == PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_GBR) {
Robert Schmidt's avatar
Robert Schmidt committed
509
            /* TODO all of the need to be taken from API */
510
	    //TODO: Set the max bitrate (UL)
511
512
	    lc_config[j]->has_e_rab_max_bitrate_ul = 0;
	    lc_config[j]->e_rab_max_bitrate_ul = 0;
513
	    //TODO: Set the max bitrate (DL)
514
515
	    lc_config[j]->has_e_rab_max_bitrate_dl = 0;
	    lc_config[j]->e_rab_max_bitrate_dl = 0;
516
	    //TODO: Set the guaranteed bitrate (UL)
517
518
	    lc_config[j]->has_e_rab_guaranteed_bitrate_ul = 0;
	    lc_config[j]->e_rab_guaranteed_bitrate_ul = 0;
519
	    //TODO: Set the guaranteed bitrate (DL)
520
521
	    lc_config[j]->has_e_rab_guaranteed_bitrate_dl = 0;
	    lc_config[j]->e_rab_guaranteed_bitrate_dl = 0;
522
523
524
525
526
527
528
	  }
	}
	lc_ue_config[i]->lc_config = lc_config;
      }
    } // end for UE
    lc_config_reply_msg->lc_ue_config = lc_ue_config;
  } // lc_config_reply_msg->n_lc_ue_config > 0
529
  *msg = malloc(sizeof(Protocol__FlexranMessage));
530
531
  if (*msg == NULL)
    goto error;
532
533
534
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REPLY_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
535
536
537
538
539
540
541
542
543
544
545
546
  (*msg)->lc_config_reply_msg = lc_config_reply_msg;

  return 0;

 error:
  // TODO: Need to make proper error handling
  if (header != NULL)
    free(header);
  if (lc_config_reply_msg != NULL)
    free(lc_config_reply_msg);
  if(*msg != NULL)
    free(*msg);
547
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
548
549
550
551
552
553
554
555
556
  return -1;
}

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

557
int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
558
559

  xid_t xid;
560
  Protocol__FlexHeader *header = NULL;
561
562
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexUeConfigRequest *ue_config_request_msg = input->ue_config_request_msg;
563
564
565
566
  xid = (ue_config_request_msg->header)->xid;

  int i;

567
568
  Protocol__FlexUeConfigReply *ue_config_reply_msg;
  ue_config_reply_msg = malloc(sizeof(Protocol__FlexUeConfigReply));
569
570
  if(ue_config_reply_msg == NULL)
    goto error;
571
  protocol__flex_ue_config_reply__init(ue_config_reply_msg);
572
573
574
575

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

576
577
  ue_config_reply_msg->header = header;

578
  ue_config_reply_msg->n_ue_config = flexran_get_num_ues(mod_id);
579

580
  Protocol__FlexUeConfig **ue_config;
581
  if (ue_config_reply_msg->n_ue_config > 0) {
582
    ue_config = malloc(sizeof(Protocol__FlexUeConfig *) * ue_config_reply_msg->n_ue_config);
583
584
585
586
    if (ue_config == NULL) {
      goto error;
    }
    for (i = 0; i < ue_config_reply_msg->n_ue_config; i++) {
587
588
      ue_config[i] = malloc(sizeof(Protocol__FlexUeConfig));
      protocol__flex_ue_config__init(ue_config[i]);
589

590
      ue_config[i]->rnti = flexran_get_ue_crnti(mod_id,i);
591
      ue_config[i]->has_rnti = 1;
Robert Schmidt's avatar
Robert Schmidt committed
592
593
      ue_config[i]->imsi = flexran_get_ue_imsi(mod_id, i);
      ue_config[i]->has_imsi = 1;
594
595
596
      //TODO: Set the DRX configuration (optional)
      //Not supported for now, so we do not set it

597
598
      if (flexran_get_time_alignment_timer(mod_id,i) != -1) {
    	  ue_config[i]->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i);
599
    	  ue_config[i]->has_time_alignment_timer = 1;
600
      }
601

602
603
      if (flexran_get_meas_gap_config(mod_id,i) != -1) {
    	  ue_config[i]->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i);
604
    	  ue_config[i]->has_meas_gap_config_pattern = 1;
605
      }
606
 
607
      if (ue_config[i]->has_meas_gap_config_pattern == 1 &&
608
	 ue_config[i]->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) {
609
	ue_config[i]->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i);
610
611
	ue_config[i]->has_meas_gap_config_sf_offset = 1;
      }
612
613
614
615
616
617
618
619
620
      //TODO: Set the SPS configuration (Optional)
      //Not supported for noe, so we do not set it

      //TODO: Set the SR configuration (Optional)
      //We do not set it for now

      //TODO: Set the CQI configuration (Optional)
      //We do not set it for now

621
622
623
624
      if (flexran_get_ue_transmission_mode(mod_id,i) != -1) {
	ue_config[i]->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i);
	ue_config[i]->has_transmission_mode = 1;
      }
625

626
      ue_config[i]->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i);
627
628
      ue_config[i]->has_ue_aggregated_max_bitrate_ul = 1;

629
      ue_config[i]->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i);
630
631
      ue_config[i]->has_ue_aggregated_max_bitrate_dl = 1;

632
633
634
      Protocol__FlexUeCapabilities *capabilities;
      capabilities = malloc(sizeof(Protocol__FlexUeCapabilities));
      protocol__flex_ue_capabilities__init(capabilities);
635
636
637
638
639
640
641
642
643
644
      capabilities->has_half_duplex = 1;
      capabilities->half_duplex = flexran_get_half_duplex(mod_id, i);
      capabilities->has_intra_sf_hopping = 1;
      capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, i);
      capabilities->has_type2_sb_1 = 1;
      capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, i);
      capabilities->has_ue_category = 1;
      capabilities->ue_category = flexran_get_ue_category(mod_id, i);
      capabilities->has_res_alloc_type1 = 1;
      capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, i);
645
646
      //Set the capabilites to the message
      ue_config[i]->capabilities = capabilities;
647

648
649
650
651
      if (flexran_get_ue_transmission_antenna(mod_id,i) != -1) {
	ue_config[i]->has_ue_transmission_antenna = 1;
	ue_config[i]->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i);
      }
652

653
654
655
656
      if (flexran_get_tti_bundling(mod_id,i) != -1) {
	ue_config[i]->has_tti_bundling = 1;
	ue_config[i]->tti_bundling = flexran_get_tti_bundling(mod_id,i);
      }
657

658
659
660
661
      if (flexran_get_maxHARQ_TX(mod_id,i) != -1) {
	ue_config[i]->has_max_harq_tx = 1;
	ue_config[i]->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i);
      }
662

663
664
665
666
      if (flexran_get_beta_offset_ack_index(mod_id,i) != -1) {
	ue_config[i]->has_beta_offset_ack_index = 1;
	ue_config[i]->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i);
      }
667

668
669
670
671
      if (flexran_get_beta_offset_ri_index(mod_id,i) != -1) {
	ue_config[i]->has_beta_offset_ri_index = 1;
    	  ue_config[i]->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i);
      }
672

673
674
675
      if (flexran_get_beta_offset_cqi_index(mod_id,i) != -1) {
	ue_config[i]->has_beta_offset_cqi_index = 1;
	ue_config[i]->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i);
676
677
      }
      
Robert Schmidt's avatar
Robert Schmidt committed
678
679
      /* assume primary carrier */
      if (flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0) != -1) {
680
	ue_config[i]->has_ack_nack_simultaneous_trans = 1;
Robert Schmidt's avatar
Robert Schmidt committed
681
	ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id, i, 0);
682
      }
683
      
684
685
686
687
      if (flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) {
	ue_config[i]->has_simultaneous_ack_nack_cqi = 1;
	ue_config[i]->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i);
      }
688
      
689
690
691
692
693
694
695
696
      if (flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) {
	ue_config[i]->has_aperiodic_cqi_rep_mode = 1;
	int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i);
	if (mode > 4) {
	  ue_config[i]->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE;
	} else {
	  ue_config[i]->aperiodic_cqi_rep_mode = mode;
	}
697
      }
698
      
Robert Schmidt's avatar
Robert Schmidt committed
699
      if (flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) {
700
	ue_config[i]->has_tdd_ack_nack_feedback = 1;
Robert Schmidt's avatar
Robert Schmidt committed
701
	ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i);
702
      }
703
      
704
      if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) {
705
	ue_config[i]->has_ack_nack_repetition_factor = 1;
706
	ue_config[i]->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i);
707
      }
708
      
709
      if (flexran_get_extended_bsr_size(mod_id, i) != -1) {
710
	ue_config[i]->has_extended_bsr_size = 1;
711
	ue_config[i]->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i);
712
      }
713
714
715
      //TODO: Set carrier aggregation support (boolean)
      ue_config[i]->has_ca_support = 0;
      ue_config[i]->ca_support = 0;
716

717
718
      ue_config[i]->has_pcell_carrier_index = 1;
      ue_config[i]->pcell_carrier_index = UE_PCCID(mod_id, i);
719
      if(ue_config[i]->has_ca_support){
720
	//TODO: Set cross carrier scheduling support (boolean)
721
	ue_config[i]->has_cross_carrier_sched_support = 0;
722
723
724
725
	ue_config[i]->cross_carrier_sched_support = 0;
	//TODO: Set secondary cells configuration
	// We do not set it for now. No carrier aggregation support
	//TODO: Set deactivation timer for secondary cell
726
727
	ue_config[i]->has_scell_deactivation_timer = 0;
	ue_config[i]->scell_deactivation_timer = 0;
728
729
730
731
      }
    }
    ue_config_reply_msg->ue_config = ue_config;
  }
732
  *msg = malloc(sizeof(Protocol__FlexranMessage));
733
734
  if (*msg == NULL)
    goto error;
735
736
737
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG;
  (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
738
739
740
741
742
743
744
745
746
747
748
  (*msg)->ue_config_reply_msg = ue_config_reply_msg;
  return 0;

 error:
  // TODO: Need to make proper error handling
  if (header != NULL)
    free(header);
  if (ue_config_reply_msg != NULL)
    free(ue_config_reply_msg);
  if(*msg != NULL)
    free(*msg);
749
  //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__);
750
751
752
753
  return -1;
}


MKassem's avatar
MKassem committed
754
755
756
757
758
759
/*
 * ************************************
 * eNB Configuration Request and Reply
 * ************************************
 */

760
int flexran_agent_enb_config_request(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg) {
MKassem's avatar
MKassem committed
761

762
	Protocol__FlexHeader *header = NULL;
MKassem's avatar
MKassem committed
763
764
	xid_t xid = 1;

765
766
	Protocol__FlexEnbConfigRequest *enb_config_request_msg;
	enb_config_request_msg = malloc(sizeof(Protocol__FlexEnbConfigRequest));
MKassem's avatar
MKassem committed
767
	if(enb_config_request_msg == NULL)
768
	  goto error;
769
	protocol__flex_enb_config_request__init(enb_config_request_msg);
770
771
772
773
	
	if(flexran_create_header(xid,PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REQUEST, &header) != 0)
	  goto error;

MKassem's avatar
MKassem committed
774
775
	enb_config_request_msg->header = header;

776
	*msg = malloc(sizeof(Protocol__FlexranMessage));
MKassem's avatar
MKassem committed
777
	if(*msg == NULL)
778
	  goto error;
MKassem's avatar
MKassem committed
779

780
781
782
	protocol__flexran_message__init(*msg);
	(*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG;
	(*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
MKassem's avatar
MKassem committed
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
	(*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;
}

798
int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
MKassem's avatar
MKassem committed
799

800
  xid_t xid;
801
  Protocol__FlexHeader *header = NULL;
802
803
  Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params;
  Protocol__FlexEnbConfigRequest *enb_config_req_msg = input->enb_config_request_msg;
804
805
  xid = (enb_config_req_msg->header)->xid;
  
806
  int i, j;
807
  
808
  Protocol__FlexEnbConfigReply *enb_config_reply_msg;
809
  enb_config_reply_msg = malloc(sizeof(Protocol__FlexEnbConfigReply));
810
811
  if(enb_config_reply_msg == NULL)
    goto error;
812
  protocol__flex_enb_config_reply__init(enb_config_reply_msg);
813
814
815
816

  if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REPLY, &header) != 0)
    goto error;
  
817
  enb_config_reply_msg->header = header;
818
819
820
821

  enb_config_reply_msg->enb_id = RC.flexran[mod_id]->agent_id;
  enb_config_reply_msg->has_enb_id = 1;

822
823
  enb_config_reply_msg->n_cell_config = MAX_NUM_CCs;
  
824
  Protocol__FlexCellConfig **cell_conf;
825
  if(enb_config_reply_msg->n_cell_config > 0){
826
    cell_conf = malloc(sizeof(Protocol__FlexCellConfig *) * enb_config_reply_msg->n_cell_config);
827
828
829
    if(cell_conf == NULL)
      goto error;
    for(i = 0; i < enb_config_reply_msg->n_cell_config; i++){
830
831
      cell_conf[i] = malloc(sizeof(Protocol__FlexCellConfig));
      protocol__flex_cell_config__init(cell_conf[i]);
832

833
      cell_conf[i]->phy_cell_id = 1;
834
      cell_conf[i]->has_phy_cell_id = flexran_get_cell_id(mod_id,i);
835

836
      cell_conf[i]->cell_id = i;
837
      cell_conf[i]->has_cell_id = 1;
838

839
      cell_conf[i]->pusch_hopping_offset = flexran_get_hopping_offset(mod_id,i);
840
      cell_conf[i]->has_pusch_hopping_offset = 1;
841

842
      if (flexran_get_hopping_mode(mod_id,i) == 0) {
843
	cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTER;
844
      } else if(flexran_get_hopping_mode(mod_id,i) == 1) {
845
	cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTERINTRA;
846
      }
847
      cell_conf[i]->has_hopping_mode = 1;
848

849
      cell_conf[i]->n_sb = flexran_get_n_SB(mod_id,i);
850
      cell_conf[i]->has_n_sb = 1;
851

852
      if (flexran_get_phich_resource(mod_id,i) == 0) {
853
	cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE_SIXTH; //0
854
      } else if (flexran_get_phich_resource(mod_id,i) == 1) {
855
	cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_HALF; //1
856
      } else if (flexran_get_phich_resource(mod_id,i) == 2) {
857
	cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE; // 2
858
      } else if (flexran_get_phich_resource(mod_id,i) == 3) {
859
	cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_TWO;//3
860
      }
861
      cell_conf[i]->has_phich_resource = 1;
862

863
      if (flexran_get_phich_duration(mod_id,i) == 0) {
864
    	cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_NORMAL;
865
      } else if(flexran_get_phich_duration(mod_id,i) == 1) {
866
	cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_EXTENDED;
867
      }
868
      cell_conf[i]->has_phich_duration = 1;
869
      cell_conf[i]->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(mod_id,i);
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
      cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 1;
      Protocol__FlexSiConfig *si_config;
      si_config = malloc(sizeof(Protocol__FlexSiConfig));
      if(si_config == NULL)
        goto error;
      protocol__flex_si_config__init(si_config);

      si_config->sfn = flexran_get_current_system_frame_num(mod_id);
      si_config->has_sfn = 1;

      si_config->sib1_length = flexran_get_sib1_length(mod_id,i);
      si_config->has_sib1_length = 1;

      si_config->si_window_length = (uint32_t) flexran_get_si_window_length(mod_id, i);
      si_config->has_si_window_length = 1;

      si_config->n_si_message = 0;

888
889
      /* Protocol__FlexSiMessage **si_message; */
      /* si_message = malloc(sizeof(Protocol__FlexSiMessage *) * si_config->n_si_message); */
890
891
892
      /* if(si_message == NULL) */
      /* 	goto error; */
      /* for(j = 0; j < si_config->n_si_message; j++){ */
893
      /* 	si_message[j] = malloc(sizeof(Protocol__FlexSiMessage)); */
894
895
      /* 	if(si_message[j] == NULL) */
      /* 	  goto error; */
896
      /* 	protocol__flex_si_message__init(si_message[j]); */
897
898
899
900
901
902
903
904
905
906
      /* 	//TODO: Fill in with actual value, Periodicity of SI msg in radio frames */
      /* 	si_message[j]->periodicity = 1;				//SIPeriod */
      /* 	si_message[j]->has_periodicity = 1; */
      /* 	//TODO: Fill in with actual value, rhe length of the SI message in bytes */
      /* 	si_message[j]->length = 10; */
      /* 	si_message[j]->has_length = 1; */
      /* } */
      /* if(si_config->n_si_message > 0){ */
      /* 	si_config->si_message = si_message; */
      /* } */
907
908
909

      cell_conf[i]->si_config = si_config;

910
      cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(mod_id,i);
911
      cell_conf[i]->has_dl_bandwidth = 1;
912

913
      cell_conf[i]->ul_bandwidth = flexran_get_N_RB_UL(mod_id,i);
914
      cell_conf[i]->has_ul_bandwidth = 1;
915

916
      if (flexran_get_ul_cyclic_prefix_length(mod_id, i) == 0) {
917
	cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_NORMAL;
918
919
      } else if(flexran_get_ul_cyclic_prefix_length(mod_id, i) == 1) {
	cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED;
920
      }
921
      cell_conf[i]->has_ul_cyclic_prefix_length = 1;
922