flexran_agent_mac_internal.c 28.4 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.0  (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 flexran_agent_mac_internal.c
23
24
25
26
27
28
 * \brief Helper functions for the MAC agent
 * \author Xenofon Foukas
 * \date 2016
 * \version 0.1
 */

29
30
31
#include <string.h>
#include <dlfcn.h>

32
#include "flexran_agent_common_internal.h"
33
#include "flexran_agent_mac_internal.h"
34

35
36
Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol__FlexranMessage *new_message,
									Protocol__FlexranMessage *old_message) {
37
38
39

  int i, j;
  
40
  Protocol__FlexStatsReply *old_report, *new_report;
41

42
43
  Protocol__FlexStatsReply *stats_reply_msg = NULL;
  Protocol__FlexranMessage *msg = NULL;
44
  
45
46
47
48
  Protocol__FlexUeStatsReport **ue_report;
  Protocol__FlexUeStatsReport *tmp_ue_report[NUM_MAX_UE];
  Protocol__FlexCellStatsReport **cell_report;
  Protocol__FlexCellStatsReport *tmp_cell_report[NUM_MAX_UE];
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  
  old_report = old_message->stats_reply_msg;
  new_report = new_message->stats_reply_msg;

  /*See how many and which UE reports should be included in the final stats message*/
  int n_ue_report = 0;
  int ue_found = 0;
  
  /*Go through each RNTI of the new report and see if it exists in the old one*/
  for (i = 0; i < new_report->n_ue_report; i++) {
    for (j = 0; j < old_report->n_ue_report; i++) {
     if (new_report->ue_report[i]->rnti == old_report->ue_report[j]->rnti) {
  	ue_found = 1;
	/*Need to check if something changed*/
	if (compare_ue_stats_reports(new_report->ue_report[i], old_report->ue_report[j]) != 0) {
	  tmp_ue_report[n_ue_report] = copy_ue_stats_report(new_report->ue_report[i]);
	  n_ue_report++;
	}
	break;
     }
    }
    if (!ue_found) {
      tmp_ue_report[n_ue_report] = copy_ue_stats_report(new_report->ue_report[i]);
      n_ue_report++;
    }
    ue_found = 0;
  }

  /*See how many and which cell reports should be included in the final stats message*/
  int n_cell_report = 0;
  int cell_found = 0;
  
  /*Go through each cell of the new report and see if it exists in the old one*/
  for (i = 0; i < new_report->n_cell_report; i++) {
    for (j = 0; j < old_report->n_cell_report; i++) {
     if (new_report->cell_report[i]->carrier_index == old_report->cell_report[j]->carrier_index) {
  	cell_found = 1;
	/*Need to check if something changed*/
	if (compare_cell_stats_reports(new_report->cell_report[i], old_report->cell_report[j]) != 0) {
	  tmp_cell_report[n_cell_report] = copy_cell_stats_report(new_report->cell_report[i]);
	  n_cell_report++;
	}
	break;
     }
    }
    if (!cell_found) {
      tmp_cell_report[n_cell_report] = copy_cell_stats_report(new_report->cell_report[i]);
      n_cell_report++;
    }
    cell_found = 0;
  }
  
  if (n_cell_report > 0 || n_ue_report > 0) {
    /*Create header*/
    int xid = old_report->header->xid;
104
    Protocol__FlexHeader *header;
105
    if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_STATS_REPLY, &header) != 0) {
106
107
    goto error;
    }
108
109
    stats_reply_msg = malloc(sizeof(Protocol__FlexStatsReply));
    protocol__flex_stats_reply__init(stats_reply_msg);
110

111
    stats_reply_msg->header = header;
112
113
114
    
    /*TODO: create the reply message based on the findings*/
    /*Create ue report list*/
115
    stats_reply_msg->n_ue_report = n_ue_report;
116
117
118
119
120
121
122
123
124
    if (n_ue_report > 0) {
      ue_report = malloc(sizeof(Protocol__FlexUeStatsReport *));
      for (i = 0; i<n_ue_report; i++) {
	ue_report[i] = tmp_ue_report[i];
      }
      stats_reply_msg->ue_report = ue_report;
    }
    
    /*Create cell report list*/
125
    stats_reply_msg->n_cell_report = n_cell_report;
126
127
128
129
130
131
132
133
    if (n_cell_report > 0) {
      cell_report = malloc(sizeof(Protocol__FlexCellStatsReport *));
      for (i = 0; i<n_cell_report; i++) {
	cell_report[i] = tmp_cell_report[i];
      }
      stats_reply_msg->cell_report = cell_report;
    }

134
    msg = malloc(sizeof(Protocol__FlexranMessage));
