pre_processor.c 48 KB
Newer Older
1
/*******************************************************************************
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9 10


11 12 13 14
    OpenAirInterface is distributed in the hope that 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.
15

16 17 18 19
    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is
    included in this distribution in the file called "COPYING". If not,
    see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
22 23
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

28
*******************************************************************************/
29
/*! \file pre_processor.c
30
 * \brief eNB scheduler preprocessing fuction prior to scheduling
31
 * \author Navid Nikaein and Ankit Bhamri
32
 * \date 2013 - 2014
33
 * \email navid.nikaein@eurecom.fr
34
 * \version 1.0
35 36 37 38
 * @ingroup _mac

 */

39
#include "assertions.h"
40 41 42 43 44 45 46
#include "PHY/defs.h"
#include "PHY/extern.h"

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

#include "LAYER2/MAC/defs.h"
47
#include "LAYER2/MAC/proto.h"
48 49 50 51 52 53 54
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
55
#include "rlc.h"
56 57


58

59 60 61 62 63 64 65 66 67 68
#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
Raymond Knopp's avatar
 
Raymond Knopp committed
69
*/
70 71


72
// This function stores the downlink buffer for all the logical channels
73 74
void store_dlsch_buffer (module_id_t Mod_id,
                         frame_t     frameP,
75 76
                         sub_frame_t subframeP)
{
Cedric Roux's avatar
Cedric Roux committed
77

Raymond Knopp's avatar
 
Raymond Knopp committed
78
  int                   UE_id,i;
79
  rnti_t                rnti;
80
  mac_rlc_status_resp_t rlc_status;
Raymond Knopp's avatar
 
Raymond Knopp committed
81 82 83
  UE_list_t             *UE_list = &eNB_mac_inst[Mod_id].UE_list;
  UE_TEMPLATE           *UE_template;

84
  for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
85 86

    UE_template = &UE_list->UE_template[UE_PCCID(Mod_id,UE_id)][UE_id];
87 88

    // clear logical channel interface variables
Raymond Knopp's avatar
 
Raymond Knopp committed
89 90
    UE_template->dl_buffer_total = 0;
    UE_template->dl_pdus_total = 0;
91 92

    for(i=0; i< MAX_NUM_LCID; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
93 94 95 96 97
      UE_template->dl_buffer_info[i]=0;
      UE_template->dl_pdus_in_buffer[i]=0;
      UE_template->dl_buffer_head_sdu_creation_time[i]=0;
      UE_template->dl_buffer_head_sdu_remaining_size_to_send[i]=0;
    }
98

Raymond Knopp's avatar
 
Raymond Knopp committed
99
    rnti = UE_RNTI(Mod_id,UE_id);
100 101 102

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

103
      rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 );
Raymond Knopp's avatar
 
Raymond Knopp committed
104 105 106
      UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel
      UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer;
      UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ;
107 108
      UE_template->dl_buffer_head_sdu_creation_time_max = cmax(UE_template->dl_buffer_head_sdu_creation_time_max,
          rlc_status.head_sdu_creation_time );
Raymond Knopp's avatar
 
Raymond Knopp committed
109 110
      UE_template->dl_buffer_head_sdu_remaining_size_to_send[i] = rlc_status.head_sdu_remaining_size_to_send;
      UE_template->dl_buffer_head_sdu_is_segmented[i] = rlc_status.head_sdu_is_segmented;
111 112
      UE_template->dl_buffer_total += UE_template->dl_buffer_info[i];//storing the total dlsch buffer
      UE_template->dl_pdus_total   += UE_template->dl_pdus_in_buffer[i];
113

Cedric Roux's avatar
Cedric Roux committed
114
#ifdef DEBUG_eNB_SCHEDULER
115

Raymond Knopp's avatar
 
Raymond Knopp committed
116 117 118 119
      /* 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 (UE_template->dl_buffer_info[i]>0)
120 121
        LOG_D(MAC,
              "[eNB %d] Frame %d Subframe %d : RLC status for UE %d in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n",
122 123 124 125 126 127 128
              Mod_id, frameP, subframeP, UE_id,
              i, UE_template->dl_pdus_in_buffer[i],UE_template->dl_buffer_info[i],
              UE_template->dl_buffer_head_sdu_creation_time[i],
              UE_template->dl_buffer_head_sdu_remaining_size_to_send[i],
              UE_template->dl_buffer_head_sdu_is_segmented[i]
             );

Cedric Roux's avatar
Cedric Roux committed
129
#endif
130

Raymond Knopp's avatar
 
Raymond Knopp committed
131
    }
132

133
    //#ifdef DEBUG_eNB_SCHEDULER
Raymond Knopp's avatar
 
Raymond Knopp committed
134 135
    if ( UE_template->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",
136 137 138 139 140 141
            Mod_id, frameP, subframeP, UE_id,
            UE_template->dl_buffer_total,
            UE_template->dl_pdus_total
           );

    //#endif
142 143 144
  }
}

145

146
// This function returns the estimated number of RBs required by each UE for downlink scheduling
Raymond Knopp's avatar
 
Raymond Knopp committed
147
void assign_rbs_required (module_id_t Mod_id,
148 149 150 151 152
                          frame_t     frameP,
                          sub_frame_t subframe,
                          uint16_t    nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
                          int         min_rb_unit[MAX_NUM_CCs])
{
153

154

Raymond Knopp's avatar
 
Raymond Knopp committed
155 156 157 158 159
  rnti_t           rnti;
  uint16_t         TBS = 0;
  LTE_eNB_UE_stats *eNB_UE_stats[MAX_NUM_CCs];
  int              UE_id,n,i,j,CC_id,pCCid,tmp;
  UE_list_t        *UE_list = &eNB_mac_inst[Mod_id].UE_list;
160
  //  UE_TEMPLATE           *UE_template;
161
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs];
162

Raymond Knopp's avatar
 
Raymond Knopp committed
163
  // clear rb allocations across all CC_ids
164
  for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
165
    pCCid = UE_PCCID(Mod_id,UE_id);
166
    rnti = UE_list->UE_template[pCCid][UE_id].rnti;
167

Raymond Knopp's avatar
 
Raymond Knopp committed
168
    //update CQI information across component carriers
169
    for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
170

Raymond Knopp's avatar
 
Raymond Knopp committed
171
      CC_id = UE_list->ordered_CCids[n][UE_id];
172 173
      frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id);
      eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti);
174
      /*
175 176
      DevCheck(((eNB_UE_stats[CC_id]->DL_cqi[0] < MIN_CQI_VALUE) || (eNB_UE_stats[CC_id]->DL_cqi[0] > MAX_CQI_VALUE)),
      eNB_UE_stats[CC_id]->DL_cqi[0], MIN_CQI_VALUE, MAX_CQI_VALUE);
177 178
      */
      eNB_UE_stats[CC_id]->dlsch_mcs1=cqi_to_mcs[eNB_UE_stats[CC_id]->DL_cqi[0]];
