eNB_scheduler_ulsch.c 55.3 KB
Newer Older
1
/*******************************************************************************
nikaeinn's avatar
nikaeinn committed
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

nikaeinn's avatar
nikaeinn committed
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


nikaeinn's avatar
nikaeinn committed
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

nikaeinn's avatar
nikaeinn committed
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
nikaeinn's avatar
nikaeinn committed
22 23 24 25
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr

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

gauthier's avatar
 
gauthier committed
28
 *******************************************************************************/
nikaeinn's avatar
nikaeinn committed
29 30 31

/*! \file eNB_scheduler_ulsch.c
 * \brief eNB procedures for the ULSCH transport channel
32 33 34
 * \author Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \email: navid.nikaein@eurecom.fr
nikaeinn's avatar
nikaeinn committed
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
 * @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/proto.h"
#include "LAYER2/MAC/extern.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

66
#define ENABLE_MAC_PAYLOAD_DEBUG
67 68 69 70 71
#define DEBUG_eNB_SCHEDULER 1

// This table holds the allowable PRB sizes for ULSCH transmissions
uint8_t rb_table[33] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,72,75,80,81,90,96,100};

gauthier's avatar
gauthier committed
72
void rx_sdu(
73 74 75
  const module_id_t enb_mod_idP,
  const int         CC_idP,
  const frame_t     frameP,
gauthier's avatar
gauthier committed
76
  const sub_frame_t subframeP,
77 78 79 80 81
  const rnti_t      rntiP,
  uint8_t          *sduP,
  const uint16_t    sdu_lenP,
  const int         harq_pidP,
  uint8_t          *msg3_flagP)
82 83 84 85 86 87 88 89 90 91 92 93 94
{

  unsigned char  rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
  unsigned char  rx_lcids[NB_RB_MAX];
  unsigned short rx_lengths[NB_RB_MAX];
  int    UE_id = find_UE_id(enb_mod_idP,rntiP);
  int ii,j;
  eNB_MAC_INST *eNB = &eNB_mac_inst[enb_mod_idP];
  UE_list_t *UE_list= &eNB->UE_list;

  start_meas(&eNB->rx_ulsch_sdu);

  if ((UE_id >  NUMBER_OF_UE_MAX) || (UE_id == -1)  )
95 96 97
    for(ii=0; ii<NB_RB_MAX; ii++) {
      rx_lengths[ii] = 0;
    }
98

gauthier's avatar
gauthier committed
99
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,1);
gauthier's avatar
gauthier committed
100
  if (opt_enabled == 1) {
nikaeinn's avatar
nikaeinn committed
101
    trace_pdu(0, sduP,sdu_lenP, 0, 3, rntiP,subframeP, 0,0);
gauthier's avatar
gauthier committed
102
    LOG_D(OPT,"[eNB %d][ULSCH] Frame %d  rnti %x  with size %d\n",
nikaeinn's avatar
nikaeinn committed
103
    		  enb_mod_idP, frameP, rntiP, sdu_lenP);
gauthier's avatar
gauthier committed
104
  }
105

106
  LOG_D(MAC,"[eNB %d] CC_id %d Received ULSCH sdu from PHY (rnti %x, UE_id %d), parsing header\n",enb_mod_idP,CC_idP,rntiP,UE_id);
107
  
108
  payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP);
109 110 111 112
 
  eNB->eNB_stats[CC_idP].ulsch_bytes_rx=sdu_lenP;
  eNB->eNB_stats[CC_idP].total_ulsch_bytes_rx+=sdu_lenP;
  eNB->eNB_stats[CC_idP].total_ulsch_pdus_rx+=1;
113 114 115 116 117 118 119
  // control element
  for (i=0; i<num_ce; i++) {

    switch (rx_ces[i]) { // implement and process BSR + CRNTI +
    case POWER_HEADROOM:
      if (UE_id != -1) {
        UE_list->UE_template[CC_idP][UE_id].phr_info =  (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET;
120 121
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n",
              enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].phr_info);
122 123 124 125 126 127 128
        UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1;
      }

      payload_ptr+=sizeof(POWER_HEADROOM_CMD);
      break;

    case CRNTI:
129 130
      LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received CRNTI %d \n",
            enb_mod_idP, CC_idP, rx_ces[i], payload_ptr[0]);
131 132 133 134 135 136 137 138
      payload_ptr+=1;
      break;

    case TRUNCATED_BSR:
    case SHORT_BSR: {
      if (UE_id  != -1) {
        uint8_t lcgid;
        lcgid = (payload_ptr[0] >> 6);
139 140
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
              enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f);
141 142
        UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f);

143
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
144
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
145
        }
146 147 148
      }

      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
 
knopp committed
149
    }
150
    break;
gauthier's avatar
 
gauthier committed
151

152 153 154 155 156 157 158 159
    case LONG_BSR:
      if (UE_id  != -1) {
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2);
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] =
          ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4);
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] =
          ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6);
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F);
160
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
161
              "%u LCGID2 = %u LCGID3 = %u\n",
162
              enb_mod_idP, CC_idP,
163 164 165 166 167 168
              rx_ces[i],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]);

169
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) {
170
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0;
171
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) {
172
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP;
173
        }
174

175
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) {
176
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0;
177
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) {
178
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP;
179
        }
180

181
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0 ) {
182
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=0;
183
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) {
184
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=frameP;
185
        }
186

187
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0 ) {
188
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]= 0;
189
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) {
190 191
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]=frameP;

192
        }
193 194 195 196 197 198
      }

      payload_ptr += 3;////sizeof(LONG_BSR);
      break;

    default:
199
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
200 201 202 203 204 205 206 207 208
      break;
    }
  }

  for (i=0; i<num_sdu; i++) {
    LOG_D(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);

    switch (rx_lcids[i]) {
    case CCCH :
209 210
      LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH:  %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
            enb_mod_idP,CC_idP,frameP,
211 212 213
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);

      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
214 215
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %p Checking proc %d : rnti (%x, %x), active %d\n",
              enb_mod_idP, CC_idP, ii,
216 217
              eNB->common_channels[CC_idP].RA_template[ii].rnti, rntiP,
              eNB->common_channels[CC_idP].RA_template[ii].RA_active);
gauthier's avatar
 
gauthier committed
218

219 220
        if ((eNB->common_channels[CC_idP].RA_template[ii].rnti==rntiP) &&
            (eNB->common_channels[CC_idP].RA_template[ii].RA_active==TRUE)) {
gauthier's avatar
 
gauthier committed
221

222
          //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len);
gauthier's avatar
 
gauthier committed
223

224 225
          if (UE_id < 0) {
            memcpy(&eNB->common_channels[CC_idP].RA_template[ii].cont_res_id[0],payload_ptr,6);
knopp's avatar
knopp committed
226
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %d\n",
227
                  enb_mod_idP,CC_idP,frameP,rx_lengths[ii],payload_ptr-sduP);
gauthier's avatar
 
gauthier committed
228

229
            if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pidP)) == -1 ) {
230
              mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n");
kaltenbe's avatar
kaltenbe committed
231
	      // kill RA procedure
232
            } else
233 234
              LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
                    enb_mod_idP,CC_idP,frameP,eNB->common_channels[CC_idP].RA_template[ii].rnti,UE_id);
235
          } else {
knopp's avatar
knopp committed
236
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %d\n",
237
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[ii],payload_ptr-sduP);
kaltenbe's avatar
kaltenbe committed
238
	    // kill RA procedure
239
          }
gauthier's avatar
 
gauthier committed
240

241
          if (Is_rrc_registered == 1)
242 243
            mac_rrc_data_ind(
              enb_mod_idP,
244
              CC_idP,
gauthier's avatar
gauthier committed
245
              frameP,subframeP,
246 247 248 249 250 251 252
              rntiP,
              CCCH,
              (uint8_t*)payload_ptr,
              rx_lengths[ii],
              ENB_FLAG_YES,
              enb_mod_idP,
              0);
gauthier's avatar
 
gauthier committed
253 254


255 256 257
          if (num_ce >0) {  // handle msg3 which is not RRCConnectionRequest
            //  process_ra_message(msg3,num_ce,rx_lcids,rx_ces);
          }
gauthier's avatar
 
gauthier committed
258

259 260
          eNB->common_channels[CC_idP].RA_template[ii].generate_Msg4 = 1;
          eNB->common_channels[CC_idP].RA_template[ii].wait_ack_Msg4 = 0;
gauthier's avatar
 
gauthier committed
261

262 263
        } // if process is active
      } // loop on RA processes
gauthier's avatar
 
gauthier committed
264

265
      break;
gauthier's avatar
 
gauthier committed
266

267 268 269
    case  DCCH :
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
gauthier's avatar
 
gauthier committed
270

knopp's avatar
 
knopp committed
271
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
272 273
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));

274
      for (j=0; j<32; j++) {
275
        LOG_T(MAC,"%x ",payload_ptr[j]);
276
      }
277 278

      LOG_T(MAC,"\n");
knopp's avatar
 
knopp committed
279
#endif
gauthier's avatar
 
gauthier committed
280

281 282
      //  This check is just to make sure we didn't get a bogus SDU length, to be removed ...
      if (rx_lengths[i]<CCCH_PAYLOAD_SIZE_MAX) {
283 284
        LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n",
              enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i]);
285

286 287 288
        mac_rlc_data_ind(
          enb_mod_idP,
          rntiP,
gauthier's avatar
gauthier committed
289
	      enb_mod_idP,
290 291 292
          frameP,
          ENB_FLAG_YES,
          MBMS_FLAG_NO,
293 294 295 296 297
          rx_lcids[i],
          (char *)payload_ptr,
          rx_lengths[i],
          1,
          NULL);//(unsigned int*)crc_status);
298 299 300 301 302 303 304 305 306
        UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1;
        UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i];
      }

      //      }
      break;

    case DTCH: // default DRB
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
gauthier's avatar
 
gauthier committed
307

knopp's avatar
 
knopp committed
308
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
309
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
gauthier's avatar
 
gauthier committed
310

311
      for (j=0; j<32; j++) {
312
        LOG_T(MAC,"%x ",payload_ptr[j]);
313
      }
gauthier's avatar
 
gauthier committed
314

315 316 317
      LOG_T(MAC,"\n");
#endif

318 319
      LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n",
            enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id,rx_lcids[i]);
320 321

      if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) &&  (rx_lengths[i] > 0) ) {   // MAX SIZE OF transport block
322 323 324
        mac_rlc_data_ind(
          enb_mod_idP,
          rntiP,
325
          enb_mod_idP,
326 327 328
          frameP,
          ENB_FLAG_YES,
          MBMS_FLAG_NO,
329 330 331 332 333
          DTCH,
          (char *)payload_ptr,
          rx_lengths[i],
          1,
          NULL);//(unsigned int*)crc_status);
334 335 336 337 338 339 340 341 342
        UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1;
        UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i];
      }

      //      }
      break;

    default :  //if (rx_lcids[i] >= DTCH) {
      UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
343 344
      LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ",
            enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id);
345
      break;
knopp's avatar
 
knopp committed
346
    }
347 348 349 350 351 352 353 354 355 356

    payload_ptr+=rx_lengths[i];
  }

  /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */
  if ((num_sdu == 0) && (num_ce==0)) {
    UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;

    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
357
        LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP);
