eNB_scheduler_ulsch.c 55.4 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

Lionel Gauthier's avatar
 
Lionel Gauthier committed
28
 *******************************************************************************/
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
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};

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

  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;
90
  int crnti_rx=0;
91 92 93 94

  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

99
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,1);
100
  if (opt_enabled == 1) {
101
    trace_pdu(0, sduP,sdu_lenP, 0, 3, rntiP,subframeP, 0,0);
102
    LOG_D(OPT,"[eNB %d][ULSCH] Frame %d  rnti %x  with size %d\n",
103
    		  enb_mod_idP, frameP, rntiP, sdu_lenP);
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
      UE_id = find_UE_id(enb_mod_idP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
130
      LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n",enb_mod_idP, CC_idP, rx_ces[i], i,num_ce,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1],UE_id);
131
      crnti_rx=1;
132
      payload_ptr+=2;
133

134
      if (msg3_flagP != NULL) {
135
	*msg3_flagP = 0;
136
      }
137 138 139 140
      break;

    case TRUNCATED_BSR:
    case SHORT_BSR: {
141 142 143 144 145 146
      uint8_t lcgid;
      lcgid = (payload_ptr[0] >> 6);

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

147 148 149
      if (crnti_rx==1)
	LOG_I(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);
150
      if (UE_id  != -1) {
151

152 153
        UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f);

154
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
155
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
156
        }
157
      }
158
      else {
159

160
      }
161
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
Raymond Knopp's avatar
 
Raymond Knopp committed
162
    }
163
    break;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
164

165 166 167 168 169 170 171 172
    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);
173
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
174
              "%u LCGID2 = %u LCGID3 = %u\n",
175
              enb_mod_idP, CC_idP,
176 177 178 179 180
              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]);
181 182
      if (crnti_rx==1)
        LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
183
              "%u LCGID2 = %u LCGID3 = %u\n",
184
              enb_mod_idP, CC_idP,
185 186 187 188 189 190
              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]);

191
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) {
192
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0;
193
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) {
194
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP;
195
        }
196

197
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) {
198
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0;
199
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) {
200
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP;
201
        }
202

203
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0 ) {
204
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=0;
205
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) {
206
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=frameP;
207
        }
208

209
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0 ) {
210
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]= 0;
211
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) {
212 213
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]=frameP;

214
        }
215 216 217 218 219 220
      }

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

    default:
221
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
222 223 224 225 226 227 228
      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]);

229 230
    if (rx_lcids[i] == CCCH) {

231 232
      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,
233 234 235
            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++) {
236
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n",
237
              enb_mod_idP, CC_idP, ii,
238 239
              eNB->common_channels[CC_idP].RA_template[ii].rnti, rntiP,
              eNB->common_channels[CC_idP].RA_template[ii].RA_active);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
240

241 242
        if ((eNB->common_channels[CC_idP].RA_template[ii].rnti==rntiP) &&
            (eNB->common_channels[CC_idP].RA_template[ii].RA_active==TRUE)) {
Lionel Gauthier's avatar
 
Lionel Gauthier committed
243

244
          //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
245

246 247
          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
248
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %d\n",
249
                  enb_mod_idP,CC_idP,frameP,rx_lengths[i],payload_ptr-sduP);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
250

251
            if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pidP)) == -1 ) {
252
              mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n");
kaltenbe's avatar
kaltenbe committed
253
	      // kill RA procedure
254
            } else
255 256
              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);
257
          } else {
knopp's avatar
knopp committed
258
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %d\n",
259
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP);
kaltenbe's avatar
kaltenbe committed
260
	    // kill RA procedure
261
          }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
262

263
          if (Is_rrc_registered == 1)
264 265
            mac_rrc_data_ind(
              enb_mod_idP,
266
              CC_idP,
267
              frameP,subframeP,
268 269 270
              rntiP,
              CCCH,
              (uint8_t*)payload_ptr,
271
              rx_lengths[i],
272 273 274
              ENB_FLAG_YES,
              enb_mod_idP,
              0);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
275 276


277 278 279
          if (num_ce >0) {  // handle msg3 which is not RRCConnectionRequest
            //  process_ra_message(msg3,num_ce,rx_lcids,rx_ces);
          }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
280

281 282
          eNB->common_channels[CC_idP].RA_template[ii].generate_Msg4 = 1;
          eNB->common_channels[CC_idP].RA_template[ii].wait_ack_Msg4 = 0;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
283

284 285
        } // if process is active
      } // loop on RA processes
Lionel Gauthier's avatar
 