179

180
      eNB_UE_stats[CC_id]->dlsch_mcs1 = cmin(eNB_UE_stats[CC_id]->dlsch_mcs1,openair_daq_vars.target_ue_dl_mcs);
181

Raymond Knopp's avatar
 
Raymond Knopp committed
182
    }
183

Raymond Knopp's avatar
 
Raymond Knopp committed
184
    // provide the list of CCs sorted according to MCS
185 186
    for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) {
      for (j=i+1; j<UE_list->numactiveCCs[UE_id]; j++) {
187
        DevAssert( j < MAX_NUM_CCs );
188 189 190 191 192 193 194

        if (eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]]->dlsch_mcs1 >
            eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]]->dlsch_mcs1) {
          tmp = UE_list->ordered_CCids[i][UE_id];
          UE_list->ordered_CCids[i][UE_id] = UE_list->ordered_CCids[j][UE_id];
          UE_list->ordered_CCids[j][UE_id] = tmp;
        }
195
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
196
    }
197

198
    /*
Raymond Knopp's avatar
 
Raymond Knopp committed
199 200 201 202
    if ((mac_get_rrc_status(Mod_id,1,UE_id) < RRC_RECONFIGURED)){  // If we still don't have a default radio bearer
      nb_rbs_required[pCCid][UE_id] = PHY_vars_eNB_g[Mod_id][pCCid]->lte_frame_parms.N_RB_DL;
      continue;
    }
203 204
    */
    /* NN --> RK
205 206
     * check the index of UE_template"
     */
207 208
    //    if (UE_list->UE_template[UE_id]->dl_buffer_total> 0) {
    if (UE_list->UE_template[pCCid][UE_id].dl_buffer_total> 0) {
209
      LOG_D(MAC,"[preprocessor] assign RB for UE %d\n",UE_id);
210 211 212 213 214 215

      for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) {
        CC_id = UE_list->ordered_CCids[i][UE_id];
        frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id);
        eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti);

216 217 218 219 220
        if (eNB_UE_stats[CC_id]->dlsch_mcs1==0) {
          nb_rbs_required[CC_id][UE_id] = 4;  // don't let the TBS get too small
        } else {
          nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id];
        }
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

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

        LOG_D(MAC,"[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n",
              UE_id, CC_id, UE_list->UE_template[pCCid][UE_id].dl_buffer_total,
              nb_rbs_required[CC_id][UE_id],eNB_UE_stats[CC_id]->dlsch_mcs1,TBS);

        /* calculating required number of RBs for each UE */
        while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total)  {
          nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id];

          if (nb_rbs_required[CC_id][UE_id] > frame_parms[CC_id]->N_RB_DL) {
            TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,frame_parms[CC_id]->N_RB_DL);
            nb_rbs_required[CC_id][UE_id] = frame_parms[CC_id]->N_RB_DL;
            break;
          }

          TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
        } // end of while

        LOG_D(MAC,"[eNB %d] Frame %d: UE %d on CC %d: RB unit %d,  nb_required RB %d (TBS %d, mcs %d)\n",
              Mod_id, frameP,UE_id, CC_id,  min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats[CC_id]->dlsch_mcs1);
Raymond Knopp's avatar
 
Raymond Knopp committed
243 244 245 246
      }
    }
  }
}
247 248


Raymond Knopp's avatar
 
Raymond Knopp committed
249
// This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes
250

251 252
int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uint8_t ul_flag )
{
253

254
  uint8_t round,round_max=0,UE_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
255
  int CC_id;
256
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
257

258 259
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

260 261
    UE_id = find_UE_id(Mod_id,rnti);
    round    = UE_list->UE_sched_ctrl[UE_id].round[CC_id];
262
    if (round > round_max) {
Raymond Knopp's avatar
 
Raymond Knopp committed
263
      round_max = round;
264
    }
265 266
  }

267
  return round_max;
Raymond Knopp's avatar
 
Raymond Knopp committed
268
}
269

Raymond Knopp's avatar
 
Raymond Knopp committed
270
// This function scans all CC_ids for a particular UE to find the maximum DL CQI
271

272 273
int maxcqi(module_id_t Mod_id,int32_t UE_id)
{
274

Raymond Knopp's avatar
 
Raymond Knopp committed
275
  LTE_eNB_UE_stats *eNB_UE_stats = NULL;
276 277
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
  int CC_id,n;
Raymond Knopp's avatar
 
Raymond Knopp committed
278
  int CQI = 0;
279

280
  for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
281 282
    CC_id = UE_list->ordered_CCids[n][UE_id];
    eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,UE_RNTI(Mod_id,UE_id));
283

284
    if (eNB_UE_stats==NULL) {
285
      mac_xface->macphy_exit("maxcqi: could not get eNB_UE_stats\n");
286 287
      return 0; // not reached
    }
288

289
    if (eNB_UE_stats->DL_cqi[0] > CQI) {
Raymond Knopp's avatar
 
Raymond Knopp committed
290
      CQI = eNB_UE_stats->DL_cqi[0];
291
    }
292
  }
293

Raymond Knopp's avatar
 
Raymond Knopp committed
294 295
  return(CQI);
}
296 297 298



Raymond Knopp's avatar
 
Raymond Knopp committed
299
// This fuction sorts the UE in order their dlsch buffer and CQI
Raymond Knopp's avatar
 