135
136
    if(msg == NULL)
      goto error;
137
138
139
    protocol__flexran_message__init(msg);
    msg->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG;
    msg->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME;
140
141
142
143
144
145
146
147
    msg->stats_reply_msg = stats_reply_msg;
  }
  return msg;
  
 error:
   return NULL;
}

148
149
int compare_ue_stats_reports(Protocol__FlexUeStatsReport *rep1,
			    Protocol__FlexUeStatsReport *rep2) {
150
151
152
  return 1;
}

153
154
int compare_cell_stats_reports(Protocol__FlexCellStatsReport *rep1,
			      Protocol__FlexCellStatsReport *rep2) {
155
156
157
  return 1;
}

158
Protocol__FlexUeStatsReport * copy_ue_stats_report(Protocol__FlexUeStatsReport * original) {
159
  int i;
160
  Protocol__FlexUeStatsReport *copy =  malloc(sizeof(Protocol__FlexUeStatsReport));
161
162
  if (copy == NULL)
    goto error;
163
  protocol__flex_ue_stats_report__init(copy);
164
165
166
167
168
  copy->rnti = original->rnti;
  copy->has_rnti = original->has_rnti;
  copy->flags = original->flags;
  copy->has_flags = original->has_flags;
  
169
  if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) {
170
171
172
173
174
175
176
177
178
179
180
181
182
    copy->n_bsr = original->n_bsr;
    if (copy->n_bsr > 0) {
      uint32_t *elem;
      elem = (uint32_t *) malloc(sizeof(uint32_t)*copy->n_bsr);
      if (elem == NULL)
	goto error;
      for (i = 0; i < original->n_bsr; i++) {
	elem[i] = original->bsr[i];
      }
      copy->bsr = elem;
    }
  }

shahab's avatar
shahab committed
183
184
185
186
187
188
  

   if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { 
     copy->has_phr = original->has_phr;
     copy->phr = original->phr;
   }
189

190
  if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) {
191
192
    copy->n_rlc_report = original->n_rlc_report; 
    if (copy->n_rlc_report > 0) {
193
194
      Protocol__FlexRlcBsr ** rlc_reports;
      rlc_reports = malloc(sizeof(Protocol__FlexRlcBsr) * copy->n_rlc_report);
195
196
197
198
199
200
201
202
203
      if (rlc_reports == NULL)
	goto error;
      for (i = 0; i < copy->n_rlc_report; i++) {
	rlc_reports[i] = copy_rlc_report(original->rlc_report[i]);
      }
      copy->rlc_report = rlc_reports;
    }
  }

204
  if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) {
205
206
207
208
209
    copy->has_pending_mac_ces = original->has_pending_mac_ces;
    copy->pending_mac_ces = original->pending_mac_ces;
  
  }
  
210
  if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) {
211
212
213
    copy->dl_cqi_report = copy_dl_cqi_report(original->dl_cqi_report);
  }

214
  if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) {  
215
216
217
218
    /*Copy the Paging Buffer report*/
    copy->pbr = copy_paging_buffer_report(original->pbr);
  }

219
  if (copy->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) {
220
221
222
223
224
225
226
227
228
229
    /*TODO: Copy the UL report*/  
    copy->ul_cqi_report = copy_ul_cqi_report(original->ul_cqi_report);
  }

  return copy;

 error:
  return NULL;
}

230
231
Protocol__FlexRlcBsr * copy_rlc_report(Protocol__FlexRlcBsr * original) {
  Protocol__FlexRlcBsr * copy = malloc(sizeof(Protocol__FlexRlcBsr));
232
233
  if (copy == NULL)
    goto error;
234
  protocol__flex_rlc_bsr__init(copy);
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
  copy->lc_id = original->lc_id;
  copy->has_lc_id = original->has_lc_id;
  copy->tx_queue_size = original->tx_queue_size;
  copy->has_tx_queue_size = original->has_tx_queue_size;
  copy->tx_queue_hol_delay = original->tx_queue_hol_delay;
  copy->has_tx_queue_hol_delay = original->has_tx_queue_hol_delay;
  copy->retransmission_queue_size = original->retransmission_queue_size;
  copy->has_retransmission_queue_size = original->has_retransmission_queue_size;
  copy->retransmission_queue_hol_delay = original->retransmission_queue_hol_delay;
  copy->has_retransmission_queue_hol_delay = original->has_retransmission_queue_hol_delay;
  copy->status_pdu_size = original->status_pdu_size;
  copy->has_status_pdu_size = original->has_status_pdu_size;
  
  return copy;

 error:
  return NULL;
}

