eNB_scheduler_primitives.c 33.3 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 78 79 80 81 82 83 84 85 86 87 88

  for (i=0; i<NUMBER_OF_eNB_MAX; i++) {
    for (k=0; i<MAX_NUM_CCs; i++) {
      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

Raymond Knopp's avatar
 
Raymond 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

Raymond Knopp's avatar
 
Raymond 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]) {
Raymond Knopp's avatar
 
Raymond 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

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

}

132
//------------------------------------------------------------------------------
133
int UE_num_active_CC(UE_list_t *listP,int ue_idP)
134
//------------------------------------------------------------------------------
135
{
Raymond Knopp's avatar
 
Raymond 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
{
Raymond Knopp's avatar
 
Raymond 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

Raymond Knopp's avatar
 
Raymond 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) {
Raymond Knopp's avatar
 
Raymond 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
}
Raymond Knopp's avatar
 
Raymond Knopp committed
161

162
//------------------------------------------------------------------------------
163
boolean_t is_UE_active(module_id_t mod_idP, int ue_idP)
164
//------------------------------------------------------------------------------
165
{
Raymond Knopp's avatar
 
Raymond Knopp committed
166
  return(eNB_mac_inst[mod_idP].UE_list.active[ue_idP]);
167
}
Raymond Knopp's avatar
 
Raymond 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++) {

Raymond Knopp's avatar
 
Raymond 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);
}
Raymond Knopp's avatar
 