Lionel Gauthier committed
286 287


288
    } else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) {
289
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
Lionel Gauthier's avatar
 
Lionel Gauthier committed
290

Raymond Knopp's avatar
 
Raymond Knopp committed
291
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
292
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
293
      for (j=0; j<32; j++) {
294
        LOG_T(MAC,"%x ",payload_ptr[j]);
295
      }
296
      LOG_T(MAC,"\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
297
#endif
Lionel Gauthier's avatar
 
Lionel Gauthier committed
298

299 300 301
      if (UE_id != -1) {
        //  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) {
302 303 304
          LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH%d, received %d bytes form UE %d \n",
                enb_mod_idP,CC_idP,frameP, rx_lcids[i], rx_lengths[i], UE_id);
	  
305
          mac_rlc_data_ind(
306 307 308 309 310 311 312 313 314 315 316
			   enb_mod_idP,
			   rntiP,
			   enb_mod_idP,
			   frameP,
			   ENB_FLAG_YES,
			   MBMS_FLAG_NO,
			   rx_lcids[i],
			   (char *)payload_ptr,
			   rx_lengths[i],
			   1,
			   NULL);//(unsigned int*)crc_status);
317 318 319 320
          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];
        }
      } /* UE_id != -1 */
321 322
      
    } else if ((rx_lcids[i]  < NB_RB_MAX) && (rx_lcids[i] > DCCH1 )) {
323
      LOG_I(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH%d, received %d bytes form UE %d \n",
324
	    enb_mod_idP,CC_idP,frameP, rx_lcids[i], rx_lengths[i], UE_id);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
325

Raymond Knopp's avatar
 
Raymond Knopp committed
326
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
327
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
328
      for (j=0; j<32; j++) {
329
        LOG_T(MAC,"%x ",payload_ptr[j]);
330
      }
331 332 333
      LOG_T(MAC,"\n");
#endif

334 335 336
      if (UE_id != -1) {
        if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) &&  (rx_lengths[i] > 0) ) {   // MAX SIZE OF transport block
          mac_rlc_data_ind(
337 338 339 340 341 342 343 344 345 346 347 348
			   enb_mod_idP,
			   rntiP,
			   enb_mod_idP,
			   frameP,
			   ENB_FLAG_YES,
			   MBMS_FLAG_NO,
			   rx_lcids[i],
			   (char *)payload_ptr,
			   rx_lengths[i],
			   1,
			   NULL);//(unsigned int*)crc_status);

349 350 351
          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];
        }
352 353 354 355 356
      } else { /* UE_id != -1 */
	UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
      }    
    } else {
      UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
357 358
      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);
Raymond Knopp's avatar
 
Raymond Knopp committed
359
    }
360
    
361 362 363 364 365
    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)) {
366 367
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
368 369 370

    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
371
        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);
372 373
        *msg3_flagP=0;
      }
374
    }
375
  } else {
376 377 378 379 380
    if (UE_id != -1) {
      UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx=sdu_lenP;
      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;
    }
381 382
  }

383
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
384
  stop_meas(&eNB->rx_ulsch_sdu);
Raymond Knopp's avatar
 
Raymond Knopp committed
385 386 387
}


388 389
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
390

391
  uint32_t i=0;
392

393
  if (nbytes<0) {
394
    return(0);
395
  }
396

397 398 399 400 401 402
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
403 404
}

405
void adjust_bsr_info(int buffer_occupancy,
Lionel Gauthier's avatar
 
Lionel Gauthier committed
406
                     uint16_t TBS,
407 408 409 410 411 412 413 414 415 416 417 418 419
                     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]];
Lionel Gauthier's avatar
 
Lionel Gauthier committed
420
        UE_template->bsr_info[LCGID1] = 0;
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439

        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);
440
    }
441 442 443 444 445 446
  } 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;
  }
447 448 449


}
450

451 452
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
453

454 455 456
  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;
457

458
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
459 460 461

}

Raymond Knopp's avatar
 
