pre_processor.c 28.1 KB
Newer Older
gauthier's avatar
gauthier committed
1

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*******************************************************************************

  Eurecom OpenAirInterface
  Copyright(c) 1999 - 2010 Eurecom

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  more details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information
  Openair Admin: openair_admin@eurecom.fr
  Openair Tech : openair_tech@eurecom.fr
  Forums       : http://forums.eurecom.fsr/openairinterface
  Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France

gauthier's avatar
gauthier committed
29
 *******************************************************************************/
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
/*! \file pre_processor.c
 * \brief procedures related to UE
 * \author Ankit Bhamri
 * \date 2013
 * \version 0.1
 * @ingroup _mac

 */

#include "PHY/defs.h"
#include "PHY/extern.h"

#include "SCHED/defs.h"
#include "SCHED/extern.h"

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/defs.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/from_grlib_softregs.h"

#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"


gauthier's avatar
gauthier committed
59

60 61 62 63 64 65 66 67 68 69
#define DEBUG_eNB_SCHEDULER 1
#define DEBUG_HEADER_PARSING 1
//#define DEBUG_PACKET_TRACE 1

//#define ICIC 0

/*
  #ifndef USER_MODE
  #define msg debug_msg
  #endif
gauthier's avatar
gauthier committed
70
 */
71 72 73 74 75 76

extern inline unsigned int taus(void);



// This function stores the downlink buffer for all the logical channels 
gauthier's avatar
gauthier committed
77 78 79
void store_dlsch_buffer (module_id_t Mod_id,
                         frame_t     frameP,
                         sub_frame_t subframeP){
Cedric Roux's avatar
Cedric Roux committed
80

gauthier's avatar
gauthier committed
81 82 83
  module_id_t           next_ue;
  rnti_t                rnti;
  u16                   i=0;
84
  mac_rlc_status_resp_t rlc_status;
gauthier's avatar
gauthier committed
85
  unsigned char         UE_id,granted_UEs;
86 87 88 89

  granted_UEs = find_dlgranted_UEs(Mod_id);

  for (UE_id=0;UE_id<granted_UEs;UE_id++){
gauthier's avatar
gauthier committed
90 91 92 93 94 95 96 97
      eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_total = 0;
      eNB_mac_inst[Mod_id].UE_template[UE_id].dl_pdus_total = 0;
      for(i=0;i< MAX_NUM_LCID; i++) {
          eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_info[i]=0;
          eNB_mac_inst[Mod_id].UE_template[UE_id].dl_pdus_in_buffer[i]=0;
          eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_head_sdu_creation_time[i]=0;
          eNB_mac_inst[Mod_id].UE_template[UE_id].dl_buffer_head_sdu_remaining_size_to_send[i]=0;
      }
98 99 100
  }

  for (UE_id=0;UE_id<granted_UEs;UE_id++) {
gauthier's avatar
gauthier committed
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116

      next_ue = UE_id;
      rnti = find_UE_RNTI(Mod_id,next_ue);
      if (rnti == 0)
        continue;

      for(i=0;i< MAX_NUM_LCID; i++){ // loop over all the logical channels

          rlc_status = mac_rlc_status_ind(Mod_id,next_ue, frameP,1,RLC_MBMS_NO,i,0 );
          eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel
          eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer;
          eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ;
          eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_remaining_size_to_send;
          eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented;
          eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total = eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total + eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i];//storing the total dlsch buffer
          eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_total += eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i];
117

Cedric Roux's avatar
Cedric Roux committed
118
#ifdef DEBUG_eNB_SCHEDULER
gauthier's avatar
gauthier committed
119 120 121 122 123 124 125 126 127 128 129
          /* note for dl_buffer_head_sdu_remaining_size_to_send[i] :
           * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent
           */
          if (eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i]>0)
            LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and %d size, head sdu queuing time %d, remaining size %d, is segmeneted %d \n",
                Mod_id, frameP, subframeP, next_ue,
                i, eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_in_buffer[i],eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_info[i],
                eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_creation_time[i],
                eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_remaining_size_to_send[i],
                eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_head_sdu_is_segmented[i]
            );
