flexran_agent_mac.c 51 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
23
/*! \file flexran_agent_mac.c
 * \brief FlexRAN agent message handler for MAC layer
24
 * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein
nikaeinn's avatar
nikaeinn committed
25
26
27
28
 * \date 2016
 * \version 0.1
 */

29
30
31
32
#include "flexran_agent_mac.h"
#include "flexran_agent_extern.h"
#include "flexran_agent_common.h"
#include "flexran_agent_mac_internal.h"
33
#include "flexran_agent_net_comm.h"
shahab's avatar
shahab committed
34
#include "flexran_agent_timer.h"
shahab's avatar
shahab committed
35
#include "flexran_agent_ran_api.h"
36

37
38
#include "LAYER2/MAC/proto.h"

39
40
#include "liblfds700.h"

nikaeinn's avatar
nikaeinn committed
41
42
#include "log.h"

43
44
45
46

/*Flags showing if a mac agent has already been registered*/
unsigned int mac_agent_registered[NUM_MAX_ENB];

47
48
49
/*Array containing the Agent-MAC interfaces*/
AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB];

50
51
52
53
54
55
56
/* Ringbuffer related structs used for maintaining the dl mac config messages */
//message_queue_t *dl_mac_config_queue;
struct lfds700_misc_prng_state ps[NUM_MAX_ENB];
struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB];
struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB];


shahab's avatar
shahab committed
57
58
59
60
int flexran_agent_mac_stats_reply(mid_t mod_id,       
          const report_config_t *report_config,
           Protocol__FlexUeStatsReport **ue_report,
           Protocol__FlexCellStatsReport **cell_report) {
61
62


shahab's avatar
shahab committed
63
64
  // Protocol__FlexHeader *header;
  int i, j, k;
shahab's avatar
shahab committed
65
  // int cc_id = 0;
66
  int enb_id = mod_id;
nikaeinn's avatar
nikaeinn committed
67

shahab's avatar
shahab committed
68
69
  /* Allocate memory for list of UE reports */
  if (report_config->nr_ue > 0) {
nikaeinn's avatar
nikaeinn committed
70

shahab's avatar
shahab committed
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
          
          for (i = 0; i < report_config->nr_ue; i++) {



                /* Check flag for creation of buffer status report */
                if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) {
                      //TODO should be automated
                        ue_report[i]->n_bsr = 4; 
                        uint32_t *elem;
                        elem = (uint32_t *) malloc(sizeof(uint32_t)*ue_report[i]->n_bsr);
                        if (elem == NULL)
                               goto error;
                        for (j = 0; j < ue_report[i]->n_bsr; j++) {
                                // NN: we need to know the cc_id here, consider the first one 
86
                                elem[j] = flexran_get_ue_bsr_ul_buffer_info (enb_id, i, j);
shahab's avatar
shahab committed
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
                        }
                          
                        ue_report[i]->bsr = elem;
                }
                
                /* Check flag for creation of PHR report */
                if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) {
                        ue_report[i]->phr = flexran_get_ue_phr (enb_id, i); // eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].phr_info;
                        ue_report[i]->has_phr = 1;
                      
                }

                /* Check flag for creation of RLC buffer status report */
                if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS) {
                        ue_report[i]->n_rlc_report = 3; // Set this to the number of LCs for this UE. This needs to be generalized for for LCs
                        Protocol__FlexRlcBsr ** rlc_reports;
                        rlc_reports = malloc(sizeof(Protocol__FlexRlcBsr *) * ue_report[i]->n_rlc_report);
                        if (rlc_reports == NULL)
                              goto error;

                        // NN: see LAYER2/openair2_proc.c for rlc status
                        for (j = 0; j < ue_report[i]->n_rlc_report; j++) {

                              rlc_reports[j] = malloc(sizeof(Protocol__FlexRlcBsr));
                              if (rlc_reports[j] == NULL)
                                 goto error;
                              protocol__flex_rlc_bsr__init(rlc_reports[j]);
                              rlc_reports[j]->lc_id = j+1;
                              rlc_reports[j]->has_lc_id = 1;
shahab's avatar
shahab committed
116
                              rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id, i, j + 1);
shahab's avatar
shahab committed
117
118
119
                              rlc_reports[j]->has_tx_queue_size = 1;

                              //TODO:Set tx queue head of line delay in ms
shahab's avatar
shahab committed
120
                              rlc_reports[j]->tx_queue_hol_delay = flexran_get_hol_delay(enb_id, i, j + 1);
shahab's avatar
shahab committed
121
122
123
124
125
126
127
128
                              rlc_reports[j]->has_tx_queue_hol_delay = 1;
                              //TODO:Set retransmission queue size in bytes
                              rlc_reports[j]->retransmission_queue_size = 10;
                              rlc_reports[j]->has_retransmission_queue_size = 0;
                              //TODO:Set retransmission queue head of line delay in ms
                              rlc_reports[j]->retransmission_queue_hol_delay = 100;
                              rlc_reports[j]->has_retransmission_queue_hol_delay = 0;
                              //TODO DONE:Set current size of the pending message in bytes
129
                              rlc_reports[j]->status_pdu_size = flexran_get_num_pdus_buffer(enb_id , i, j + 1);
shahab's avatar
shahab committed
130
131
132
133
134
135
136
137
138
139
140
141
142
                              rlc_reports[j]->has_status_pdu_size = 1;

                        }
                        // Add RLC buffer status reports to the full report
                        if (ue_report[i]->n_rlc_report > 0)
                            ue_report[i]->rlc_report = rlc_reports;

                      
                }

                /* Check flag for creation of MAC CE buffer status report */
                if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) {
                        // TODO: Fill in the actual MAC CE buffer status report
shahab's avatar
shahab committed
143
144
145
146
147
                        ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; 
                                      // Use as bitmap. Set one or more of the; /* Use as bitmap. Set one or more of the
                                       // PROTOCOL__FLEX_CE_TYPE__FLPCET_ values
                                       // found in stats_common.pb-c.h. See
                                       // flex_ce_type in FlexRAN specification 
shahab's avatar
shahab committed
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
                        ue_report[i]->has_pending_mac_ces = 1;
                  
                }

                /* Check flag for creation of DL CQI report */
                if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) {
                        // TODO: Fill in the actual DL CQI report for the UE based on its configuration
                        Protocol__FlexDlCqiReport * dl_report;
                        dl_report = malloc(sizeof(Protocol__FlexDlCqiReport));
                        if (dl_report == NULL)
                          goto error;
                        protocol__flex_dl_cqi_report__init(dl_report);

                        dl_report->sfn_sn = flexran_get_sfn_sf(enb_id);
                        dl_report->has_sfn_sn = 1;
                        //Set the number of DL CQI reports for this UE. One for each CC
                        dl_report->n_csi_report = flexran_get_active_CC(enb_id,i);
                        dl_report->n_csi_report = 1 ;
                        //Create the actual CSI reports.
                        Protocol__FlexDlCsi **csi_reports;
                        csi_reports = malloc(sizeof(Protocol__FlexDlCsi *)*dl_report->n_csi_report);
                        if (csi_reports == NULL)
                          goto error;                    
                        for (j = 0; j < dl_report->n_csi_report; j++) {

                              csi_reports[j] = malloc(sizeof(Protocol__FlexDlCsi));
                              if (csi_reports[j] == NULL)
                                goto error;
                              protocol__flex_dl_csi__init(csi_reports[j]);
                              //The servCellIndex for this report
                              csi_reports[j]->serv_cell_index = j;
                              csi_reports[j]->has_serv_cell_index = 1;
                              //The rank indicator value for this cc
                              csi_reports[j]->ri = flexran_get_current_RI(enb_id,i,j);
                              csi_reports[j]->has_ri = 1;
                              //TODO: the type of CSI report based on the configuration of the UE
                              //For now we only support type P10, which only needs a wideband value
                              //The full set of types can be found in stats_common.pb-c.h and
                              //in the FlexRAN specifications
                              csi_reports[j]->type =  PROTOCOL__FLEX_CSI_TYPE__FLCSIT_P10;
                              csi_reports[j]->has_type = 1;
                              csi_reports[j]->report_case = PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI;

                              if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI){

                                    Protocol__FlexCsiP10 *csi10;
                                    csi10 = malloc(sizeof(Protocol__FlexCsiP10));
                                    if (csi10 == NULL)
                                    goto error;
                                    protocol__flex_csi_p10__init(csi10);
                                    //TODO: set the wideband value
                                    // NN: this is also depends on cc_id
                                    csi10->wb_cqi = flexran_get_ue_wcqi (enb_id, i); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].dl_cqi;
                                    csi10->has_wb_cqi = 1;
                                    //Add the type of measurements to the csi report in the proper union type
                                    csi_reports[j]->p10csi = csi10;
                              }

                              else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P11CSI){


                                    Protocol__FlexCsiP11 *csi11;
                                    csi11 = malloc(sizeof(Protocol__FlexCsiP11));
                                    if (csi11 == NULL)
                                    goto error;
                                    protocol__flex_csi_p11__init(csi11);
                                  
Xenofon Foukas's avatar
Xenofon Foukas committed
215
216
217
                                    csi11->wb_cqi = malloc(sizeof(csi11->wb_cqi));  
				    csi11->n_wb_cqi = 1;
				    csi11->wb_cqi[0] = flexran_get_ue_wcqi (enb_id, i);                                       		    
shahab's avatar
shahab committed
218
219
220
221
                                    // According To spec 36.213                                  
                                     
                                    if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 1) {
                                        // TODO PMI
Robert Schmidt's avatar
Robert Schmidt committed
222
                                        csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0);