254
Protocol__FlexUlCqiReport * copy_ul_cqi_report(Protocol__FlexUlCqiReport * original) {
255
256
257
  int i, j;
  
  //Fill in the full UL CQI report of the UE
258
259
  Protocol__FlexUlCqiReport *full_ul_report;
  full_ul_report = malloc(sizeof(Protocol__FlexUlCqiReport));
260
261
262
  if(full_ul_report == NULL) {
    goto error;
  }
263
  protocol__flex_ul_cqi_report__init(full_ul_report);
264
265
266
267
268
  //TODO:Set the SFN and SF of the generated report
  full_ul_report->sfn_sn = original->sfn_sn;
  full_ul_report->has_sfn_sn = original->has_sfn_sn;
  full_ul_report->n_cqi_meas = original->n_cqi_meas;

269
270
  Protocol__FlexUlCqi **ul_report;
  ul_report = malloc(sizeof(Protocol__FlexUlCqi *) * full_ul_report->n_cqi_meas);
271
272
  if(ul_report == NULL)
    goto error;
273
  for(i = 0; i < full_ul_report->n_cqi_meas; i++) {
274
    ul_report[i] = malloc(sizeof(Protocol__FlexUlCqi));
275
276
    if(ul_report[i] == NULL)
      goto error;
277
    protocol__flex_ul_cqi__init(ul_report[i]);
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    ul_report[i]->type = original->cqi_meas[i]->type;
    ul_report[i]->has_type = original->cqi_meas[i]->has_type;
    ul_report[i]->n_sinr = original->cqi_meas[i]->n_sinr;
    uint32_t *sinr_meas;
    sinr_meas = (uint32_t *) malloc(sizeof(uint32_t) * ul_report[i]->n_sinr);
    if (sinr_meas == NULL)
      goto error;
    for (j = 0; j < ul_report[i]->n_sinr; j++) {
      sinr_meas[j] = original->cqi_meas[i]->sinr[j];
    }
    ul_report[i]->sinr = sinr_meas;
    ul_report[i]->serv_cell_index = original->cqi_meas[i]->serv_cell_index;
    ul_report[i]->has_serv_cell_index = original->cqi_meas[i]->has_serv_cell_index;
  }
  full_ul_report->cqi_meas = ul_report;

  return full_ul_report;
  
  error:
    return NULL;
}

300
Protocol__FlexDlCqiReport * copy_dl_cqi_report(Protocol__FlexDlCqiReport * original) {
301
302
  int i;
  /*Copy the DL report*/
303
304
  Protocol__FlexDlCqiReport * dl_report;
  dl_report = malloc(sizeof(Protocol__FlexDlCqiReport));
305
306
  if (dl_report == NULL)
    goto error;
307
  protocol__flex_dl_cqi_report__init(dl_report);
308
309
310
311
312

  dl_report->sfn_sn = original->sfn_sn;
  dl_report->has_sfn_sn = original->has_sfn_sn;
  dl_report->n_csi_report = original->n_csi_report;

313
314
  Protocol__FlexDlCsi **csi_reports;
  csi_reports = malloc(sizeof(Protocol__FlexDlCsi *) * dl_report->n_csi_report);
315
316
317
318
319
320
321
322
323
324
325
326
327
328
  if (csi_reports == NULL)
    goto error;
  
  for (i = 0; i < dl_report->n_csi_report; i++) {
    csi_reports[i] = copy_csi_report(original->csi_report[i]); 
  }
  dl_report->csi_report = csi_reports;
  return dl_report;

 error:
  /*TODO: Must free memory properly*/
  return NULL;
}

329
Protocol__FlexPagingBufferReport * copy_paging_buffer_report(Protocol__FlexPagingBufferReport *original) {
330
331
  
  int i;
332
333
  Protocol__FlexPagingBufferReport *copy;
  copy = malloc(sizeof(Protocol__FlexPagingBufferReport));
334
335
336
  if (copy == NULL)
    goto error;
  
337
  protocol__flex_paging_buffer_report__init(copy);
338
339
  copy->n_paging_info = original->n_paging_info;
  
340
341
  Protocol__FlexPagingInfo **p_info;
  p_info = malloc(sizeof(Protocol__FlexPagingInfo *) * copy->n_paging_info);
342
343
344
  if (p_info == NULL)
    goto error;
  for (i = 0; i < copy->n_paging_info; i++) {
345
    p_info[i] = malloc(sizeof(Protocol__FlexPagingInfo));
346
347
    if(p_info[i] == NULL)
      goto error;
348
    protocol__flex_paging_info__init(p_info[i]);
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
    p_info[i]->paging_index = original->paging_info[i]->paging_index;
    p_info[i]->has_paging_index = original->paging_info[i]->has_paging_index;;
    p_info[i]->paging_message_size = original->paging_info[i]->paging_message_size;
    p_info[i]->has_paging_message_size =  original->paging_info[i]->has_paging_message_size;
    p_info[i]->paging_subframe = original->paging_info[i]->paging_subframe;
    p_info[i]->has_paging_subframe = original->paging_info[i]->has_paging_subframe;
    p_info[i]->carrier_index = original->paging_info[i]->carrier_index;
    p_info[i]->has_carrier_index = original->paging_info[i]->has_carrier_index;
  }
  copy->paging_info = p_info;
  return copy;

 error:
  /*TODO: free memory properly*/
  return NULL;
}

