eNB_scheduler_primitives.c 34.6 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 30 31

*******************************************************************************/

/*! \file eNB_scheduler_primitives.c
 * \brief primitives used by eNB for BCH, RACH, ULSCH, DLSCH scheduling
32 33 34
 * \author  Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \email: navid.nikaein@eurecom.fr
35
 * \version 1.0
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
 * @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

#define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1


71
//------------------------------------------------------------------------------
72
void init_ue_sched_info(void)
73
//------------------------------------------------------------------------------
74
{
75
  module_id_t i,j,k;
76 77

  for (i=0; i<NUMBER_OF_eNB_MAX; i++) {
Cedric Roux's avatar
Cedric Roux committed
78
    for (k=0; k<MAX_NUM_CCs; k++) {
79 80 81 82 83 84 85 86 87 88
      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;
89
      }
90
    }
91 92 93 94 95
  }
}



96
//------------------------------------------------------------------------------
97
unsigned char get_ue_weight(module_id_t module_idP, int CC_id, int ue_idP)
98
//------------------------------------------------------------------------------
99
{
100

101
  return(eNB_dlsch_info[module_idP][CC_id][ue_idP].weight);
102 103 104

}

105
//------------------------------------------------------------------------------
106
DCI_PDU *get_dci_sdu(module_id_t module_idP, int CC_id,frame_t frameP, sub_frame_t subframeP)
107
//------------------------------------------------------------------------------
108
{
109

knopp's avatar
knopp committed
110
  return(&eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu);
111 112 113

}

114
//------------------------------------------------------------------------------
115
int find_UE_id(module_id_t mod_idP, rnti_t rntiP)
116
//------------------------------------------------------------------------------
117
{
118

knopp's avatar
knopp committed
119 120
  int UE_id;
  UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
121 122

  for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
knopp's avatar
knopp committed
123 124 125
    if (UE_list->UE_template[UE_PCCID(mod_idP,UE_id)][UE_id].rnti==rntiP) {
      return(UE_id);
    }
126
  }
127

knopp's avatar
knopp committed
128
  return(-1);
129 130 131

}

132
//------------------------------------------------------------------------------
133
int UE_num_active_CC(UE_list_t *listP,int ue_idP)
134
//------------------------------------------------------------------------------
135
{
knopp's avatar
knopp committed
136 137
  return(listP->numactiveCCs[ue_idP]);
}
138

139
//------------------------------------------------------------------------------
140
int UE_PCCID(module_id_t mod_idP,int ue_idP)
141
//------------------------------------------------------------------------------
142
{
knopp's avatar
knopp committed
143 144
  return(eNB_mac_inst[mod_idP].UE_list.pCC_id[ue_idP]);
}
145

146
//------------------------------------------------------------------------------
147
rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP)
148
//------------------------------------------------------------------------------
149
{
150

knopp's avatar
knopp committed
151
  rnti_t rnti = eNB_mac_inst[mod_idP].UE_list.UE_template[UE_PCCID(mod_idP,ue_idP)][ue_idP].rnti;
152

153
  if (rnti>0) {
knopp's avatar
knopp committed
154
    return (rnti);
155
  }
156

157 158 159
  LOG_E(MAC,"[eNB %d] Couldn't find RNTI for UE %d\n",mod_idP,ue_idP);
  //display_backtrace();
  return(NOT_A_RNTI);
160
}
knopp's avatar
knopp committed
161

162
//------------------------------------------------------------------------------
163
boolean_t is_UE_active(module_id_t mod_idP, int ue_idP)
164
//------------------------------------------------------------------------------
165
{
knopp's avatar
knopp committed
166
  return(eNB_mac_inst[mod_idP].UE_list.active[ue_idP]);
167
}
knopp's avatar
knopp committed
168 169 170

/*
uint8_t find_active_UEs(module_id_t module_idP,int CC_id){
171 172 173 174 175 176 177

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

knopp's avatar
knopp committed
178
      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)){
179 180

          if (mac_xface->get_eNB_UE_stats(module_idP,rnti) != NULL){ // check at the phy enb_ue state for this rnti
181
      nb_active_ue++;
182 183
          }
          else { // this ue is removed at the phy => remove it at the mac as well
184
      mac_remove_ue(module_idP, CC_id, ue_mod_id);
185 186 187 188 189
          }
      }
  }
  return(nb_active_ue);
}
knopp's avatar
knopp committed
190
*/
191 192 193


