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

22 23
/*! \file eNB_scheduler_primitives.c
 * \brief primitives used by eNB for BCH, RACH, ULSCH, DLSCH scheduling
24 25 26
 * \author  Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \email: navid.nikaein@eurecom.fr
27
 * \version 1.0
28 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
 * @ingroup _mac

 */

#include "assertions.h"
#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 "LAYER2/MAC/proto.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.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"

//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"

#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

Cedric Roux's avatar
Cedric Roux committed
59 60
#include "T.h"

61 62 63 64
#define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1


65
//------------------------------------------------------------------------------
66
void init_ue_sched_info(void)
67
//------------------------------------------------------------------------------
68
{
69
  module_id_t i,j,k;
70 71

  for (i=0; i<NUMBER_OF_eNB_MAX; i++) {
Cedric Roux's avatar
Cedric Roux committed
72
    for (k=0; k<MAX_NUM_CCs; k++) {
73 74 75 76 77 78 79 80 81 82
      for (j=0; j<NUMBER_OF_UE_MAX; j++) {
        // init DL
        eNB_dlsch_info[i][k][j].weight           = 0;
        eNB_dlsch_info[i][k][j].subframe         = 0;
        eNB_dlsch_info[i][k][j].serving_num      = 0;
        eNB_dlsch_info[i][k][j].status           = S_DL_NONE;
        // init UL
        eNB_ulsch_info[i][k][j].subframe         = 0;
        eNB_ulsch_info[i][k][j].serving_num      = 0;
        eNB_ulsch_info[i][k][j].status           = S_UL_NONE;
83
      }
84
    }
85 86 87 88 89
  }
}



90
//------------------------------------------------------------------------------
91
unsigned char get_ue_weight(module_id_t module_idP, int CC_id, int ue_idP)
92
//------------------------------------------------------------------------------
93
{
94

95
  return(eNB_dlsch_info[module_idP][CC_id][ue_idP].weight);
96 97 98

}

99
//------------------------------------------------------------------------------
100
DCI_PDU *get_dci_sdu(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframeP)
101
//------------------------------------------------------------------------------
102
{
103

Raymond Knopp's avatar
 
Raymond Knopp committed
104
  return(&eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu);
105 106 107

}

108
//------------------------------------------------------------------------------
109
int find_UE_id(module_id_t mod_idP, rnti_t rntiP)
110
//------------------------------------------------------------------------------
111
{
Raymond Knopp's avatar
 
Raymond Knopp committed
112 113
  int UE_id;
  UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
114

115 116
  for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
    if (UE_list->active[UE_id] != TRUE) continue;
Raymond Knopp's avatar
 
Raymond Knopp committed
117 118 119
    if (UE_list->UE_template[UE_PCCID(mod_idP,UE_id)][UE_id].rnti==rntiP) {
      return(UE_id);
    }
120
  }
121

Raymond Knopp's avatar
 
Raymond Knopp committed
122
  return(-1);
123 124
}

125
//------------------------------------------------------------------------------
126
int UE_num_active_CC(UE_list_t *listP,int ue_idP)
127
//------------------------------------------------------------------------------
128
{
Raymond Knopp's avatar
 
Raymond Knopp committed
129 130
  return(listP->numactiveCCs[ue_idP]);
}
131

132
//------------------------------------------------------------------------------
133
int UE_PCCID(module_id_t mod_idP,int ue_idP)
134
//------------------------------------------------------------------------------
135
{
Raymond Knopp's avatar
 
Raymond Knopp committed
136 137
  return(eNB_mac_inst[mod_idP].UE_list.pCC_id[ue_idP]);
}
138

139
//------------------------------------------------------------------------------
140
rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP)
141
//------------------------------------------------------------------------------
142
{
143

Raymond Knopp's avatar
 
Raymond Knopp committed
144
  rnti_t rnti = eNB_mac_inst[mod_idP].UE_list.UE_template[UE_PCCID(mod_idP,ue_idP)][ue_idP].rnti;
145

146
  if (rnti>0) {
Raymond Knopp's avatar
 
Raymond Knopp committed
147
    return (rnti);
148
  }
149

150
  LOG_D(MAC,"[eNB %d] Couldn't find RNTI for UE %d\n",mod_idP,ue_idP);
151 152
  //display_backtrace();
  return(NOT_A_RNTI);
153
}
Raymond Knopp's avatar
 
Raymond Knopp committed
154

155
//------------------------------------------------------------------------------
156
boolean_t is_UE_active(module_id_t mod_idP, int ue_idP)
157
//------------------------------------------------------------------------------
158
{
Raymond Knopp's avatar
 
Raymond Knopp committed
159
  return(eNB_mac_inst[mod_idP].UE_list.active[ue_idP]);
160
}
Raymond Knopp's avatar
 
Raymond Knopp committed
161 162 163

/*
uint8_t find_active_UEs(module_id_t module_idP,int CC_id){
164 165 166 167 168 169 170

  module_id_t        ue_mod_id      = 0;
  rnti_t        rnti         = 0;
  uint8_t            nb_active_ue = 0;

  for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) {

Raymond Knopp's avatar
 
Raymond Knopp committed
171
      if (((rnti=eNB_mac_inst[module_idP][CC_id].UE_template[ue_mod_id].rnti) !=0)&&(eNB_mac_inst[module_idP][CC_id].UE_template[ue_mod_id].ul_active==TRUE)){
172 173

          if (mac_xface->get_eNB_UE_stats(module_idP,rnti) != NULL){ // check at the phy enb_ue state for this rnti
174
      nb_active_ue++;
175 176
          }
          else { // this ue is removed at the phy => remove it at the mac as well
177
      mac_remove_ue(module_idP, CC_id, ue_mod_id);
178 179 180 181 182
          }
      }
  }
  return(nb_active_ue);
}
Raymond Knopp's avatar
 
Raymond Knopp committed
183
*/
184 185