366
Protocol__FlexDlCsi * copy_csi_report(Protocol__FlexDlCsi * original) {
367
  int i, j;
368
  Protocol__FlexDlCsi *copy = malloc(sizeof(Protocol__FlexDlCsi));
369
370
  if (copy == NULL)
    goto error;
371
  protocol__flex_dl_csi__init(copy);
372
373
374
375
376
377
378
379
380
381
  copy->serv_cell_index = original->serv_cell_index;
  copy->has_serv_cell_index = original->has_serv_cell_index;
  copy->ri = original->ri;
  copy->has_ri = original->ri;

  copy->type = original->type;
  copy->has_type = original->has_type;
  copy->report_case = original->report_case;
  
  switch (copy->report_case) {
382
  case PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI:
383
384
385
    copy->p10csi->wb_cqi = original->p10csi->wb_cqi;
    copy->p10csi->has_wb_cqi = original->p10csi->has_wb_cqi;
    break;
386
  case PROTOCOL__FLEX_DL_CSI__REPORT_P11CSI:
387
388
389
390
391
392
393
394
    copy->p11csi->n_wb_cqi = original->p11csi->n_wb_cqi;
    copy->p11csi->wb_cqi = (uint32_t *) malloc(sizeof(uint32_t) * copy->p11csi->n_wb_cqi);
    for (i = 0; i < copy->p11csi->n_wb_cqi; i++) {
      copy->p11csi->wb_cqi[i] = original->p11csi->wb_cqi[i];
    }
    copy->p11csi->has_wb_pmi = original->p11csi->has_wb_pmi;
    copy->p11csi->wb_pmi = original->p11csi->wb_pmi;
    break;
395
  case PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI:
396
397
398
399
400
401
402
403
404
    copy->p20csi->has_wb_cqi = original->p20csi->has_wb_cqi;
    copy->p20csi->wb_cqi = original->p20csi->wb_cqi;
    copy->p20csi->has_sb_cqi = original->p20csi->has_sb_cqi;
    copy->p20csi->sb_cqi = original->p20csi->sb_cqi;
    copy->p20csi->has_bandwidth_part_index = original->p20csi->has_bandwidth_part_index;
    copy->p20csi->bandwidth_part_index = original->p20csi->bandwidth_part_index;
    copy->p20csi->has_sb_index = original->p20csi->has_sb_index;
    copy->p20csi->sb_index = original->p20csi->sb_index;
    break;
405
  case PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI:
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
    copy->p21csi->n_wb_cqi = original->p21csi->n_wb_cqi;
    copy->p21csi->wb_cqi = (uint32_t *) malloc(sizeof(uint32_t) * copy->p21csi->n_wb_cqi);
    for (i = 0; i < copy->p21csi->n_wb_cqi; i++) {
      copy->p21csi->wb_cqi[i] = original->p21csi->wb_cqi[i];
    }
    copy->p21csi->has_wb_pmi = original->p21csi->has_wb_pmi;
    copy->p21csi->wb_pmi = original->p21csi->wb_pmi;
    copy->p21csi->n_sb_cqi = original->p21csi->n_sb_cqi;
    copy->p21csi->sb_cqi = (uint32_t *) malloc(sizeof(uint32_t) * copy->p21csi->n_sb_cqi);
    for (i = 0; i < copy->p21csi->n_sb_cqi; i++) {
      copy->p21csi->sb_cqi[i] = original->p21csi->sb_cqi[i];
    }
     copy->p21csi->has_badwidth_part_index = original->p21csi->has_badwidth_part_index;
    copy->p21csi->badwidth_part_index = original->p21csi->badwidth_part_index;
    copy->p21csi->has_sb_index = original->p21csi->has_sb_index;
    copy->p21csi->sb_index = original->p21csi->sb_index;
    break;
423
  case PROTOCOL__FLEX_DL_CSI__REPORT_A12CSI:
424
425
426
427
428
429
430
431
432
433
434
    copy->a12csi->n_wb_cqi = original->a12csi->n_wb_cqi;
    copy->a12csi->wb_cqi = (uint32_t *) malloc(sizeof(uint32_t) * copy->a12csi->n_wb_cqi);
    for (i = 0; i < copy->a12csi->n_wb_cqi; i++) {
      copy->a12csi->wb_cqi[i] = original->a12csi->wb_cqi[i];
    }
    copy->a12csi->n_sb_pmi = original->a12csi->n_sb_pmi;
    copy->a12csi->sb_pmi = (uint32_t *) malloc(sizeof(uint32_t) * copy->a12csi->n_sb_pmi);
    for (i = 0; i < copy->a12csi->n_sb_pmi; i++) {
      copy->a12csi->sb_pmi[i] = original->a12csi->sb_pmi[i];
    }
    break;
435
  case PROTOCOL__FLEX_DL_CSI__REPORT_A22CSI:
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
    copy->a22csi->n_wb_cqi = original->a22csi->n_wb_cqi;
    copy->a22csi->wb_cqi = (uint32_t *) malloc(sizeof(uint32_t) * copy->a22csi->n_wb_cqi);
    for (i = 0; i < copy->a22csi->n_wb_cqi; i++) {
      copy->a22csi->wb_cqi[i] = original->a22csi->wb_cqi[i];
    }
    copy->a22csi->n_sb_cqi = original->a22csi->n_sb_cqi;
    copy->a22csi->sb_cqi = (uint32_t *) malloc(sizeof(uint32_t) * copy->a22csi->n_sb_cqi);
    for (i = 0; i < copy->a22csi->n_sb_cqi; i++) {
      copy->a22csi->sb_cqi[i] = original->a22csi->sb_cqi[i];
    }
    copy->a22csi->has_wb_pmi = original->a22csi->has_wb_pmi;
    copy->a22csi->wb_pmi = original->a22csi->wb_pmi;
    copy->a22csi->has_sb_pmi = original->a22csi->has_sb_pmi;
    copy->a22csi->sb_pmi = original->a22csi->sb_pmi;
    copy->a22csi->n_sb_list = original->a22csi->n_sb_list;
    copy->a22csi->sb_list = (uint32_t *) malloc(sizeof(uint32_t) * copy->a22csi->n_sb_list);
    for (i = 0; i < copy->a22csi->n_sb_list; i++) {
      copy->a22csi->sb_list[i] = original->a22csi->sb_list[i];
    }
    break;
456
  case PROTOCOL__FLEX_DL_CSI__REPORT_A20CSI:
457
458
459
460
461
462
463
464
465
466
    copy->a20csi->has_wb_cqi = original->a20csi->has_wb_cqi;
    copy->a20csi->wb_cqi = original->a20csi->wb_cqi;
    copy->a20csi->has_sb_cqi = original->a20csi->has_sb_cqi;
    copy->a20csi->sb_cqi = original->a20csi->sb_cqi;
    copy->a20csi->n_sb_list = original->a20csi->n_sb_list;
    copy->a20csi->sb_list = (uint32_t *) malloc(sizeof(uint32_t) * copy->a20csi->n_sb_list);
    for (i = 0; i < copy->a20csi->n_sb_list; i++) {
      copy->a20csi->sb_list[i] = original->a20csi->sb_list[i];
    }
    break;
467
  case PROTOCOL__FLEX_DL_CSI__REPORT_A30CSI:
468
469
470
471
472
473
474
475
    copy->a30csi->has_wb_cqi = original->a30csi->has_wb_cqi;
    copy->a30csi->wb_cqi = original->a30csi->wb_cqi;
    copy->a30csi->n_sb_cqi = original->a30csi->n_sb_cqi;
    copy->a30csi->sb_cqi = (uint32_t *) malloc(sizeof(uint32_t) * copy->a30csi->n_sb_cqi);
    for (i = 0; i < copy->a30csi->n_sb_cqi; i++) {
      copy->a30csi->sb_cqi[i] = original->a30csi->sb_cqi[i];
    }
    break;
476
  case PROTOCOL__FLEX_DL_CSI__REPORT_A31CSI:
477
478
479
480
481
482
483
484
    copy->a31csi->n_wb_cqi = original->a31csi->n_wb_cqi;
    copy->a31csi->wb_cqi = (uint32_t *) malloc(sizeof(uint32_t) * copy->a31csi->n_wb_cqi);
    for (i = 0; i < copy->a31csi->n_wb_cqi; i++) {
      copy->a31csi->wb_cqi[i] = original->a31csi->wb_cqi[i];
    }
    copy->a31csi->has_wb_pmi = original->a31csi->has_wb_pmi;
    copy->a31csi->wb_pmi = original->a31csi->wb_pmi;
    copy->a31csi->n_sb_cqi = original->a31csi->n_sb_cqi;
485
    copy->a31csi->sb_cqi = malloc(sizeof(Protocol__FlexMsbCqi *) * copy->a31csi->n_sb_cqi);
486
487
488
489
    if (copy->a31csi == NULL) {
      goto error;
    }
    for (i = 0; i < copy->a31csi->n_sb_cqi; i++) {
490
      copy->a31csi->sb_cqi[i] = malloc(sizeof(Protocol__FlexMsbCqi));
491
492
493
      if (copy->a31csi->sb_cqi[i] == NULL) {
	goto error;
      }
494
      protocol__flex_msb_cqi__init(copy->a31csi->sb_cqi[i]);
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
      copy->a31csi->sb_cqi[i]->n_sb_cqi = original->a31csi->sb_cqi[i]->n_sb_cqi;
      copy->a31csi->sb_cqi[i]->sb_cqi = (uint32_t *) malloc(sizeof(uint32_t) * copy->a31csi->sb_cqi[i]->n_sb_cqi);
      for (j = 0; j < copy->a31csi->sb_cqi[i]->n_sb_cqi; j++) {
	copy->a31csi->sb_cqi[i]->sb_cqi[j] = original->a31csi->sb_cqi[i]->sb_cqi[j];
      }
    }
    break;
  default:
    goto error;
  }
  return copy;

 error:
  return NULL;
}