358 359
        *msg3_flagP=0;
      }
360
    }
361
  } else {
362
    UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx=sdu_lenP;
363 364 365 366
    UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx+=sdu_lenP;
    UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx+=1;
  }

gauthier's avatar
gauthier committed
367
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
368
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
 
knopp committed
369 370 371
}


372 373
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
374

375
  uint32_t i=0;
376

377
  if (nbytes<0) {
378
    return(0);
379
  }
380

381 382 383 384 385 386
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
387 388
}

389
void adjust_bsr_info(int buffer_occupancy,
gauthier's avatar
 
gauthier committed
390
                     uint16_t TBS,
391 392 393 394 395 396 397 398 399 400 401 402 403
                     UE_TEMPLATE *UE_template)
{

  uint32_t         tmp_bsr;

  // could not serve all the uplink traffic
  if (buffer_occupancy > 0 ) {
    if (BSR_TABLE[UE_template->bsr_info[LCGID0]] <=  TBS ) {
      tmp_bsr = BSR_TABLE[UE_template->bsr_info[LCGID0]]; // serving this amout of  bytes
      UE_template->bsr_info[LCGID0] = 0;

      if (BSR_TABLE[UE_template->bsr_info[LCGID1]] <= (TBS-tmp_bsr)) {
        tmp_bsr += BSR_TABLE[UE_template->bsr_info[LCGID1]];
gauthier's avatar
 
gauthier committed
404
        UE_template->bsr_info[LCGID1] = 0;
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423

        if (BSR_TABLE[UE_template->bsr_info[LCGID2]] <= (TBS-tmp_bsr)) {
          tmp_bsr += BSR_TABLE[UE_template->bsr_info[LCGID2]];
          UE_template->bsr_info[LCGID2] = 0;

          if (BSR_TABLE[UE_template->bsr_info[LCGID3]] <= (TBS-tmp_bsr)) {
            tmp_bsr += BSR_TABLE[UE_template->bsr_info[LCGID3]];
            UE_template->bsr_info[LCGID3] = 0;
          } else {
            UE_template->bsr_info[LCGID3] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID3]] - ((int32_t) TBS - (int32_t)tmp_bsr));
          }
        } else {
          UE_template->bsr_info[LCGID2] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID2]] - ((int32_t)TBS - (int32_t)tmp_bsr));
        }
      } else {
        UE_template->bsr_info[LCGID1] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID1]] - ((int32_t)TBS - (int32_t)tmp_bsr));
      }
    } else {
      UE_template->bsr_info[LCGID0] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID0]] - (int32_t)TBS);