// get aggregatiob form phy for a give UE
194 195
unsigned char process_ue_cqi (module_id_t module_idP, int ue_idP)
{
196
  unsigned char aggregation=1;
197 198 199 200
  // check the MCS and SNR and set the aggregation accordingly
  return aggregation;
}
#ifdef CBA
201
/*
knopp's avatar
knopp committed
202
uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, int CC_id,unsigned char group_id){
203 204 205 206 207 208

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

209
  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) {
210

knopp's avatar
knopp committed
211 212
      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)    &&
213
          (mac_get_rrc_status(module_idP,1,UE_id) > RRC_CONNECTED)){
214 215 216 217 218 219 220
  //  && (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++;
    }
  }
221 222 223 224
      }
  }
  return(nb_ue_in_pusch);
}
225
*/
226
#endif
knopp's avatar
knopp committed
227

228 229
void dump_ue_list(UE_list_t *listP, int ul_flag)
{
knopp's avatar
knopp committed
230
  int j;
231 232 233

  if ( ul_flag == 0 ) {
    for (j=listP->head; j>=0; j=listP->next[j]) {
234 235 236
      LOG_T(MAC,"node %d => %d\n",j,listP->next[j]);
    }
  } else {
237
    for (j=listP->head_ul; j>=0; j=listP->next_ul[j]) {
238 239
      LOG_T(MAC,"node %d => %d\n",j,listP->next_ul[j]);
    }
knopp's avatar
knopp committed
240 241 242
  }
}

243 244
int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP,int harq_pidP)
{
knopp's avatar
knopp committed
245 246
  int UE_id;
  int j;
247

knopp's avatar
knopp committed
248
  UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
249

knopp's avatar
knopp committed
250
  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);
251
  dump_ue_list(UE_list,0);
knopp's avatar
knopp committed
252 253 254

  if (UE_list->avail>=0) {
    UE_id = UE_list->avail;
255
    AssertFatal( UE_id < NUMBER_OF_UE_MAX, "BAD UE_id %u > NUMBER_OF_UE_MAX",UE_id );
knopp's avatar
knopp committed
256 257
    UE_list->avail = UE_list->next[UE_list->avail];
    UE_list->next[UE_id] = UE_list->head;
258
    UE_list->next_ul[UE_id] = UE_list->head_ul;
knopp's avatar
knopp committed
259
    UE_list->head = UE_id;
260
    UE_list->head_ul = UE_id;
knopp's avatar
knopp committed
261 262 263 264 265 266 267
    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;
knopp's avatar
knopp committed
268
    UE_list->num_UEs++;
knopp's avatar
knopp committed
269
    UE_list->active[UE_id]                         = TRUE;
270
    memset((void*)&UE_list->UE_sched_ctrl[UE_id],0,sizeof(UE_sched_ctrl));
knopp's avatar
knopp committed
271

272 273
    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
knopp's avatar
knopp committed
274
      UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = (j==harq_pidP)?0:1; // 1st transmission is with Msg3;
knopp's avatar
knopp committed
275
    }
276

277
    eNB_ulsch_info[mod_idP][cc_idP][UE_id].status = S_UL_WAITING;
278
    eNB_dlsch_info[mod_idP][cc_idP][UE_id].status = S_DL_WAITING;
knopp's avatar
knopp committed
279
    LOG_D(MAC,"[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n",mod_idP,UE_id,cc_idP,rntiP);
280
    dump_ue_list(UE_list,0);
knopp's avatar
knopp committed
281
    return(UE_id);
282
  }
knopp's avatar
knopp committed
283 284

  LOG_E(MAC,"error in add_new_ue(), could not find space in UE_list, Dumping UE list\n");
285
  dump_ue_list(UE_list,0);
286 287 288
  return(-1);
}

289
//------------------------------------------------------------------------------
290
int rrc_mac_remove_ue(module_id_t mod_idP,rnti_t rntiP) 
291
//------------------------------------------------------------------------------
292
{
knopp's avatar
knopp committed
293

294
  int prev,i, ret=-1;
knopp's avatar
knopp committed
295

296

knopp's avatar
knopp committed
297
  UE_list_t *UE_list = &eNB_mac_inst[mod_idP].UE_list;
298 299
  int UE_id = find_UE_id(mod_idP,rntiP);
  int pCC_id = UE_PCCID(mod_idP,UE_id);
300

301 302 303 304 305 306
  if (UE_id == -1) {
    LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP);
    mac_phy_remove_ue(mod_idP,rntiP);
    return 0;
  }