511
Protocol__FlexCellStatsReport * copy_cell_stats_report(Protocol__FlexCellStatsReport *original) {
512
 
513
  Protocol__FlexCellStatsReport * copy =  malloc(sizeof(Protocol__FlexCellStatsReport));
514
515
516
517
  
  if(copy == NULL) {
    goto error;
  }
518
  protocol__flex_cell_stats_report__init(copy);
519
520
521
522
523
  copy->carrier_index = original->carrier_index;
  copy->has_carrier_index = original->has_carrier_index;
  copy->flags = original->flags;
  copy->has_flags = original->has_flags;

524
   if(copy->flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) {
525
526
527
528
529
530
531
532
533
     copy->noise_inter_report = copy_noise_inter_report(original->noise_inter_report);
   }

   return copy;

 error:
   return NULL;
}

534
535
536
Protocol__FlexNoiseInterferenceReport * copy_noise_inter_report(Protocol__FlexNoiseInterferenceReport *original) {
  Protocol__FlexNoiseInterferenceReport *ni_report;
  ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport));
537
538
539
  if(ni_report == NULL) {
    goto error;
  }
540
  protocol__flex_noise_interference_report__init(ni_report);
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  // Current frame and subframe number
  ni_report->sfn_sf = original->sfn_sf;
  ni_report->has_sfn_sf = original->sfn_sf;
  // Received interference power in dbm
  ni_report->rip = original->rip;
  ni_report->has_rip = original->has_rip;
  // Thermal noise power in dbm
  ni_report->tnp = original->tnp;
  ni_report->has_tnp = original->has_tnp;
  
  return ni_report;
  
 error:
  return NULL;
}
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573