Cedric Roux's avatar
Cedric Roux committed
130 131
#endif

gauthier's avatar
gauthier committed
132
      }
Cedric Roux's avatar
Cedric Roux committed
133
#ifdef DEBUG_eNB_SCHEDULER
gauthier's avatar
gauthier committed
134 135 136 137 138 139
      if ( eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total>0)
        LOG_D(MAC,"[eNB %d] Frame %d Subframe %d : RLC status for UE %d : total DL buffer size %d and total number of pdu %d \n",
            Mod_id, frameP, subframeP, next_ue,
            eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total,
            eNB_mac_inst[Mod_id].UE_template[next_ue].dl_pdus_total
        );
140
#endif   
141 142 143 144 145
  }
}


// This function returns the estimated number of RBs required by each UE for downlink scheduling
gauthier's avatar
gauthier committed
146 147 148 149
void assign_rbs_required (module_id_t      Mod_id,
    frame_t     frameP,
    sub_frame_t subframe,
    u16 *nb_rbs_required){
150

gauthier's avatar
gauthier committed
151 152 153 154 155 156 157

  module_id_t            next_ue;
  rnti_t            rnti;
  u16               TBS = 0;
  LTE_eNB_UE_stats *eNB_UE_stats = NULL;
  module_id_t            ue_inst;
  unsigned char granted_UEs;
158 159 160

  granted_UEs = find_dlgranted_UEs(Mod_id);

gauthier's avatar
gauthier committed
161 162
  for (ue_inst=0;ue_inst<granted_UEs;ue_inst++){
      nb_rbs_required[ue_inst] = 0; //initialization
163 164 165 166
  }



gauthier's avatar
gauthier committed
167 168 169 170 171 172 173 174 175 176 177 178 179
  for (ue_inst=0;ue_inst<granted_UEs;ue_inst++) {

      next_ue = ue_inst;
      rnti = find_UE_RNTI(Mod_id,next_ue);
      if (rnti == 0)
        continue;

      eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,rnti);
      //if(eNB_UE_stats == NULL)
      //continue;


      switch(eNB_UE_stats->DL_cqi[0])
180 181
      {
      case 0:
gauthier's avatar
gauthier committed
182 183
        eNB_UE_stats->dlsch_mcs1 = 0;
        break;
184
      case 1:
gauthier's avatar
gauthier committed
185 186
        eNB_UE_stats->dlsch_mcs1 = 0;
        break;
187
      case 2:
gauthier's avatar
gauthier committed
188 189
        eNB_UE_stats->dlsch_mcs1 = 0;
        break;
190
      case 3:
gauthier's avatar
gauthier committed
191 192
        eNB_UE_stats->dlsch_mcs1 = 2;
        break;
193
      case 4:
gauthier's avatar
gauthier committed
194 195
        eNB_UE_stats->dlsch_mcs1 = 4;
        break;
196
      case 5:
gauthier's avatar
gauthier committed
197 198
        eNB_UE_stats->dlsch_mcs1 = 6;
        break;
199
      case 6:
gauthier's avatar
gauthier committed
200 201
        eNB_UE_stats->dlsch_mcs1 = 8;
        break;
202
      case 7:
gauthier's avatar
gauthier committed
203 204
        eNB_UE_stats->dlsch_mcs1 = 11;
        break;
205
      case 8:
gauthier's avatar
gauthier committed
206 207
        eNB_UE_stats->dlsch_mcs1 = 13;
        break;
208
      case 9:
gauthier's avatar
gauthier committed
209 210
        eNB_UE_stats->dlsch_mcs1 = 16;
        break;
211
      case 10:
gauthier's avatar
gauthier committed
212 213
        eNB_UE_stats->dlsch_mcs1 = 18;
        break;
214
      case 11:
gauthier's avatar
gauthier committed
215 216
        eNB_UE_stats->dlsch_mcs1 = 20;
        break;
217
      case 12:
gauthier's avatar
gauthier committed
218 219
        eNB_UE_stats->dlsch_mcs1 = 22;
        break;
220
      case 13:
gauthier's avatar
gauthier committed
221 222
        eNB_UE_stats->dlsch_mcs1 = 22;//25
        break;
223
      case 14:
gauthier's avatar
gauthier committed
224 225
        eNB_UE_stats->dlsch_mcs1 = 22;//27
        break;
226
      case 15:
gauthier's avatar
gauthier committed
227 228
        eNB_UE_stats->dlsch_mcs1 = 22;//28
        break;
229
      default:
gauthier's avatar
gauthier committed
230 231
        printf("Invalid CQI");
        exit(-1);
232
      }
gauthier's avatar
gauthier committed
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



      if ((mac_get_rrc_status(Mod_id,1,next_ue) < RRC_RECONFIGURED)){
          nb_rbs_required[next_ue] = mac_xface->lte_frame_parms->N_RB_DL;
          continue;
      }


      if (eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total> 0) {

          if (eNB_UE_stats->dlsch_mcs1==0) nb_rbs_required[next_ue] = 4;  // don't let the TBS get too small
          else nb_rbs_required[next_ue] = 2;

          TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rbs_required[next_ue]);

          while (TBS < eNB_mac_inst[Mod_id].UE_template[next_ue].dl_buffer_total)  {
              nb_rbs_required[next_ue] += 2;
              if (nb_rbs_required[next_ue]>mac_xface->lte_frame_parms->N_RB_DL) {
                  TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,mac_xface->lte_frame_parms->N_RB_DL);
                  nb_rbs_required[next_ue] = mac_xface->lte_frame_parms->N_RB_DL;// calculating required number of RBs for each UE
                  break;
              }
              TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rbs_required[next_ue]);
          }