Raymond Knopp committed
462 463 464
// This seems not to be used anymore
/*
int schedule_next_ulue(module_id_t module_idP, int UE_id, sub_frame_t subframeP){
465

Raymond Knopp's avatar
 
Raymond Knopp committed
466
  int next_ue;
467 468 469

  // first phase: scheduling for ACK
  switch (subframeP) {
Raymond Knopp's avatar
 
Raymond Knopp committed
470
    // scheduling for subframeP 2: for scheduled user during subframeP 5 and 6
471
  case 8:
Raymond Knopp's avatar
 
Raymond Knopp committed
472
    if  ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
473
   (eNB_dlsch_info[module_idP][UE_id].subframe == 5 || eNB_dlsch_info[module_idP][UE_id].subframe == 6)){
Raymond Knopp's avatar
 
Raymond Knopp committed
474 475 476
      // set the downlink status
      eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
      return UE_id;
477 478 479 480
    }
    break;
    // scheduling for subframeP 3: for scheduled user during subframeP 7 and 8
  case 9:
Raymond Knopp's avatar
 
Raymond Knopp committed
481
    if  ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
482
   (eNB_dlsch_info[module_idP][UE_id].subframe == 7 || eNB_dlsch_info[module_idP][UE_id].subframe == 8)){
Raymond Knopp's avatar
 
Raymond Knopp committed
483 484
      eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
      return UE_id;
485 486 487 488
    }
    break;
    // scheduling UL subframeP 4: for scheduled user during subframeP 9 and 0
  case 0 :
Raymond Knopp's avatar
 
Raymond Knopp committed
489
    if  ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
490
   (eNB_dlsch_info[module_idP][UE_id].subframe == 9 || eNB_dlsch_info[module_idP][UE_id].subframe == 0)){
Raymond Knopp's avatar
 
Raymond Knopp committed
491 492
      eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
      return UE_id;
493 494 495 496 497 498 499 500 501
    }
    break;
  default:
    break;
  }

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

Raymond Knopp's avatar
 
Raymond Knopp committed
502 503 504 505 506
    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;
    }
507 508
  }
  for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ){
Raymond Knopp's avatar
 
Raymond Knopp committed
509 510
    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;
511 512 513 514 515
  }
  next_ue = 0;
  return next_ue;

}
Lionel Gauthier's avatar
 
Lionel Gauthier committed
516
 */
517 518 519 520 521 522





unsigned char *parse_ulsch_header(unsigned char *mac_header,
Lionel Gauthier's avatar
 
Lionel Gauthier committed
523 524 525 526 527
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
528 529 530 531 532 533 534 535 536
                                  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) {

537
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
538
      not_done = 0;
539
    }
540 541 542 543 544 545 546 547

    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;

548
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
549
          length -= rx_lengths[num_sdu_cnt];
550
        }
551 552 553 554 555 556 557
      } 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);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
558
        }
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
      }

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

574
        if (lcid==LONG_BSR) {
575
          ce_len+=3;
576
        } else if (lcid==CRNTI) {
577
          ce_len+=2;
578
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
579
          ce_len++;
580
        } else {
581 582
          LOG_E(MAC,"unknown CE %d \n", lcid);
          mac_xface->macphy_exit("unknown CE");
Lionel Gauthier's avatar
 
Lionel Gauthier committed
583
        }
584
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
585
    }
586
  }
587

588 589 590 591
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
592 593 594
}


595 596 597 598 599 600
void schedule_ulsch(module_id_t module_idP, 
		    frame_t frameP,
		    unsigned char cooperation_flag,
		    sub_frame_t subframeP, 
		    unsigned char sched_subframe) {

Lionel Gauthier's avatar
 
Lionel Gauthier committed
601 602


603 604 605
  uint16_t first_rb[MAX_NUM_CCs],i;
  int CC_id;
  eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP];
Lionel Gauthier's avatar
 
Lionel Gauthier committed
606

607
  start_meas(&eNB->schedule_ulsch);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
608 609


610
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Lionel Gauthier's avatar
 
Lionel Gauthier committed
611

612
    first_rb[CC_id] = 1;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
613

614 615 616 617
    // UE data info;
    // check which UE has data to transmit
    // function to decide the scheduling
    // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB)
Lionel Gauthier's avatar
 
Lionel Gauthier committed
618

619 620
    // default function for default scheduling
    //
Lionel Gauthier's avatar
 
Lionel Gauthier committed
621

622 623 624 625
    // 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?)
Lionel Gauthier's avatar
 
Lionel Gauthier committed
626

627 628 629 630
    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)) {
631
	//leave out first RB for PUCCH
632 633 634
        first_rb[CC_id]++;
        break;
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
635
    }
636 637 638 639 640 641

    /*
    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),
    */

642
  }
643

644
  schedule_ulsch_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe,first_rb);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
645

646
#ifdef CBA
647
  schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, first_rb);
648 649
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
650

651
  stop_meas(&eNB->schedule_ulsch);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
652

653 654 655 656 657 658 659 660 661
}