Raymond Knopp committed
300
void sort_UEs (module_id_t Mod_idP,
301 302 303
               int         frameP,
               sub_frame_t subframeP)
{
304 305


Raymond Knopp's avatar
 
Raymond Knopp committed
306 307 308
  int               UE_id1,UE_id2;
  int               pCC_id1,pCC_id2;
  int               cqi1,cqi2,round1,round2;
309
  int               i=0,ii=0;//,j=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
310
  rnti_t            rnti1,rnti2;
311

Raymond Knopp's avatar
 
Raymond Knopp committed
312
  UE_list_t *UE_list = &eNB_mac_inst[Mod_idP].UE_list;
313

314
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
315

316
    for(ii=UE_list->next[i]; ii>=0; ii=UE_list->next[ii]) {
317

318 319
      UE_id1  = i;
      rnti1 = UE_RNTI(Mod_idP,UE_id1);
320 321
      if(rnti1 == NOT_A_RNTI)
	continue;
kaltenbe's avatar
kaltenbe committed
322 323
      if (UE_list->UE_sched_ctrl[UE_id1].ul_out_of_sync == 1)
	continue;
324 325 326
      pCC_id1 = UE_PCCID(Mod_idP,UE_id1);
      cqi1    = maxcqi(Mod_idP,UE_id1); //
      round1  = maxround(Mod_idP,rnti1,frameP,subframeP,0);
327

328 329
      UE_id2 = ii;
      rnti2 = UE_RNTI(Mod_idP,UE_id2);
330 331
      if(rnti2 == NOT_A_RNTI)
        continue;
kaltenbe's avatar
kaltenbe committed
332 333
      if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
	continue;
334
      cqi2    = maxcqi(Mod_idP,UE_id2);
335
      round2  = maxround(Mod_idP,rnti2,frameP,subframeP,0);  //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
336
      pCC_id2 = UE_PCCID(Mod_idP,UE_id2);
337

338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
      if(round2 > round1) { // Check first if one of the UEs has an active HARQ process which needs service and swap order
        swap_UEs(UE_list,UE_id1,UE_id2,0);
      } else if (round2 == round1) {
        // RK->NN : I guess this is for fairness in the scheduling. This doesn't make sense unless all UEs have the same configuration of logical channels.  This should be done on the sum of all information that has to be sent.  And still it wouldn't ensure fairness.  It should be based on throughput seen by each UE or maybe using the head_sdu_creation_time, i.e. swap UEs if one is waiting longer for service.
        //  for(j=0;j<MAX_NUM_LCID;j++){
        //    if (eNB_mac_inst[Mod_id][pCC_id1].UE_template[UE_id1].dl_buffer_info[j] <
        //      eNB_mac_inst[Mod_id][pCC_id2].UE_template[UE_id2].dl_buffer_info[j]){

        // first check the buffer status for SRB1 and SRB2

        if ( (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2]) <
             (UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2])   ) {
          swap_UEs(UE_list,UE_id1,UE_id2,0);
        } else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max <
                   UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max   ) {
          swap_UEs(UE_list,UE_id1,UE_id2,0);
        } else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total <
                   UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total   ) {
          swap_UEs(UE_list,UE_id1,UE_id2,0);
        } else if (cqi1 < cqi2) {
          swap_UEs(UE_list,UE_id1,UE_id2,0);
        }
Raymond Knopp's avatar
 
Raymond Knopp committed
360 361
      }
    }
362 363 364
  }
}

365

Raymond Knopp's avatar
 
Raymond Knopp committed
366 367


368
// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
Raymond Knopp's avatar
 
Raymond Knopp committed
369
void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
370 371 372 373 374
                                    frame_t       frameP,
                                    sub_frame_t   subframeP,
                                    int           N_RBG[MAX_NUM_CCs],
                                    int           *mbsfn_flag)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
375

376
  unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],harq_pid=0,round=0,total_ue_count;
Raymond Knopp's avatar
 
Raymond Knopp committed
377
  unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
378
  int                     UE_id, i; 
379
  uint16_t                ii,j;
Raymond Knopp's avatar
 
Raymond Knopp committed
380 381 382
  uint16_t                nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
  uint16_t                nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
  uint16_t                nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
383
  uint16_t                average_rbs_per_user[MAX_NUM_CCs] = {0};
384
  rnti_t             rnti;
Raymond Knopp's avatar
 
Raymond Knopp committed
385
  int                min_rb_unit[MAX_NUM_CCs];
386
  uint16_t r1=0;
387
  uint8_t CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
388
  UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
389
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs] = {0};
390

391
  int transmission_mode = 0;
392 393 394 395 396 397 398 399 400 401 402 403 404
  UE_sched_ctrl *ue_sched_ctl;
  //  int rrc_status           = RRC_IDLE;

#ifdef TM5
  int harq_pid1=0,harq_pid2=0;
  int round1=0,round2=0;
  int UE_id2;
  uint16_t                i1,i2,i3;
  rnti_t             rnti1,rnti2;
  LTE_eNB_UE_stats  *eNB_UE_stats1 = NULL;
  LTE_eNB_UE_stats  *eNB_UE_stats2 = NULL;
  UE_sched_ctrl *ue_sched_ctl1,*ue_sched_ctl2;
#endif
405 406

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
407 408 409

    if (mbsfn_flag[CC_id]>0)  // If this CC is allocated for MBSFN skip it here
      continue;
410 411 412

    frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id);

Raymond Knopp's avatar
 
Raymond Knopp committed
413

414
    min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id);
415 416

    for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
417
      UE_id = i;
418
      // Initialize scheduling information for all active UEs
419 420
      

421

422
      dlsch_scheduler_pre_processor_reset(Mod_id,
423 424
        UE_id,
        CC_id,
425 426
        frameP,
        subframeP,
427 428 429 430 431
        N_RBG[CC_id],
        nb_rbs_required,
        nb_rbs_required_remaining,
        rballoc_sub,
        MIMO_mode_indicator);
432

Raymond Knopp's avatar
 
Raymond Knopp committed
433
    }
434
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
435 436


437
  // Store the DLSCH buffer for each logical channel
438
  store_dlsch_buffer (Mod_id,frameP,subframeP);
439

Raymond Knopp's avatar
 
Raymond Knopp committed
440 441


442
  // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
Raymond Knopp's avatar
 
Raymond Knopp committed
443
  assign_rbs_required (Mod_id,frameP,subframeP,nb_rbs_required,min_rb_unit);
444

Raymond Knopp's avatar
 
Raymond Knopp committed
445 446


447
  // Sorts the user on the basis of dlsch logical channel buffer and CQI
Raymond Knopp's avatar
 
Raymond Knopp committed
448 449 450
  sort_UEs (Mod_id,frameP,subframeP);


Raymond Knopp's avatar
 
Raymond Knopp committed
451

452
  total_ue_count =0;
453

Raymond Knopp's avatar
 
Raymond Knopp committed
454
  // loop over all active UEs
455
  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
456
    rnti = UE_RNTI(Mod_id,i);
457

458
    if(rnti == NOT_A_RNTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
459
      continue;
kaltenbe's avatar
kaltenbe committed
460 461
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;
462
    UE_id = i;
463

464 465 466 467
    // if there is no available harq_process, skip the UE
    if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0)
      continue;

468
    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
469
      CC_id = UE_list->ordered_CCids[ii][UE_id];
470 471 472
      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
      harq_pid = ue_sched_ctl->harq_pid[CC_id];
      round    = ue_sched_ctl->round[CC_id];
Raymond Knopp's avatar
 
Raymond Knopp committed
473 474 475

      average_rbs_per_user[CC_id]=0;

476
      frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id);
Raymond Knopp's avatar
 
Raymond Knopp committed
477

478
      //      mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
479