259
      }
gauthier's avatar
gauthier committed
260

261 262 263 264 265 266
  }
}



// This fuction sorts the UE in order their dlsch buffer and CQI
gauthier's avatar
gauthier committed
267 268 269 270 271 272 273 274 275 276 277 278 279
void sort_UEs (module_id_t      Mod_id,
    sub_frame_t subframe,
    module_id_t        *UE_id_sorted){

  module_id_t            next_ue1,next_ue2;
  unsigned char     round1=0,round2=0,harq_pid1=0,harq_pid2=0;
  module_id_t            ue_inst;
  u16               granted_UEs,i=0,ii=0,j=0;
  rnti_t            rnti1,rnti2;
  LTE_eNB_UE_stats *eNB_UE_stats1 = NULL;
  LTE_eNB_UE_stats *eNB_UE_stats2 = NULL;


280
  granted_UEs = find_dlgranted_UEs(Mod_id);
gauthier's avatar
gauthier committed
281 282 283 284 285


  for (ue_inst=0;ue_inst<granted_UEs;ue_inst++) {
      UE_id_sorted[i] = ue_inst;
      i++;
286
  }
gauthier's avatar
gauthier committed
287

288
  for(i=0; i < granted_UEs;i++){
gauthier's avatar
gauthier committed
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334

      next_ue1 = UE_id_sorted[i];

      rnti1 = find_UE_RNTI(Mod_id,next_ue1);
      if(rnti1 == 0)
        continue;


      eNB_UE_stats1 = mac_xface->get_eNB_UE_stats(Mod_id,rnti1);

      mac_xface->get_ue_active_harq_pid(Mod_id,rnti1,subframe,&harq_pid1,&round1,0);


      for(ii=i+1;ii<granted_UEs;ii++){

          next_ue2 = UE_id_sorted[ii];

          rnti2 = find_UE_RNTI(Mod_id,next_ue2);
          if(rnti2 == 0)
            continue;

          eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,rnti2);

          mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);

          if(round2 > round1){
              UE_id_sorted[i] = next_ue2;
              UE_id_sorted[ii] = next_ue1;
          }
          else if (round2 == round1){
              for(j=0;j<MAX_NUM_LCID;j++){

                  if(eNB_mac_inst[Mod_id].UE_template[next_ue1].dl_buffer_info[j] < eNB_mac_inst[Mod_id].UE_template[next_ue2].dl_buffer_info[j]){
                      UE_id_sorted[i] = next_ue2;
                      UE_id_sorted[ii] = next_ue1;
                      break;
                  }
                  else if((j == MAX_NUM_LCID-1))
                    {
                      if(eNB_UE_stats1->DL_cqi[0] < eNB_UE_stats2->DL_cqi[0]){
                          UE_id_sorted[i] = next_ue2;
                          UE_id_sorted[ii] = next_ue1;
                      }
                    }
              }
          }
335 336 337 338
      }
  }
}