186 187
// get aggregation (L) form phy for a give UE
unsigned char get_aggregation (uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt)
188
{
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
  unsigned char aggregation=3;
  
  switch (dci_fmt){
    
  case format0:
    aggregation = cqi2fmt0_agg[bw_index][cqi];
    break;
  case format1:
  case format1A:
  case format1B:
  case format1D:
    aggregation = cqi2fmt1x_agg[bw_index][cqi]; 
    break;
  case format2:
  case format2A:
  case format2B:
  case format2C:
  case format2D:
    aggregation = cqi2fmt2x_agg[bw_index][cqi]; 
    break;
  case format1C:
  case format1E_2A_M10PRB:
  case format3:
  case format3A:
  case format4:
  default:
    LOG_W(MAC,"unsupported DCI format %d\n",dci_fmt);
  }

   LOG_D(MAC,"Aggregation level %d (cqi %d, bw_index %d, format %d)\n", 
   	1<<aggregation, cqi,bw_index,dci_fmt);
   
221 222 223
  return aggregation;
}
#ifdef CBA
224
/*
Raymond Knopp's avatar
 
Raymond Knopp committed
225
uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, int CC_id,unsigned char group_id){
226 227 228 229 230 231

  module_id_t    UE_id;
  rnti_t    rnti;
  unsigned char nb_ue_in_pusch=0;
  LTE_eNB_UE_stats* eNB_UE_stats;

232
  for (UE_id=group_id;UE_id<NUMBER_OF_UE_MAX;UE_id+=eNB_mac_inst[module_idP].common_channels[CC_id].num_active_cba_groups) {
233

Raymond Knopp's avatar
 
Raymond Knopp committed
234 235
      if (((rnti=eNB_mac_inst[module_idP][CC_id].UE_template[UE_id].rnti) !=0) &&
          (eNB_mac_inst[module_idP][CC_id].UE_template[UE_id].ul_active==TRUE)    &&
236
          (mac_get_rrc_status(module_idP,1,UE_id) > RRC_CONNECTED)){
237 238 239 240 241 242 243
  //  && (UE_is_to_be_scheduled(module_idP,UE_id)))
  // check at the phy enb_ue state for this rnti
  if ((eNB_UE_stats= mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti)) != NULL){
    if ((eNB_UE_stats->mode == PUSCH) && (UE_is_to_be_scheduled(module_idP,UE_id) == 0)){
      nb_ue_in_pusch++;
    }
  }
244 245 246 247
      }
  }
  return(nb_ue_in_pusch);
}
248
*/
249
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
250

251 252
void dump_ue_list(UE_list_t *listP, int ul_flag)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
253
  int j;
254 255 256

  if ( ul_flag == 0 ) {
    for (j=listP->head; j>=0; j=listP->next[j]) {
257 258 259
      LOG_T(MAC,"node %d => %d\n",j,listP->next[j]);
    }
  } else {
260
    for (j=listP->head_ul; j>=0; j=listP->next_ul[j]) {
261 262
      LOG_T(MAC,"node %d => %d\n",j,listP->next_ul[j]);
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
263 264 265
  }
}

266 267
int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
268
  int UE_id;
269
  int i, j;
270

Raymond Knopp's avatar
 
Raymond Knopp committed
271
  UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
272

Raymond Knopp's avatar
 
Raymond Knopp committed
273
  LOG_D(MAC,"[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n",mod_idP,cc_idP,rntiP,UE_list->avail,UE_list->num_UEs);
