flexran_agent_mac.c 51.1 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
 */ 
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
#include "LAYER2/MAC/proto.h"
38
39
#include "LAYER2/MAC/flexran_agent_mac_proto.h"
#include "LAYER2/MAC/flexran_agent_scheduler_dlsch_ue_remote.h"
40

41
42
#include "liblfds700.h"

nikaeinn's avatar
nikaeinn committed
43
44
#include "log.h"

45
46
47
48

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

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

52
53
54
55
56
57
58
/* 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
59
60
61
62
int flexran_agent_mac_stats_reply(mid_t mod_id,       
          const report_config_t *report_config,
           Protocol__FlexUeStatsReport **ue_report,
           Protocol__FlexCellStatsReport **cell_report) {
63
64


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

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

shahab's avatar
shahab committed
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
          
          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 
                                elem[j] = flexran_get_ue_bsr (enb_id, i, j); 
                        }
                          
                        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
118
                              rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id, i, j + 1);
shahab's avatar
shahab committed
119
120
121
                              rlc_reports[j]->has_tx_queue_size = 1;

                              //TODO:Set tx queue head of line delay in ms
shahab's avatar
shahab committed
122
                              rlc_reports[j]->tx_queue_hol_delay = flexran_get_hol_delay(enb_id, i, j + 1);
shahab's avatar
shahab committed
123
124
125
126
127
128
129
130
                              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
shahab's avatar
shahab committed
131
                              rlc_reports[j]->status_pdu_size = flexran_get_tx_queue_size(enb_id, i, j + 1);
shahab's avatar
shahab committed
132
133
134
135
136
137
138
139
140
141
142
143
144
                              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
145
146
147
148
149
                        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
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
215
216
                        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
217
218
219
                                    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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
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
262
263
                                    // According To spec 36.213                                  
                                     
                                    if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 1) {
                                        // TODO PMI
                                        csi11->wb_pmi = flexran_get_ue_pmi(enb_id);                          
                                        csi11->has_wb_pmi = 1;

                                       }   

                                      else if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 2){
                                        // TODO PMI
                                        csi11->wb_pmi = flexran_get_ue_pmi(enb_id);                                      
                                        csi11->has_wb_pmi = 1;

                                      }

                                      else if (flexran_get_antenna_ports(enb_id, j) == 4 && csi_reports[j]->ri == 2){
                                        // TODO PMI
                                        csi11->wb_pmi = flexran_get_ue_pmi(enb_id);                                      
                                        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
264

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

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


shahab's avatar
shahab committed
273
                                    csi_reports[j]->p20csi = csi20;
274

275

shahab's avatar
shahab committed
276
                              }
277

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

shahab's avatar
shahab committed
280
281
282
283
284
285
286
287
288
289
290
                                  // 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;
291

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

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

300

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

shahab's avatar
shahab committed
303
                              }
304

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

307

shahab's avatar
shahab committed
308
309
310
311
312
313
314
315
316
                                  // 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
317

shahab's avatar
shahab committed
318
319
                                  // TODO continou
                              }
nikaeinn's avatar
nikaeinn committed
320

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

shahab's avatar
shahab committed
323
324
325
326
327
328
329
330
331
                                    // 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                                      
332

shahab's avatar
shahab committed
333
334
335
336
337
                                    // 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;
338

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

shahab's avatar
shahab committed
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
503
504

                                }

                                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
505
506
507

  /* Allocate memory for list of cell reports */
  if (report_config->nr_cc > 0) {
shahab's avatar
shahab committed
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
539
540
    
            
            // 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
541
  }
542

nikaeinn's avatar
nikaeinn committed
543
  return 0;
544

nikaeinn's avatar
nikaeinn committed
545
 error:
shahab's avatar
shahab committed
546
547
548
549
550
551

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

nikaeinn's avatar
nikaeinn committed
552
553
554
  return -1;
}

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

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

  // 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