void schedule_ulsch_rnti(module_id_t   module_idP,
                         unsigned char cooperation_flag,
                         frame_t       frameP,
                         sub_frame_t   subframeP,
                         unsigned char sched_subframe,
662 663 664 665 666 667 668 669 670 671 672 673 674
                         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;
675
  uint16_t                TBS = 0;
676 677 678 679 680
  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;

681
  int n,CC_id = 0;
682 683 684 685 686 687 688 689 690 691 692 693 694
  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,
695
                                aggregation);
696 697 698 699 700 701 702

  //  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
703
    if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
704
      continue;
705
    }
706 707 708

    rnti = UE_RNTI(module_idP,UE_id);

709
    if (rnti==NOT_A_RNTI) {
710
      LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id);
711 712
      continue;
    }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
713

714 715 716 717 718 719
    // 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);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
720

721 722 723 724 725
      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");
      }

726 727
      if (CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)) {
        LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
728 729
        continue; // break;
      }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
730

731
      //      printf("UE %d/%x is feasible, mode %s\n",UE_id,rnti,mode_string[eNB_UE_stats->mode]);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
732

733
      if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
Lionel Gauthier's avatar
 
Lionel Gauthier committed
734

735 736
        DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
        UE_template = &UE_list->UE_template[CC_id][UE_id];
Lionel Gauthier's avatar
 
Lionel Gauthier committed
737

738
        if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,1) == -1 ) {
739
          LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
740 741 742 743 744
                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
745 746
          LOG_T(MAC,"[eNB %d] Frame %d, subframeP %d, UE %d CC %d : got harq pid %d  round %d (rnti %x,mode %s)\n",
                module_idP,frameP,subframeP,UE_id,CC_id, harq_pid, round,rnti,mode_string[eNB_UE_stats->mode]);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
747

748
	//#undef EXMIMO_IOT
749
#ifndef EXMIMO_IOT
750 751 752

        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
753
#else
754
        if (round==0)
755
#endif
756 757 758 759
        {
          // reset the scheduling request
          UE_template->ul_SR = 0;
          aggregation = process_ue_cqi(module_idP,UE_id); // =2 by default!!
760
          status = mac_eNB_get_rrc_status(module_idP,rnti);
761 762 763 764 765 766 767
          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];
768
          target_rx_power = mac_xface->get_target_pusch_rx_power(module_idP,CC_id);
769 770

          // this assumes accumulated tpc
kaltenbe's avatar
kaltenbe committed
771
	  // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
772 773 774 775
	  int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe;
          if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case
	      ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around
	    {
776 777
	    UE_template->pusch_tpc_tx_frame=frameP;
	    UE_template->pusch_tpc_tx_subframe=subframeP;
778 779 780 781 782 783
            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++;
784
            } else {
785
              tpc = 1; //0
786 787
            }
          } else {
788
            tpc = 1; //0
789
          }
790

791
	  if (tpc!=1) {
navid's avatar
navid committed
792
	    LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
793 794 795 796
		  module_idP,frameP,subframeP,harq_pid,tpc,
		  tpc_accumulated,normalized_rx_power,target_rx_power);
	  }

797 798 799 800 801
          // new transmission
          if (round==0) {

            ndi = 1-UE_template->oldNDI_UL[harq_pid];
            UE_template->oldNDI_UL[harq_pid]=ndi;
802 803 804
	    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;
805 806
            mcs = cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS

807
            if (UE_template->pre_allocated_rb_table_index_ul >=0) {
808
              rb_table_index=UE_template->pre_allocated_rb_table_index_ul;
809
            } else {
810
	      mcs=cmin (10, openair_daq_vars.target_ue_ul_mcs);
811
              rb_table_index=5; // for PHR
812
	    }
813 814 815 816 817 818 819 820 821 822

            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]);
823 824
	    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;
825 826 827 828 829 830 831 832 833
            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];

834 835
            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,
836 837 838 839 840 841 842 843 844 845 846
                  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];

847
            if ((round&3)==0) {
848
              mcs = openair_daq_vars.target_ue_ul_mcs;
849
            } else {
850 851
              mcs = rvidx_tab[round&3] + 28; //not correct for round==4!

852
            }
853

854
            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",
855
                  module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs,
856
                  first_rb[CC_id],UE_template->nb_rb_ul[harq_pid],
857
		  harq_pid, round);
858 859 860 861 862

            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
863 864 865 866 867 868 869
         
	    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;
	  }