307
  LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",UE_id,pCC_id, rntiP);
308
  dump_ue_list(UE_list,0);
309 310

  // clear all remaining pending transmissions
311 312 313 314 315 316 317 318 319 320 321 322
  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;
knopp's avatar
knopp committed
323 324

  prev = UE_list->head;
325 326

  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
327
    if (i == UE_id) {
knopp's avatar
knopp committed
328
      // link prev to next in Active list
329
      if (i==UE_list->head) {
330
        UE_list->head = UE_list->next[i];
331
      } else {
332
        UE_list->next[prev] = UE_list->next[i];
333
      }
334 335

      // add UE id (i)to available
knopp's avatar
knopp committed
336 337 338
      UE_list->next[i] = UE_list->avail;
      UE_list->avail = i;
      UE_list->active[i] = FALSE;
339
      UE_list->num_UEs--;
340 341
      ret=0;
      break;
knopp's avatar
knopp committed
342
    }
343

knopp's avatar
knopp committed
344 345
    prev=i;
  }
346

347 348
  // do the same for UL
  prev = UE_list->head_ul;
349 350

  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
351
    if (i == UE_id) {
352
      // link prev to next in Active list
353
      if (i==UE_list->head_ul) {
354
        UE_list->head_ul = UE_list->next_ul[i];
355
      } else {
356
        UE_list->next_ul[prev] = UE_list->next_ul[i];
357
      }
358 359

      // add UE id (i)to available
360 361 362 363
      UE_list->next_ul[i] = UE_list->avail;
      ret = 0;
      break;
    }
364

365 366
    prev=i;
  }
367

368 369
  mac_phy_remove_ue(mod_idP,rntiP);

370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
  // 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];
    if ((RA_template->RA_active == TRUE) && 
	(RA_template->rnti == rntiP)){
      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;
      break;
    }
  }
386
  if (ret == 0) {
387
    return (0);
388
  }
389

390
  LOG_E(MAC,"error in mac_remove_ue(), could not find previous to %d in UE_list, should never happen, Dumping UE list\n",UE_id);
391
  dump_ue_list(UE_list,0);
392
  mac_xface->macphy_exit("mac_remove_ue: Problem in UE_list");
knopp's avatar
knopp committed
393 394
  return(-1);

395 396 397
}


knopp's avatar
knopp committed
398

399 400
int prev(UE_list_t *listP, int nodeP, int ul_flag)
{
knopp's avatar
knopp committed
401
  int j;
402

403
  if (ul_flag == 0 ) {
404
    if (nodeP==listP->head) {
405
      return(nodeP);
406
    }
407 408

    for (j=listP->head; j>=0; j=listP->next[j]) {
409
      if (listP->next[j]==nodeP) {
410
        return(j);
411
    }
412
    }
413
  } else {
414
    if (nodeP==listP->head_ul) {
415
      return(nodeP);
416
    }
417 418

    for (j=listP->head_ul; j>=0; j=listP->next_ul[j]) {
419
      if (listP->next_ul[j]==nodeP) {
420
        return(j);
421
      }
422
    }
knopp's avatar
knopp committed
423
  }
knopp's avatar
knopp committed
424

425
  LOG_E(MAC,"error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n",
426
        nodeP, (ul_flag == 0)? "DL" : "UL");
427
  dump_ue_list(listP, ul_flag);
knopp's avatar
knopp committed
428 429


knopp's avatar
knopp committed
430 431
  return(-1);
}
432