274
  dump_ue_list(UE_list,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
275

276 277
  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
    if (UE_list->active[i] == TRUE) continue;
278
printf("MAC: new UE id %d rnti %x\n", i, rntiP);
279
    UE_id = i;
Raymond Knopp's avatar
 
Raymond Knopp committed
280 281 282 283 284 285 286
    UE_list->UE_template[cc_idP][UE_id].rnti       = rntiP;
    UE_list->UE_template[cc_idP][UE_id].configured = FALSE;
    UE_list->numactiveCCs[UE_id]                   = 1;
    UE_list->numactiveULCCs[UE_id]                 = 1;
    UE_list->pCC_id[UE_id]                         = cc_idP;
    UE_list->ordered_CCids[0][UE_id]               = cc_idP;
    UE_list->ordered_ULCCids[0][UE_id]             = cc_idP;
Raymond Knopp's avatar
 
Raymond Knopp committed
287
    UE_list->num_UEs++;
Raymond Knopp's avatar
 
Raymond Knopp committed
288
    UE_list->active[UE_id]                         = TRUE;
289
    memset((void*)&UE_list->UE_sched_ctrl[UE_id],0,sizeof(UE_sched_ctrl));
Raymond Knopp's avatar
 
Raymond Knopp committed
290

291 292
    for (j=0; j<8; j++) {
      UE_list->UE_template[cc_idP][UE_id].oldNDI[j]    = (j==0)?1:0;   // 1 because first transmission is with format1A (Msg4) for harq_pid 0
Raymond Knopp's avatar
 
Raymond Knopp committed
293
      UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = (j==harq_pidP)?0:1; // 1st transmission is with Msg3;
Raymond Knopp's avatar
 
Raymond Knopp committed
294
    }
295

296
    eNB_ulsch_info[mod_idP][cc_idP][UE_id].status = S_UL_WAITING;
297
    eNB_dlsch_info[mod_idP][cc_idP][UE_id].status = S_DL_WAITING;
Raymond Knopp's avatar
 
Raymond Knopp committed
298
    LOG_D(MAC,"[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n",mod_idP,UE_id,cc_idP,rntiP);
299
    dump_ue_list(UE_list,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
300
    return(UE_id);
301
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
302

303
printf("MAC: cannot add new UE for rnti %x\n", rntiP);
Raymond Knopp's avatar
 
Raymond Knopp committed
304
  LOG_E(MAC,"error in add_new_ue(), could not find space in UE_list, Dumping UE list\n");
305
  dump_ue_list(UE_list,0);
306 307 308
  return(-1);
}

309
//------------------------------------------------------------------------------
310
int rrc_mac_remove_ue(module_id_t mod_idP,rnti_t rntiP) 
311
//------------------------------------------------------------------------------
312
{
313
  int i;
Raymond Knopp's avatar
 
Raymond Knopp committed
314
  UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
315
  int UE_id = find_UE_id(mod_idP,rntiP);
316
  int pCC_id;
317

318
  if (UE_id == -1) {
319
printf("MAC: cannot remove UE rnti %x\n", rntiP);
320
    LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP);
321
    mac_phy_remove_ue(mod_idP, rntiP);
322 323 324
    return 0;
  }

325 326
  pCC_id = UE_PCCID(mod_idP,UE_id);

327
printf("MAC: remove UE %d rnti %x\n", UE_id, rntiP);
328
  LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",UE_id,pCC_id, rntiP);
329
  dump_ue_list(UE_list,0);
330

331 332 333
  UE_list->active[UE_id] = FALSE;
  UE_list->num_UEs--;

334
  // clear all remaining pending transmissions
335 336 337 338 339 340 341 342 343 344 345 346
  UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0]  = 0;
  UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1]  = 0;
  UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2]  = 0;
  UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3]  = 0;

  UE_list->UE_template[pCC_id][UE_id].ul_SR             = 0;
  UE_list->UE_template[pCC_id][UE_id].rnti              = NOT_A_RNTI;
  UE_list->UE_template[pCC_id][UE_id].ul_active         = FALSE;
  eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti                        = NOT_A_RNTI;
  eNB_ulsch_info[mod_idP][pCC_id][UE_id].status                      = S_UL_NONE;
  eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti                        = NOT_A_RNTI;
  eNB_dlsch_info[mod_idP][pCC_id][UE_id].status                      = S_DL_NONE;
Raymond Knopp's avatar
 
Raymond Knopp committed
347

348 349
  mac_phy_remove_ue(mod_idP,rntiP);

350 351 352 353
  // check if this has an RA process active
  RA_TEMPLATE *RA_template;
  for (i=0;i<NB_RA_PROC_MAX;i++) {
    RA_template = (RA_TEMPLATE *)&eNB_mac_inst[mod_idP].common_channels[pCC_id].RA_template[i];
354
    if (RA_template->rnti == rntiP){
355 356 357 358 359 360 361
      RA_template->RA_active=FALSE;
      RA_template->generate_rar=0;
      RA_template->generate_Msg4=0;
      RA_template->wait_ack_Msg4=0;
      RA_template->timing_offset=0;
      RA_template->RRC_timer=20;
      RA_template->rnti = 0;
362
      //break;
363 364
    }
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
365

366
  return 0;
367 368 369
}


Raymond Knopp's avatar
 
Raymond Knopp committed
370

371 372
int prev(UE_list_t *listP, int nodeP, int ul_flag)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
373
  int j;
374