480
      if(round>0) {
481
        nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
482
      }
483

Raymond Knopp's avatar
 
Raymond Knopp committed
484 485
      //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id];
      if (nb_rbs_required[CC_id][UE_id] > 0) {
486
        total_ue_count = total_ue_count + 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
487
      }
488 489 490 491 492 493 494 495 496 497 498 499


      // hypotetical assignement
      /*
       * If schedule is enabled and if the priority of the UEs is modified
       * The average rbs per logical channel per user will depend on the level of
       * priority. Concerning the hypothetical assignement, we should assign more
       * rbs to prioritized users. Maybe, we can do a mapping between the
       * average rbs per user and the level of priority or multiply the average rbs
       * per user by a coefficient which represents the degree of priority.
       */

500
      if (total_ue_count == 0) {
501
        average_rbs_per_user[CC_id] = 0;
502
      } else if( (min_rb_unit[CC_id] * total_ue_count) <= (frame_parms[CC_id]->N_RB_DL) ) {
503
        average_rbs_per_user[CC_id] = (uint16_t) floor(frame_parms[CC_id]->N_RB_DL/total_ue_count);
504
      } else {
505
        average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE
506
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
507 508
    }
  }
509

510 511
  // note: nb_rbs_required is assigned according to total_buffer_dl
  // extend nb_rbs_required to capture per LCID RB required
512
  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
513
    rnti = UE_RNTI(Mod_id,i);
514

515
    for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
516
      CC_id = UE_list->ordered_CCids[ii][i];
517

518
      // control channel
519
      if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED) {
520
        nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i];
521
      } else {
522 523
        nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]);

524
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
525
    }
526
  }
527

528
  //Allocation to UEs is done in 2 rounds,
529 530
  // 1st stage: average number of RBs allocated to each UE
  // 2nd stage: remaining RBs are allocated to high priority UEs
531 532 533 534 535 536
  for(r1=0; r1<2; r1++) {

    for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
      for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
        CC_id = UE_list->ordered_CCids[ii][i];

537
        if(r1 == 0) {
538
          nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][i];
539
        } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
540
          nb_rbs_required_remaining[CC_id][i] = nb_rbs_required[CC_id][i]-nb_rbs_required_remaining_1[CC_id][i]+nb_rbs_required_remaining[CC_id][i];
541
        }
542 543 544 545 546 547 548

        if (nb_rbs_required[CC_id][i]> 0 )
          LOG_D(MAC,"round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d,  pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n",
                r1, CC_id, i,
                nb_rbs_required_remaining[CC_id][i],
                nb_rbs_required_remaining_1[CC_id][i],
                nb_rbs_required[CC_id][i],
549
                UE_list->UE_sched_ctrl[i].pre_nb_available_rbs[CC_id],
550 551 552
                N_RBG[CC_id],
                min_rb_unit[CC_id]);

553
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
554
    }
555

556
    if (total_ue_count > 0 ) {
557 558 559 560 561
      for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
        UE_id = i;

        for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
          CC_id = UE_list->ordered_CCids[ii][UE_id];
562 563 564
	  ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
	  harq_pid = ue_sched_ctl->harq_pid[CC_id];
	  round    = ue_sched_ctl->round[CC_id];
565 566 567 568

          rnti = UE_RNTI(Mod_id,UE_id);

          // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti );
569
          if(rnti == NOT_A_RNTI)
570
            continue;
kaltenbe's avatar
kaltenbe committed
571 572
	  if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
	    continue;
573 574

          transmission_mode = mac_xface->get_transmission_mode(Mod_id,CC_id,rnti);
575 576
	  //          mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
          //rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti);
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
          /* 1st allocate for the retx */

          // retransmission in data channels
          // control channel in the 1st transmission
          // data channel for all TM
          LOG_T(MAC,"calling dlsch_scheduler_pre_processor_allocate .. \n ");
          dlsch_scheduler_pre_processor_allocate (Mod_id,
                                                  UE_id,
                                                  CC_id,
                                                  N_RBG[CC_id],
                                                  transmission_mode,
                                                  min_rb_unit[CC_id],
                                                  frame_parms[CC_id]->N_RB_DL,
                                                  nb_rbs_required,
                                                  nb_rbs_required_remaining,
                                                  rballoc_sub,
                                                  MIMO_mode_indicator);

595
#ifdef TM5
596 597 598 599

          // data chanel TM5: to be revisted
          if ((round == 0 )  &&
              (transmission_mode == 5)  &&
600
              (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
601 602 603

            for(j=0; j<N_RBG[CC_id]; j+=2) {

604 605
              if( (((j == (N_RBG[CC_id]-1))&& (rballoc_sub[CC_id][j] == 0) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 0))  ||
                   ((j < (N_RBG[CC_id]-1)) && (rballoc_sub[CC_id][j+1] == 0) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] == 0)) ) &&
606 607 608 609 610 611
                  (nb_rbs_required_remaining[CC_id][UE_id]>0)) {

                for (ii = UE_list->next[i+1]; ii >=0; ii=UE_list->next[ii]) {

                  UE_id2 = ii;
                  rnti2 = UE_RNTI(Mod_id,UE_id2);
612 613 614
		  ue_sched_ctl2 = &UE_list->UE_sched_ctrl[UE_id2];
		  harq_pid2 = ue_sched_ctl2->harq_pid[CC_id];
		  round2    = ue_sched_ctl2->round[CC_id];
615
                  if(rnti2 == NOT_A_RNTI)
616
                    continue;
kaltenbe's avatar
kaltenbe committed
617 618
		  if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
		    continue;
619 620

                  eNB_UE_stats2 = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti2);
621
                  //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0);
622

623
                  if ((mac_eNB_get_rrc_status(Mod_id,rnti2) >= RRC_RECONFIGURED) &&
624 625
                      (round2==0) &&
                      (mac_xface->get_transmission_mode(Mod_id,CC_id,rnti2)==5) &&
626
                      (ue_sched_ctl->dl_pow_off[CC_id] != 1)) {
627

628 629
                    if( (((j == (N_RBG[CC_id]-1)) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 0)) ||
                         ((j < (N_RBG[CC_id]-1)) && (ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] == 0))  ) &&
630 631 632 633 634
                        (nb_rbs_required_remaining[CC_id][UE_id2]>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[CC_id][j] = 1;
635 636
                        ue_sched_ctl->rballoc_sub_UE[CC_id][j] = 1;
                        ue_sched_ctl2->rballoc_sub_UE[CC_id][j] = 1;
637 638 639 640
                        MIMO_mode_indicator[CC_id][j] = 0;

                        if (j< N_RBG[CC_id]-1) {
                          rballoc_sub[CC_id][j+1] = 1;
641 642
                          ue_sched_ctl->rballoc_sub_UE[CC_id][j+1] = 1;
                          ue_sched_ctl2->rballoc_sub_UE[CC_id][j+1] = 1;
643 644 645
                          MIMO_mode_indicator[CC_id][j+1] = 0;
                        }

646 647
                        ue_sched_ctl->dl_pow_off[CC_id] = 0;
                        ue_sched_ctl2->dl_pow_off[CC_id] = 0;
648 649 650 651 652


                        if ((j == N_RBG[CC_id]-1) &&
                            ((PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 25) ||
                             (PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms.N_RB_DL == 50))) {
653
			  
654
                          nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit[CC_id]+1;
655
                          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1;
656
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - min_rb_unit[CC_id]+1;
657
                          ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + min_rb_unit[CC_id]-1;
658
                        } else {
659 660
                          
			  nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - 4;
661
                          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + 4;
662
                          nb_rbs_required_remaining[CC_id][UE_id2] = nb_rbs_required_remaining[CC_id][UE_id2] - 4;
663
                          ue_sched_ctl2->pre_nb_available_rbs[CC_id] = ue_sched_ctl2->pre_nb_available_rbs[CC_id] + 4;
664 665 666 667 668 669 670 671 672 673 674 675 676
                        }

                        break;
                      }
                    }
                  }
                }
              }
            }
          }