433 434
void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP, int ul_flag)
{
435

knopp's avatar
knopp committed
436 437
  int prev_i,prev_j,next_i,next_j;

438 439
  LOG_T(MAC,"Swapping UE %d,%d\n",nodeiP,nodejP);
  dump_ue_list(listP,ul_flag);
knopp's avatar
knopp committed
440

441 442
  prev_i = prev(listP,nodeiP,ul_flag);
  prev_j = prev(listP,nodejP,ul_flag);
443

444
  if ((prev_i<0) || (prev_j<0)) {
445
    mac_xface->macphy_exit("swap_UEs: problem");
446 447
    return; // not reached
  }
knopp's avatar
knopp committed
448

449
  if (ul_flag == 0) {
450 451 452 453 454
    next_i = listP->next[nodeiP];
    next_j = listP->next[nodejP];
  } else {
    next_i = listP->next_ul[nodeiP];
    next_j = listP->next_ul[nodejP];
knopp's avatar
knopp committed
455
  }
knopp's avatar
knopp committed
456

457
  LOG_T(MAC,"[%s] next_i %d, next_i, next_j %d, head %d \n",
458 459
        (ul_flag == 0)? "DL" : "UL",
        next_i,next_j,listP->head);
460 461

  if (ul_flag == 0 ) {
knopp's avatar
knopp committed
462

463 464
    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");
465

466 467
      listP->next[nodeiP] = next_j;
      listP->next[nodejP] = nodeiP;
468

469
      if (nodeiP==listP->head) { // case i j n(j)
470
        listP->head = nodejP;
471
      } else {
472
        listP->next[prev_i] = nodejP;
473
      }
474
    } else if (next_j == nodeiP) {  // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
475 476 477
      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;
478

479
      if (nodejP==listP->head) { // case j i n(i)
480
        listP->head = nodeiP;
481
      } else {
482
        listP->next[prev_j] = nodeiP;
483
      }
484
    } else {  // case ...  p(i) i n(i) ... p(j) j n(j) ...
485 486
      listP->next[nodejP] = next_i;
      listP->next[nodeiP] = next_j;
487 488


489
      if (nodeiP==listP->head) {
490 491 492 493 494 495 496 497 498 499
        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;
500 501 502 503 504 505
      }
    }
  } 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");
506

507 508
      listP->next_ul[nodeiP] = next_j;
      listP->next_ul[nodejP] = nodeiP;
509

510
      if (nodeiP==listP->head_ul) { // case i j n(j)
511
        listP->head_ul = nodejP;
512
      } else {
513
        listP->next_ul[prev_i] = nodejP;
514
      }
515
    } else if (next_j == nodeiP) {  // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
516 517 518
      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;
519

520
      if (nodejP==listP->head_ul) { // case j i n(i)
521
        listP->head_ul = nodeiP;
522
      } else {
523
        listP->next_ul[prev_j] = nodeiP;
524
      }
525 526
    } else {  // case ...  p(i) i n(i) ... p(j) j n(j) ...

527 528
      listP->next_ul[nodejP] = next_i;
      listP->next_ul[nodeiP] = next_j;
529 530


531
      if (nodeiP==listP->head_ul) {
532 533 534 535 536 537 538 539 540 541
        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;
542
      }
knopp's avatar
knopp committed
543 544
    }
  }
545

546 547
  LOG_T(MAC,"After swap\n");
  dump_ue_list(listP,ul_flag);
knopp's avatar
knopp committed
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 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669