shahab's avatar
shahab committed
223
224
225
226
227
228
                                        csi11->has_wb_pmi = 1;

                                       }   

                                      else if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 2){
                                        // TODO PMI
Robert Schmidt's avatar
Robert Schmidt committed
229
                                        csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0);
shahab's avatar
shahab committed
230
231
232
233
234
235
                                        csi11->has_wb_pmi = 1;

                                      }

                                      else if (flexran_get_antenna_ports(enb_id, j) == 4 && csi_reports[j]->ri == 2){
                                        // TODO PMI
Robert Schmidt's avatar
Robert Schmidt committed
236
                                        csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0);
shahab's avatar
shahab committed
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
                                        csi11->has_wb_pmi = 1;


                                      }

                                      csi11->has_wb_pmi = 0;                                      

                                      csi_reports[j]->p11csi = csi11;

                               }

                                      
                                     


                              else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI){

                                    Protocol__FlexCsiP20 *csi20;
                                    csi20 = malloc(sizeof(Protocol__FlexCsiP20));
                                    if (csi20 == NULL)
                                    goto error;
                                    protocol__flex_csi_p20__init(csi20);
                                    
                                    csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i);                                       
                                    csi20->has_wb_cqi = 1;
nikaeinn's avatar
nikaeinn committed
262

shahab's avatar
shahab committed
263
264
265
                                      
                                    csi20->bandwidth_part_index = 1 ;//TODO
                                    csi20->has_bandwidth_part_index = 1;
266

shahab's avatar
shahab committed
267
268
                                    csi20->sb_index = 1 ;//TODO
                                    csi20->has_sb_index = 1 ;                                     
nikaeinn's avatar
nikaeinn committed
269
270


shahab's avatar
shahab committed
271
                                    csi_reports[j]->p20csi = csi20;
272

273

shahab's avatar
shahab committed
274
                              }
275

shahab's avatar
shahab committed
276
                              else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI){
277

shahab's avatar
shahab committed
278
279
280
281
282
283
284
285
286
287
288
                                  // Protocol__FlexCsiP21 *csi21;
                                  // csi21 = malloc(sizeof(Protocol__FlexCsiP21));
                                  // if (csi21 == NULL)
                                  // goto error;
                                  // protocol__flex_csi_p21__init(csi21);
                                
                                  // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, i);                                       
                                  
                                  
                                  // csi21->wb_pmi = flexran_get_ue_pmi(enb_id); //TDO inside
                                  // csi21->has_wb_pmi = 1;
289

shahab's avatar
shahab committed
290
291
292
293
                                  // csi21->sb_cqi = 1; // TODO 
                                   
                                  // csi21->bandwidth_part_index = 1 ; //TDO inside
                                  // csi21->has_bandwidth_part_index = 1 ;   
294

shahab's avatar
shahab committed
295
296
                                  // csi21->sb_index = 1 ;//TODO
                                  // csi21->has_sb_index = 1 ;                                     
297

298

shahab's avatar
shahab committed
299
                                  // csi_reports[j]->p20csi = csi21;
300

shahab's avatar
shahab committed
301
                              }
nikaeinn's avatar
nikaeinn committed
302

shahab's avatar
shahab committed
303
                              else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A12CSI){
nikaeinn's avatar
nikaeinn committed
304

305

shahab's avatar
shahab committed
306
307
308
309
310
311
312
313
314
                                  // Protocol__FlexCsiA12 *csi12;
                                  // csi12 = malloc(sizeof(Protocol__FlexCsiA12));
                                  // if (csi12 == NULL)
                                  // goto error;
                                  // protocol__flex_csi_a12__init(csi12);
                                
                                  // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, i);                                       
                                  
                                  // csi12->sb_pmi = 1 ; //TODO inside                                                                      
nikaeinn's avatar
nikaeinn committed
315

shahab's avatar
shahab committed
316
317
                                  // TODO continou
                              }