int parse_mac_config(mid_t mod_id, yaml_parser_t *parser) {
  
  yaml_event_t event;
  
  int done = 0;

  int sequence_started = 0;
  int mapping_started = 0;

  while (!done) {

    if (!yaml_parser_parse(parser, &event))
      goto error;
   
    switch (event.type) {
    case YAML_SEQUENCE_START_EVENT:
574
      LOG_D(ENB_APP, "A sequence just started as expected\n");
575
576
577
      sequence_started = 1;
      break;
    case YAML_SEQUENCE_END_EVENT:
578
      LOG_D(ENB_APP, "A sequence ended\n");
579
580
581
582
583
584
      sequence_started = 0;
      break;
    case YAML_MAPPING_START_EVENT:
      if (!sequence_started) {
	goto error;
      }
585
      LOG_D(ENB_APP, "A mapping started\n");
586
587
588
589
590
591
      mapping_started = 1;
      break;
    case YAML_MAPPING_END_EVENT:
      if (!mapping_started) {
	goto error;
      }
592
      LOG_D(ENB_APP, "A mapping ended\n");
593
594
595
596
597
598
599
      mapping_started = 0;
      break;
    case YAML_SCALAR_EVENT:
      if (!mapping_started) {
	goto error;
      }
      // Check the types of subsystems offered and handle their values accordingly
600
      if (strcmp((char *) event.data.scalar.value, "dl_scheduler") == 0) {
601
	LOG_D(ENB_APP, "This is for the dl_scheduler subsystem\n");
602
603
	// Call the proper handler
	if (parse_dl_scheduler_config(mod_id, parser) == -1) {
604
	  LOG_D(ENB_APP, "An error occured\n");
605
606
	  goto error;
	}
607
      } else if (strcmp((char *) event.data.scalar.value, "ul_scheduler") == 0) {
608
	// Call the proper handler
609
	LOG_D(ENB_APP, "This is for the ul_scheduler subsystem\n");
shahab's avatar
shahab committed
610
	if (parse_ul_scheduler_config(mod_id, parser) == -1) {
shahab's avatar
shahab committed
611
612
613
    LOG_D(ENB_APP, "An error occured\n");
    goto error;
  }
614
	// TODO
615
      } else if (strcmp((char *) event.data.scalar.value, "ra_scheduler") == 0) {
616
617
	// Call the proper handler
	// TODO
618
      } else if (strcmp((char *) event.data.scalar.value, "page_scheduler") == 0) {
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
	// Call the proper handler
	// TODO
      } else {
	// Unknown subsystem
	goto error;
      }
      break;
    default: // We expect nothing else at this level of the hierarchy
      goto error;
    }
   
    done = (event.type == YAML_SEQUENCE_END_EVENT);

    yaml_event_delete(&event);
 
  }
  
  return 0;

  error:
  yaml_event_delete(&event);
  return -1;

}