/*
  #ifdef Rel10
  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,
670 671 672 673 674 675 676 677
                    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)
{
678 679 680 681 682 683 684 685 686 687

  memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].dci_pdu[0],pdu,dci_size_bytes);
  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].dci_length = dci_size_bits;
  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].L          = aggregation;
  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].rnti       = rnti;
  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].format     = dci_fmt;
  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci].ra_flag    = ra_flag;


  DCI_pdu->Num_common_dci++;
688
  LOG_D(MAC,"add common dci format %d for rnti %x \n",dci_fmt,rnti);
689 690
}

691 692
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)
{
693 694 695 696 697 698 699 700 701

  memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].dci_pdu[0],pdu,dci_size_bytes);
  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].dci_length = dci_size_bits;
  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].L          = aggregation;
  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].rnti       = rnti;
  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].format     = dci_fmt;
  DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci].ra_flag    = ra_flag;

  DCI_pdu->Num_ue_spec_dci++;
702

703
  LOG_D(MAC,"add ue specific dci format %d for rnti %x \n",dci_fmt,rnti);
704 705 706 707 708 709 710
}





// This has to be updated to include BSR information
711 712
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id)
{
713

714 715
  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];
716

717

718 719 720 721 722 723
  // 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);

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

knopp's avatar
knopp committed
726 727 728 729
  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
730
      (UE_template->ul_SR>0) || // uplink scheduling request
731
      ((UE_sched_ctl->ul_inactivity_timer>20)&&
732 733 734 735 736
       (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
    { 
737

738
    LOG_D(MAC,"[eNB %d][PUSCH] UE %d/%x should be scheduled\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id));
739
    return(1);
740
  } else {
741
    return(0);
742
  }
743 744 745 746 747
}




748 749
uint32_t allocate_prbs(int UE_id,unsigned char nb_rb, uint32_t *rballoc)
{
750 751 752 753 754

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

755
  for (i=0; i<(mac_xface->frame_parms->N_RB_DL-2); i+=2) {
756 757 758 759 760 761
    if (((*rballoc>>i)&3)==0) {
      *rballoc |= (3<<i);
      rballoc_dci |= (1<<((12-i)>>1));
      nb_rb_alloc+=2;
    }

762
    if (nb_rb_alloc==nb_rb) {
763
      return(rballoc_dci);
764
    }
765 766
  }

767 768 769 770
  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));
771
    }
772
  }
773

774 775 776
  return(rballoc_dci);
}

777 778 779
int get_min_rb_unit(module_id_t module_id, uint8_t CC_id)
{

780
  int min_rb_unit=0;
781 782
  LTE_DL_FRAME_PARMS* frame_parms = mac_xface->get_lte_frame_parms(module_id,CC_id);

783 784 785 786
  switch (frame_parms->N_RB_DL) {
  case 6: // 1.4 MHz
    min_rb_unit=1;
    break;
787

788 789 790
  case 25: // 5HMz
    min_rb_unit=2;
    break;
791

792 793 794
  case 50: // 10HMz
    min_rb_unit=3;
    break;
795

796 797 798
  case 100: // 20HMz
    min_rb_unit=4;
    break;
799

800 801 802 803 804
  default:
    min_rb_unit=2;
    LOG_W(MAC,"[eNB %d] N_DL_RB %d unknown for CC_id %d, setting min_rb_unit to 2\n", module_id, CC_id);
    break;
  }
805

806 807
  return min_rb_unit;
}
808

809 810
uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc)
{
811 812 813 814 815

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

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

819
  while((nb_rb >0) && (check < mac_xface->frame_parms->N_RBG)) {
knopp's avatar
knopp committed
820
    //printf("rballoc[%d] %d\n",check,rballoc[check]);
821
    if(rballoc[check] == 1) {
822
      rballoc_dci |= (1<<((mac_xface->frame_parms->N_RBG-1)-check));
823

824
      switch (mac_xface->frame_parms->N_RB_DL) {
825 826 827 828 829
      case 6:
        nb_rb--;
        break;

      case 25:
830
        if ((check == mac_xface->frame_parms->N_RBG-1)) {
831
          nb_rb--;
832
        } else {
833
          nb_rb-=2;
834
        }
835 836 837 838

        break;

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

        break;

      case 100:
        nb_rb-=4;
        break;
850
      }
851 852 853 854 855
    }

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

858 859 860 861 862 863 864
  // rballoc_dci = (rballoc_dci)&(0x1fff);
  LOG_T(MAC,"*********RBALLOC : %x\n",rballoc_dci);
  // exit(-1);
  return (rballoc_dci);
}


865 866 867
int get_nb_subband(void)
{

868 869
  int nb_sb=0;

870
  switch (mac_xface->frame_parms->N_RB_DL) {
871
  case 6:
872
    nb_sb=0;
873
    break;
874

875 876
  case 15:
    nb_sb = 4;  // sb_size =4
877 878

  case 25:
879 880
    nb_sb = 7; // sb_size =4, 1 sb with 1PRB, 6 with 2 RBG, each has 2 PRBs
    break;
881

882 883 884
  case 50:    // sb_size =6
    nb_sb = 9;
    break;
885

886 887 888
  case 75:  // sb_size =8
    nb_sb = 10;
    break;
889

890 891 892
  case 100: // sb_size =8 , 1 sb with 1 RBG + 12 sb with 2RBG, each RBG has 4 PRBs
    nb_sb = 13;
    break;
893

894 895 896 897
  default:
    nb_sb=0;
    break;
  }
898

899
  return nb_sb;
900 901

}
902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928

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);
knopp's avatar
knopp committed
929

930
    //    printf("Common DCI nb_candidates %d, L %d\n",nb_candidates,L);
knopp's avatar
knopp committed
931

932 933 934 935
    for (m = nb_candidates-1 ; m >=0 ; m--) {

      search_space_free = 1;
      for (l=0; l<L; l++) {
knopp's avatar
knopp committed
936

937
	//	printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]);
938 939 940 941 942 943 944
        if (CCE_table[(m*L) + l] == 1) {
          search_space_free = 0;
          break;
        }
      }
     
      if (search_space_free == 1) {
knopp's avatar
knopp committed
945

946
	//	printf("returning %d\n",m*L);
knopp's avatar
knopp committed
947

948 949 950 951 952 953 954 955 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
        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;
    }

knopp's avatar
knopp committed
983

984
    LOG_D(MAC,"rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n",rnti,Yk,nCCE,nCCE/L,nb_candidates);
985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007

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

      for (l=0; l<L; l++) {
        if (CCE_table[(((Yk+m)%(nCCE/L))*L) + l] == 1) {
          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);
  }
}

1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
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;
  
  for (i=0;i<nCCE;i++) {
    printf("%1d.",CCE_table[i]);
    if ((i&7) == 0)
      printf("\n");
  }

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

}

1048 1049 1050 1051 1052 1053 1054 1055 1056
// 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;
1057
  int nCCE_max = mac_xface->get_nCCE_max(module_idP,CC_idP,1,subframeP);
1058
  int fCCE;
1059
  int i,j;
1060
  DCI_ALLOC_t *dci_alloc;
1061
  int nCCE=0;
1062

1063
  LOG_D(MAC,"Allocate CCEs subframe %d, test %d : (common %d,uspec %d)\n",subframeP,test_onlyP,DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci);
1064
  DCI_pdu->num_pdcch_symbols=1;
knopp's avatar
knopp committed
1065

1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098
try_again:
  init_CCE_table(module_idP,CC_idP);
  nCCE=0;

  for (i=0;i<DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci;i++) {
    dci_alloc = &DCI_pdu->dci_alloc[i];
    LOG_D(MAC,"Trying to allocate DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
          i,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci,
          DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci,
          dci_alloc->rnti,1<<dci_alloc->L,
          nCCE,nCCE_max,DCI_pdu->num_pdcch_symbols);

    if (nCCE + (1<<dci_alloc->L) > nCCE_max) {
      if (DCI_pdu->num_pdcch_symbols == 3)
        goto failed;
      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;
    }

    // number of CCEs left can potentially hold this allocation
    fCCE = get_nCCE_offset(CCE_table,
                           1<<(dci_alloc->L),
                           nCCE_max,
                           (i<DCI_pdu->Num_common_dci) ? 1 : 0,
                           dci_alloc->rnti,
                           subframeP);
    if (fCCE == -1) {
      if (DCI_pdu->num_pdcch_symbols == 3) {
        LOG_I(MAC,"subframe %d: Dropping Allocation for RNTI %x\n",
              subframeP,dci_alloc->rnti);
        for (j=0;j<=i;j++){
          LOG_I(MAC,"DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
1099
                j,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci,
1100 1101 1102 1103 1104
                DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci,
                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);
        }
1105 1106
	dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,dci_alloc->L);

1107
        goto failed;
1108
      }
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
      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
1122

1123
  return 0;
1124

1125 1126
failed:
  return -1;
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
}

boolean_t CCE_allocation_infeasible(int module_idP,
				    int CC_idP,
				    int common_flag,
				    int subframe,
				    int aggregation,
				    int rnti) {


  DCI_PDU *DCI_pdu = &eNB_mac_inst[module_idP].common_channels[CC_idP].DCI_pdu;
1138
  //DCI_ALLOC_t *dci_alloc;
1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156
  int ret;
  boolean_t res=FALSE;

  if (common_flag==1) {
    DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci].rnti = rnti;
    DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci].L = aggregation;
    DCI_pdu->Num_common_dci++;
    ret = allocate_CCEs(module_idP,CC_idP,subframe,1);
    if (ret==-1)
      res = TRUE;
    DCI_pdu->Num_common_dci--;
  }
  else {
    DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci].rnti = rnti;
    DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci].L = aggregation;
    DCI_pdu->Num_ue_spec_dci++;
    ret = allocate_CCEs(module_idP,CC_idP,subframe,1);
    if (ret==-1)
Rohit Gupta's avatar
Rohit Gupta committed
1157
      res = TRUE;
1158 1159
    DCI_pdu->Num_ue_spec_dci--;
  }
Rohit Gupta's avatar
Rohit Gupta committed
1160
  return(res);
1161 1162
}

1163 1164 1165 1166 1167 1168 1169
void SR_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) {
1170 1171
    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);
1172 1173
    UE_list->UE_template[cc_idP][UE_id].ul_SR = 1;
    UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE;
1174 1175
    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);
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189
  } 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) {
1190 1191
    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,
1192 1193 1194
	  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;
1195 1196 1197 1198 1199 1200
  } 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);
  }
}