flexran_agent_mac.c 49.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */ 
21

22 23
/*! \file flexran_agent_mac.c
 * \brief FlexRAN agent message handler for MAC layer
24
 * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein
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"
34
#include "flexran_agent_timer.h"
shahab SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI 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"

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


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


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

70 71
  /* Allocate memory for list of UE reports */
  if (report_config->nr_ue > 0) {
72

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 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;
118
                              rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id, i, j + 1);
119 120 121
                              rlc_reports[j]->has_tx_queue_size = 1;

                              //TODO:Set tx queue head of line delay in ms
122
                              rlc_reports[j]->tx_queue_hol_delay = flexran_get_hol_delay(enb_id, i, j + 1);
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
131
                              rlc_reports[j]->status_pdu_size = flexran_get_tx_queue_size(enb_id, i, j + 1);
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 SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI 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 
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);                                       		    
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;
264

265 266 267
                                      
                                    csi20->bandwidth_part_index = 1 ;//TODO
                                    csi20->has_bandwidth_part_index = 1;
268

269 270
                                    csi20->sb_index = 1 ;//TODO
                                    csi20->has_sb_index = 1 ;                                     
271 272


273
                                    csi_reports[j]->p20csi = csi20;
274

275

276
                              }
277

278
                              else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI){
279

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

292 293 294 295
                                  // csi21->sb_cqi = 1; // TODO 
                                   
                                  // csi21->bandwidth_part_index = 1 ; //TDO inside
                                  // csi21->has_bandwidth_part_index = 1 ;   
296

297 298
                                  // csi21->sb_index = 1 ;//TODO
                                  // csi21->has_sb_index = 1 ;                                     
299

300

301
                                  // csi_reports[j]->p20csi = csi21;
302

303
                              }
304

305
                              else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A12CSI){
306

307

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                                                                      
317

318 319
                                  // TODO continou
                              }
320

321
                              else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_A22CSI){
322

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

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

339
                                    // csi22->sb_list = flexran_get_ue_wcqi (enb_id, i);                                       
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 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;
                      

                     }    
                             
                 

                            
             }       

          
         
         
     } 
505 506 507

  /* Allocate memory for list of cell reports */
  if (report_config->nr_cc > 0) {
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;
                      }
            }
            

      
            
541
  }
542

543
  return 0;
544

545
 error:
546 547 548 549 550 551

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

552 553 554
  return -1;
}

555
int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg) {
556
  //TODO: Need to deallocate memory for the stats reply message
557
  if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG)
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;
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) {
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:
582 583
	  free(dl_report->csi_report[j]->p10csi);
	  break;
584
	case PROTOCOL__FLEX_DL_CSI__REPORT_P11CSI:
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:
589 590
	  free(dl_report->csi_report[j]->p20csi);
	  break;
591
	case PROTOCOL__FLEX_DL_CSI__REPORT_P21CSI:
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:
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:
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:
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:
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:
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
	}

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

665 666 667
  free(reply);
  free(msg);
  return 0;
668

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 SHARIATBAGHERI's avatar
shahab SHARIATBAGHERI 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;
}


1080
void flexran_agent_get_pending_dl_mac_config(mid_t mod_id, Protocol__FlexranMessage **msg) {
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091

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

1092
int flexran_agent_mac_handle_dl_mac_config(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
1093 1094 1095

  struct lfds700_misc_prng_state ls;
  enum lfds700_misc_flag overwrite_occurred_flag;
1096
  Protocol__FlexranMessage *overwritten_dl_config;
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
   
  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
1111
    flexran_agent_mac_destroy_dl_config(overwritten_dl_config);
1112 1113 1114 1115
  }
  *msg = NULL;
  return 2;

1116 1117 1118
  // error:
  //*msg = NULL;
  //return -1;
1119 1120
}

1121
void flexran_agent_init_mac_agent(mid_t mod_id) {
1122
  int i, j;
1123 1124 1125 1126 1127 1128
  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 );