424
    }
425 426 427 428 429 430
  } else { // we have flushed all buffers so clear bsr
    UE_template->bsr_info[LCGID0] = 0;
    UE_template->bsr_info[LCGID1] = 0;
    UE_template->bsr_info[LCGID2] = 0;
    UE_template->bsr_info[LCGID3] = 0;
  }
431 432 433


}
434

435 436
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
437

438 439 440
  eNB_ulsch_info[module_idP][CC_id][UE_id].rnti             = UE_RNTI(module_idP,UE_id);
  eNB_ulsch_info[module_idP][CC_id][UE_id].subframe         = subframeP;
  eNB_ulsch_info[module_idP][CC_id][UE_id].status           = status;
441

442
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
443 444 445

}

knopp's avatar
 
knopp committed
446 447 448
// This seems not to be used anymore
/*
int schedule_next_ulue(module_id_t module_idP, int UE_id, sub_frame_t subframeP){
449

knopp's avatar
 
knopp committed
450
  int next_ue;
451 452 453

  // first phase: scheduling for ACK
  switch (subframeP) {
knopp's avatar
 
knopp committed
454
    // scheduling for subframeP 2: for scheduled user during subframeP 5 and 6
455
  case 8:
knopp's avatar
 
knopp committed
456
    if  ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
457
   (eNB_dlsch_info[module_idP][UE_id].subframe == 5 || eNB_dlsch_info[module_idP][UE_id].subframe == 6)){
knopp's avatar
 
knopp committed
458 459 460
      // set the downlink status
      eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
      return UE_id;
461 462 463 464
    }
    break;
    // scheduling for subframeP 3: for scheduled user during subframeP 7 and 8
  case 9:
knopp's avatar
 
knopp committed
465
    if  ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
466
   (eNB_dlsch_info[module_idP][UE_id].subframe == 7 || eNB_dlsch_info[module_idP][UE_id].subframe == 8)){
knopp's avatar
 
knopp committed
467 468
      eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
      return UE_id;
469 470 471 472
    }
    break;
    // scheduling UL subframeP 4: for scheduled user during subframeP 9 and 0
  case 0 :
knopp's avatar
 
knopp committed
473
    if  ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
474
   (eNB_dlsch_info[module_idP][UE_id].subframe == 9 || eNB_dlsch_info[module_idP][UE_id].subframe == 0)){
knopp's avatar
 
knopp committed
475 476
      eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
      return UE_id;
477 478 479 480 481 482 483 484 485
    }
    break;
  default:
    break;
  }

  // second phase
  for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ){

knopp's avatar
 
knopp committed
486 487 488 489 490
    if  (eNB_ulsch_info[module_idP][next_ue].status == S_UL_WAITING )
      return next_ue;
    else if (eNB_ulsch_info[module_idP][next_ue].status == S_UL_SCHEDULED){
      eNB_ulsch_info[module_idP][next_ue].status = S_UL_BUFFERED;
    }
491 492
  }
  for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ){
knopp's avatar
 
knopp committed
493 494
    if (eNB_ulsch_info[module_idP][next_ue].status != S_UL_NONE )// do this just for active UEs
      eNB_ulsch_info[module_idP][next_ue].status = S_UL_WAITING;
495 496 497 498 499
  }
  next_ue = 0;
  return next_ue;

}
gauthier's avatar
 
gauthier committed
500
 */