575
    if (reply->ue_report[i]->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI) {
nikaeinn's avatar
nikaeinn committed
576
577
578
579
580
      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) {
581
	case PROTOCOL__FLEX_DL_CSI__REPORT_P10CSI:
nikaeinn's avatar
nikaeinn committed
582
583
	  free(dl_report->csi_report[j]->p10csi);
	  break;
584
	case PROTOCOL__FLEX_DL_CSI__REPORT_P11CSI:
nikaeinn's avatar
nikaeinn committed
585
586
587
	  free(dl_report->csi_report[j]->p11csi->wb_cqi);
	  free(dl_report->csi_report[j]->p11csi);
	  break;
588
	case PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI:
nikaeinn's avatar
nikaeinn committed
589
590
	  free(dl_report->csi_report[j]->p20csi);
	  break;
591
	case PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI:
nikaeinn's avatar
nikaeinn committed
592
593
594
595
	  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;
596
	case PROTOCOL__FLEX_DL_CSI__REPORT_A12CSI:
nikaeinn's avatar
nikaeinn committed
597
598
599
600
	  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;
601
	case PROTOCOL__FLEX_DL_CSI__REPORT_A22CSI:
nikaeinn's avatar
nikaeinn committed
602
603
604
605
606
	  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;
607
	case PROTOCOL__FLEX_DL_CSI__REPORT_A20CSI:
nikaeinn's avatar
nikaeinn committed
608
609
610
	  free(dl_report->csi_report[j]->a20csi->sb_list);
	  free(dl_report->csi_report[j]->a20csi);
	  break;
611
	case PROTOCOL__FLEX_DL_CSI__REPORT_A30CSI:
nikaeinn's avatar
nikaeinn committed
612
613
614
	  free(dl_report->csi_report[j]->a30csi->sb_cqi);
	  free(dl_report->csi_report[j]->a30csi);
	  break;
615
	case PROTOCOL__FLEX_DL_CSI__REPORT_A31CSI:
nikaeinn's avatar
nikaeinn committed
616
617
618
619
620
621
	  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;
622
623
	default:
	  break;
624
625
	}

nikaeinn's avatar
nikaeinn committed
626
627
628
629
630
631
	free(dl_report->csi_report[j]);
      }
      free(dl_report->csi_report);
      free(dl_report);
    }
    // If Paging buffer report flag was set
632
    if (reply->ue_report[i]->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS) {
nikaeinn's avatar
nikaeinn committed
633
634
635
636
637
638
639
640
641
      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
642
    if (reply->ue_report[i]->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI) {
nikaeinn's avatar
nikaeinn committed
643
644
645
646
647
648
      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);
649
650
651
652
      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
653
654
655
656
657
658
659
660
661
662
663
    }
    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);
664

nikaeinn's avatar
nikaeinn committed
665
666
667
  free(reply);
  free(msg);
  return 0;
668

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

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

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

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

689
690
  ul_sr_info_msg->header = header;
  ul_sr_info_msg->has_sfn_sf = 1;
691
  ul_sr_info_msg->sfn_sf = flexran_get_sfn_sf(mod_id);
692
693
694
695
696
697
698
699
700
701
702
  /*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;
  }
703

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

713
714
715
716
717
718
719
720
721
722
723
724
725
726
 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;
}

727
int flexran_agent_mac_destroy_sr_info(Protocol__FlexranMessage *msg) {
728
   if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_SR_INFO_MSG)
729
730
731
732
733
734
735
736
737
738
739
740
741
     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;
}

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

750

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

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

761
762
763
  frame_t frame;
  sub_frame_t subframe;

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

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

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

779
780
781
  int additional_frames = ahead_of_time / 10;
  frame = (frame + additional_frames) % 1024;

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

786
787
788
789
790
791
792
793
794
795
796
  sf_trigger_msg->n_dl_info = 0;

  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
    for (j = 0; j < 8; j++) {
      if (harq_pid_updated[i][j] == 1) {
	available_harq[i] = j;
	sf_trigger_msg->n_dl_info++;
	break;
      }
    }
  }
797
  
798
799
800

  //  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);

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

806
  Protocol__FlexDlInfo **dl_info = NULL;
807

808
  if (sf_trigger_msg->n_dl_info > 0) {
809
    dl_info = malloc(sizeof(Protocol__FlexDlInfo *) * sf_trigger_msg->n_dl_info);
810
811
    if(dl_info == NULL)
      goto error;
812
    i = -1;
813
    //Fill the status of the current HARQ process for each UE
814
815
816
817
818
819
    for(UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
      if (available_harq[UE_id] < 0) {
	continue;
      } else {
	i++;
      }
820
      dl_info[i] = malloc(sizeof(Protocol__FlexDlInfo));
821
822
      if(dl_info[i] == NULL)
	goto error;
823
      protocol__flex_dl_info__init(dl_info[i]);
824
      dl_info[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id);
825
      dl_info[i]->has_rnti = 1;
826
      /*Fill in the right id of this round's HARQ process for this UE*/
827
828
829
830
831
832
833
      //      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];
      harq_pid_updated[UE_id][available_harq[UE_id]] = 0;
834
      dl_info[i]->has_harq_process_id = 1;
835
      /* Fill in the status of the HARQ process (2 TBs)*/
836
837
      dl_info[i]->n_harq_status = 2;
      dl_info[i]->harq_status = malloc(sizeof(uint32_t) * dl_info[i]->n_harq_status);
838
      for (j = 0; j < dl_info[i]->n_harq_status; j++) {
839
	dl_info[i]->harq_status[j] = harq_pid_round[UE_id][available_harq[UE_id]];
840
	// TODO: This should be different per TB
841
842
843
844
      }
      //      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]);
845
      }
846
      /*Fill in the serving cell index for this UE */