gauthier's avatar
gauthier committed
339

340
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
gauthier's avatar
gauthier committed
341 342 343 344 345 346 347
void dlsch_scheduler_pre_processor (module_id_t        Mod_id,
    frame_t       frameP,
    sub_frame_t   subframeP,
    u8           *dl_pow_off,
    u16          *pre_nb_available_rbs,
    int           N_RBGS,
    unsigned char rballoc_sub_UE[NUMBER_OF_UE_MAX][N_RBGS_MAX]){
348 349 350

  unsigned char next_ue,next_ue1,next_ue2,rballoc_sub[mac_xface->lte_frame_parms->N_RBGS],harq_pid=0,harq_pid1=0,harq_pid2=0,round=0,round1=0,round2=0,total_ue_count=0;
  unsigned char MIMO_mode_indicator[mac_xface->lte_frame_parms->N_RBGS];
gauthier's avatar
gauthier committed
351 352 353 354 355 356 357 358 359 360 361 362 363
  module_id_t             UE_id, i;
  module_id_t             UE_id_sorted[NUMBER_OF_UE_MAX];
  module_id_t             granted_UEs;
  u16                ii,j;
  u16                nb_rbs_required[NUMBER_OF_UE_MAX];
  u16                nb_rbs_required_remaining[NUMBER_OF_UE_MAX];
  u16                nb_rbs_required_remaining_1[NUMBER_OF_UE_MAX];
  u16                i1,i2,i3,r1=0;
  u16                average_rbs_per_user=0;
  rnti_t             rnti,rnti1,rnti2;
  LTE_eNB_UE_stats  *eNB_UE_stats1 = NULL;
  LTE_eNB_UE_stats  *eNB_UE_stats2 = NULL;
  u16                min_rb_unit;
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382


  switch (mac_xface->lte_frame_parms->N_RB_DL) {
  case 6:
    min_rb_unit=1;
    break;
  case 25:
    min_rb_unit=2;
    break;
  case 50:
    min_rb_unit=3;
    break;
  case 100:
    min_rb_unit=4;
    break;
  default:
    min_rb_unit=2;
    break;
  }
383 384 385 386

  granted_UEs = find_dlgranted_UEs(Mod_id);


387
  for(i=0;i<NUMBER_OF_UE_MAX;i++){
gauthier's avatar
gauthier committed
388 389 390 391 392 393 394 395 396 397 398
      nb_rbs_required[i] = 0;
      UE_id_sorted[i] = i;
      dl_pow_off[i]  =2;
      pre_nb_available_rbs[i] = 0;
      nb_rbs_required_remaining[i] = 0;
      for(j=0;j<N_RBGS;j++)
        {
          MIMO_mode_indicator[j] = 2;
          rballoc_sub[j] = 0;
          rballoc_sub_UE[i][j] = 0;
        }
399
  }
gauthier's avatar
gauthier committed
400

401 402 403
  //printf("SUCCESS %d",mac_xface->lte_frame_parms->N_RBGS);
  //exit(-1);
  // Store the DLSCH buffer for each logical channel
gauthier's avatar
gauthier committed
404
  store_dlsch_buffer (Mod_id,frameP,subframeP);
405 406 407


  // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
gauthier's avatar
gauthier committed
408
  assign_rbs_required (Mod_id,frameP,subframeP,nb_rbs_required);
409 410

  // Sorts the user on the basis of dlsch logical channel buffer and CQI
gauthier's avatar
gauthier committed
411 412 413
  sort_UEs (Mod_id,subframeP,UE_id_sorted);
  //printf ("Frame:%d,SUCCESS %d[%d] %d[%d]\n",frameP,UE_id_sorted[0],nb_rbs_required[UE_id_sorted[0]],UE_id_sorted[1],nb_rbs_required[UE_id_sorted[1]]);

414
  for (i=0;i<granted_UEs;i++){
gauthier's avatar
gauthier committed
415 416 417 418 419 420 421 422 423
      rnti = find_UE_RNTI(Mod_id,i);
      if(rnti == 0)
        continue;
      mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0);
      if(round>0)
        nb_rbs_required[i] = eNB_mac_inst[Mod_id].UE_template[i].nb_rb[harq_pid];
      //nb_rbs_required_remaining[i] = nb_rbs_required[i];
      if(nb_rbs_required[i] > 0)
        total_ue_count = total_ue_count + 1;
424 425 426 427 428 429 430 431
  }
  // hypotetical assignement
  if((total_ue_count > 0) && ( min_rb_unit * total_ue_count <= mac_xface->lte_frame_parms->N_RB_DL ) )
    average_rbs_per_user = (u16) ceil(mac_xface->lte_frame_parms->N_RB_DL/total_ue_count);
  else 
    average_rbs_per_user = min_rb_unit;

  for(i=0;i<granted_UEs;i++){
gauthier's avatar
gauthier committed
432 433 434 435 436
      // control channel
      if (mac_get_rrc_status(Mod_id,1,i) < RRC_RECONFIGURED)
        nb_rbs_required_remaining_1[i] = nb_rbs_required[i];
      else
        nb_rbs_required_remaining_1[i] = cmin(average_rbs_per_user,nb_rbs_required[i]);
437
  }