501 502 503 504 505 506





unsigned char *parse_ulsch_header(unsigned char *mac_header,
gauthier's avatar
 
gauthier committed
507 508 509 510 511
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
512 513 514 515 516 517 518 519 520
                                  unsigned short tb_length)
{

  unsigned char not_done=1,num_ces=0,num_sdus=0,lcid,num_sdu_cnt;
  unsigned char *mac_header_ptr = mac_header;
  unsigned short length, ce_len=0;

  while (not_done==1) {

521
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
522
      not_done = 0;
523
    }
524 525 526 527 528 529 530 531

    lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID;

    if (lcid < EXTENDED_POWER_HEADROOM) {
      if (not_done==0) { // last MAC SDU, length is implicit
        mac_header_ptr++;
        length = tb_length-(mac_header_ptr-mac_header)-ce_len;

532
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
533
          length -= rx_lengths[num_sdu_cnt];
534
        }
535 536 537 538 539 540 541
      } else {
        if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) {
          length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L;
          mac_header_ptr += 2;//sizeof(SCH_SUBHEADER_SHORT);
        } else { // F = 1
          length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff);
          mac_header_ptr += 3;//sizeof(SCH_SUBHEADER_LONG);
gauthier's avatar
 
gauthier committed
542
        }
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
      }

      LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %d)\n",
            num_sdus,lcid,tb_length, length,mac_header_ptr-mac_header);
      rx_lcids[num_sdus] = lcid;
      rx_lengths[num_sdus] = length;
      num_sdus++;
    } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI
      if (lcid == SHORT_PADDING) {
        mac_header_ptr++;
      } else {
        rx_ces[num_ces] = lcid;
        num_ces++;
        mac_header_ptr++;

558
        if (lcid==LONG_BSR) {
559
          ce_len+=3;
560
        } else if (lcid==CRNTI) {
561
          ce_len+=2;
562
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
563
          ce_len++;
564
        } else {
565 566
          LOG_E(MAC,"unknown CE %d \n", lcid);
          mac_xface->macphy_exit("unknown CE");
gauthier's avatar
 
gauthier committed
567
        }
568
      }