nikaeinn's avatar
nikaeinn committed
318

shahab's avatar
shahab committed
319
                              else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A22CSI){
320

shahab's avatar
shahab committed
321
322
323
324
325
326
327
328
329
                                    // Protocol__FlexCsiA22 *csi22;
                                    // csi22 = malloc(sizeof(Protocol__FlexCsiA22));
                                    // if (csi22 == NULL)
                                    // goto error;
                                    // protocol__flex_csi_a22__init(csi22);
                                  
                                    // csi22->wb_cqi = flexran_get_ue_wcqi (enb_id, i);                                       
                                    
                                    // csi22->sb_cqi = 1 ; //TODO inside                                      
330

shahab's avatar
shahab committed
331
332
333
334
335
                                    // csi22->wb_pmi = flexran_get_ue_wcqi (enb_id, i);                                       
                                    // csi22->has_wb_pmi = 1;
                                    
                                    // csi22->sb_pmi = 1 ; //TODO inside                                                                            
                                    // csi22->has_wb_pmi = 1;
336

shahab's avatar
shahab committed
337
                                    // csi22->sb_list = flexran_get_ue_wcqi (enb_id, i);                                       
338

shahab's avatar
shahab committed
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502

                                }

                                else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A20CSI){

                                    // Protocol__FlexCsiA20 *csi20;
                                    // csi20 = malloc(sizeof(Protocol__FlexCsiA20));
                                    // if (csi20 == NULL)
                                    // goto error;
                                    // protocol__flex_csi_a20__init(csi20);

                                    // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i);                                       
                                    // csi20->has_wb_cqi = 1;

                                    // csi20>sb_cqi = 1 ; //TODO inside                                      
                                    // csi20>has_sb_cqi = 1 ;

                                    // csi20->sb_list = 1; // TODO inside


                                }

                                else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A30CSI){

                                }

                                else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A31CSI){

                                }

                        }
                     //Add the csi reports to the full DL CQI report
                    dl_report->csi_report = csi_reports;
                    //Add the DL CQI report to the stats report
                     ue_report[i]->dl_cqi_report = dl_report;
                      
                }

                /* Check flag for creation of paging buffer status report */
                if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) {
                            //TODO: Fill in the actual paging buffer status report. For this field to be valid, the RNTI
                            //set in the report must be a P-RNTI
                            Protocol__FlexPagingBufferReport *paging_report;
                            paging_report = malloc(sizeof(Protocol__FlexPagingBufferReport));
                            if (paging_report == NULL)
                              goto error;
                            protocol__flex_paging_buffer_report__init(paging_report);
                            //Set the number of pending paging messages
                            paging_report->n_paging_info = 1;
                            //Provide a report for each pending paging message
                            Protocol__FlexPagingInfo **p_info;
                            p_info = malloc(sizeof(Protocol__FlexPagingInfo *) * paging_report->n_paging_info);
                            if (p_info == NULL)
                              goto error;

                            for (j = 0; j < paging_report->n_paging_info; j++) {

                                    p_info[j] = malloc(sizeof(Protocol__FlexPagingInfo));
                                    if(p_info[j] == NULL)
                                      goto error;
                                    protocol__flex_paging_info__init(p_info[j]);
                                    //TODO: Set paging index. This index is the same that will be used for the scheduling of the
                                    //paging message by the controller
                                    p_info[j]->paging_index = 10;
                                    p_info[j]->has_paging_index = 1;
                                    //TODO:Set the paging message size
                                    p_info[j]->paging_message_size = 100;
                                    p_info[j]->has_paging_message_size = 1;
                                    //TODO: Set the paging subframe
                                    p_info[j]->paging_subframe = 10;
                                    p_info[j]->has_paging_subframe = 1;
                                    //TODO: Set the carrier index for the pending paging message
                                    p_info[j]->carrier_index = 0;
                                    p_info[j]->has_carrier_index = 1;

                            }
                            //Add all paging info to the paging buffer rerport
                            paging_report->paging_info = p_info;
                            //Add the paging report to the UE report
                            ue_report[i]->pbr = paging_report;
                }

                  /* Check flag for creation of UL CQI report */
                if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) {

                      //Fill in the full UL CQI report of the UE
                      Protocol__FlexUlCqiReport *full_ul_report;
                      full_ul_report = malloc(sizeof(Protocol__FlexUlCqiReport));
                      if(full_ul_report == NULL)
                        goto error;
                      protocol__flex_ul_cqi_report__init(full_ul_report);
                      //TODO:Set the SFN and SF of the generated report
                      full_ul_report->sfn_sn = flexran_get_sfn_sf(enb_id);
                      full_ul_report->has_sfn_sn = 1;
                      //TODO:Set the number of UL measurement reports based on the types of measurements
                      //configured for this UE and on the servCellIndex
                      full_ul_report->n_cqi_meas = 1;
                      Protocol__FlexUlCqi **ul_report;
                      ul_report = malloc(sizeof(Protocol__FlexUlCqi *) * full_ul_report->n_cqi_meas);
                      if(ul_report == NULL)
                        goto error;
                      //Fill each UL report of the UE for each of the configured report types
                      for(j = 0; j < full_ul_report->n_cqi_meas; j++) {

                              ul_report[j] = malloc(sizeof(Protocol__FlexUlCqi));
                              if(ul_report[j] == NULL)
                              goto error;
                              protocol__flex_ul_cqi__init(ul_report[j]);
                              //TODO: Set the type of the UL report. As an example set it to SRS UL report
                              // See enum flex_ul_cqi_type in FlexRAN specification for more details
                              ul_report[j]->type = PROTOCOL__FLEX_UL_CQI_TYPE__FLUCT_SRS;
                              ul_report[j]->has_type = 1;
                              //TODO:Set the number of SINR measurements based on the report type
                              //See struct flex_ul_cqi in FlexRAN specification for more details
                              ul_report[j]->n_sinr = 0;
                              uint32_t *sinr_meas;
                              sinr_meas = (uint32_t *) malloc(sizeof(uint32_t) * ul_report[j]->n_sinr);
                              if (sinr_meas == NULL)
                                goto error;
                              //TODO:Set the SINR measurements for the specified type
                              for (k = 0; k < ul_report[j]->n_sinr; k++) {
                                      sinr_meas[k] = 10;
                              }
                              ul_report[j]->sinr = sinr_meas;
                              //TODO: Set the servCellIndex for this report
                              ul_report[j]->serv_cell_index = 0;
                              ul_report[j]->has_serv_cell_index = 1;
                              
                              //Set the list of UL reports of this UE to the full UL report
                              full_ul_report->cqi_meas = ul_report;

                              full_ul_report->n_pucch_dbm = MAX_NUM_CCs;
                              full_ul_report->pucch_dbm = malloc(sizeof(Protocol__FlexPucchDbm *) * full_ul_report->n_pucch_dbm);

                              for (j = 0; j < MAX_NUM_CCs; j++) {

                                      full_ul_report->pucch_dbm[j] = malloc(sizeof(Protocol__FlexPucchDbm));
                                      protocol__flex_pucch_dbm__init(full_ul_report->pucch_dbm[j]);
                                      full_ul_report->pucch_dbm[j]->has_serv_cell_index = 1;
                                      full_ul_report->pucch_dbm[j]->serv_cell_index = j;

                                      if(flexran_get_p0_pucch_dbm(enb_id,i, j) != -1){
                                        full_ul_report->pucch_dbm[j]->p0_pucch_dbm = flexran_get_p0_pucch_dbm(enb_id,i,j);
                                        full_ul_report->pucch_dbm[j]->has_p0_pucch_dbm = 1;
                                      }
                              }


                          }
                        //  Add full UL CQI report to the UE report
                        ue_report[i]->ul_cqi_report = full_ul_report;
                      

                     }    
                             
                 

                            
             }       

          
         
         
     } 