gauthier's avatar
gauthier committed
438 439


440 441 442 443 444
  //Allocation to UEs is done in 2 rounds,
  // 1st round: average number of RBs allocated to each UE
  // 2nd round: remaining RBs are allocated to high priority UEs
  for(r1=0;r1<2;r1++){ 

gauthier's avatar
gauthier committed
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
      for(i=0; i<granted_UEs;i++)
        {
          if(r1 == 0)
            nb_rbs_required_remaining[i] = nb_rbs_required_remaining_1[i];
          else  // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
            nb_rbs_required_remaining[i] = nb_rbs_required[i]-nb_rbs_required_remaining_1[i]+nb_rbs_required_remaining[i];
        }
      // retransmission in control channels
      for (i = 0 ;i<granted_UEs; i++){

          next_ue = UE_id_sorted[i];
          rnti = find_UE_RNTI(Mod_id,next_ue);
          if(rnti == 0)
            continue;
          mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0);

          if ((mac_get_rrc_status(Mod_id,1,next_ue) < RRC_RECONFIGURED) && (round >0)) {



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

                  if((rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue][j] == 0) && (nb_rbs_required_remaining[next_ue]>0)){

                      rballoc_sub[j] = 1;
                      rballoc_sub_UE[next_ue][j] = 1;

                      MIMO_mode_indicator[j] = 1;

                      if(mac_xface->get_transmission_mode(Mod_id,rnti)==5)
                        dl_pow_off[next_ue] = 1;
                      // if the total rb is odd
                      if ((j == N_RBGS-1) &&
                          ((mac_xface->lte_frame_parms->N_RB_DL == 25)||
                              (mac_xface->lte_frame_parms->N_RB_DL == 50))) {
                          nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit+1;
                          pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit - 1;
                      }
                      else {
                          nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit;
                          pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit;
                      }
                  }
              }
          }
490 491 492 493
      }