#endif
        }
Raymond Knopp's avatar
 
Raymond Knopp committed
677
      }
678
    } // total_ue_count
679
  } // end of for for r1 and r2
680 681 682

#ifdef TM5

Raymond Knopp's avatar
 
Raymond Knopp committed
683
  // This has to be revisited!!!!
684
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
685 686 687
    i1=0;
    i2=0;
    i3=0;
688 689

    for (j=0; j<N_RBG[CC_id]; j++) {
690
      if(MIMO_mode_indicator[CC_id][j] == 2) {
691
        i1 = i1+1;
692
      } else if(MIMO_mode_indicator[CC_id][j] == 1) {
693
        i2 = i2+1;
694
      } else if(MIMO_mode_indicator[CC_id][j] == 0) {
695
        i3 = i3+1;
696
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
697
    }
698

699
    if((i1 < N_RBG[CC_id]) && (i2>0) && (i3==0)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
700
      PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions + 1;
701
    }
702

703
    if(i3 == N_RBG[CC_id] && i1==0 && i2==0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
704
      PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1;
705
    }
706

707
    if((i1 < N_RBG[CC_id]) && (i3 > 0)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
708
      PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions + 1;
709
    }
710

Raymond Knopp's avatar
 
Raymond Knopp committed
711
    PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + 1;
712

713 714
  }

715 716 717
#endif

  for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
718
    UE_id = i;
719
    ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
720 721

    for (ii=0; ii<UE_num_active_CC(UE_list,UE_id); ii++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
722
      CC_id = UE_list->ordered_CCids[ii][UE_id];
723
      //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
724

725
      if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0 ) {
726
        LOG_D(MAC,"******************DL Scheduling Information for UE%d ************************\n",UE_id);
727
        LOG_D(MAC,"dl power offset UE%d = %d \n",UE_id,ue_sched_ctl->dl_pow_off[CC_id]);
728 729 730 731
        LOG_D(MAC,"***********RB Alloc for every subband for UE%d ***********\n",UE_id);

        for(j=0; j<N_RBG[CC_id]; j++) {
          //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i];
732
          LOG_D(MAC,"RB Alloc for UE%d and Subband%d = %d\n",UE_id,j,ue_sched_ctl->rballoc_sub_UE[CC_id][j]);
733 734 735
        }

        //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
736
        LOG_D(MAC,"Total RBs allocated for UE%d = %d\n",UE_id,ue_sched_ctl->pre_nb_available_rbs[CC_id]);
737
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
738
    }
739 740 741
  }
}

742
#define SF05_LIMIT 1
743

744
void dlsch_scheduler_pre_processor_reset (int module_idP,
745 746 747 748 749 750 751 752 753 754
					  int UE_id,
					  uint8_t  CC_id,
					  int frameP,
					  int subframeP,					  
					  int N_RBG,
					  uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
					  uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
					  unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
					  unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX])
  
755
{
756
  int i,j;
757 758 759
  UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list;
  UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
  rnti_t rnti = UE_RNTI(module_idP,UE_id);
760 761
  uint8_t *vrb_map = &eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map;
  int RBGsize = PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL/N_RBG;
762 763 764 765
#ifdef SF05_LIMIT
  int subframe05_limit=0;
  int sf05_upper=-1,sf05_lower=-1;
#endif
766
  LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
767 768 769 770 771 772
  // initialize harq_pid and round
  mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,
				    frameP,subframeP,
				    &ue_sched_ctl->harq_pid[CC_id],
				    &ue_sched_ctl->round[CC_id],
				    0);
773
  if (ue_sched_ctl->ta_timer == 0) {
774

775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809
    // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ...

    ue_sched_ctl->ta_timer = 20;  // wait 20 subframes before taking TA measurement from PHY
    switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) {
    case 6:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update;
      break;
      
    case 15:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/2;
      break;
      
    case 25:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/4;
      break;
      
    case 50:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/8;
      break;
      
    case 75:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/12;
      break;
      
    case 100:
      ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/16;
      break;
    }
    // clear the update in case PHY does not have a new measurement after timer expiry
    eNB_UE_stats->timing_advance_update =  0;
  }
  else {
    ue_sched_ctl->ta_timer--;
    ue_sched_ctl->ta_update =0; // don't trigger a timing advance command
  }
810
  nb_rbs_required[CC_id][UE_id]=0;
811 812
  ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
  ue_sched_ctl->dl_pow_off[CC_id] = 2;
813
  nb_rbs_required_remaining[CC_id][UE_id] = 0;
814

815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
#ifdef SF05_LIMIT  
  switch (N_RBG) {
  case 6:
    sf05_lower=0;
    sf05_upper=5;
    break;
  case 8:
    sf05_lower=2;
    sf05_upper=5;
    break;
  case 13:
    sf05_lower=4;
    sf05_upper=7;
    break;
  case 17:
    sf05_lower=7;
    sf05_upper=9;
    break;
  case 25:
    sf05_lower=11;
    sf05_upper=13;
    break;
  }
#endif
839
  // Initialize Subbands according to VRB map