knopp's avatar
 
knopp committed
569
    }
570
  }
571

572 573 574 575
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
576 577 578
}


579
void schedule_ulsch(module_id_t module_idP, frame_t frameP,unsigned char cooperation_flag,sub_frame_t subframeP, unsigned char sched_subframe,
580 581
                    unsigned int *nCCE)  //,int calibration_flag) {
{
gauthier's avatar
 
gauthier committed
582 583


584 585 586 587
  unsigned int nCCE_available[MAX_NUM_CCs];
  uint16_t first_rb[MAX_NUM_CCs],i;
  int CC_id;
  eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP];
gauthier's avatar
 
gauthier committed
588

589
  start_meas(&eNB->schedule_ulsch);
gauthier's avatar
 
gauthier committed
590 591


592
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
gauthier's avatar
 
gauthier committed
593

594 595
    first_rb[CC_id] = 1;
    nCCE_available[CC_id] = mac_xface->get_nCCE_max(module_idP,CC_id) - nCCE[CC_id];
gauthier's avatar
 
gauthier committed
596

597 598 599 600
    // UE data info;
    // check which UE has data to transmit
    // function to decide the scheduling
    // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB)
gauthier's avatar
 
gauthier committed
601

602 603
    // default function for default scheduling
    //
gauthier's avatar
 