gauthier's avatar
gauthier committed
494 495 496 497 498 499 500 501 502 503
      // retransmission in data channels
      for (i = 0 ;i<granted_UEs; i++){

          next_ue = UE_id_sorted[i];
          rnti = find_UE_RNTI(Mod_id,next_ue);
          if(rnti == 0)
            continue;
          mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0);

          if ((mac_get_rrc_status(Mod_id,1,next_ue) >= RRC_RECONFIGURED) && (round > 0)) {
504 505 506



gauthier's avatar
gauthier committed
507
              for(j=0;j<N_RBGS;j++){
508

gauthier's avatar
gauthier committed
509
                  if((rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue][j] == 0) && (nb_rbs_required_remaining[next_ue]>0)){
510

gauthier's avatar
gauthier committed
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
                      rballoc_sub[j] = 1;
                      rballoc_sub_UE[next_ue][j] = 1;

                      MIMO_mode_indicator[j] = 1;

                      if(mac_xface->get_transmission_mode(Mod_id,rnti)==5)
                        dl_pow_off[next_ue] = 1;

                      if((j == N_RBGS-1) &&
                          ((mac_xface->lte_frame_parms->N_RB_DL == 25)||
                              (mac_xface->lte_frame_parms->N_RB_DL == 50))){
                          nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit + 1;
                          pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit - 1;
                      }
                      else {
                          nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit;
                          pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit;
                      }
                  }
              }
          }
532 533 534
      }


gauthier's avatar
gauthier committed
535 536
      // control channel in the 1st transmission
      for (i = 0 ;i<granted_UEs; i++){
537

gauthier's avatar
gauthier committed
538 539 540 541 542 543 544
          next_ue = UE_id_sorted[i];
          rnti = find_UE_RNTI(Mod_id,next_ue);
          if(rnti == 0)
            continue;
          mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0);

          if ((mac_get_rrc_status(Mod_id,1,next_ue) < RRC_RECONFIGURED) && (round == 0)) {
545 546 547 548




gauthier's avatar
gauthier committed
549
              for(j=0;j<N_RBGS;j++){
550

gauthier's avatar
gauthier committed
551
                  if((rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue][j] == 0) && (nb_rbs_required_remaining[next_ue]>0)){
552

gauthier's avatar
gauthier committed
553 554
                      rballoc_sub[j] = 1;
                      rballoc_sub_UE[next_ue][j] = 1;
555

gauthier's avatar
gauthier committed
556
                      MIMO_mode_indicator[j] = 1;
557

gauthier's avatar
gauthier committed
558 559
                      if(mac_xface->get_transmission_mode(Mod_id,rnti)==5)
                        dl_pow_off[next_ue] = 1;
560

gauthier's avatar
gauthier committed
561 562 563 564 565 566 567 568 569 570 571 572 573
                      if((j == N_RBGS-1) &&
                          ((mac_xface->lte_frame_parms->N_RB_DL == 25)||
                              (mac_xface->lte_frame_parms->N_RB_DL == 50))){
                          nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit + 1;
                          pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit - 1;
                      }
                      else {
                          nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit;
                          pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit;
                      }
                  }
              }
          }
574 575 576 577
      }