375
  if (ul_flag == 0 ) {
376
    if (nodeP==listP->head) {
377
      return(nodeP);
378
    }
379 380

    for (j=listP->head; j>=0; j=listP->next[j]) {
381
      if (listP->next[j]==nodeP) {
382
        return(j);
383
    }
384
    }
385
  } else {
386
    if (nodeP==listP->head_ul) {
387
      return(nodeP);
388
    }
389 390

    for (j=listP->head_ul; j>=0; j=listP->next_ul[j]) {
391
      if (listP->next_ul[j]==nodeP) {
392
        return(j);
393
      }
394
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
395
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
396

397
  LOG_E(MAC,"error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n",
398
        nodeP, (ul_flag == 0)? "DL" : "UL");
399
  dump_ue_list(listP, ul_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
400 401


Raymond Knopp's avatar
 
Raymond Knopp committed
402 403
  return(-1);
}
404

405 406
void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP, int ul_flag)
{
407

Raymond Knopp's avatar
 
Raymond Knopp committed
408 409
  int prev_i,prev_j,next_i,next_j;

410 411
  LOG_T(MAC,"Swapping UE %d,%d\n",nodeiP,nodejP);
  dump_ue_list(listP,ul_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
412

413 414
  prev_i = prev(listP,nodeiP,ul_flag);
  prev_j = prev(listP,nodejP,ul_flag);
415

416
  if ((prev_i<0) || (prev_j<0)) {
417
    mac_xface->macphy_exit("swap_UEs: problem");
418 419
    return; // not reached
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
420

421
  if (ul_flag == 0) {
422 423 424 425 426
    next_i = listP->next[nodeiP];
    next_j = listP->next[nodejP];
  } else {
    next_i = listP->next_ul[nodeiP];
    next_j = listP->next_ul[nodejP];
Raymond Knopp's avatar
 
Raymond Knopp committed
427
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
428

429
  LOG_T(MAC,"[%s] next_i %d, next_i, next_j %d, head %d \n",
430 431
        (ul_flag == 0)? "DL" : "UL",
        next_i,next_j,listP->head);
432 433

  if (ul_flag == 0 ) {
Raymond Knopp's avatar
 
Raymond Knopp committed
434

435 436
    if (next_i == nodejP) {   // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...
      LOG_T(MAC,"Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n");
437

438 439
      listP->next[nodeiP] = next_j;
      listP->next[nodejP] = nodeiP;
440

441
      if (nodeiP==listP->head) { // case i j n(j)
442
        listP->head = nodejP;
443
      } else {
444
        listP->next[prev_i] = nodejP;
445
      }
446
    } else if (next_j == nodeiP) {  // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
447 448 449
      LOG_T(MAC,"Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n");
      listP->next[nodejP] = next_i;
      listP->next[nodeiP] = nodejP;
450

451
      if (nodejP==listP->head) { // case j i n(i)
452
        listP->head = nodeiP;
453
      } else {
454
        listP->next[prev_j] = nodeiP;
455
      }
456
    } else {  // case ...  p(i) i n(i) ... p(j) j n(j) ...
457 458
      listP->next[nodejP] = next_i;
      listP->next[nodeiP] = next_j;
459 460


461
      if (nodeiP==listP->head) {
462 463 464 465 466 467 468 469 470 471
        LOG_T(MAC,"changing head to %d\n",nodejP);
        listP->head=nodejP;
        listP->next[prev_j] = nodeiP;
      } else if (nodejP==listP->head) {
        LOG_D(MAC,"changing head to %d\n",nodeiP);
        listP->head=nodeiP;
        listP->next[prev_i] = nodejP;
      } else {
        listP->next[prev_i] = nodejP;
        listP->next[prev_j] = nodeiP;
472 473 474 475 476 477
      }
    }
  } else { // ul_flag

    if (next_i == nodejP) {   // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...
      LOG_T(MAC,"[UL] Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n");
478

479 480
      listP->next_ul[nodeiP] = next_j;
      listP->next_ul[nodejP] = nodeiP;
481

482
      if (nodeiP==listP->head_ul) { // case i j n(j)
483
        listP->head_ul = nodejP;
484
      } else {
485
        listP->next_ul[prev_i] = nodejP;
486
      }
487
    } else if (next_j == nodeiP) {  // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
488 489 490
      LOG_T(MAC,"[UL]Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n");
      listP->next_ul[nodejP] = next_i;
      listP->next_ul[nodeiP] = nodejP;
491

492
      if (nodejP==listP->head_ul) { // case j i n(i)
493
        listP->head_ul = nodeiP;
494
      } else {
495
        listP->next_ul[prev_j] = nodeiP;
496
      }
497 498
    } else {  // case ...  p(i) i n(i) ... p(j) j n(j) ...

499 500
      listP->next_ul[nodejP] = next_i;
      listP->next_ul[nodeiP] = next_j;
501 502


503
      if (nodeiP==listP->head_ul) {
504 505 506 507 508 509 510 511 512 513
        LOG_T(MAC,"[UL]changing head to %d\n",nodejP);
        listP->head_ul=nodejP;
        listP->next_ul[prev_j] = nodeiP;
      } else if (nodejP==listP->head_ul) {
        LOG_T(MAC,"[UL]changing head to %d\n",nodeiP);
        listP->head_ul=nodeiP;
        listP->next_ul[prev_i] = nodejP;
      } else {
        listP->next_ul[prev_i] = nodejP;
        listP->next_ul[prev_j] = nodeiP;
514
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
515 516
    }
  }
517

518 519
  LOG_T(MAC,"After swap\n");
  dump_ue_list(listP,ul_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
520 521 522 523
}



524

525 526 527 528 529




/*
Cedric Roux's avatar
Cedric Roux committed
530
  #if defined(Rel10) || defined(Rel14)
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
  unsigned char generate_mch_header( unsigned char *mac_header,
  unsigned char num_sdus,
  unsigned short *sdu_lengths,
  unsigned char *sdu_lcids,
  unsigned char msi,
  unsigned char short_padding,
  unsigned short post_padding) {

  SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *)mac_header;
  uint8_t first_element=0,last_size=0,i;
  uint8_t mac_header_control_elements[2*num_sdus],*ce_ptr;

  ce_ptr = &mac_header_control_elements[0];

  if ((short_padding == 1) || (short_padding == 2)) {
  mac_header_ptr->R    = 0;
  mac_header_ptr->E    = 0;
  mac_header_ptr->LCID = SHORT_PADDING;
  first_element=1;
  last_size=1;
  }
  if (short_padding == 2) {
  mac_header_ptr->E = 1;
  mac_header_ptr++;
  mac_header_ptr->R = 0;
  mac_header_ptr->E    = 0;
  mac_header_ptr->LCID = SHORT_PADDING;
  last_size=1;
  }

  // SUBHEADER for MSI CE
  if (msi != 0) {// there is MSI MAC Control Element
  if (first_element>0) {
  mac_header_ptr->E = 1;
  mac_header_ptr+=last_size;
  }
  else {
  first_element = 1;
  }
  if (num_sdus*2 < 128) {
  ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R    = 0;
  ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E    = 0;
  ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F    = 0;
  ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = MCH_SCHDL_INFO;
  ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L    = num_sdus*2;
  last_size=2;
  }
  else {
  ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R    = 0;
  ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E    = 0;
  ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F    = 1;
  ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = MCH_SCHDL_INFO;
  ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L    = (num_sdus*2)&0x7fff;
  last_size=3;
  }
  // Create the MSI MAC Control Element here
  }

  // SUBHEADER for MAC SDU (MCCH+MTCHs)
  for (i=0;i<num_sdus;i++) {
  if (first_element>0) {
  mac_header_ptr->E = 1;
  mac_header_ptr+=last_size;
  }
  else {
  first_element = 1;
  }
  if (sdu_lengths[i] < 128) {
  ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R    = 0;
  ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E    = 0;
  ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F    = 0;
  ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i];
  ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L    = (unsigned char)sdu_lengths[i];
  last_size=2;
  }
  else {
  ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R    = 0;
  ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E    = 0;
  ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F    = 1;
  ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i];
  ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L    = (unsigned short) sdu_lengths[i]&0x7fff;
  last_size=3;
  }
  }

  if (post_padding>0) {// we have lots of padding at the end of the packet
  mac_header_ptr->E = 1;
  mac_header_ptr+=last_size;
  // add a padding element
  mac_header_ptr->R    = 0;
  mac_header_ptr->E    = 0;
  mac_header_ptr->LCID = SHORT_PADDING;
  mac_header_ptr++;
  }
  else { // no end of packet padding
  // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE)
  mac_header_ptr++;
  }

  // Copy MSI Control Element to the end of the MAC Header if it presents
  if ((ce_ptr-mac_header_control_elements) > 0) {
  // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements);
  memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements);
  mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements);
  }

  return((unsigned char*)mac_header_ptr - mac_header);
  }
  #endif
 */
void add_common_dci(DCI_PDU *DCI_pdu,
642 643 644 645 646 647 648 649
                    void *pdu,
                    rnti_t rnti,
                    unsigned char dci_size_bytes,
                    unsigned char aggregation,
                    unsigned char dci_size_bits,
                    unsigned char dci_fmt,
                    uint8_t ra_flag)
{
650
  if (DCI_pdu->Num_dci == NUM_DCI_MAX) { printf("%s: DCI FULL, fatal!\n", __FUNCTION__); abort(); }
651

652 653 654 655 656 657 658
  memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_pdu[0],pdu,dci_size_bytes);
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_length   = dci_size_bits;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].L            = aggregation;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].rnti         = rnti;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].format       = dci_fmt;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].ra_flag      = ra_flag;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].search_space = DCI_COMMON_SPACE;
659 660


661
  DCI_pdu->Num_dci++;
662
  LOG_D(MAC,"add common dci format %d for rnti %x \n",dci_fmt,rnti);
663 664
}