870 871 872

          // Cyclic shift for DM RS
          if(cooperation_flag == 2) {
873
            if(UE_id == 1) { // For Distriibuted Alamouti, cyclic shift applied to 2nd UE
874
              cshift = 1;
875
            } else {
876
              cshift = 0;
877 878
            }
          } else {
879
            cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
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 946 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 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 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 1048 1049 1050 1051 1052 1053 1054 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 1083 1084 1085 1086

          if (frame_parms->frame_type == TDD) {
            switch (frame_parms->N_RB_UL) {
            case 6:
              ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];

              ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
              ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs;
              ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = ndi;
              ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = tpc;
              ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cshift;
              ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->padding  = 0;
              ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_template->DAI_ul[sched_subframe];
              ((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = cqi_req;

              add_ue_spec_dci(DCI_pdu,
                              ULSCH_dci,
                              rnti,
                              sizeof(DCI0_1_5MHz_TDD_1_6_t),
                              aggregation,
                              sizeof_DCI0_1_5MHz_TDD_1_6_t,
                              format0,
                              0);
              break;

            default:
            case 25:
              ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];

              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = ndi;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = tpc;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cshift;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->padding  = 0;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_template->DAI_ul[sched_subframe];
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = cqi_req;

              add_ue_spec_dci(DCI_pdu,
                              ULSCH_dci,
                              rnti,
                              sizeof(DCI0_5MHz_TDD_1_6_t),
                              aggregation,
                              sizeof_DCI0_5MHz_TDD_1_6_t,
                              format0,
                              0);
              break;

            case 50:
              ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];

              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = ndi;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = tpc;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cshift;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->padding  = 0;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_template->DAI_ul[sched_subframe];
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = cqi_req;

              add_ue_spec_dci(DCI_pdu,
                              ULSCH_dci,
                              rnti,
                              sizeof(DCI0_10MHz_TDD_1_6_t),
                              aggregation,
                              sizeof_DCI0_10MHz_TDD_1_6_t,
                              format0,
                              0);
              break;

            case 100:
              ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];

              ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
              ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs;
              ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = ndi;
              ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = tpc;
              ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cshift;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->padding  = 0;
              ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_template->DAI_ul[sched_subframe];
              ((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = cqi_req;

              add_ue_spec_dci(DCI_pdu,
                              ULSCH_dci,
                              rnti,
                              sizeof(DCI0_20MHz_TDD_1_6_t),
                              aggregation,
                              sizeof_DCI0_20MHz_TDD_1_6_t,
                              format0,
                              0);
              break;
            }
          } // TDD
          else { //FDD
            switch (frame_parms->N_RB_UL) {
            case 25:
            default:

              ULSCH_dci          = UE_template->ULSCH_DCI[harq_pid];

              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->type     = 0;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->mcs      = mcs;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->ndi      = ndi;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->TPC      = tpc;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cshift   = cshift;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->padding  = 0;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cqi_req  = cqi_req;

              add_ue_spec_dci(DCI_pdu,
                              ULSCH_dci,
                              rnti,
                              sizeof(DCI0_5MHz_FDD_t),
                              aggregation,
                              sizeof_DCI0_5MHz_FDD_t,
                              format0,
                              0);
              break;

            case 6:
              ULSCH_dci          = UE_template->ULSCH_DCI[harq_pid];

              ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->type     = 0;
              ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->mcs      = mcs;
              ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->ndi      = ndi;
              ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->TPC      = tpc;
              ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cshift   = cshift;
              ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->padding  = 0;
              ((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cqi_req  = cqi_req;

              add_ue_spec_dci(DCI_pdu,
                              ULSCH_dci,
                              rnti,
                              sizeof(DCI0_1_5MHz_FDD_t),
                              aggregation,
                              sizeof_DCI0_1_5MHz_FDD_t,
                              format0,
                              0);
              break;

            case 50:
              ULSCH_dci          = UE_template->ULSCH_DCI[harq_pid];

              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->type     = 0;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->mcs      = mcs;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->ndi      = ndi;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->TPC      = tpc;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->padding  = 0;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cshift   = cshift;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cqi_req  = cqi_req;

              add_ue_spec_dci(DCI_pdu,
                              ULSCH_dci,
                              rnti,
                              sizeof(DCI0_10MHz_FDD_t),
                              aggregation,
                              sizeof_DCI0_10MHz_FDD_t,
                              format0,
                              0);
              break;

            case 100:
              ULSCH_dci          = UE_template->ULSCH_DCI[harq_pid];

              ((DCI0_20MHz_FDD_t *)ULSCH_dci)->type     = 0;
              ((DCI0_20MHz_FDD_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_20MHz_FDD_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_20MHz_FDD_t *)ULSCH_dci)->mcs      = mcs;
              ((DCI0_20MHz_FDD_t *)ULSCH_dci)->ndi      = ndi;
              ((DCI0_20MHz_FDD_t *)ULSCH_dci)->TPC      = tpc;
              ((DCI0_20MHz_FDD_t *)ULSCH_dci)->padding  = 0;
              ((DCI0_20MHz_FDD_t *)ULSCH_dci)->cshift   = cshift;
              ((DCI0_20MHz_FDD_t *)ULSCH_dci)->cqi_req  = cqi_req;

              add_ue_spec_dci(DCI_pdu,
                              ULSCH_dci,
                              rnti,
                              sizeof(DCI0_20MHz_FDD_t),
                              aggregation,
                              sizeof_DCI0_20MHz_FDD_t,
                              format0,
                              0);
              break;

            }
          }

          add_ue_ulsch_info(module_idP,
                            CC_id,
                            UE_id,
                            subframeP,
                            S_UL_SCHEDULED);

1087
          LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id);
1088
#ifdef DEBUG
1089
          dump_dci(frame_parms, &DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci-1]);
1090
#endif
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1091

1092 1093 1094 1095
        } // UE_is_to_be_scheduled
      } // UE is in PUSCH
    } // loop over UE_id
  } // loop of CC_id