gauthier's avatar
gauthier committed
578 579
      // data chanel TM5
      for (i = 0 ;i<granted_UEs; i++){
580 581


gauthier's avatar
gauthier committed
582 583 584 585
          next_ue1 = UE_id_sorted[i];
          rnti1 = find_UE_RNTI(Mod_id,next_ue1);
          if(rnti1 == 0)
            continue;
586

gauthier's avatar
gauthier committed
587
          eNB_UE_stats1 = mac_xface->get_eNB_UE_stats(Mod_id,rnti1);
588

gauthier's avatar
gauthier committed
589
          mac_xface->get_ue_active_harq_pid(Mod_id,rnti1,subframeP,&harq_pid1,&round1,0);
590

gauthier's avatar
gauthier committed
591
          if ((mac_get_rrc_status(Mod_id,1,next_ue1) >= RRC_RECONFIGURED) && (round1==0) && (mac_xface->get_transmission_mode(Mod_id,rnti1)==5) && (dl_pow_off[next_ue1] != 1)) {
592 593


gauthier's avatar
gauthier committed
594
              for(j=0;j<N_RBGS;j+=2){
595

gauthier's avatar
gauthier committed
596
                  if((((j == (N_RBGS-1))&& (rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue1][j] == 0)) || ((j < (N_RBGS-1)) && (rballoc_sub[j+1] == 0) && (rballoc_sub_UE[next_ue1][j+1] == 0))) && (nb_rbs_required_remaining[next_ue1]>0)){
597

gauthier's avatar
gauthier committed
598
                      for (ii = i+1;ii < granted_UEs;ii++) {
599

gauthier's avatar
gauthier committed
600 601 602 603
                          next_ue2 = UE_id_sorted[ii];
                          rnti2 = find_UE_RNTI(Mod_id,next_ue2);
                          if(rnti2 == 0)
                            continue;
604

gauthier's avatar
gauthier committed
605 606
                          eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,rnti2);
                          mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframeP,&harq_pid2,&round2,0);
607

gauthier's avatar
gauthier committed
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
                          if ((mac_get_rrc_status(Mod_id,1,next_ue2) >= RRC_RECONFIGURED) && (round2==0) && (mac_xface->get_transmission_mode(Mod_id,rnti2)==5) && (dl_pow_off[next_ue2] != 1)) {

                              if((((j == (N_RBGS-1)) && (rballoc_sub_UE[next_ue2][j] == 0)) || ((j < (N_RBGS-1)) && (rballoc_sub_UE[next_ue2][j+1] == 0))) && (nb_rbs_required_remaining[next_ue2]>0)){

                                  if((((eNB_UE_stats2->DL_pmi_single^eNB_UE_stats1->DL_pmi_single)<<(14-j))&0xc000)== 0x4000){ //MU-MIMO only for 25 RBs configuration

                                      rballoc_sub[j] = 1;
                                      rballoc_sub_UE[next_ue1][j] = 1;
                                      rballoc_sub_UE[next_ue2][j] = 1;
                                      MIMO_mode_indicator[j] = 0;

                                      if (j< N_RBGS-1) {
                                          rballoc_sub[j+1] = 1;
                                          rballoc_sub_UE[next_ue1][j+1] = 1;
                                          rballoc_sub_UE[next_ue2][j+1] = 1;
                                          MIMO_mode_indicator[j+1] = 0;
                                      }

                                      dl_pow_off[next_ue1] = 0;
                                      dl_pow_off[next_ue2] = 0;
628

gauthier's avatar
gauthier committed
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653



                                      if ((j == N_RBGS-1) &&
                                          ((mac_xface->lte_frame_parms->N_RB_DL == 25) ||
                                              (mac_xface->lte_frame_parms->N_RB_DL == 50))){
                                          nb_rbs_required_remaining[next_ue1] = nb_rbs_required_remaining[next_ue1] - min_rb_unit+1;
                                          pre_nb_available_rbs[next_ue1] = pre_nb_available_rbs[next_ue1] + min_rb_unit-1;
                                          nb_rbs_required_remaining[next_ue2] = nb_rbs_required_remaining[next_ue2] - min_rb_unit+1;
                                          pre_nb_available_rbs[next_ue2] = pre_nb_available_rbs[next_ue2] + min_rb_unit-1;
                                      }
                                      else {
                                          nb_rbs_required_remaining[next_ue1] = nb_rbs_required_remaining[next_ue1] - 4;
                                          pre_nb_available_rbs[next_ue1] = pre_nb_available_rbs[next_ue1] + 4;
                                          nb_rbs_required_remaining[next_ue2] = nb_rbs_required_remaining[next_ue2] - 4;
                                          pre_nb_available_rbs[next_ue2] = pre_nb_available_rbs[next_ue2] + 4;
                                      }
                                      break;
                                  }
                              }
                          }
                      }
                  }
              }
          }
654
      }