int parse_dl_scheduler_config(mid_t mod_id, yaml_parser_t *parser) {
  
  yaml_event_t event;

  int done = 0;
  int mapping_started = 0;

  while (!done) {
    
    if (!yaml_parser_parse(parser, &event))
      goto error;

    switch (event.type) {
      // We are expecting a mapping (behavior and parameters)
    case YAML_MAPPING_START_EVENT:
      LOG_D(ENB_APP, "The mapping of the subsystem started\n");
      mapping_started = 1;
      break;
    case YAML_MAPPING_END_EVENT:
      LOG_D(ENB_APP, "The mapping of the subsystem ended\n");
      mapping_started = 0;
      break;
    case YAML_SCALAR_EVENT:
      if (!mapping_started) {
	goto error;
      }
      // Check what key needs to be set
671
      if (strcmp((char *) event.data.scalar.value, "behavior") == 0) {
672
	LOG_I(ENB_APP, "Time to set the behavior attribute\n");
673
674
675
676
677
	yaml_event_delete(&event);
	if (!yaml_parser_parse(parser, &event)) {
	  goto error;
	}
	if (event.type == YAML_SCALAR_EVENT) {
678
	  if (load_dl_scheduler_function(mod_id, (char *) event.data.scalar.value) == -1) {
679
	    goto error;
680
	  } 
681
682
683
	} else {
	  goto error;
	}
684
      } else if (strcmp((char *) event.data.scalar.value, "parameters") == 0) {
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
	LOG_D(ENB_APP, "Now it is time to set the parameters for this subsystem\n");
	if (parse_dl_scheduler_parameters(mod_id, parser) == -1) {
	  goto error;
	}
      }
      break;
    default:
      goto error;
    }

    done = (event.type == YAML_MAPPING_END_EVENT);
    yaml_event_delete(&event);
  }

  return 0;

 error:
  yaml_event_delete(&event);
  return -1;
}

shahab's avatar
shahab committed
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
int parse_ul_scheduler_config(mid_t mod_id, yaml_parser_t *parser) {
  
  yaml_event_t event;

  int done = 0;
  int mapping_started = 0;

  while (!done) {
    
    if (!yaml_parser_parse(parser, &event))
      goto error;

    switch (event.type) {
      // We are expecting a mapping (behavior and parameters)
    case YAML_MAPPING_START_EVENT:
      LOG_D(ENB_APP, "The mapping of the subsystem started\n");
      mapping_started = 1;
      break;
    case YAML_MAPPING_END_EVENT:
      LOG_D(ENB_APP, "The mapping of the subsystem ended\n");
      mapping_started = 0;
      break;
    case YAML_SCALAR_EVENT:
      if (!mapping_started) {
  goto error;
      }
      // Check what key needs to be set
      if (strcmp((char *) event.data.scalar.value, "parameters") == 0) {
  LOG_D(ENB_APP, "Now it is time to set the parameters for this subsystem\n");
  if (parse_ul_scheduler_parameters(mod_id, parser) == -1) {
    goto error;
  }
      }
      break;
    default:
      goto error;
    }

    done = (event.type == YAML_MAPPING_END_EVENT);
    yaml_event_delete(&event);
  }

  return 0;

 error:
  yaml_event_delete(&event);
  return -1;
}