MKassem's avatar
MKassem committed
847
      dl_info[i]->serv_cell_index = UE_PCCID(mod_id,i);
848
849
850
      dl_info[i]->has_serv_cell_index = 1;
    }
  }
851

852
  sf_trigger_msg->dl_info = dl_info;
853

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

859
  Protocol__FlexUlInfo **ul_info = NULL;
860

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

898
899
  sf_trigger_msg->ul_info = ul_info;

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

909
910
911
 error:
  if (header != NULL)
    free(header);
912
913
914
915
  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);
    }
916
    free(sf_trigger_msg->dl_info);    
917
918
    free(sf_trigger_msg->ul_info);
    free(sf_trigger_msg);
919
920
921
922
923
924
925
  }
  if(*msg != NULL)
    free(*msg);
  //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
  return -1;
}

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

931
932
933
  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);
934
    free(msg->sf_trigger_msg->dl_info[i]);
935
  }
936
937
  free(msg->sf_trigger_msg->dl_info);
  for (i = 0; i < msg->sf_trigger_msg->n_ul_info; i++) {
938
939
    free(msg->sf_trigger_msg->ul_info[i]->ul_reception);
    free(msg->sf_trigger_msg->ul_info[i]);
940
941
942
  }
  free(msg->sf_trigger_msg->ul_info);
  free(msg->sf_trigger_msg);
943
  free(msg);
944

945
946
947
948
949
950
951
  return 0;

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

952
int flexran_agent_mac_create_empty_dl_config(mid_t mod_id, Protocol__FlexranMessage **msg) {
953
954

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

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

966
967
  dl_mac_config_msg->header = header;
  dl_mac_config_msg->has_sfn_sf = 1;
968
  dl_mac_config_msg->sfn_sf = flexran_get_sfn_sf(mod_id);
969

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

  return 0;

 error:
  return -1;
}

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

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

  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);
1011

1012
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
  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);
1038
1039
  free(msg->dl_mac_config_msg);
  free(msg);
1040
1041
1042
1043

  return 0;

 error:
1044
1045
1046
  return -1;
}

shahab's avatar
shahab committed
1047
1048
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
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
1080
int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) {
shahab's avatar
shahab committed
1081
  int i; //,j, k;
shahab's avatar
shahab committed
1082
1083
1084
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UL_MAC_CONFIG_MSG)
    goto error;

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

  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
1099
    // ul_dci = msg->ul_mac_config_msg->ul_ue_data[i]->ul_dci;
shahab's avatar
shahab committed
1100
1101
1102
1103
1104
    // 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
1105
    // free(msg->ul_mac_config_msg->ul_ue_data[i]);
shahab's avatar
shahab committed
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
  }
  free(msg->ul_mac_config_msg->ul_ue_data);
  
  free(msg->ul_mac_config_msg);
  free(msg);

  return 0;

 error:
  return -1;
}


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

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

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

  struct lfds700_misc_prng_state ls;
  enum lfds700_misc_flag overwrite_occurred_flag;
1135
  Protocol__FlexranMessage *overwritten_dl_config;
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
   
  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
1150
    flexran_agent_mac_destroy_dl_config(overwritten_dl_config);
1151
1152
1153
1154
  }
  *msg = NULL;
  return 2;

1155
1156
1157
  // error:
  //*msg = NULL;
  //return -1;
1158
1159
}

1160
void flexran_agent_init_mac_agent(mid_t mod_id) {
1161
  int i, j;
1162
1163
1164
1165
1166
1167
  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 );
1168
1169
1170
1171
1172
  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
    for (j = 0; j < 8; j++) {
      harq_pid_updated[i][j] = 0;
    }
  }
1173
1174
}

1175
/***********************************************
1176
 * FlexRAN agent - technology mac API implementation
1177
1178
 ***********************************************/

1179
void flexran_agent_send_sr_info(mid_t mod_id) {
1180
  int size;
1181
  Protocol__FlexranMessage *msg;
1182
  void *data;
1183
  int priority = 0;
1184
1185
  err_code_t err_code;

1186
1187
  int xid = 0;

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

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

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

1209
void flexran_agent_send_sf_trigger(mid_t mod_id) {
1210
  int size;
1211
  Protocol__FlexranMessage *msg;
1212
  void *data;
1213
  int priority = 0;
1214
1215
  err_code_t err_code;

1216
  int xid = 0;
1217

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

  if (msg != NULL){
1225
    data=flexran_agent_pack_message(msg, &size);
1226
    /*Send sr info using the MAC channel of the eNB*/
1227
    if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_MAC, data, size, priority)) {
1228
      err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING;
1229
1230
1231
      goto error;
    }

1232
    LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size);
1233
1234
1235
    return;
  }
 error:
1236
  LOG_D(FLEXRAN_AGENT, "Could not send sf trigger message\n");
1237
1238
1239
}


1240