1096 1097 1098
}

#ifdef CBA
1099
void schedule_ulsch_cba_rnti(module_id_t module_idP, unsigned char cooperation_flag, frame_t frameP, sub_frame_t subframeP, unsigned char sched_subframe, uint16_t *first_rb)
1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143
{

  eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP];
  UE_list_t         *UE_list=&eNB->UE_list;
  //UE_TEMPLATE       *UE_template;
  void              *ULSCH_dci      = NULL;
  DCI_PDU *DCI_pdu;
  uint8_t CC_id=0;
  uint8_t rb_table_index=0, aggregation=2;
  uint32_t rballoc;
  uint8_t cba_group, cba_resources;
  uint8_t required_rbs[NUM_MAX_CBA_GROUP];
  int8_t num_cba_resources[NUM_MAX_CBA_GROUP];// , weight[NUM_MAX_CBA_GROUP]
  // the following vars should become a vector [MAX_NUM_CCs]
  LTE_DL_FRAME_PARMS   *frame_parms;
  int8_t available_rbs=0;
  uint8_t remaining_rbs=0;
  uint8_t allocated_rbs=0;
  uint8_t total_UEs=UE_list->num_UEs;
  uint8_t active_UEs[NUM_MAX_CBA_GROUP];
  uint8_t total_groups=eNB_mac_inst[module_idP].common_channels[CC_id].num_active_cba_groups;
  int     min_rb_unit=2;
  uint8_t cba_policy=CBA_ES;
  int     UE_id;
  uint8_t mcs[NUM_MAX_CBA_GROUP];
  uint32_t total_cba_resources=0;
  uint32_t total_rbs=0;
  // We compute the weight of each group and initialize some variables

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

  for (cba_group=0; cba_group<total_groups; cba_group++) {
    // UEs in PUSCH with traffic
    //    weight[cba_group] = 0;
    required_rbs[cba_group] = 0;
    num_cba_resources[cba_group]=0;
    active_UEs[cba_group]=0;
    mcs[cba_group]=openair_daq_vars.target_ue_ul_mcs;
  }

  //LOG_D(MAC, "[eNB ] CBA granted ues are %d\n",granted_UEs );

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1144

1145 1146 1147 1148 1149
    frame_parms=mac_xface->get_lte_frame_parms(module_idP,CC_id);
    available_rbs=frame_parms->N_RB_DL-1-first_rb[CC_id];
    remaining_rbs=available_rbs;
    total_groups=eNB_mac_inst[module_idP].common_channels[CC_id].num_active_cba_groups;
    min_rb_unit=get_min_rb_unit(module_idP,CC_id);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1150

1151 1152
    if (available_rbs  < min_rb_unit )
      continue;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1153

1154 1155 1156 1157
    // remove this condition later
    // cba group template uses the exisitng UE template, and thus if a UE
    // is scheduled, the correspodning group can't be used for CBA
    // this can be fixed later