gauthier committed
604

605 606 607 608
    // output of scheduling, the UE numbers in RBs, where it is in the code???
    // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3
    // Msg3 is using 1 PRB so we need to increase first_rb accordingly
    // not sure about the break (can there be more than 1 active RA procedure?)
gauthier's avatar
 
gauthier committed
609

610 611 612 613
    for (i=0; i<NB_RA_PROC_MAX; i++) {
      if ((eNB->common_channels[CC_id].RA_template[i].RA_active == TRUE) &&
          (eNB->common_channels[CC_id].RA_template[i].generate_rar == 0) &&
          (eNB->common_channels[CC_id].RA_template[i].Msg3_subframe == sched_subframe)) {
knopp's avatar
knopp committed
614
	//leave out first RB for PUCCH
615 616 617
        first_rb[CC_id]++;
        break;
      }
knopp's avatar
 
knopp committed
618
    }
knopp's avatar
knopp committed
619 620 621 622 623 624

    /*
    if (mac_xface->is_prach_subframe(&(mac_xface->lte_frame_parms),frameP,subframeP)) {
      first_rb[CC_id] = (mac_xface->get_prach_prb_offset(&(mac_xface->lte_frame_parms),
    */

625
  }
626

627
  schedule_ulsch_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, nCCE, nCCE_available, first_rb);
gauthier's avatar
 
gauthier committed
628

629
#ifdef CBA
630
  schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, nCCE, nCCE_available, first_rb);
631 632
#endif

knopp's avatar
 
knopp committed
633

634
  stop_meas(&eNB->schedule_ulsch);
gauthier's avatar
 
gauthier committed
635

636 637 638 639 640 641 642 643 644 645 646
}