nikaeinn's avatar
nikaeinn committed
503
504
505

  /* Allocate memory for list of cell reports */
  if (report_config->nr_cc > 0) {
shahab's avatar
shahab committed
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
    
            
            // Fill in the Cell reports
            for (i = 0; i < report_config->nr_cc; i++) {


                      /* Check flag for creation of noise and interference report */
                      if(report_config->cc_report_type[i].cc_report_flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) {
                            // TODO: Fill in the actual noise and interference report for this cell
                            Protocol__FlexNoiseInterferenceReport *ni_report;
                            ni_report = malloc(sizeof(Protocol__FlexNoiseInterferenceReport));
                            if(ni_report == NULL)
                              goto error;
                            protocol__flex_noise_interference_report__init(ni_report);
                            // Current frame and subframe number
                            ni_report->sfn_sf = flexran_get_sfn_sf(enb_id);
                            ni_report->has_sfn_sf = 1;
                            //TODO:Received interference power in dbm
                            ni_report->rip = 0;
                            ni_report->has_rip = 1;
                            //TODO:Thermal noise power in dbm
                            ni_report->tnp = 0;
                            ni_report->has_tnp = 1;

                            ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0);
                            ni_report->has_p0_nominal_pucch = 1;
                            cell_report[i]->noise_inter_report = ni_report;
                      }
            }
            

      
            
nikaeinn's avatar
nikaeinn committed
539
  }
540

nikaeinn's avatar
nikaeinn committed
541
  return 0;
542

nikaeinn's avatar
nikaeinn committed
543
 error:
shahab's avatar
shahab committed
544
545
546
547
548
549

  if (cell_report != NULL)
        free(cell_report);
  if (ue_report != NULL)
        free(ue_report);

nikaeinn's avatar
nikaeinn committed
550
551
552
  return -1;
}

553
int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg) {
nikaeinn's avatar
nikaeinn committed
554
  //TODO: Need to deallocate memory for the stats reply message
555
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG)
nikaeinn's avatar
nikaeinn committed
556
557
558
    goto error;
  free(msg->stats_reply_msg->header);
  int i, j, k;
559

560
561
562
563
  Protocol__FlexStatsReply *reply = msg->stats_reply_msg;
  Protocol__FlexDlCqiReport *dl_report;
  Protocol__FlexUlCqiReport *ul_report;
  Protocol__FlexPagingBufferReport *paging_report;