Raymond 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
/*
Raymond Knopp's avatar
 
Raymond 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

Raymond Knopp's avatar
 
Raymond 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
Raymond Knopp's avatar
 
Raymond Knopp committed
227

228 229
void dump_ue_list(UE_list_t *listP, int ul_flag)
{
Raymond Knopp's avatar
 
Raymond 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]);
    }
Raymond Knopp's avatar
 
Raymond 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)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
245 246
  int UE_id;
  int j;
247

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

Raymond Knopp's avatar
 
Raymond 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);
Raymond Knopp's avatar
 
Raymond 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 );
Raymond Knopp's avatar
 
Raymond 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;
Raymond Knopp's avatar
 
Raymond Knopp committed
259
    UE_list->head = UE_id;
260
    UE_list->head_ul = UE_id;
Raymond Knopp's avatar
 
Raymond 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;
Raymond Knopp's avatar
 
Raymond Knopp committed
268
    UE_list->num_UEs++;
Raymond Knopp's avatar
 
Raymond Knopp committed
269
    UE_list->active[UE_id]                         = TRUE;
270
    memset((void*)&UE_list->UE_sched_ctrl[UE_id],0,sizeof(UE_sched_ctrl));
Raymond Knopp's avatar
 
Raymond 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
Raymond Knopp's avatar
 
Raymond Knopp committed
274
      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
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;
Raymond Knopp's avatar
 
Raymond 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);
Raymond Knopp's avatar
 
Raymond Knopp committed
281
    return(UE_id);
282
  }
Raymond Knopp's avatar
 
Raymond 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
{
Raymond Knopp's avatar
 
Raymond Knopp committed
293

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

296

Raymond Knopp's avatar
 
Raymond 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
  LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",UE_id,pCC_id, rntiP);
302
  dump_ue_list(UE_list,0);
303 304

  // clear all remaining pending transmissions
305 306 307 308 309 310 311 312 313 314 315 316
  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
317 318

  prev = UE_list->head;
319 320

  for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
321
    if (i == UE_id) {
Raymond Knopp's avatar
 
Raymond Knopp committed
322
      // link prev to next in Active list
323
      //if (prev==UE_list->head)
324
      if (i==UE_list->head) {
325
        UE_list->head = UE_list->next[i];
326
      } else {
327
        UE_list->next[prev] = UE_list->next[i];
328
      }
329 330

      // add UE id (i)to available
Raymond Knopp's avatar
 
Raymond Knopp committed
331 332 333
      UE_list->next[i] = UE_list->avail;
      UE_list->avail = i;
      UE_list->active[i] = FALSE;
334
      UE_list->num_UEs--;
335 336
      ret=0;
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
337
    }
338

Raymond Knopp's avatar
 
Raymond Knopp committed
339 340
    prev=i;
  }
341

342 343
  // do the same for UL
  prev = UE_list->head_ul;
344 345

  for (i=UE_list->head_ul; i>=0; i=UE_list->next_ul[i]) {
346
    if (i == UE_id) {
347
      // link prev to next in Active list
348
      if (prev==UE_list->head_ul) {
349
        UE_list->head_ul = UE_list->next_ul[i];
350
      } else {
351
        UE_list->next_ul[prev] = UE_list->next_ul[i];
352
      }
353 354

      // add UE id (i)to available
355 356 357 358
      UE_list->next_ul[i] = UE_list->avail;
      ret = 0;
      break;
    }
359

360 361
    prev=i;
  }
362

363 364
  mac_phy_remove_ue(mod_idP,rntiP);

365
  if (ret == 0) {
366
    return (0);
367
  }
368

369
  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);
370
  dump_ue_list(UE_list,0);
371
  mac_xface->macphy_exit("mac_remove_ue: Problem in UE_list");
Raymond Knopp's avatar
 
Raymond Knopp committed
372 373
  return(-1);

374 375 376
}


Raymond Knopp's avatar
 
Raymond Knopp committed
377

378 379
int prev(UE_list_t *listP, int nodeP, int ul_flag)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
380
  int j;
381

382
  if (ul_flag == 0 ) {
383
    if (nodeP==listP->head) {
384
      return(nodeP);
385
    }
386 387

    for (j=listP->head; j>=0; j=listP->next[j]) {
388
      if (listP->next[j]==nodeP) {
389
        return(j);
390
    }
391
    }
392
  } else {
393
    if (nodeP==listP->head_ul) {
394
      return(nodeP);
395
    }
396 397

    for (j=listP->head_ul; j>=0; j=listP->next_ul[j]) {
398
      if (listP->next_ul[j]==nodeP) {
399
        return(j);
400
      }
401
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
402
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
403

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


Raymond Knopp's avatar
 
Raymond Knopp committed
409 410
  return(-1);
}
411

412 413
void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP, int ul_flag)
{
414

Raymond Knopp's avatar
 
Raymond Knopp committed
415 416
  int prev_i,prev_j,next_i,next_j;

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

420 421
  prev_i = prev(listP,nodeiP,ul_flag);
  prev_j = prev(listP,nodejP,ul_flag);
422

423
  if ((prev_i<0) || (prev_j<0)) {
424
    mac_xface->macphy_exit("swap_UEs: problem");
425 426
    return; // not reached
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
427

428
  if (ul_flag == 0) {
429 430 431 432 433
    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
434
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
435

436
  LOG_T(MAC,"[%s] next_i %d, next_i, next_j %d, head %d \n",
437 438
        (ul_flag == 0)? "DL" : "UL",
        next_i,next_j,listP->head);
439 440

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

442 443
    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");
444

445 446
      listP->next[nodeiP] = next_j;
      listP->next[nodejP] = nodeiP;
447

448
      if (nodeiP==listP->head) { // case i j n(j)
449
        listP->head = nodejP;
450
      } else {
451
        listP->next[prev_i] = nodejP;
452
      }
453
    } else if (next_j == nodeiP) {  // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
454 455 456
      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;
457

458
      if (nodejP==listP->head) { // case j i n(i)
459
        listP->head = nodeiP;
460
      } else {
461
        listP->next[prev_j] = nodeiP;
462
      }
463
    } else {  // case ...  p(i) i n(i) ... p(j) j n(j) ...
464 465
      listP->next[nodejP] = next_i;
      listP->next[nodeiP] = next_j;
466 467


468
      if (nodeiP==listP->head) {
469 470 471 472 473 474 475 476 477 478
        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;
479 480 481 482 483 484
      }
    }
  } 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");
485

486 487
      listP->next_ul[nodeiP] = next_j;
      listP->next_ul[nodejP] = nodeiP;
488

489
      if (nodeiP==listP->head_ul) { // case i j n(j)
490
        listP->head_ul = nodejP;
491
      } else {
492
        listP->next_ul[prev_i] = nodejP;
493
      }
494
    } else if (next_j == nodeiP) {  // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...
495 496 497
      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;
498

499
      if (nodejP==listP->head_ul) { // case j i n(i)
500
        listP->head_ul = nodeiP;
501
      } else {
502
        listP->next_ul[prev_j] = nodeiP;
503
      }
504 505
    } else {  // case ...  p(i) i n(i) ... p(j) j n(j) ...

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


510
      if (nodeiP==listP->head_ul) {
511 512 513 514 515 516 517 518 519 520
        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;
521
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
522 523
    }
  }
524

525 526
  LOG_T(MAC,"After swap\n");
  dump_ue_list(listP,ul_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
527 528 529 530
}



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 642 643 644 645 646 647 648




/*
  #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,
649 650 651 652 653 654 655 656
                    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)
{
657 658 659 660 661 662 663 664 665 666

  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++;
667
  LOG_D(MAC,"add common dci format %d for rnti %x \n",dci_fmt,rnti);
668 669
}

670 671
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)
{
672 673 674 675 676 677 678 679 680

  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++;
681

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





// This has to be updated to include BSR information
690 691
uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id)
{
692

693 694
  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];
695

696

kaltenbe's avatar
kaltenbe committed
697 698 699 700 701 702
  // 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);

703 704
  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
705 706 707 708
  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
709
      (UE_template->ul_SR>0) || // uplink scheduling request
710
      ((UE_sched_ctl->ul_inactivity_timer>20)&&
711 712 713 714 715
       (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
    { 
716

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




727 728
uint32_t allocate_prbs(int UE_id,unsigned char nb_rb, uint32_t *rballoc)
{
729 730 731 732 733

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

734 735 736 737 738 739 740
  for (i=0; i<(mac_xface->lte_frame_parms->N_RB_DL-2); i+=2) {
    if (((*rballoc>>i)&3)==0) {
      *rballoc |= (3<<i);
      rballoc_dci |= (1<<((12-i)>>1));
      nb_rb_alloc+=2;
    }

741
    if (nb_rb_alloc==nb_rb) {
742
      return(rballoc_dci);
743
    }
744 745 746
  }

  if ((mac_xface->lte_frame_parms->N_RB_DL&1)==1) {
747 748 749 750
    if ((*rballoc>>(mac_xface->lte_frame_parms->N_RB_DL-1)&1)==0) {
      *rballoc |= (1<<(mac_xface->lte_frame_parms->N_RB_DL-1));
      rballoc_dci |= 1;//(1<<(mac_xface->lte_frame_parms->N_RB_DL>>1));
    }
751
  }
752

753 754 755
  return(rballoc_dci);
}

756 757 758
int get_min_rb_unit(module_id_t module_id, uint8_t CC_id)
{

759
  int min_rb_unit=0;
760 761
  LTE_DL_FRAME_PARMS* frame_parms = mac_xface->get_lte_frame_parms(module_id,CC_id);

762 763 764 765
  switch (frame_parms->N_RB_DL) {
  case 6: // 1.4 MHz
    min_rb_unit=1;
    break;
766

767 768 769
  case 25: // 5HMz
    min_rb_unit=2;
    break;
770

771 772 773
  case 50: // 10HMz
    min_rb_unit=3;
    break;
774

775 776 777
  case 100: // 20HMz
    min_rb_unit=4;
    break;
778

779 780 781 782 783
  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;
  }
784

785 786
  return min_rb_unit;
}
787

788 789
uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc)
{
790 791 792 793 794

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

795
  LOG_T(MAC,"*****Check1RBALLOC****: %d%d%d%d (nb_rb %d,N_RBG %d)\n",
796 797 798
        rballoc[3],rballoc[2],rballoc[1],rballoc[0],nb_rb,mac_xface->lte_frame_parms->N_RBG);

  while((nb_rb >0) && (check < mac_xface->lte_frame_parms->N_RBG)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
799
    //printf("rballoc[%d] %d\n",check,rballoc[check]);
800 801 802 803 804 805 806 807 808
    if(rballoc[check] == 1) {
      rballoc_dci |= (1<<((mac_xface->lte_frame_parms->N_RBG-1)-check));

      switch (mac_xface->lte_frame_parms->N_RB_DL) {
      case 6:
        nb_rb--;
        break;

      case 25:
809
        if ((check == mac_xface->lte_frame_parms->N_RBG-1)) {
810
          nb_rb--;
811
        } else {
812
          nb_rb-=2;
813
        }
814 815 816 817

        break;

      case 50:
818
        if ((check == mac_xface->lte_frame_parms->N_RBG-1)) {
819
          nb_rb-=2;
820
        } else {
821
          nb_rb-=3;
822
        }
823 824 825 826 827 828

        break;

      case 100:
        nb_rb-=4;
        break;
829
      }
830 831 832 833 834
    }

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

837 838 839 840 841 842 843
  // rballoc_dci = (rballoc_dci)&(0x1fff);
  LOG_T(MAC,"*********RBALLOC : %x\n",rballoc_dci);
  // exit(-1);
  return (rballoc_dci);
}


844 845 846
int get_nb_subband(void)
{

847 848 849 850
  int nb_sb=0;

  switch (mac_xface->lte_frame_parms->N_RB_DL) {
  case 6:
851
    nb_sb=0;
852
    break;
853

854 855
  case 15:
    nb_sb = 4;  // sb_size =4
856 857

  case 25:
858 859
    nb_sb = 7; // sb_size =4, 1 sb with 1PRB, 6 with 2 RBG, each has 2 PRBs
    break;
860

861 862 863
  case 50:    // sb_size =6
    nb_sb = 9;
    break;
864

865 866 867
  case 75:  // sb_size =8
    nb_sb = 10;
    break;
868

869 870 871
  case 100: // sb_size =8 , 1 sb with 1 RBG + 12 sb with 2RBG, each RBG has 4 PRBs
    nb_sb = 13;
    break;
872

873 874 875 876
  default:
    nb_sb=0;
    break;
  }
877

878
  return nb_sb;
879 880

}
881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907

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
908

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

911 912 913 914
    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
915

916
	//	printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]);
917 918 919 920 921 922 923
        if (CCE_table[(m*L) + l] == 1) {
          search_space_free = 0;
          break;
        }
      }
     
      if (search_space_free == 1) {
Raymond Knopp's avatar
Raymond Knopp committed
924

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

927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961
        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
962

963
    LOG_D(MAC,"rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n",rnti,Yk,nCCE,nCCE/L,nb_candidates);
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 992 993 994 995

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

// 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
996
  int nCCE_max = mac_xface->get_nCCE_max(module_idP,CC_idP,1,subframeP);
997
  int fCCE;
998
  int i,j;
999 1000
  int allocation_is_feasible = 1;
  DCI_ALLOC_t *dci_alloc;
Raymond Knopp's avatar
Raymond Knopp committed
1001
  int nCCE=0;
1002

1003
  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);
Raymond Knopp's avatar
Raymond Knopp committed
1004
  DCI_pdu->num_pdcch_symbols=1;
Raymond Knopp's avatar
Raymond Knopp committed
1005

1006
  while (allocation_is_feasible == 1) {
Cedric Roux's avatar
Cedric Roux committed
1007
    init_CCE_table(module_idP,CC_idP);
Raymond Knopp's avatar
Raymond Knopp committed
1008
    nCCE=0;
1009 1010 1011

    for (i=0;i<DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci;i++) {
      dci_alloc = &DCI_pdu->dci_alloc[i];
1012
      LOG_D(MAC,"Trying to allocate DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
1013 1014 1015
	    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,
Raymond Knopp's avatar
Raymond Knopp committed
1016
	    nCCE,nCCE_max,DCI_pdu->num_pdcch_symbols);
1017

Raymond Knopp's avatar
Raymond Knopp committed
1018
      if (nCCE + (1<<dci_alloc->L) > nCCE_max) {
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
	if (DCI_pdu->num_pdcch_symbols == 3)
	  allocation_is_feasible = 0;
	else {
	  DCI_pdu->num_pdcch_symbols++;
	  nCCE_max = mac_xface->get_nCCE_max(module_idP,CC_idP,DCI_pdu->num_pdcch_symbols,subframeP);
	}
	break;
      }
      else { // number of CCEs left can potentially hold this allocation
	if ((fCCE = get_nCCE_offset(CCE_table,
1029 1030 1031 1032
				    1<<(dci_alloc->L), 
				    nCCE_max,
				    (i<DCI_pdu->Num_common_dci) ? 1 : 0, 
				    dci_alloc->rnti, 
1033
				    subframeP))>=0) {// the allocation is feasible, rnti rule passes
Raymond Knopp's avatar
Raymond Knopp committed
1034

1035
	  LOG_D(MAC,"Allocating at nCCE %d\n",fCCE);
1036
	  if (test_onlyP == 0) {
Raymond Knopp's avatar
Raymond Knopp committed
1037
	    nCCE += (1<<dci_alloc->L);
1038
	    dci_alloc->firstCCE=fCCE;
1039
	    LOG_D(MAC,"Allocate CCEs subframe %d, test %d\n",subframeP,test_onlyP);
1040 1041 1042
	  }
	} // fCCE>=0
	else {
1043
	  if (DCI_pdu->num_pdcch_symbols == 3) {
1044
	    allocation_is_feasible = 0;
1045 1046
	    LOG_I(MAC,"subframe %d: Dropping Allocation for RNTI %x\n",
		  subframeP,dci_alloc->rnti);
1047 1048 1049 1050 1051 1052 1053
	    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",
		    i,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci,
		    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,
Raymond Knopp's avatar
Raymond Knopp committed
1054
		    nCCE,nCCE_max,DCI_pdu->num_pdcch_symbols);
1055
	    }
1056
	  }
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
	  else {
	    DCI_pdu->num_pdcch_symbols++;
	    nCCE_max = mac_xface->get_nCCE_max(module_idP,CC_idP,DCI_pdu->num_pdcch_symbols,subframeP);
	  }
	  break;
	} // fCCE==-1
      } // nCCE <= nCCE_max
    } // for i = 0 ... num_dcis  
    if (allocation_is_feasible==1)
      return (0);
  } // allocation_is_feasible == 1

  return(-1);
  

}

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;
1083
  //DCI_ALLOC_t *dci_alloc;
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101
  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
1102
      res = TRUE;
1103 1104
    DCI_pdu->Num_ue_spec_dci--;
  }
Rohit Gupta's avatar
Rohit Gupta committed
1105
  return(res);
1106 1107
}

1108 1109 1110 1111 1112 1113 1114
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) {
1115 1116
    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);
1117 1118
    UE_list->UE_template[cc_idP][UE_id].ul_SR = 1;
    UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE;
1119 1120
    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);
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
  } 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) {
1135 1136
    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
1137 1138 1139
	  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;
1140 1141 1142 1143 1144 1145
  } 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);
  }
}