void schedule_ulsch_rnti(module_id_t   module_idP,
                         unsigned char cooperation_flag,
                         frame_t       frameP,
                         sub_frame_t   subframeP,
                         unsigned char sched_subframe,
                         unsigned int *nCCE,
                         unsigned int *nCCE_available,
647 648 649 650 651 652 653 654 655 656 657 658 659
                         uint16_t     *first_rb)
{

  int                UE_id;
  uint8_t            aggregation    = 2;
  rnti_t             rnti           = -1;
  uint8_t            round          = 0;
  uint8_t            harq_pid       = 0;
  void              *ULSCH_dci      = NULL;
  LTE_eNB_UE_stats  *eNB_UE_stats   = NULL;
  DCI_PDU           *DCI_pdu;
  uint8_t                 status         = 0;
  uint8_t                 rb_table_index = -1;
knopp's avatar
knopp committed
660
  uint16_t                TBS = 0;
661 662 663 664 665
  int32_t                buffer_occupancy=0;
  uint32_t                cqi_req,cshift,ndi,mcs,rballoc,tpc;
  int32_t                 normalized_rx_power, target_rx_power=-90;
  static int32_t          tpc_accumulated=0;

666
  int n,CC_id = 0;
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
  eNB_MAC_INST      *eNB=&eNB_mac_inst[module_idP];
  UE_list_t         *UE_list=&eNB->UE_list;
  UE_TEMPLATE       *UE_template;
  int                rvidx_tab[4] = {0,2,3,1};
  LTE_DL_FRAME_PARMS   *frame_parms;


  //  LOG_I(MAC,"entering ulsch preprocesor\n");

  ulsch_scheduler_pre_processor(module_idP,
                                frameP,
                                subframeP,
                                first_rb,
                                aggregation,
                                nCCE);

  //  LOG_I(MAC,"exiting ulsch preprocesor\n");

  // loop over all active UEs
  for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) {

    // don't schedule if Msg4 is not received yet
689
    if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
690
      continue;
691
    }
692 693 694

    rnti = UE_RNTI(module_idP,UE_id);

695
    if (rnti==NOT_A_RNTI) {
696
      LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id);
697 698
      continue;
    }
gauthier's avatar
 
gauthier committed
699

700 701 702 703 704 705
    // loop over all active UL CC_ids for this UE
    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
      // This is the actual CC_id in the list
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
      frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);
      eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
gauthier's avatar
 
gauthier committed
706

707 708 709 710 711 712 713 714 715
      if (eNB_UE_stats==NULL) {
        LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,CC_id);
        continue; // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
      }

      if (nCCE_available[CC_id] < (1<<aggregation)) {
        LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d CC %d: not enough nCCE (%d)\n", module_idP,frameP,subframeP,UE_id,CC_id,nCCE_available[CC_id]);
        continue; // break;
      }
gauthier's avatar
 
gauthier committed
716 717


718
      if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
gauthier's avatar
 
gauthier committed
719

720 721
        DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
        UE_template = &UE_list->UE_template[CC_id][UE_id];
gauthier's avatar
 
gauthier committed
722

723
        if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,1) == -1 ) {
724
          LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
725 726 727 728 729 730 731
                module_idP,frameP,subframeP, UE_id, CC_id, rnti);
          //  NN --> RK: Don't schedule UE if we cannot get harq pid
          //should we continue or set harq_pid to 0?
          continue;
        } else
          LOG_T(MAC,"[eNB %d] Frame %d, subframeP %d, UE %d CC %d : got harq pid %d  round %d (nCCE %d, rnti %x,mode %s)\n",
                module_idP,frameP,subframeP,UE_id,CC_id, harq_pid, round,nCCE[CC_id],rnti,mode_string[eNB_UE_stats->mode]);
gauthier's avatar
 
gauthier committed
732

733

knopp's avatar
 
knopp committed
734

735
#ifndef EXMIMO_IOT
736 737 738

        if (((UE_is_to_be_scheduled(module_idP,CC_id,UE_id)>0)) || (round>0) || ((frameP%10)==0))
          // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames
739
#else
740
        if (round==0)