nikaeinn's avatar
nikaeinn committed
564
565
566
567
568
569
570
571
572

  // Free the memory for the UE reports
  for (i = 0; i < reply->n_ue_report; i++) {
    free(reply->ue_report[i]->bsr);
    for (j = 0; j < reply->ue_report[i]->n_rlc_report; j++) {
      free(reply->ue_report[i]->rlc_report[j]);
    }
    free(reply->ue_report[i]->rlc_report);
    // If DL CQI report flag was set
573
    if (reply->ue_report[i]->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) {
nikaeinn's avatar
nikaeinn committed
574
575
576
577
578
      dl_report = reply->ue_report[i]->dl_cqi_report;
      // Delete all CSI reports
      for (j = 0; j < dl_report->n_csi_report; j++) {
	//Must free memory based on the type of report
	switch(dl_report->csi_report[j]->report_case) {
579
	case PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI:
nikaeinn's avatar
nikaeinn committed
580
581
	  free(dl_report->csi_report[j]->p10csi);
	  break;
582
	case PROTOCOL__FLEX_DL_CSI__REPORT_P11CSI:
nikaeinn's avatar
nikaeinn committed
583
584
585
	  free(dl_report->csi_report[j]->p11csi->wb_cqi);
	  free(dl_report->csi_report[j]->p11csi);
	  break;
586
	case PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI:
nikaeinn's avatar
nikaeinn committed
587
588
	  free(dl_report->csi_report[j]->p20csi);
	  break;
589
	case PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI:
nikaeinn's avatar
nikaeinn committed
590
591
592
593
	  free(dl_report->csi_report[j]->p21csi->wb_cqi);
	  free(dl_report->csi_report[j]->p21csi->sb_cqi);
	  free(dl_report->csi_report[j]->p21csi);
	  break;
594
	case PROTOCOL__FLEX_DL_CSI__REPORT_A12CSI:
nikaeinn's avatar
nikaeinn committed
595
596
597
598
	  free(dl_report->csi_report[j]->a12csi->wb_cqi);
	  free(dl_report->csi_report[j]->a12csi->sb_pmi);
	  free(dl_report->csi_report[j]->a12csi);
	  break;
599
	case PROTOCOL__FLEX_DL_CSI__REPORT_A22CSI:
nikaeinn's avatar
nikaeinn committed
600
601
602
603
604
	  free(dl_report->csi_report[j]->a22csi->wb_cqi);
	  free(dl_report->csi_report[j]->a22csi->sb_cqi);
	  free(dl_report->csi_report[j]->a22csi->sb_list);
	  free(dl_report->csi_report[j]->a22csi);
	  break;
605
	case PROTOCOL__FLEX_DL_CSI__REPORT_A20CSI:
nikaeinn's avatar
nikaeinn committed
606
607
608
	  free(dl_report->csi_report[j]->a20csi->sb_list);
	  free(dl_report->csi_report[j]->a20csi);
	  break;
609
	case PROTOCOL__FLEX_DL_CSI__REPORT_A30CSI:
nikaeinn's avatar
nikaeinn committed
610
611
612
	  free(dl_report->csi_report[j]->a30csi->sb_cqi);
	  free(dl_report->csi_report[j]->a30csi);
	  break;
613
	case PROTOCOL__FLEX_DL_CSI__REPORT_A31CSI:
nikaeinn's avatar
nikaeinn committed
614
615
616
617
618
619
	  free(dl_report->csi_report[j]->a31csi->wb_cqi);
	  for (k = 0; k < dl_report->csi_report[j]->a31csi->n_sb_cqi; k++) {
	    free(dl_report->csi_report[j]->a31csi->sb_cqi[k]);
	  }
	  free(dl_report->csi_report[j]->a31csi->sb_cqi);
	  break;
620
621
	default:
	  break;
622
623
	}

nikaeinn's avatar
nikaeinn committed
624
625
626
627
628
629
	free(dl_report->csi_report[j]);
      }
      free(dl_report->csi_report);
      free(dl_report);
    }
    // If Paging buffer report flag was set
630
    if (reply->ue_report[i]->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) {
nikaeinn's avatar
nikaeinn committed
631
632
633
634
635
636
637
638
639
      paging_report = reply->ue_report[i]->pbr;
      // Delete all paging buffer reports
      for (j = 0; j < paging_report->n_paging_info; j++) {
	free(paging_report->paging_info[j]);
      }
      free(paging_report->paging_info);
      free(paging_report);
    }
    // If UL CQI report flag was set
640
    if (reply->ue_report[i]->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) {
nikaeinn's avatar
nikaeinn committed
641
642
643
644
645
646
      ul_report = reply->ue_report[i]->ul_cqi_report;
      for (j = 0; j < ul_report->n_cqi_meas; j++) {
	free(ul_report->cqi_meas[j]->sinr);
	free(ul_report->cqi_meas[j]);
      }
      free(ul_report->cqi_meas);
647
648
649
650
      for (j = 0; j < ul_report->n_pucch_dbm; j++) {
	free(ul_report->pucch_dbm[j]);
      }
      free(ul_report->pucch_dbm);
nikaeinn's avatar
nikaeinn committed
651
652
653
654
655
656
657
658
659
660
661
    }
    free(reply->ue_report[i]);
  }
  free(reply->ue_report);

  // Free memory for all Cell reports
  for (i = 0; i < reply->n_cell_report; i++) {
    free(reply->cell_report[i]->noise_inter_report);
    free(reply->cell_report[i]);
  }
  free(reply->cell_report);
662

nikaeinn's avatar
nikaeinn committed
663
664
665
  free(reply);
  free(msg);
  return 0;
666

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

672
int flexran_agent_mac_sr_info(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
673
  Protocol__FlexHeader *header;
674
675
676
  int i;
  const int xid = *((int *)params);

677
678
  Protocol__FlexUlSrInfo *ul_sr_info_msg;
  ul_sr_info_msg = malloc(sizeof(Protocol__FlexUlSrInfo));
679
680
681
  if (ul_sr_info_msg == NULL) {
    goto error;
  }
682
  protocol__flex_ul_sr_info__init(ul_sr_info_msg);
683

684
685
686
  if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_UL_SR_INFO, &header) != 0)
    goto error;

687
688
  ul_sr_info_msg->header = header;
  ul_sr_info_msg->has_sfn_sf = 1;
689
  ul_sr_info_msg->sfn_sf = flexran_get_sfn_sf(mod_id);
690
691
692
693
694
695
696
697
698
699
700
  /*TODO: Set the number of UEs that sent an SR */
  ul_sr_info_msg->n_rnti = 1;
  ul_sr_info_msg->rnti = (uint32_t *) malloc(ul_sr_info_msg->n_rnti * sizeof(uint32_t));

  if(ul_sr_info_msg->rnti == NULL) {
    goto error;
  }
  /*TODO:Set the rnti of the UEs that sent an SR */
  for (i = 0; i < ul_sr_info_msg->n_rnti; i++) {
    ul_sr_info_msg->rnti[i] = 1;
  }
701

702
  *msg = malloc(sizeof(Protocol__FlexranMessage));
703
704
  if(*msg == NULL)
    goto error;
705
706
707
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_SR_INFO_MSG;
  (*msg)->msg_dir =  PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
708
709
  (*msg)->ul_sr_info_msg = ul_sr_info_msg;
  return 0;
710

711
712
713
714
715
716
717
718
719
720
721
722
723
724
 error:
  // TODO: Need to make proper error handling
  if (header != NULL)
    free(header);
  if (ul_sr_info_msg != NULL) {
    free(ul_sr_info_msg->rnti);
    free(ul_sr_info_msg);
  }
  if(*msg != NULL)
    free(*msg);
  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}

725
int flexran_agent_mac_destroy_sr_info(Protocol__FlexranMessage *msg) {
726
   if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_SR_INFO_MSG)
727
728
729
730
731
732
733
734
735
736
737
738
739
     goto error;

   free(msg->ul_sr_info_msg->header);
   free(msg->ul_sr_info_msg->rnti);
   free(msg->ul_sr_info_msg);
   free(msg);
   return 0;

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

740
int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
741
  Protocol__FlexHeader *header;
742
743
744
745
  int i, j, UE_id;
  
  int available_harq[NUMBER_OF_UE_MAX];
  
746
747
  const int xid = *((int *)params);

748

749
750
  Protocol__FlexSfTrigger *sf_trigger_msg;
  sf_trigger_msg = malloc(sizeof(Protocol__FlexSfTrigger));
751
  if (sf_trigger_msg == NULL) {
752
753
    goto error;
  }
754
  protocol__flex_sf_trigger__init(sf_trigger_msg);
755

756
757
758
  if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_SF_TRIGGER, &header) != 0)
    goto error;

759
760
761
  frame_t frame;
  sub_frame_t subframe;

762
763
764
765
766
  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
    available_harq[i] = -1;
  }

  int ahead_of_time = 0;
767
  
768
769
  frame = (frame_t) flexran_get_current_system_frame_num(mod_id);
  subframe = (sub_frame_t) flexran_get_current_subframe(mod_id);
770
771
772

  subframe = ((subframe + ahead_of_time) % 10);
  