665 666
void add_ue_spec_dci(DCI_PDU *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size_bytes,unsigned char aggregation,unsigned char dci_size_bits,unsigned char dci_fmt,uint8_t ra_flag)
{
667
  if (DCI_pdu->Num_dci == NUM_DCI_MAX) { printf("%s: DCI FULL, fatal!\n", __FUNCTION__); abort(); }
668

669 670 671 672 673 674 675
  memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_pdu[0],pdu,dci_size_bytes);
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_length   = dci_size_bits;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].L            = aggregation;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].rnti         = rnti;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].format       = dci_fmt;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].ra_flag      = ra_flag;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].search_space = DCI_UE_SPACE;
676

677
  DCI_pdu->Num_dci++;
678

679
  LOG_D(MAC,"add ue specific dci format %d for rnti %x \n",dci_fmt,rnti);
680 681 682 683 684 685 686
}





// This has to be updated to include BSR information
687 688
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id)
{
689

690 691
  UE_TEMPLATE *UE_template    = &eNB_mac_inst[module_idP].UE_list.UE_template[CC_id][UE_id];
  UE_sched_ctrl *UE_sched_ctl = &eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[UE_id];
692

693

kaltenbe's avatar
kaltenbe committed
694 695 696 697 698 699
  // do not schedule UE if UL is not working
  if (UE_sched_ctl->ul_failure_timer>0)
    return(0);
  if (UE_sched_ctl->ul_out_of_sync>0)
    return(0);

700 701
  LOG_D(MAC,"[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id));

Raymond Knopp's avatar
 
Raymond Knopp committed
702 703 704 705
  if ((UE_template->bsr_info[LCGID0]>0) ||
      (UE_template->bsr_info[LCGID1]>0) ||
      (UE_template->bsr_info[LCGID2]>0) ||
      (UE_template->bsr_info[LCGID3]>0) ||
gauthier's avatar
gauthier committed
706
      (UE_template->ul_SR>0) || // uplink scheduling request
707
      ((UE_sched_ctl->ul_inactivity_timer>20)&&
708 709 710 711 712
       (UE_sched_ctl->ul_scheduled==0))||  // every 2 frames when RRC_CONNECTED
      ((UE_sched_ctl->ul_inactivity_timer>10)&&
       (UE_sched_ctl->ul_scheduled==0)&&
       (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) // every Frame when not RRC_CONNECTED
    { 
713

714
    LOG_D(MAC,"[eNB %d][PUSCH] UE %d/%x should be scheduled\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id));
715
    return(1);
716
  } else {
717
    return(0);
718
  }
719 720 721 722 723
}




724 725
uint32_t allocate_prbs(int UE_id,unsigned char nb_rb, uint32_t *rballoc)
{
726 727 728 729 730

  int i;
  uint32_t rballoc_dci=0;
  unsigned char nb_rb_alloc=0;

731
  for (i=0; i<(mac_xface->frame_parms->N_RB_DL-2); i+=2) {
732 733 734 735 736 737
    if (((*rballoc>>i)&3)==0) {
      *rballoc |= (3<<i);
      rballoc_dci |= (1<<((12-i)>>1));
      nb_rb_alloc+=2;
    }

738
    if (nb_rb_alloc==nb_rb) {
739
      return(rballoc_dci);
740
    }
741 742
  }

743 744 745 746
  if ((mac_xface->frame_parms->N_RB_DL&1)==1) {
    if ((*rballoc>>(mac_xface->frame_parms->N_RB_DL-1)&1)==0) {
      *rballoc |= (1<<(mac_xface->frame_parms->N_RB_DL-1));
      rballoc_dci |= 1;//(1<<(mac_xface->frame_parms->N_RB_DL>>1));
747
    }
748
  }
749

750 751 752
  return(rballoc_dci);
}

753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777
int get_bw_index(module_id_t module_id, uint8_t CC_id)
{

  int bw_index=0;
  LTE_DL_FRAME_PARMS* frame_parms = mac_xface->get_lte_frame_parms(module_id,CC_id);

  switch (frame_parms->N_RB_DL) {
  case 6: // 1.4 MHz
    bw_index=0;
    break;

  case 25: // 5HMz
    bw_index=1;
    break;

  case 50: // 10HMz
    bw_index=2;
    break;

  case 100: // 20HMz
    bw_index=3;
    break;

  default:
    bw_index=1;
778
    LOG_W(MAC,"[eNB %d] N_DL_RB %d unknown for CC_id %d, setting bw_index to 1\n", module_id, frame_parms->N_RB_DL, CC_id);
779 780 781 782 783 784
    break;
  }

  return bw_index;
}

785 786 787
int get_min_rb_unit(module_id_t module_id, uint8_t CC_id)
{

788
  int min_rb_unit=0;
789 790
  LTE_DL_FRAME_PARMS* frame_parms = mac_xface->get_lte_frame_parms(module_id,CC_id);

791 792 793 794
  switch (frame_parms->N_RB_DL) {
  case 6: // 1.4 MHz
    min_rb_unit=1;
    break;
795

796 797 798
  case 25: // 5HMz
    min_rb_unit=2;
    break;
799

800 801 802
  case 50: // 10HMz
    min_rb_unit=3;
    break;
803

804 805 806
  case 100: // 20HMz
    min_rb_unit=4;
    break;
807

808 809
  default:
    min_rb_unit=2;
Cedric Roux's avatar
Cedric Roux committed
810 811
    LOG_W(MAC,"[eNB %d] N_DL_RB %d unknown for CC_id %d, setting min_rb_unit to 2\n",
          module_id, frame_parms->N_RB_DL, CC_id);
812 813
    break;
  }
814

815 816
  return min_rb_unit;
}
817

818 819
uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc)
{
820 821 822 823 824

  int check=0;//check1=0,check2=0;
  uint32_t rballoc_dci=0;
  //uint8_t number_of_subbands=13;

825
  LOG_T(MAC,"*****Check1RBALLOC****: %d%d%d%d (nb_rb %d,N_RBG %d)\n",
826
        rballoc[3],rballoc[2],rballoc[1],rballoc[0],nb_rb,mac_xface->frame_parms->N_RBG);
827

828
  while((nb_rb >0) && (check < mac_xface->frame_parms->N_RBG)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
829
    //printf("rballoc[%d] %d\n",check,rballoc[check]);
830
    if(rballoc[check] == 1) {
831
      rballoc_dci |= (1<<((mac_xface->frame_parms->N_RBG-1)-check));
832

833
      switch (mac_xface->frame_parms->N_RB_DL) {
834 835 836 837 838
      case 6:
        nb_rb--;
        break;

      case 25:
839
        if ((check == mac_xface->frame_parms->N_RBG-1)) {
840
          nb_rb--;
841
        } else {
842
          nb_rb-=2;
843
        }
844 845 846 847

        break;

      case 50:
848
        if ((check == mac_xface->frame_parms->N_RBG-1)) {
849
          nb_rb-=2;
850
        } else {
851
          nb_rb-=3;
852
        }
853 854 855 856 857 858

        break;

      case 100:
        nb_rb-=4;
        break;
859
      }
860 861 862 863 864
    }

    //      printf("rb_alloc %x\n",rballoc_dci);
    check = check+1;
    //    check1 = check1+2;
865
  }
866

867 868 869 870 871 872 873
  // rballoc_dci = (rballoc_dci)&(0x1fff);
  LOG_T(MAC,"*********RBALLOC : %x\n",rballoc_dci);
  // exit(-1);
  return (rballoc_dci);
}


874 875 876
int get_nb_subband(void)
{

877 878
  int nb_sb=0;

879
  switch (mac_xface->frame_parms->N_RB_DL) {
880
  case 6:
881
    nb_sb=0;
882
    break;
883

884 885
  case 15:
    nb_sb = 4;  // sb_size =4
886 887

  case 25:
888 889
    nb_sb = 7; // sb_size =4, 1 sb with 1PRB, 6 with 2 RBG, each has 2 PRBs
    break;
890

891 892 893
  case 50:    // sb_size =6
    nb_sb = 9;
    break;
894

895 896 897
  case 75:  // sb_size =8
    nb_sb = 10;
    break;
898

899 900 901
  case 100: // sb_size =8 , 1 sb with 1 RBG + 12 sb with 2RBG, each RBG has 4 PRBs
    nb_sb = 13;
    break;
902

903 904 905 906
  default:
    nb_sb=0;
    break;
  }
907

908
  return nb_sb;
909 910

}
911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937

void init_CCE_table(int module_idP,int CC_idP)
{
  memset(eNB_mac_inst[module_idP].CCE_table[CC_idP],0,800*sizeof(int));
} 


int get_nCCE_offset(int *CCE_table,
		    const unsigned char L, 
		    const int nCCE, 
		    const int common_dci, 
		    const unsigned short rnti, 
		    const unsigned char subframe)
{

  int search_space_free,m,nb_candidates = 0,l,i;
  unsigned int Yk;
   /*
    printf("CCE Allocation: ");
    for (i=0;i<nCCE;i++)
    printf("%d.",CCE_table[i]);
    printf("\n");
  */
  if (common_dci == 1) {
    // check CCE(0 ... L-1)
    nb_candidates = (L==4) ? 4 : 2;
    nb_candidates = min(nb_candidates,nCCE/L);
Raymond Knopp's avatar
Raymond Knopp committed
938

939
    //    printf("Common DCI nb_candidates %d, L %d\n",nb_candidates,L);
Raymond Knopp's avatar
Raymond Knopp committed
940

941 942 943 944
    for (m = nb_candidates-1 ; m >=0 ; m--) {

      search_space_free = 1;
      for (l=0; l<L; l++) {
Raymond Knopp's avatar
Raymond Knopp committed
945

946
	//	printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]);
947 948 949 950 951 952 953
        if (CCE_table[(m*L) + l] == 1) {
          search_space_free = 0;
          break;
        }
      }
     
      if (search_space_free == 1) {
Raymond Knopp's avatar
Raymond Knopp committed
954

955
	//	printf("returning %d\n",m*L);
Raymond Knopp's avatar
Raymond Knopp committed
956

957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991
        for (l=0; l<L; l++)
          CCE_table[(m*L)+l]=1;
        return(m*L);
      }
    }

    return(-1);

  } else { // Find first available in ue specific search space
    // according to procedure in Section 9.1.1 of 36.213 (v. 8.6)
    // compute Yk
    Yk = (unsigned int)rnti;

    for (i=0; i<=subframe; i++)
      Yk = (Yk*39827)%65537;

    Yk = Yk % (nCCE/L);


    switch (L) {
    case 1:
    case 2:
      nb_candidates = 6;
      break;

    case 4:
    case 8:
      nb_candidates = 2;
      break;

    default:
      DevParam(L, nCCE, rnti);
      break;
    }

Raymond Knopp's avatar
Raymond Knopp committed
992

993
    LOG_D(MAC,"rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n",rnti,Yk,nCCE,nCCE/L,nb_candidates);
994 995 996 997 998

    for (m = 0 ; m < nb_candidates ; m++) {
      search_space_free = 1;

      for (l=0; l<L; l++) {
Cedric Roux's avatar
Cedric Roux committed
999 1000
        int cce = (((Yk+m)%(nCCE/L))*L) + l;
        if (cce >= nCCE || CCE_table[cce] == 1) {
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
          search_space_free = 0;
          break;
        }
      }

      if (search_space_free == 1) {
        for (l=0; l<L; l++)
          CCE_table[(((Yk+m)%(nCCE/L))*L)+l]=1;

        return(((Yk+m)%(nCCE/L))*L);
      }
    }

    return(-1);
  }
}

1018 1019 1020 1021 1022
void dump_CCE_table(int *CCE_table,const int nCCE,const unsigned short rnti,const int subframe,int L) {

  int nb_candidates = 0,i;
  unsigned int Yk;
  
1023
  printf("CCE 0: ");
1024 1025
  for (i=0;i<nCCE;i++) {
    printf("%1d.",CCE_table[i]);
1026
    if ((i&7) == 7)
Raymond Knopp's avatar
Raymond Knopp committed
1027
      printf("\n CCE %d: ",i);
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
  }

  Yk = (unsigned int)rnti;
  
  for (i=0; i<=subframe; i++)
    Yk = (Yk*39827)%65537;
  
  Yk = Yk % (nCCE/L);
  
  
  switch (L) {
  case 1:
  case 2:
    nb_candidates = 6;
    break;
    
  case 4:
  case 8:
    nb_candidates = 2;
    break;
    
  default:
    DevParam(L, nCCE, rnti);
    break;
  }
  
  
  printf("rnti %x, Yk*L = %d, nCCE %d (nCCE/L %d),nb_cand*L %d\n",rnti,Yk*L,nCCE,nCCE/L,nb_candidates*L);

}

1059 1060 1061 1062 1063 1064 1065 1066 1067
// Allocate the CCEs
int allocate_CCEs(int module_idP,
		  int CC_idP,
		  int subframeP,
		  int test_onlyP) {


  int *CCE_table = eNB_mac_inst[module_idP].CCE_table[CC_idP];
  DCI_PDU *DCI_pdu = &eNB_mac_inst[module_idP].common_channels[CC_idP].DCI_pdu;
Raymond Knopp's avatar
Raymond Knopp committed
1068
  int nCCE_max = mac_xface->get_nCCE_max(module_idP,CC_idP,1,subframeP);
1069
  int fCCE;
1070
  int i,j;
1071
  DCI_ALLOC_t *dci_alloc;
Raymond Knopp's avatar
Raymond Knopp committed
1072
  int nCCE=0;
1073

1074
  LOG_D(MAC,"Allocate CCEs subframe %d, test %d : (Num_dci %d)\n",subframeP,test_onlyP,DCI_pdu->Num_dci);
Raymond Knopp's avatar
Raymond Knopp committed
1075
  DCI_pdu->num_pdcch_symbols=1;
Raymond Knopp's avatar
Raymond Knopp committed
1076

1077 1078 1079 1080
try_again:
  init_CCE_table(module_idP,CC_idP);
  nCCE=0;

1081
  for (i=0;i<DCI_pdu->Num_dci;i++) {
1082
    dci_alloc = &DCI_pdu->dci_alloc[i];
1083 1084
    LOG_D(MAC,"Trying to allocate DCI %d/%d : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
          i,DCI_pdu->Num_dci,
1085 1086 1087
          dci_alloc->rnti,1<<dci_alloc->L,
          nCCE,nCCE_max,DCI_pdu->num_pdcch_symbols);

1088 1089
    if (nCCE + (1<<dci_alloc->L) > nCCE_max)
      goto failed;
1090 1091 1092 1093 1094

    // number of CCEs left can potentially hold this allocation
    fCCE = get_nCCE_offset(CCE_table,
                           1<<(dci_alloc->L),
                           nCCE_max,
1095
                           dci_alloc->search_space == DCI_COMMON_SPACE ? 1 : 0,
1096 1097 1098
                           dci_alloc->rnti,
                           subframeP);
    if (fCCE == -1) {
1099
failed:
1100
      if (DCI_pdu->num_pdcch_symbols == 3) {
1101 1102
        LOG_I(MAC,"subframe %d: Dropping Allocation for RNTI %x (DCI %d/%d)\n",
              subframeP,dci_alloc->rnti,
1103
              i, DCI_pdu->Num_dci);
1104
        for (j=0;j<=i;j++){
1105 1106
          LOG_I(MAC,"DCI %d/%d : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
                j,DCI_pdu->Num_dci,
1107 1108 1109 1110
                DCI_pdu->dci_alloc[j].rnti,DCI_pdu->dci_alloc[j].format,
                1<<DCI_pdu->dci_alloc[j].L,
                nCCE,nCCE_max,DCI_pdu->num_pdcch_symbols);
        }
1111
	//dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L);
1112
        goto fatal;
1113
      }
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126
      DCI_pdu->num_pdcch_symbols++;
      nCCE_max = mac_xface->get_nCCE_max(module_idP,CC_idP,DCI_pdu->num_pdcch_symbols,subframeP);
      goto try_again;
    } // fCCE==-1

    // the allocation is feasible, rnti rule passes
    nCCE += (1<<dci_alloc->L);
    LOG_D(MAC,"Allocating at nCCE %d\n",fCCE);
    if (test_onlyP == 0) {
      dci_alloc->firstCCE=fCCE;
      LOG_D(MAC,"Allocate CCEs subframe %d, test %d\n",subframeP,test_onlyP);
    }
  } // for i = 0 ... num_dcis
1127

1128
  return 0;
1129

1130
fatal:
1131
  return -1;
1132 1133 1134
}

boolean_t CCE_allocation_infeasible(int module_idP,
1135 1136 1137 1138 1139 1140
                                    int CC_idP,
                                    int common_flag,
                                    int subframe,
                                    int aggregation,
                                    int rnti)
{
1141
  DCI_PDU *DCI_pdu = &eNB_mac_inst[module_idP].common_channels[CC_idP].DCI_pdu;
1142
  //DCI_ALLOC_t *dci_alloc;
1143 1144 1145
  int ret;
  boolean_t res=FALSE;

1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157
  if (DCI_pdu->Num_dci == NUM_DCI_MAX) return TRUE;

  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].rnti = rnti;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].L = aggregation;
  DCI_pdu->dci_alloc[DCI_pdu->Num_dci].search_space = common_flag == 1 ? DCI_COMMON_SPACE : DCI_UE_SPACE;
  DCI_pdu->Num_dci++;
  ret = allocate_CCEs(module_idP,CC_idP,subframe,1);
  if (ret==-1)
    res = TRUE;
  DCI_pdu->Num_dci--;

  return res;
1158 1159
}

1160 1161
void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP)
{
Cedric Roux's avatar
Cedric Roux committed
1162
  T(T_ENB_MAC_SCHEDULING_REQUEST, T_INT(mod_idP), T_INT(cc_idP), T_INT(frameP), T_INT(subframeP), T_INT(rntiP));
1163 1164 1165 1166 1167
 
  int UE_id = find_UE_id(mod_idP, rntiP);
  UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
 
  if (UE_id  != -1) {
1168 1169
    if (mac_eNB_get_rrc_status(mod_idP,UE_RNTI(mod_idP,UE_id)) < RRC_CONNECTED)
      LOG_I(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
1170 1171
    UE_list->UE_template[cc_idP][UE_id].ul_SR = 1;
    UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE;
1172 1173
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION,1);
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION,0);
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187
  } else {
    //     AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP);
    //    AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP);
    LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
  }
}

void UL_failure_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP)
{

  int UE_id = find_UE_id(mod_idP, rntiP);
  UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;

  if (UE_id  != -1) {
1188 1189
    LOG_I(MAC,"[eNB %d][UE %d/%x] Frame %d subframeP %d Signaling UL Failure for UE %d on CC_id %d (timer %d)\n",
	  mod_idP,UE_id,rntiP,frameP,subframeP, UE_id,cc_idP,
kaltenbe's avatar
kaltenbe committed
1190 1191 1192
	  UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
    if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0)
      UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=1;
1193 1194 1195 1196 1197 1198
  } else {
    //     AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP);
    //    AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP);
    LOG_W(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling UL Failure for UE %d (unknown UEid) on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
  }
}