gauthier's avatar
gauthier committed
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
      // data channel for all TM
      for (i = 0;i<granted_UEs; i++){

          next_ue = UE_id_sorted[i];
          rnti = find_UE_RNTI(Mod_id,next_ue);
          if (rnti == 0)
            continue;

          mac_xface->get_ue_active_harq_pid(Mod_id,rnti,subframeP,&harq_pid,&round,0);

          if ((mac_get_rrc_status(Mod_id,1,next_ue) >= RRC_RECONFIGURED) && (round==0)) {


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

                  if((rballoc_sub[j] == 0) && (rballoc_sub_UE[next_ue][j] == 0) && (nb_rbs_required_remaining[next_ue]>0)){


                      switch (mac_xface->get_transmission_mode(Mod_id,rnti)) {
                      case 1:
                      case 2:
                      case 4:
                      case 6:
                        rballoc_sub[j] = 1;
                        rballoc_sub_UE[next_ue][j] = 1;

                        MIMO_mode_indicator[j] = 1;

                        if((j == N_RBGS-1) &&
                            ((mac_xface->lte_frame_parms->N_RB_DL == 25)||
                                (mac_xface->lte_frame_parms->N_RB_DL == 50))){
                            nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit+1;
                            pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] +min_rb_unit-1;
                        }
                        else {
                            nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit;
                            pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit;
                        }

                        break;
                      case 5:
                        if (dl_pow_off[next_ue] != 0){

                            dl_pow_off[next_ue] = 1;

                            rballoc_sub[j] = 1;
                            rballoc_sub_UE[next_ue][j] = 1;

                            MIMO_mode_indicator[j] = 1;

                            if((j == N_RBGS-1) &&
                                ((mac_xface->lte_frame_parms->N_RB_DL == 25)||
                                    (mac_xface->lte_frame_parms->N_RB_DL == 50))){
                                nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit+1;
                                pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit-1;
                            }
                            else {
                                nb_rbs_required_remaining[next_ue] = nb_rbs_required_remaining[next_ue] - min_rb_unit;
                                pre_nb_available_rbs[next_ue] = pre_nb_available_rbs[next_ue] + min_rb_unit;
                            }
                        }
                        break;
                      default:
                        break;
                      }
                  }
              }
          }
723 724
      }
  }
gauthier's avatar
gauthier committed
725

726 727 728
  i1=0;
  i2=0;
  i3=0;
729
  for (j=0;j<N_RBGS;j++){
gauthier's avatar
gauthier committed
730 731 732 733 734 735
      if(MIMO_mode_indicator[j] == 2)
        i1 = i1+1;
      else if(MIMO_mode_indicator[j] == 1)
        i2 = i2+1;
      else if(MIMO_mode_indicator[j] == 0)
        i3 = i3+1;
736 737 738
  }


739
  if((i1 < N_RBGS) && (i2>0) && (i3==0))
740
    PHY_vars_eNB_g[Mod_id]->check_for_SUMIMO_transmissions = PHY_vars_eNB_g[Mod_id]->check_for_SUMIMO_transmissions + 1;
gauthier's avatar
gauthier committed
741

742
  if(i3 == N_RBGS && i1==0 && i2==0)
743 744
    PHY_vars_eNB_g[Mod_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id]->FULL_MUMIMO_transmissions + 1;

745
  if((i1 < N_RBGS) && (i3 > 0))
746 747 748
    PHY_vars_eNB_g[Mod_id]->check_for_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id]->check_for_MUMIMO_transmissions + 1;

  PHY_vars_eNB_g[Mod_id]->check_for_total_transmissions = PHY_vars_eNB_g[Mod_id]->check_for_total_transmissions + 1;
gauthier's avatar
gauthier committed
749 750 751 752




753
  for(UE_id=0;UE_id<granted_UEs;UE_id++){
gauthier's avatar
gauthier committed
754 755 756 757 758 759 760 761 762 763
      //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
      LOG_D(PHY,"******************Scheduling Information for UE%d ************************\n",UE_id);
      LOG_D(PHY,"dl power offset UE%d = %d \n",UE_id,dl_pow_off[UE_id]);
      LOG_D(PHY,"***********RB Alloc for every subband for UE%d ***********\n",UE_id);
      for(j=0;j<N_RBGS;j++){
          //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[UE_id][i];
          LOG_D(PHY,"RB Alloc for UE%d and Subband%d = %d\n",UE_id,j,rballoc_sub_UE[UE_id][j]);
      }
      //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[UE_id];
      LOG_D(PHY,"Total RBs allocated for UE%d = %d\n",UE_id,pre_nb_available_rbs[UE_id]);
764 765 766
  }
}