840
  for (i=0; i<N_RBG; i++) {
841
    ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0;
842
    rballoc_sub[CC_id][i] = 0;
843 844 845 846 847 848 849 850
#ifdef SF05_LIMIT
    // for avoiding 6+ PRBs around DC in subframe 0-5 (avoid excessive errors)

    if ((subframeP==0 || subframeP==5) && 
	(i>=sf05_lower && i<=sf05_upper))
      rballoc_sub[CC_id][i]=1;
#endif
    // for SI-RNTI,RA-RNTI and P-RNTI allocations
851
    for (j=0;j<RBGsize;j++) {
852
      if (vrb_map[j+(i*RBGsize)]!=0)  {
853
	rballoc_sub[CC_id][i] = 1;
854
	LOG_D(MAC,"Frame %d, subframe %d : vrb %d allocated\n",frameP,subframeP,j+(i*RBGsize));
855 856 857 858
	break;
      }
    }
    LOG_D(MAC,"Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n",frameP,subframeP,CC_id,i,rballoc_sub[CC_id][i]);
859
    MIMO_mode_indicator[CC_id][i] = 2;
860 861 862 863 864
  }
}


void dlsch_scheduler_pre_processor_allocate (module_id_t   Mod_id,
865 866 867 868 869 870 871 872 873 874 875 876
    int           UE_id,
    uint8_t       CC_id,
    int           N_RBG,
    int           transmission_mode,
    int           min_rb_unit,
    uint8_t       N_RB_DL,
    uint16_t      nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
    uint16_t      nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
    unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],
    unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX])
{

877
  int i;
878 879
  UE_list_t *UE_list=&eNB_mac_inst[Mod_id].UE_list;
  UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
880 881 882 883

  for(i=0; i<N_RBG; i++) {

    if((rballoc_sub[CC_id][i] == 0)           &&
884
        (ue_sched_ctl->rballoc_sub_UE[CC_id][i] == 0) &&
885
        (nb_rbs_required_remaining[CC_id][UE_id]>0)   &&
886
        (ue_sched_ctl->pre_nb_available_rbs[CC_id] < nb_rbs_required[CC_id][UE_id])) {
887

888
      // if this UE is not scheduled for TM5
889
      if (ue_sched_ctl->dl_pow_off[CC_id] != 0 )  {
890

891 892
	if ((i == N_RBG-1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
	  rballoc_sub[CC_id][i] = 1;
893
	  ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
894 895
	  MIMO_mode_indicator[CC_id][i] = 1;
	  if (transmission_mode == 5 ) {
896
	    ue_sched_ctl->dl_pow_off[CC_id] = 1;
897 898
	  }   
	  nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1;
899
          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1;
900
        } else {
901 902
	  if (nb_rbs_required_remaining[CC_id][UE_id] >=  min_rb_unit){
	    rballoc_sub[CC_id][i] = 1;
903
	    ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
904 905
	    MIMO_mode_indicator[CC_id][i] = 1;
	    if (transmission_mode == 5 ) {
906
	      ue_sched_ctl->dl_pow_off[CC_id] = 1;
907 908
	    }
	    nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit;
909
	    ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit;
910 911
	  }
	}
912 913
      } // dl_pow_off[CC_id][UE_id] ! = 0
    }
914 915
  }

916 917 918
}


919
/// ULSCH PRE_PROCESSOR
920

921

922
void ulsch_scheduler_pre_processor(module_id_t module_idP,
923 924 925
                                   int frameP,
                                   sub_frame_t subframeP,
                                   uint16_t *first_rb,
926
                                   uint8_t aggregation)
927
{
928 929 930 931 932 933 934 935

  int16_t            i;
  uint16_t           UE_id,n,r;
  uint8_t            CC_id, round, harq_pid;
  uint16_t           nb_allocated_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX],total_allocated_rbs[MAX_NUM_CCs],average_rbs_per_user[MAX_NUM_CCs];
  int16_t            total_remaining_rbs[MAX_NUM_CCs];
  uint16_t           max_num_ue_to_be_scheduled=0,total_ue_count=0;
  rnti_t             rnti= -1;
936
  UE_list_t          *UE_list = &eNB_mac_inst[module_idP].UE_list;
937 938
  UE_TEMPLATE        *UE_template = 0;
  LTE_DL_FRAME_PARMS   *frame_parms = 0;
939

940
  // LOG_I(MAC,"store ulsch buffers\n");
941
  // convert BSR to bytes for comparison with tbs
942
  //  store_ulsch_buffer(module_idP,frameP, subframeP);
943

944
  //LOG_I(MAC,"assign max mcs min rb\n");
945 946
  // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB
  assign_max_mcs_min_rb(module_idP,frameP, subframeP, first_rb);
947

948
  //LOG_I(MAC,"sort ue \n");
949
  // sort ues
950 951
  sort_ue_ul (module_idP,frameP, subframeP);

952

953 954
  // we need to distribute RBs among UEs
  // step1:  reset the vars
955
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
956 957 958
    total_allocated_rbs[CC_id]=0;
    total_remaining_rbs[CC_id]=0;
    average_rbs_per_user[CC_id]=0;
959 960

    for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
961 962 963 964
      nb_allocated_rbs[CC_id][i]=0;
    }
  }

965
  //LOG_I(MAC,"step2 \n");
966 967 968
  // step 2: calculate the average rb per UE
  total_ue_count =0;
  max_num_ue_to_be_scheduled=0;
969 970 971 972 973

  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {

    rnti = UE_RNTI(module_idP,i);

974
    if (rnti==NOT_A_RNTI)
975 976
      continue;

kaltenbe's avatar
kaltenbe committed
977 978 979
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;

980
    UE_id = i;
981 982

    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
983 984 985 986
      // This is the actual CC_id in the list
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
      UE_template = &UE_list->UE_template[CC_id][UE_id];
      average_rbs_per_user[CC_id]=0;
987 988
      frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);

989
      if (UE_template->pre_allocated_nb_rb_ul > 0) {
990
        total_ue_count+=1;
991
      }
992 993
      /*
      if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id])  > (1<<aggregation)) {
994 995
        nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<<aggregation);
        max_num_ue_to_be_scheduled+=1;
996 997 998
	}*/

      max_num_ue_to_be_scheduled+=1;
999

1000
      if (total_ue_count == 0) {
1001
        average_rbs_per_user[CC_id] = 0;
1002
      } else if (total_ue_count == 1 ) { // increase the available RBs, special case,
1003
        average_rbs_per_user[CC_id] = frame_parms->N_RB_UL-first_rb[CC_id]+1;
1004
      } else if( (total_ue_count <= (frame_parms->N_RB_DL-first_rb[CC_id])) &&
1005
                 (total_ue_count <= max_num_ue_to_be_scheduled)) {
1006
        average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/total_ue_count);