1129 1130 1131 1132 1133
  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
    for (j = 0; j < 8; j++) {
      harq_pid_updated[i][j] = 0;
    }
  }
1134 1135
}

1136
/***********************************************
1137
 * FlexRAN agent - technology mac API implementation
1138 1139
 ***********************************************/

1140
void flexran_agent_send_sr_info(mid_t mod_id) {
1141
  int size;
1142
  Protocol__FlexranMessage *msg;
1143
  void *data;
1144
  int priority = 0;
1145 1146
  err_code_t err_code;

1147 1148
  int xid = 0;

1149
  /*TODO: Must use a proper xid*/
1150
  err_code = flexran_agent_mac_sr_info(mod_id, (void *) &xid, &msg);
1151 1152 1153 1154 1155
  if (err_code < 0) {
    goto error;
  }

  if (msg != NULL){
1156
    data=flexran_agent_pack_message(msg, &size);
1157
    /*Send sr info using the MAC channel of the eNB*/
1158
    if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_MAC, data, size, priority)) {
1159
      err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING;
1160 1161
      goto error;
    }
1162

1163
    LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size);
1164
    return;
1165 1166
  }
 error:
1167
  LOG_D(FLEXRAN_AGENT, "Could not send sr message\n");
1168 1169
}

1170
void flexran_agent_send_sf_trigger(mid_t mod_id) {
1171
  int size;
1172
  Protocol__FlexranMessage *msg;
1173
  void *data;
1174
  int priority = 0;
1175 1176
  err_code_t err_code;

1177
  int xid = 0;
1178

1179
  /*TODO: Must use a proper xid*/
1180
  err_code = flexran_agent_mac_sf_trigger(mod_id, (void *) &xid, &msg);
1181 1182 1183 1184 1185
  if (err_code < 0) {
    goto error;
  }

  if (msg != NULL){
1186
    data=flexran_agent_pack_message(msg, &size);
1187
    /*Send sr info using the MAC channel of the eNB*/
1188
    if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_MAC, data, size, priority)) {
1189
      err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING;
1190 1191 1192
      goto error;
    }

1193
    LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size);
1194 1195 1196
    return;
  }
 error:
1197
  LOG_D(FLEXRAN_AGENT, "Could not send sf trigger message\n");
1198 1199 1200
}


1201

1202
int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
1203
  if (mac_agent_registered[mod_id]) {
1204 1205 1206 1207
    LOG_E(MAC, "MAC agent for eNB %d is already registered\n", mod_id);
    return -1;
  }

1208
  //xface->agent_ctxt = &shared_ctxt[mod_id];
1209 1210
  xface->flexran_agent_send_sr_info = flexran_agent_send_sr_info;
  xface->flexran_agent_send_sf_trigger = flexran_agent_send_sf_trigger;
1211
  //xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats;
1212
  xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_default;
1213
  xface->flexran_agent_schedule_ul_spec = flexran_agent_schedule_ulsch_ue_spec;
1214
  //xface->flexran_agent_schedule_ue_spec = flexran_schedule_ue_spec_remote;
1215
  xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config;
1216 1217
  
  xface->dl_scheduler_loaded_lib = NULL;
1218

1219
  mac_agent_registered[mod_id] = 1;
1220
  agent_mac_xface[mod_id] = xface;
1221 1222

  return 0;
1223 1224
}

1225
int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) {
1226

1227
  //xface->agent_ctxt = NULL;
1228 1229
  xface->flexran_agent_send_sr_info = NULL;
  xface->flexran_agent_send_sf_trigger = NULL;
1230
  //xface->flexran_agent_send_update_mac_stats = NULL;
1231 1232
  xface->flexran_agent_schedule_ue_spec = NULL;
  xface->flexran_agent_get_pending_dl_mac_config = NULL;
1233
  
1234

1235 1236
  xface->dl_scheduler_loaded_lib = NULL;

1237 1238
  mac_agent_registered[mod_id] = 0;
  agent_mac_xface[mod_id] = NULL;
1239

1240 1241 1242 1243
  return 0;
}


1244 1245


1246 1247