773
  if (subframe < flexran_get_current_subframe(mod_id)) {
774
    frame = (frame + 1) % 1024;
775
776
  }

777
778
779
  int additional_frames = ahead_of_time / 10;
  frame = (frame + additional_frames) % 1024;

780
781
  sf_trigger_msg->header = header;
  sf_trigger_msg->has_sfn_sf = 1;
782
  sf_trigger_msg->sfn_sf = flexran_get_future_sfn_sf(mod_id, 3);
783

784
785
786
787
  sf_trigger_msg->n_dl_info = 0;

  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
    for (j = 0; j < 8; j++) {
788
      if (RC.mac && RC.mac[mod_id] && RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid == 1) {
789
790
791
792
793
794
	available_harq[i] = j;
	sf_trigger_msg->n_dl_info++;
	break;
      }
    }
  }
795
  
796
797
798

  //  LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10);

799
800
801
  /*TODO: Fill in the number of dl HARQ related info, based on the number of currently
   *transmitting UEs
   */
802
  //  sf_trigger_msg->n_dl_info = flexran_get_num_ues(mod_id);
803

804
  Protocol__FlexDlInfo **dl_info = NULL;
805

806
  if (sf_trigger_msg->n_dl_info > 0) {
807
    dl_info = malloc(sizeof(Protocol__FlexDlInfo *) * sf_trigger_msg->n_dl_info);
808
809
    if(dl_info == NULL)
      goto error;
810
    i = -1;
811
    //Fill the status of the current HARQ process for each UE
812
813
814
815
816
817
    for(UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
      if (available_harq[UE_id] < 0) {
	continue;
      } else {
	i++;
      }
818
      dl_info[i] = malloc(sizeof(Protocol__FlexDlInfo));
819
820
      if(dl_info[i] == NULL)
	goto error;
821
      protocol__flex_dl_info__init(dl_info[i]);
822
      dl_info[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id);
823
      dl_info[i]->has_rnti = 1;
824
      /*Fill in the right id of this round's HARQ process for this UE*/
825
826
827
828
829
830
      //      uint8_t harq_id;
      //uint8_t harq_status;
      //      flexran_get_harq(mod_id, UE_PCCID(mod_id,i), i, frame, subframe, &harq_id, &harq_status);
      
      
      dl_info[i]->harq_process_id = available_harq[UE_id];
831
832
      if (RC.mac && RC.mac[mod_id])
        RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][UE_id].harq_pid = 0;
833
      dl_info[i]->has_harq_process_id = 1;
834
      /* Fill in the status of the HARQ process (2 TBs)*/
835
836
      dl_info[i]->n_harq_status = 2;
      dl_info[i]->harq_status = malloc(sizeof(uint32_t) * dl_info[i]->n_harq_status);
837
      for (j = 0; j < dl_info[i]->n_harq_status; j++) {
838
839
        dl_info[i]->harq_status[j] = RC.mac[mod_id]->UE_list.UE_sched_ctrl[i].round[UE_PCCID(mod_id,i)][j];
        // TODO: This should be different per TB
840
841
842
843
      }
      //      LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d and harq %d (round %d)\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10, dl_info[i]->harq_process_id, dl_info[i]->harq_status[0]);
      if(dl_info[i]->harq_status[0] > 0) {
	//	LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d]Need to make a retransmission for harq %d (round %d)\n", flexran_get_current_frame(mod_id), flexran_get_current_subframe(mod_id), dl_info[i]->harq_process_id, dl_info[i]->harq_status[0]);
844
      }
845
      /*Fill in the serving cell index for this UE */
MKassem's avatar
MKassem committed
846
      dl_info[i]->serv_cell_index = UE_PCCID(mod_id,i);
847
848
849
      dl_info[i]->has_serv_cell_index = 1;
    }
  }
850

851
  sf_trigger_msg->dl_info = dl_info;
852

853
854
  /* Fill in the number of UL reception status related info, based on the number of currently
   * transmitting UEs
855
   */
856
  sf_trigger_msg->n_ul_info = flexran_get_num_ues(mod_id);
857

858
  Protocol__FlexUlInfo **ul_info = NULL;
859

860
  if (sf_trigger_msg->n_ul_info > 0) {
861
    ul_info = malloc(sizeof(Protocol__FlexUlInfo *) * sf_trigger_msg->n_ul_info);
862
863
864
    if(ul_info == NULL)
      goto error;
    //Fill the reception info for each transmitting UE
865
    for(i = 0; i < sf_trigger_msg->n_ul_info; i++) {
866
      ul_info[i] = malloc(sizeof(Protocol__FlexUlInfo));
867
868
      if(ul_info[i] == NULL)
	goto error;
869
      protocol__flex_ul_info__init(ul_info[i]);
870
      ul_info[i]->rnti = flexran_get_ue_crnti(mod_id, i);
871
      ul_info[i]->has_rnti = 1;
Robert Schmidt's avatar
Robert Schmidt committed
872
873
874
875
876
      /* Fill in the Tx power control command for this UE (if available),
       * primary carrier */
      if(flexran_get_tpc(mod_id, i, 0) != 1){
          /* assume primary carrier */
          ul_info[i]->tpc = flexran_get_tpc(mod_id, i, 0);
MKassem's avatar
MKassem committed
877
878
879
          ul_info[i]->has_tpc = 1;
      }
      else{
Robert Schmidt's avatar
Robert Schmidt committed
880
881
          /* assume primary carrier */
          ul_info[i]->tpc = flexran_get_tpc(mod_id, i, 0);
MKassem's avatar
MKassem committed
882
883
    	  ul_info[i]->has_tpc = 0;
      }
884
      /*TODO: fill in the amount of data in bytes in the MAC SDU received in this subframe for the
885
	given logical channel*/
886
      ul_info[i]->n_ul_reception = 0;
887
      ul_info[i]->ul_reception = malloc(sizeof(uint32_t) * ul_info[i]->n_ul_reception);
888
      for (j = 0; j < ul_info[i]->n_ul_reception; j++) {
889
890
891
	ul_info[i]->ul_reception[j] = 100;
      }
      /*TODO: Fill in the reception status for each UEs data*/
892
      ul_info[i]->reception_status = PROTOCOL__FLEX_RECEPTION_STATUS__FLRS_OK;
893
      ul_info[i]->has_reception_status = 1;
894
      /*Fill in the serving cell index for this UE */
MKassem's avatar
MKassem committed
895
      ul_info[i]->serv_cell_index = UE_PCCID(mod_id,i);
896
897
898
      ul_info[i]->has_serv_cell_index = 1;
    }
  }
899

900
901
  sf_trigger_msg->ul_info = ul_info;