741
#endif
742 743 744 745
        {
          // reset the scheduling request
          UE_template->ul_SR = 0;
          aggregation = process_ue_cqi(module_idP,UE_id); // =2 by default!!
746
          status = mac_eNB_get_rrc_status(module_idP,rnti);
747 748 749 750 751 752 753
          cqi_req = (status < RRC_CONNECTED)? 0:1;

          //power control
          //compute the expected ULSCH RX power (for the stats)

          // this is the normalized RX power and this should be constant (regardless of mcs
          normalized_rx_power = eNB_UE_stats->UL_rssi[0];
knopp's avatar
knopp committed
754
          target_rx_power = mac_xface->get_target_pusch_rx_power(module_idP,CC_id);
755 756

          // this assumes accumulated tpc
kaltenbe's avatar
kaltenbe committed
757
	  // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
knopp's avatar
knopp committed
758 759 760
          if (((UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe)%10240)<(frameP*10+subframeP+10)) {
	    UE_template->pusch_tpc_tx_frame=frameP;
	    UE_template->pusch_tpc_tx_subframe=subframeP;
761 762 763 764 765 766
            if (normalized_rx_power>(target_rx_power+1)) {
              tpc = 0; //-1
              tpc_accumulated--;
            } else if (normalized_rx_power<(target_rx_power-1)) {
              tpc = 2; //+1
              tpc_accumulated++;
767
            } else {
768
              tpc = 1; //0
769
            }
knopp's avatar
knopp committed
770 771
	    LOG_I(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
		  module_idP,frameP,subframeP,harq_pid,tpc,
kaltenbe's avatar
kaltenbe committed
772
		  tpc_accumulated,normalized_rx_power,target_rx_power);
773
          } else {
774
            tpc = 1; //0
775
          }
776 777 778 779 780 781

          // new transmission
          if (round==0) {

            ndi = 1-UE_template->oldNDI_UL[harq_pid];
            UE_template->oldNDI_UL[harq_pid]=ndi;
782 783 784
	    UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power;
	    UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power;
	    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul;
785 786
            mcs = cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS

787
            if (UE_template->pre_allocated_rb_table_index_ul >=0) {
788
              rb_table_index=UE_template->pre_allocated_rb_table_index_ul;
789
            } else {
790
	      mcs=cmin (10, openair_daq_vars.target_ue_ul_mcs);
791
              rb_table_index=5; // for PHR
792
	    }
793 794 795 796 797 798 799 800 801 802

            UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs;
            buffer_occupancy = UE_template->ul_total_buffer;

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

            TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]);
803 804
	    UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index];
	    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=TBS;
805 806 807 808 809 810 811 812 813
            buffer_occupancy -= TBS;
            rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL,
                                            first_rb[CC_id],
                                            rb_table[rb_table_index]);
            // increment for next UE allocation
            first_rb[CC_id]+=rb_table[rb_table_index];
            //store for possible retransmission
            UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index];

814 815
            LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n",
                  module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs,
816 817 818 819 820 821 822 823 824 825 826
                  first_rb[CC_id],rb_table[rb_table_index],
                  rb_table_index,TBS,harq_pid);
            // Adjust BSR entries for LCGIDs
            adjust_bsr_info(buffer_occupancy,
                            TBS,
                            UE_template);

          } else if (round > 0) { //we schedule a retransmission

            ndi = UE_template->oldNDI_UL[harq_pid];

827
            if ((round&3)==0) {
828
              mcs = openair_daq_vars.target_ue_ul_mcs;
829
            } else {
830 831
              mcs = rvidx_tab[round&3] + 28; //not correct for round==4!

832
            }
833

834
            LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n",
835
                  module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs,
836
                  first_rb[CC_id],UE_template->nb_rb_ul[harq_pid],
837
		  harq_pid, round);
838 839 840 841 842

            rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL,
                                            first_rb[CC_id],
                                            UE_template->nb_rb_ul[harq_pid]);
            first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid];  // increment for next UE allocation
843 844 845 846 847 848 849
         
	    UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1;
	    UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid];
	    UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid];
	    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs;
	    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs;
	  }
850 851 852

          // Cyclic shift for DM RS
          if(cooperation_flag == 2) {
853
            if(UE_id == 1) { // For Distriibuted Alamouti, cyclic shift applied to 2nd UE
854
              cshift = 1;
855
            } else {
856
              cshift = 0;
857 858
            }
          } else {
859
            cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
860
          }
861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 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 908 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 938 939 940 941 942 943 944 945