1007
      } else if (max_num_ue_to_be_scheduled > 0 ) {
1008
        average_rbs_per_user[CC_id] = (uint16_t) floor((frame_parms->N_RB_UL-first_rb[CC_id])/max_num_ue_to_be_scheduled);
1009
      } else {
1010 1011 1012
        average_rbs_per_user[CC_id]=1;
        LOG_W(MAC,"[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n",
              module_idP,frameP,subframeP,UE_id,CC_id);
1013 1014 1015
      }
    }
  }
1016 1017 1018
  if (total_ue_count > 0)
    LOG_D(MAC,"[eNB %d] Frame %d subframe %d: total ue to be scheduled %d/%d\n",
	  module_idP, frameP, subframeP,total_ue_count, max_num_ue_to_be_scheduled);
1019

1020
  //LOG_D(MAC,"step3\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1021

1022 1023 1024 1025
  // step 3: assigne RBS
  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
    rnti = UE_RNTI(module_idP,i);

1026
    if (rnti==NOT_A_RNTI)
1027
      continue;
kaltenbe's avatar
kaltenbe committed
1028 1029
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;
1030

1031
    UE_id = i;
1032 1033

    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
1034 1035
      // This is the actual CC_id in the list
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
1036

1037
      mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,1);
1038

1039
      if(round>0) {
1040
        nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid];
1041
      } else {
1042
        nb_allocated_rbs[CC_id][UE_id] = cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul, average_rbs_per_user[CC_id]);
1043
      }
1044

1045
      total_allocated_rbs[CC_id]+= nb_allocated_rbs[CC_id][UE_id];
1046

1047 1048
    }
  }
1049

1050
  // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly
1051 1052 1053 1054 1055
  for(r=0; r<2; r++) {

    for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
      rnti = UE_RNTI(module_idP,i);

1056
      if (rnti==NOT_A_RNTI)
1057
        continue;
kaltenbe's avatar
kaltenbe committed
1058 1059
      if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
	continue;
1060

1061
      UE_id = i;
1062 1063 1064 1065 1066 1067 1068 1069

      for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
        // This is the actual CC_id in the list
        CC_id = UE_list->ordered_ULCCids[n][UE_id];
        UE_template = &UE_list->UE_template[CC_id][UE_id];
        frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);
        total_remaining_rbs[CC_id]=frame_parms->N_RB_UL - first_rb[CC_id] - total_allocated_rbs[CC_id];

1070
        if (total_ue_count == 1 ) {
1071
          total_remaining_rbs[CC_id]+=1;
1072
        }
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086

        if ( r == 0 ) {
          while ( (UE_template->pre_allocated_nb_rb_ul > 0 ) &&
                  (nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul) &&
                  (total_remaining_rbs[CC_id] > 0)) {
            nb_allocated_rbs[CC_id][UE_id] = cmin(nb_allocated_rbs[CC_id][UE_id]+1,UE_template->pre_allocated_nb_rb_ul);
            total_remaining_rbs[CC_id]--;
            total_allocated_rbs[CC_id]++;
          }
        } else {
          UE_template->pre_allocated_nb_rb_ul= nb_allocated_rbs[CC_id][UE_id];
          LOG_D(MAC,"******************UL Scheduling Information for UE%d CC_id %d ************************\n",UE_id, CC_id);
          LOG_D(MAC,"[eNB %d] total RB allocated for UE%d CC_id %d  = %d\n", module_idP, UE_id, CC_id, UE_template->pre_allocated_nb_rb_ul);
        }
1087 1088 1089
      }
    }
  }
1090 1091

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1092
    frame_parms= mac_xface->get_lte_frame_parms(module_idP,CC_id);
1093

1094
    if (total_allocated_rbs[CC_id]>0) {
1095
      LOG_D(MAC,"[eNB %d] total RB allocated for all UEs = %d/%d\n", module_idP, total_allocated_rbs[CC_id], frame_parms->N_RB_UL - first_rb[CC_id]);
1096
    }
1097
  }
1098 1099
}

1100
/*
1101 1102
void store_ulsch_buffer(module_id_t module_idP, int frameP, sub_frame_t subframeP)
{
1103 1104 1105

  int                 UE_id,pCC_id,lcgid;
  UE_list_t           *UE_list = &eNB_mac_inst[module_idP].UE_list;
1106 1107 1108 1109 1110
  UE_TEMPLATE         *UE_template;

  for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) {


1111 1112 1113
    if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
      continue;

1114
    UE_template = &UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id];
1115 1116
    //LOG_I(MAC,"[UE %d next %d] SR is %d\n",UE_id, UE_list->next_ul[UE_id], UE_template->ul_SR);

1117
    UE_template->ul_total_buffer=0;
1118 1119

    for (lcgid=0; lcgid<MAX_NUM_LCGID; lcgid++) {
1120
      UE_template->ul_buffer_info[lcgid]=BSR_TABLE[UE_template->bsr_info[lcgid]];
1121
      UE_template->ul_total_buffer+= UE_template->ul_buffer_info[lcgid]; // apply traffic aggregtaion if packets are small
1122 1123
      //   UE_template->ul_buffer_creation_time_max=cmax(UE_template->ul_buffer_creation_time_max, frame_cycle*1024 + frameP-UE_template->ul_buffer_creation_time[lcgid]));
    }
1124

1125
    if ( UE_template->ul_total_buffer >0)
gauthier's avatar
gauthier committed
1126
      LOG_D(MAC,"[eNB %d] Frame %d subframe %d UE %d CC id %d: LCGID0 %d, LCGID1 %d, LCGID2 %d LCGID3 %d, BO %d\n",
1127 1128 1129 1130 1131 1132 1133
            module_idP, frameP,subframeP, UE_id, UE_PCCID(module_idP,UE_id),
            UE_template->ul_buffer_info[LCGID0],
            UE_template->ul_buffer_info[LCGID1],
            UE_template->ul_buffer_info[LCGID2],
            UE_template->ul_buffer_info[LCGID3],
            UE_template->ul_total_buffer);
    else if (UE_is_to_be_scheduled(module_idP,UE_PCCID(module_idP,UE_id),UE_id) > 0 ) {
1134
      if (UE_template->ul_total_buffer == 0 ) {
1135
        UE_template->ul_total_buffer = BSR_TABLE[11];
1136
      }
1137

1138
      LOG_D(MAC,"[eNB %d] Frame %d subframe %d UE %d CC id %d: SR active, set BO to %d \n",
1139 1140
            module_idP, frameP,subframeP, UE_id, UE_PCCID(module_idP,UE_id),
            UE_template->ul_total_buffer);
1141
    }
1142
  }
1143
}
1144
*/
1145 1146