1158
    if (total_groups > 0)  {
1159 1160 1161
      DCI_pdu = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu;

      for (cba_group=0;
1162
           (cba_group<total_groups)   > (1<<aggregation));
1163 1164 1165 1166 1167
           cba_group++) {
        // equal weight
        //weight[cba_group] = floor(total_UEs/active_groups);//find_num_active_UEs_in_cbagroup(module_idP, cba_group);

        for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) {
1168
          if (UE_RNTI(module_idP,UE_id)==NOT_A_RNTI)
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1169 1170
            continue;

1171 1172 1173
          // simple UE identity based grouping
          if ((UE_id % total_groups) == cba_group) { // this could be simplifed to  active_UEs[UE_id % total_groups]++;
            if ((mac_get_rrc_status(module_idP,1,UE_id) > RRC_CONNECTED) &&
1174
                (UE_is_to_be_scheduled(module_idP,CC_id,UE_id) == 0)) {
1175
              active_UEs[cba_group]++;
1176
            }
1177 1178
          }

1179
          if (UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul <= 2) {
1180
            mcs[cba_group]= 8; // apply fixed scheduling
1181
          } else if ((UE_id % total_groups) == cba_group) {
1182
            mcs[cba_group]= cmin(mcs[cba_group],UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul);
1183
          }
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249
        }

        mcs[cba_group]= cmin(mcs[cba_group],openair_daq_vars.target_ue_ul_mcs);

        if (available_rbs < min_rb_unit )
          break;

        // If the group needs some resource
        // determine the total number of allocations (one or multiple DCIs): to be refined
        if ((active_UEs[cba_group] > 0) && (eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group] != 0)) {
          // to be refined in case of : total_UEs >> weight[cba_group]*available_rbs

          switch(cba_policy) {
          case CBA_ES:
            required_rbs[cba_group] = (uint8_t)floor(available_rbs/total_groups); // allocate equally among groups
            num_cba_resources[cba_group]=1;
            break;

            // can't have more than one allocation for the same group/UE
            /*  case CBA_ES_S:
            required_rbs[cba_group] = (uint8_t)floor(available_rbs/total_groups); // allocate equally among groups
            if (required_rbs[cba_group] > min_rb_unit)
            num_cba_resources[cba_group]=(uint8_t)(required_rbs[cba_group]/ min_rb_unit);
            break;*/
          case CBA_PF:
            required_rbs[cba_group] = (uint8_t)floor((active_UEs[cba_group]*available_rbs)/total_UEs);
            num_cba_resources[cba_group]=1;
            break;
            /* case CBA_PF_S:
            required_rbs[cba_group] = (uint8_t)ceil((active_UEs[cba_group]*available_rbs)/total_UEs);
            if (required_rbs[cba_group] > min_rb_unit)
            num_cba_resources[cba_group]=(uint8_t) floor(required_rbs[cba_group] / min_rb_unit);
            break;*/

          default:
            LOG_W(MAC,"unknown CBA policy\n");
            break;
          }

          total_cba_resources+=num_cba_resources[cba_group];
          total_rbs+=required_rbs[cba_group];

          /*  while ((remaining_rbs < required_rbs[cba_group]) &&
          (required_rbs[cba_group] > 0) &&
          (required_rbs[cba_group] < min_rb_unit ))
          required_rbs[cba_group]--;
           */

          /*
          while (rb_table[rb_table_index] < required_rbs[cba_group])
          rb_table_index++;

          while (rb_table[rb_table_index] > remaining_rbs )
          rb_table_index--;

          remaining_rbs-=rb_table[rb_table_index];
          required_rbs[cba_group]=rb_table[rb_table_index];
           */
          //    num_cba_resources[cba_group]=1;

        }
      }

      // phase 2 reduce the number of cba allocations among the groups
      cba_group=0;

1250
      if (total_cba_resources <= 0) {
1251
        return;
1252
      }