902
  *msg = malloc(sizeof(Protocol__FlexranMessage));
903
904
  if(*msg == NULL)
    goto error;
905
906
907
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_SF_TRIGGER_MSG;
  (*msg)->msg_dir =  PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
908
  (*msg)->sf_trigger_msg = sf_trigger_msg;
909
  return 0;
910

911
912
913
 error:
  if (header != NULL)
    free(header);
914
915
916
917
  if (sf_trigger_msg != NULL) {
    for (i = 0; i < sf_trigger_msg->n_dl_info; i++) {
      free(sf_trigger_msg->dl_info[i]->harq_status);
    }
918
    free(sf_trigger_msg->dl_info);    
919
920
    free(sf_trigger_msg->ul_info);
    free(sf_trigger_msg);
921
922
923
924
925
926
927
  }
  if(*msg != NULL)
    free(*msg);
  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}

928
int flexran_agent_mac_destroy_sf_trigger(Protocol__FlexranMessage *msg) {
929
  int i;
930
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_SF_TRIGGER_MSG)
931
    goto error;
932

933
934
935
  free(msg->sf_trigger_msg->header);
  for (i = 0; i < msg->sf_trigger_msg->n_dl_info; i++) {
    free(msg->sf_trigger_msg->dl_info[i]->harq_status);
936
    free(msg->sf_trigger_msg->dl_info[i]);
937
  }
938
939
  free(msg->sf_trigger_msg->dl_info);
  for (i = 0; i < msg->sf_trigger_msg->n_ul_info; i++) {
940
941
    free(msg->sf_trigger_msg->ul_info[i]->ul_reception);
    free(msg->sf_trigger_msg->ul_info[i]);
942
943
944
  }
  free(msg->sf_trigger_msg->ul_info);
  free(msg->sf_trigger_msg);
945
  free(msg);
946

947
948
949
950
951
952
953
  return 0;

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

954
int flexran_agent_mac_create_empty_dl_config(mid_t mod_id, Protocol__FlexranMessage **msg) {
955
956

  int xid = 0;
957
  Protocol__FlexHeader *header;
958
  if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_DL_MAC_CONFIG, &header) != 0)
959
960
    goto error;

961
962
  Protocol__FlexDlMacConfig *dl_mac_config_msg;
  dl_mac_config_msg = malloc(sizeof(Protocol__FlexDlMacConfig));
963
964
965
  if (dl_mac_config_msg == NULL) {
    goto error;
  }
966
  protocol__flex_dl_mac_config__init(dl_mac_config_msg);
967

968
969
  dl_mac_config_msg->header = header;
  dl_mac_config_msg->has_sfn_sf = 1;
970
  dl_mac_config_msg->sfn_sf = flexran_get_sfn_sf(mod_id);
971

972
  *msg = malloc(sizeof(Protocol__FlexranMessage));
973
974
  if(*msg == NULL)
    goto error;
975
976
977
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_DL_MAC_CONFIG_MSG;
  (*msg)->msg_dir =  PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
978
979
980
981
982
983
984
985
  (*msg)->dl_mac_config_msg = dl_mac_config_msg;

  return 0;

 error:
  return -1;
}

986
int flexran_agent_mac_destroy_dl_config(Protocol__FlexranMessage *msg) {
987
  int i,j, k;
988
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_DL_MAC_CONFIG_MSG)
989
990
    goto error;

991
  Protocol__FlexDlDci *dl_dci;
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012

  free(msg->dl_mac_config_msg->header);
  for (i = 0; i < msg->dl_mac_config_msg->n_dl_ue_data; i++) {
    free(msg->dl_mac_config_msg->dl_ue_data[i]->ce_bitmap);
    for (j = 0; j < msg->dl_mac_config_msg->dl_ue_data[i]->n_rlc_pdu; j++) {
      for (k = 0; k <  msg->dl_mac_config_msg->dl_ue_data[i]->rlc_pdu[j]->n_rlc_pdu_tb; k++) {
	free(msg->dl_mac_config_msg->dl_ue_data[i]->rlc_pdu[j]->rlc_pdu_tb[k]);
      }
      free(msg->dl_mac_config_msg->dl_ue_data[i]->rlc_pdu[j]->rlc_pdu_tb);
      free(msg->dl_mac_config_msg->dl_ue_data[i]->rlc_pdu[j]);
    }
    free(msg->dl_mac_config_msg->dl_ue_data[i]->rlc_pdu);
    dl_dci = msg->dl_mac_config_msg->dl_ue_data[i]->dl_dci;
    free(dl_dci->tbs_size);
    free(dl_dci->mcs);
    free(dl_dci->ndi);
    free(dl_dci->rv);
    free(dl_dci);
    free(msg->dl_mac_config_msg->dl_ue_data[i]);
  }
  free(msg->dl_mac_config_msg->dl_ue_data);
1013

1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
  for (i = 0; i <  msg->dl_mac_config_msg->n_dl_rar; i++) {
    dl_dci = msg->dl_mac_config_msg->dl_rar[i]->rar_dci;
    free(dl_dci->tbs_size);
    free(dl_dci->mcs);
    free(dl_dci->ndi);
    free(dl_dci->rv);
    free(dl_dci);
    free(msg->dl_mac_config_msg->dl_rar[i]);
  }
  free(msg->dl_mac_config_msg->dl_rar);

  for (i = 0; i < msg->dl_mac_config_msg->n_dl_broadcast; i++) {
    dl_dci = msg->dl_mac_config_msg->dl_broadcast[i]->broad_dci;
    free(dl_dci->tbs_size);
    free(dl_dci->mcs);
    free(dl_dci->ndi);
    free(dl_dci->rv);
    free(dl_dci);
    free(msg->dl_mac_config_msg->dl_broadcast[i]);
  }
  free(msg->dl_mac_config_msg->dl_broadcast);

    for ( i = 0; i < msg->dl_mac_config_msg->n_ofdm_sym; i++) {
    free(msg->dl_mac_config_msg->ofdm_sym[i]);
  }
  free(msg->dl_mac_config_msg->ofdm_sym);
1040
1041
  free(msg->dl_mac_config_msg);
  free(msg);
1042
1043
1044
1045

  return 0;

 error:
1046
1047
1048
  return -1;
}