756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
int parse_dl_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) {
  yaml_event_t event;
  
  void *param;
  
  int done = 0;
  int mapping_started = 0;

  while (!done) {
    
    if (!yaml_parser_parse(parser, &event))
      goto error;

    switch (event.type) {
      // We are expecting a mapping of parameters
    case YAML_MAPPING_START_EVENT:
      LOG_D(ENB_APP, "The mapping of the parameters started\n");
      mapping_started = 1;
      break;
    case YAML_MAPPING_END_EVENT:
      LOG_D(ENB_APP, "The mapping of the parameters ended\n");
      mapping_started = 0;
      break;
    case YAML_SCALAR_EVENT:
      if (!mapping_started) {
	goto error;
      }
      // Check what key needs to be set
      if (mac_agent_registered[mod_id]) {
	LOG_D(ENB_APP, "Setting parameter %s\n", event.data.scalar.value);
	param = dlsym(agent_mac_xface[mod_id]->dl_scheduler_loaded_lib,
787
		      (char *) event.data.scalar.value);
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
	if (param == NULL) {
	  goto error;
	}
	apply_parameter_modification(param, parser);
      } else {
	goto error;
      }
      break;
    default:
      goto error;
    }

    done = (event.type == YAML_MAPPING_END_EVENT);
    yaml_event_delete(&event);
  }

  return 0;
  
 error:
  yaml_event_delete(&event);
  return -1;
}

shahab's avatar
shahab committed
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
int parse_ul_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) {
  yaml_event_t event;
  
  void *param;
  
  int done = 0;
  int mapping_started = 0;

  while (!done) {
    
    if (!yaml_parser_parse(parser, &event))
      goto error;

    switch (event.type) {
      // We are expecting a mapping of parameters
    case YAML_MAPPING_START_EVENT:
      LOG_D(ENB_APP, "The mapping of the parameters started\n");
      mapping_started = 1;
      break;
    case YAML_MAPPING_END_EVENT:
      LOG_D(ENB_APP, "The mapping of the parameters ended\n");
      mapping_started = 0;
      break;
    case YAML_SCALAR_EVENT:
      if (!mapping_started) {
  goto error;
      }
      // Check what key needs to be set
      if (mac_agent_registered[mod_id]) {
  LOG_D(ENB_APP, "Setting parameter %s\n", event.data.scalar.value);
  param = dlsym(agent_mac_xface[mod_id]->ul_scheduler_loaded_lib,
          (char *) event.data.scalar.value);
  if (param == NULL) {
    goto error;
  }
  apply_parameter_modification(param, parser);
      } else {
  goto error;
      }
      break;
    default:
      goto error;
    }

    done = (event.type == YAML_MAPPING_END_EVENT);
    yaml_event_delete(&event);
  }

  return 0;
  
 error:
  yaml_event_delete(&event);
  return -1;
}

866
867
868
869
870
int load_dl_scheduler_function(mid_t mod_id, const char *function_name) {
  void *lib;

  char lib_name[120];
  char target[512];
871
  snprintf(lib_name, sizeof(lib_name), "/%s.so", function_name);
872
873
  strcpy(target, local_cache);
  strcat(target, lib_name);
874
875
  
  LOG_I(FLEXRAN_AGENT, "Opening pushed code: %s\n", target);
876
877
  lib = dlopen(target, RTLD_NOW);
  if (lib == NULL) {
878
    LOG_I(FLEXRAN_AGENT, "Could not load library\n");
879
880
881
    goto error;
  }
  
882
  LOG_I(FLEXRAN_AGENT, "Loading function: %s\n", function_name);
883
884
885
  void *loaded_scheduler = dlsym(lib, function_name);
  if (loaded_scheduler) {
    if (mac_agent_registered[mod_id]) {
886
      agent_mac_xface[mod_id]->flexran_agent_schedule_ue_spec = loaded_scheduler;
887
888
889
      if (agent_mac_xface[mod_id]->dl_scheduler_loaded_lib != NULL) {
	dlclose(agent_mac_xface[mod_id]->dl_scheduler_loaded_lib);
      }
890
      agent_mac_xface[mod_id]->dl_scheduler_loaded_lib = lib;
891
      LOG_I(FLEXRAN_AGENT, "New DL UE scheduler: %s\n", function_name);
892
    }
893
894
  } else {
    LOG_I(FLEXRAN_AGENT, "Scheduler could not be loaded\n");
895
896
897
898
899
900
901
902
  }

  return 0;

 error:
  return -1;
  
}