1147 1148 1149
void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP, uint16_t *first_rb)
{

1150 1151 1152 1153
  int                i;
  uint16_t           n,UE_id;
  uint8_t            CC_id;
  rnti_t             rnti           = -1;
1154
  int                mcs;
Raymond Knopp's avatar
 
Raymond Knopp committed
1155
  int                rb_table_index=0,tbs,tx_power;
1156
  eNB_MAC_INST       *eNB = &eNB_mac_inst[module_idP];
1157 1158
  UE_list_t          *UE_list = &eNB->UE_list;

1159 1160
  UE_TEMPLATE       *UE_template;
  LTE_DL_FRAME_PARMS   *frame_parms;
1161

1162

1163 1164 1165 1166
  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {

    rnti = UE_RNTI(module_idP,i);

1167
    if (rnti==NOT_A_RNTI)
1168
      continue;
kaltenbe's avatar
kaltenbe committed
1169 1170
    if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
      continue;
1171

1172 1173 1174 1175 1176
    if (UE_list->UE_sched_ctrl[i].phr_received == 1)
      mcs = 20; // if we've received the power headroom information the UE, we can go to maximum mcs
    else
      mcs = 10; // otherwise, limit to QPSK PUSCH

1177
    UE_id = i;
1178 1179

    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
1180 1181
      // This is the actual CC_id in the list
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
1182

1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197
      if (CC_id >= MAX_NUM_CCs) {
        LOG_E( MAC, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u",
               CC_id,
               MAX_NUM_CCs,
               n,
               UE_id,
               UE_list->numactiveULCCs[UE_id]);
      }

      AssertFatal( CC_id < MAX_NUM_CCs, "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u",
                   CC_id,
                   MAX_NUM_CCs,
                   n,
                   UE_id,
                   UE_list->numactiveULCCs[UE_id]);
1198
      frame_parms=mac_xface->get_lte_frame_parms(module_idP,CC_id);
1199
      UE_template = &UE_list->UE_template[CC_id][UE_id];
1200 1201

      // if this UE has UL traffic
1202
      if (UE_template->ul_total_buffer > 0 ) {
1203

1204
        tbs = mac_xface->get_TBS_UL(mcs,3);  // 1 or 2 PRB with cqi enabled does not work well!
1205 1206 1207
        // fixme: set use_srs flag
        tx_power= mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0);

1208
        while ((((UE_template->phr_info - tx_power) < 0 ) || (tbs > UE_template->ul_total_buffer))&&
1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225
               (mcs > 3)) {
          // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs);
          mcs--;
          tbs = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]);
          tx_power = mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0); // fixme: set use_srs
        }

        while ((tbs < UE_template->ul_total_buffer) &&
               (rb_table[rb_table_index]<(frame_parms->N_RB_UL-first_rb[CC_id])) &&
               ((UE_template->phr_info - tx_power) > 0) &&
               (rb_table_index < 32 )) {
          //  LOG_I(MAC,"tbs %d ul buffer %d rb table %d max ul rb %d\n", tbs, UE_template->ul_total_buffer, rb_table[rb_table_index], frame_parms->N_RB_UL-first_rb[CC_id]);
          rb_table_index++;
          tbs = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]);
          tx_power = mac_xface->estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0);
        }

1226
        UE_template->ue_tx_power = tx_power;
1227 1228 1229 1230 1231 1232

        if (rb_table[rb_table_index]>(frame_parms->N_RB_UL-first_rb[CC_id]-1)) {
          rb_table_index--;
        }

        // 1 or 2 PRB with cqi enabled does not work well!
1233
	if (rb_table[rb_table_index]<3) {
1234
          rb_table_index=2; //3PRB
1235
        }
1236 1237 1238 1239 1240 1241 1242 1243 1244 1245

        UE_template->pre_assigned_mcs_ul=mcs;
        UE_template->pre_allocated_rb_table_index_ul=rb_table_index;
        UE_template->pre_allocated_nb_rb_ul= rb_table[rb_table_index];
        LOG_D(MAC,"[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n",
              module_idP, frameP, subframeP, UE_id, CC_id,
              UE_template->pre_assigned_mcs_ul,
              UE_template->pre_allocated_rb_table_index_ul,
              UE_template->pre_allocated_nb_rb_ul,
              UE_template->phr_info,tx_power);
1246
      } else {
1247 1248
        UE_template->pre_allocated_rb_table_index_ul=-1;
        UE_template->pre_allocated_nb_rb_ul=0;
1249 1250 1251 1252 1253 1254
      }
    }
  }
}


1255 1256
void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP)
{
1257 1258 1259 1260 1261 1262 1263 1264

  int               UE_id1,UE_id2;
  int               pCCid1,pCCid2;
  int               round1,round2;
  int               i=0,ii=0,j=0;
  rnti_t            rnti1,rnti2;

  UE_list_t *UE_list = &eNB_mac_inst[module_idP].UE_list;
1265 1266

  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1267 1268

    //LOG_I(MAC,"sort ue ul i %d\n",i);
1269
    for (ii=UE_list->next_ul[i]; ii>=0; ii=UE_list->next_ul[ii]) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1270
      //LOG_I(MAC,"sort ul ue 2 ii %d\n",ii);
1271 1272 1273 1274 1275
 
      UE_id1  = i;
      rnti1 = UE_RNTI(module_idP,UE_id1);
      
      if(rnti1 == NOT_A_RNTI)
kaltenbe's avatar
kaltenbe committed
1276 1277 1278
	continue;
      if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
	continue;
Raymond Knopp's avatar
 
Raymond Knopp committed
1279

1280 1281 1282 1283 1284 1285
      pCCid1 = UE_PCCID(module_idP,UE_id1);
      round1  = maxround(module_idP,rnti1,frameP,subframeP,1);
      
      UE_id2  = ii;
      rnti2 = UE_RNTI(module_idP,UE_id2);
      
1286
      if(rnti2 == NOT_A_RNTI)
1287
        continue;
kaltenbe's avatar
kaltenbe committed
1288 1289
      if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
	continue;
1290

1291
      pCCid2 = UE_PCCID(module_idP,UE_id2);
1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
      round2  = maxround(module_idP,rnti2,frameP,subframeP,1);

      if(round2 > round1) {
        swap_UEs(UE_list,UE_id1,UE_id2,1);
      } else if (round2 == round1) {
        if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] < UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) {
          swap_UEs(UE_list,UE_id1,UE_id2,1);
        } else if (UE_list->UE_template[pCCid1][UE_id1].ul_total_buffer <  UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer) {
          swap_UEs(UE_list,UE_id1,UE_id2,1);
        } else if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul <  UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) {
1302
          if (UE_list->UE_template[pCCid2][UE_id2].ul_total_buffer > 0 ) {
1303
            swap_UEs(UE_list,UE_id1,UE_id2,1);
1304
          }
1305
        }
1306 1307 1308 1309
      }
    }
  }
}