shahab's avatar
shahab committed
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
int flexran_agent_mac_create_empty_ul_config(mid_t mod_id, Protocol__FlexranMessage **msg) {

  int xid = 0;
  Protocol__FlexHeader *header;
  if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_UL_MAC_CONFIG, &header) != 0)
    goto error;

  Protocol__FlexUlMacConfig *ul_mac_config_msg;
  ul_mac_config_msg = malloc(sizeof(Protocol__FlexUlMacConfig));
  if (ul_mac_config_msg == NULL) {
    goto error;
  }
  protocol__flex_ul_mac_config__init(ul_mac_config_msg);

  ul_mac_config_msg->header = header;
  ul_mac_config_msg->has_sfn_sf = 1;
  ul_mac_config_msg->sfn_sf = flexran_get_sfn_sf(mod_id);

  *msg = malloc(sizeof(Protocol__FlexranMessage));
  if(*msg == NULL)
    goto error;
  protocol__flexran_message__init(*msg);
  (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_MAC_CONFIG_MSG;
  (*msg)->msg_dir =  PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE;
  (*msg)->ul_mac_config_msg = ul_mac_config_msg;

  return 0;

 error:
  return -1;
}


shahab's avatar
shahab committed
1082
int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) {
shahab's avatar
shahab committed
1083
  int i; //,j, k;
shahab's avatar
shahab committed
1084
1085
1086
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_MAC_CONFIG_MSG)
    goto error;

shahab's avatar
shahab committed
1087
  // Protocol__FlexUlDci *ul_dci;
shahab's avatar
shahab committed
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100

  free(msg->ul_mac_config_msg->header);
  for (i = 0; i < msg->ul_mac_config_msg->n_ul_ue_data; i++) {
    // TODO  uplink rlc ...
    // free(msg->ul_mac_config_msg->dl_ue_data[i]->ce_bitmap); 
  //   for (j = 0; j < msg->ul_mac_config_msg->ul_ue_data[i]->n_rlc_pdu; j++) {
  //     for (k = 0; k <  msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]->n_rlc_pdu_tb; k++) {
  // free(msg->ul_mac_config_msg->dl_ue_data[i]->rlc_pdu[j]->rlc_pdu_tb[k]);
  //     }
  //     free(msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]->rlc_pdu_tb);
  //     free(msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]);
  //   }
    // free(msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu);
shahab's avatar
shahab committed
1101
    // ul_dci = msg->ul_mac_config_msg->ul_ue_data[i]->ul_dci;
shahab's avatar
shahab committed
1102
1103
1104
1105
1106
    // free(dl_dci->tbs_size);
    // free(ul_dci->mcs);
    // free(ul_dci->ndi);
    // free(ul_dci->rv);
    // free(ul_dci);
shahab's avatar
shahab committed
1107
    // free(msg->ul_mac_config_msg->ul_ue_data[i]);
shahab's avatar
shahab committed
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
  }
  free(msg->ul_mac_config_msg->ul_ue_data);
  
  free(msg->ul_mac_config_msg);
  free(msg);

  return 0;

 error:
  return -1;
}


1121
void flexran_agent_get_pending_dl_mac_config(mid_t mod_id, Protocol__FlexranMessage **msg) {
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132

  struct lfds700_misc_prng_state ls;
  
  LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
  lfds700_misc_prng_init(&ls);
  
  if (lfds700_ringbuffer_read(&ringbuffer_state[mod_id], NULL, (void **) msg, &ls) == 0) {
    *msg = NULL;
  }
}

1133
int flexran_agent_mac_handle_dl_mac_config(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
1134
1135
1136

  struct lfds700_misc_prng_state ls;
  enum lfds700_misc_flag overwrite_occurred_flag;
1137
  Protocol__FlexranMessage *overwritten_dl_config;
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
   
  LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
  lfds700_misc_prng_init(&ls);
  
  lfds700_ringbuffer_write( &ringbuffer_state[mod_id],
			    NULL,
			    (void *) params,
			    &overwrite_occurred_flag,
			    NULL,
			    (void **)&overwritten_dl_config,
			    &ls);

  if (overwrite_occurred_flag == LFDS700_MISC_FLAG_RAISED) {
    // Delete unmanaged dl_config
1152
    flexran_agent_mac_destroy_dl_config(overwritten_dl_config);
1153
1154
1155
1156
  }
  *msg = NULL;
  return 2;

1157
1158
1159
  // error:
  //*msg = NULL;
  //return -1;
1160
1161
}

1162
void flexran_agent_init_mac_agent(mid_t mod_id) {
1163
  int i, j;
1164
1165
1166
1167
1168
1169
  lfds700_misc_library_init_valid_on_current_logical_core();
  lfds700_misc_prng_init(&ps[mod_id]);
  int num_elements = RINGBUFFER_SIZE + 1;
  //Allow RINGBUFFER_SIZE messages to be stored in the ringbuffer at any time
  dl_mac_config_array[mod_id] = malloc( sizeof(struct lfds700_ringbuffer_element) *  num_elements);
  lfds700_ringbuffer_init_valid_on_current_logical_core( &ringbuffer_state[mod_id], dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL );
1170
1171
  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
    for (j = 0; j < 8; j++) {
1172
1173
      if (RC.mac && RC.mac[mod_id])
        RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid = 0;
1174
1175
    }
  }
1176
1177
}

1178
/***********************************************
1179
 * FlexRAN agent - technology mac API implementation
1180
1181
 ***********************************************/

1182
void flexran_agent_send_sr_info(mid_t mod_id) {
1183
  int size;
1184
  Protocol__FlexranMessage *msg;
1185
  void *data;
1186
  int priority = 0;
1187
1188
  err_code_t err_code;

1189
1190
  int xid = 0;

1191
  /*TODO: Must use a proper xid*/
1192
  err_code = flexran_agent_mac_sr_info(mod_id, (void *) &xid, &msg);
1193
1194
1195
1196
1197
  if (err_code < 0) {
    goto error;
  }

  if (msg != NULL){
1198
    data=flexran_agent_pack_message(msg, &size);
1199
    /*Send sr info using the MAC channel of the eNB*/
1200
    if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_MAC, data, size, priority)) {
1201
      err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING;
1202
1203
      goto error;
    }
1204

1205
    LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size);
1206
    return;
1207
1208
  }
 error:
1209
  LOG_D(FLEXRAN_AGENT, "Could not send sr message\n");
1210
1211
}

1212
void flexran_agent_send_sf_trigger(mid_t mod_id) {
1213
  int size;
1214
  Protocol__FlexranMessage *msg;
1215
  void *data;
1216
  int priority = 0;
1217
1218
  err_code_t err_code;

1219
  int xid = 0;
1220

1221
  /*TODO: Must use a proper xid*/
1222
  err_code = flexran_agent_mac_sf_trigger(mod_id, (void *) &xid, &msg);
1223
1224
1225
1226
1227
  if (err_code < 0) {
    goto error;
  }

  if (msg != NULL){