1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265

      // increase rb if any left: to be done
      cba_group=0;

      while (total_rbs  < available_rbs - 1 ) {
        required_rbs[cba_group%total_groups]++;
        total_rbs++;
        cba_group++;
      }

      // phase 3:
      for (cba_group=0; cba_group<total_groups; cba_group++) {

1266
        LOG_N(MAC,
1267
              "[eNB %d] CC_id %d Frame %d, subframe %d: cba group %d active_ues %d total groups %d mcs %d, available/required rb (%d/%d), num resources %d, ncce required %d \n",
1268
              module_idP, CC_id, frameP, subframeP, cba_group,active_UEs[cba_group],total_groups,
1269 1270
              mcs[cba_group], available_rbs,required_rbs[cba_group],
              num_cba_resources[cba_group],
1271
              (1<<aggregation) * num_cba_resources[cba_group]);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1272

1273 1274
        for (cba_resources=0; cba_resources < num_cba_resources[cba_group]; cba_resources++) {
          rb_table_index =0;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1275

1276 1277 1278 1279
          // check if there was an allocation for this group in the 1st phase
          if (required_rbs[cba_group] == 0 )
            continue;

1280
          while (rb_table[rb_table_index] < (uint8_t) ceil(required_rbs[cba_group] / num_cba_resources[cba_group]) ) {
1281
            rb_table_index++;
1282
          }
1283

1284
          while (rb_table[rb_table_index] > remaining_rbs ) {
1285
            rb_table_index--;
1286
          }
1287 1288 1289 1290 1291 1292 1293 1294 1295

          remaining_rbs-=rb_table[rb_table_index];
          allocated_rbs=rb_table[rb_table_index];

          rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL,
                                          first_rb[CC_id],
                                          rb_table[rb_table_index]);

          first_rb[CC_id]+=rb_table[rb_table_index];
1296
          LOG_N(MAC,
1297
                "[eNB %d] CC_id %d Frame %d, subframeP %d: schedule CBA access %d rnti %x, total/required/allocated/remaining rbs (%d/%d/%d/%d), mcs %d, rballoc %d\n",
1298
                module_idP, CC_id, frameP, subframeP, cba_group,eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group],
1299
                available_rbs, required_rbs[cba_group], allocated_rbs, remaining_rbs,
1300
                mcs[cba_group],rballoc);
1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350

          switch (frame_parms->N_RB_UL) {
          case 6:
            mac_xface->macphy_exit("[MAC][eNB] CBA RB=6 not supported \n");
            break;

          case 25:
            if (frame_parms->frame_type == TDD) {
              ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0];

              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs[cba_group];
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = 1;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = 1;//tpc;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cba_group;
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_list->UE_template[CC_id][cba_group].DAI_ul[sched_subframe];
              ((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = 1;

              //add_ue_spec_dci
              add_common_dci(DCI_pdu,
                             ULSCH_dci,
                             eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group],
                             sizeof(DCI0_5MHz_TDD_1_6_t),
                             aggregation,
                             sizeof_DCI0_5MHz_TDD_1_6_t,
                             format0,
                             0);
            } else {
              ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0];

              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->type     = 0;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->mcs      = mcs[cba_group];
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->ndi      = 1;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->TPC      = 1;//tpc;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cshift   = cba_group;
              ((DCI0_5MHz_FDD_t *)ULSCH_dci)->cqi_req  = 1;

              //add_ue_spec_dci
              add_common_dci(DCI_pdu,
                             ULSCH_dci,
                             eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group],
                             sizeof(DCI0_5MHz_FDD_t),
                             aggregation,
                             sizeof_DCI0_5MHz_FDD_t,
                             format0,
                             0);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1351 1352
            }

1353
            LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for CBA group %d, RB 25 format 0\n", module_idP,CC_id,frameP,subframeP,cba_group);
1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399
            break;

          case 50:
            if (frame_parms->frame_type == TDD) {
              ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0];

              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs[cba_group];
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = 1;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = 1;//tpc;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cba_group;
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_list->UE_template[CC_id][cba_group].DAI_ul[sched_subframe];
              ((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = 1;

              //add_ue_spec_dci
              add_common_dci(DCI_pdu,
                             ULSCH_dci,
                             eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group],
                             sizeof(DCI0_10MHz_TDD_1_6_t),
                             aggregation,
                             sizeof_DCI0_10MHz_TDD_1_6_t,
                             format0,
                             0);
            } else {
              ULSCH_dci = UE_list->UE_template[CC_id][cba_group].ULSCH_DCI[0];

              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->type     = 0;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->hopping  = 0;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->rballoc  = rballoc;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->mcs      = mcs[cba_group];
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->ndi      = 1;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->TPC      = 1;//tpc;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cshift   = cba_group;
              ((DCI0_10MHz_FDD_t *)ULSCH_dci)->cqi_req  = 1;

              //add_ue_spec_dci
              add_common_dci(DCI_pdu,
                             ULSCH_dci,
                             eNB_mac_inst[module_idP].common_channels[CC_id].cba_rnti[cba_group],
                             sizeof(DCI0_10MHz_FDD_t),
                             aggregation,
                             sizeof_DCI0_10MHz_FDD_t,
                             format0,
                             0);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1400
            }
1401

1402
            LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for CBA group %d, RB 50 format 0\n", module_idP,CC_id,frameP,subframeP,cba_group);
1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413
            break;

          case 100:
            mac_xface->macphy_exit("[MAC][eNB] CBA RB=100 not supported \n");
            break;

          default:
            break;
          }

          //      break;// for the moment only schedule one
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1414
        }
1415
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1416
    }
1417
  }
1418 1419
}
#endif