eNB_scheduler_ulsch.c 56 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:
roux's avatar
roux committed
129
130
131
132
133
134
135
136
      LOG_W(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received CRNTI %2.2x%2.2x\n",
            enb_mod_idP, CC_idP, rx_ces[i], payload_ptr[0], payload_ptr[1]);
      payload_ptr+=2;
      /* FIXME we don't process this CE yet */
      if (msg3_flagP != NULL) {
        LOG_W(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : CRNTI in Msg3 not handled\n");
        *msg3_flagP = 0;
      }
137
138
139
140
141
142
143
      break;

    case TRUNCATED_BSR:
    case SHORT_BSR: {
      if (UE_id  != -1) {
        uint8_t lcgid;
        lcgid = (payload_ptr[0] >> 6);
144
145
        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);
146
147
        UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f);

148
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
149
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
150
        }
151
152
153
      }

      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
   
knopp committed
154
    }
155
    break;
gauthier's avatar
   
gauthier committed
156

157
158
159
160
161
162
163
164
    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);
165
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
166
              "%u LCGID2 = %u LCGID3 = %u\n",
167
              enb_mod_idP, CC_idP,
168
169
170
171
172
173
              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]);

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

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

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

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

197
        }
198
199
200
201
202
203
      }

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

    default:
204
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
205
206
207
208
209
210
211
212
213
      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 :
214
215
      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,
216
217
218
            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++) {
219
220
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %p Checking proc %d : rnti (%x, %x), active %d\n",
              enb_mod_idP, CC_idP, ii,
221
222
              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
223

224
225
        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
226

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

229
230
          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
231
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %d\n",
232
                  enb_mod_idP,CC_idP,frameP,rx_lengths[ii],payload_ptr-sduP);
gauthier's avatar
   
gauthier committed
233

234
            if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pidP)) == -1 ) {
235
              mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n");
kaltenbe's avatar
kaltenbe committed
236
	      // kill RA procedure
237
            } else
238
239
              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);
240
          } else {
knopp's avatar
knopp committed
241
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %d\n",
242
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[ii],payload_ptr-sduP);
kaltenbe's avatar
kaltenbe committed
243
	    // kill RA procedure
244
          }
gauthier's avatar
   
gauthier committed
245

246
          if (Is_rrc_registered == 1)
247
248
            mac_rrc_data_ind(
              enb_mod_idP,
249
              CC_idP,
gauthier's avatar
gauthier committed
250
              frameP,subframeP,
251
252
253
254
255
256
257
              rntiP,
              CCCH,
              (uint8_t*)payload_ptr,
              rx_lengths[ii],
              ENB_FLAG_YES,
              enb_mod_idP,
              0);
gauthier's avatar
   
gauthier committed
258
259


260
261
262
          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
263

264
265
          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
266

267
268
        } // if process is active
      } // loop on RA processes
gauthier's avatar
   
gauthier committed
269

270
      break;
gauthier's avatar
   
gauthier committed
271

272
273
274
    case  DCCH :
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
gauthier's avatar
   
gauthier committed
275

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

279
      for (j=0; j<32; j++) {
280
        LOG_T(MAC,"%x ",payload_ptr[j]);
281
      }
282
283

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

roux's avatar
roux committed
286
287
288
289
290
291
292
293
294
      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) {
          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]);

          mac_rlc_data_ind(
            enb_mod_idP,
            rntiP,
gauthier's avatar
gauthier committed
295
	      enb_mod_idP,
roux's avatar
roux committed
296
297
298
299
300
301
302
303
304
305
306
307
            frameP,
            ENB_FLAG_YES,
            MBMS_FLAG_NO,
            rx_lcids[i],
            (char *)payload_ptr,
            rx_lengths[i],
            1,
            NULL);//(unsigned int*)crc_status);
          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 */
308
309
310
311
312
313

      //      }
      break;

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

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

318
      for (j=0; j<32; j++) {
319
        LOG_T(MAC,"%x ",payload_ptr[j]);
320
      }
gauthier's avatar
   
gauthier committed
321

322
323
324
      LOG_T(MAC,"\n");
#endif

325
326
      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]);
327

roux's avatar
roux committed
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
      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(
            enb_mod_idP,
            rntiP,
            enb_mod_idP,
            frameP,
            ENB_FLAG_YES,
            MBMS_FLAG_NO,
            DTCH,
            (char *)payload_ptr,
            rx_lengths[i],
            1,
            NULL);//(unsigned int*)crc_status);
          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 */
346
347
348
349
350

      //      }
      break;

    default :  //if (rx_lcids[i] >= DTCH) {
roux's avatar
roux committed
351
352
      if (UE_id != -1)
        UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
353
354
      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);
355
      break;
knopp's avatar
   
knopp committed
356
    }
357
358
359
360
361
362

    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)) {
roux's avatar
roux committed
363
364
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
365
366
367

    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
368
        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);
369
370
        *msg3_flagP=0;
      }
371
    }
372
  } else {
roux's avatar
roux committed
373
374
375
376
377
    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;
    }
378
379
  }

gauthier's avatar
gauthier committed
380
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
381
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
   
knopp committed
382
383
384
}


385
386
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
387

388
  uint32_t i=0;
389

390
  if (nbytes<0) {
391
    return(0);
392
  }
393

394
395
396
397
398
399
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
400
401
}

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

        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);
437
    }
438
439
440
441
442
443
  } 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;
  }
444
445
446


}
447

448
449
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
450

451
452
453
  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;
454

455
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
456
457
458

}

knopp's avatar
   
knopp committed
459
460
461
// This seems not to be used anymore
/*
int schedule_next_ulue(module_id_t module_idP, int UE_id, sub_frame_t subframeP){
462

knopp's avatar
   
knopp committed
463
  int next_ue;
464
465
466

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

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

knopp's avatar
   
knopp committed
499
500
501
502
503
    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;
    }
504
505
  }
  for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ){
knopp's avatar
   
knopp committed
506
507
    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;
508
509
510
511
512
  }
  next_ue = 0;
  return next_ue;

}
gauthier's avatar
   
gauthier committed
513
 */
514
515
516
517
518
519





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

534
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
535
      not_done = 0;
536
    }
537
538
539
540
541
542
543
544

    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;

545
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
546
          length -= rx_lengths[num_sdu_cnt];
547
        }
548
549
550
551
552
553
554
      } 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
555
        }
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
      }

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

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

585
586
587
588
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
589
590
591
}


592
void schedule_ulsch(module_id_t module_idP, frame_t frameP,unsigned char cooperation_flag,sub_frame_t subframeP, unsigned char sched_subframe,
593
594
                    unsigned int *nCCE)  //,int calibration_flag) {
{
gauthier's avatar
   
gauthier committed
595
596


597
598
599
600
  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
601

602
  start_meas(&eNB->schedule_ulsch);
gauthier's avatar
   
gauthier committed
603
604


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

607
608
    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
609

610
611
612
613
    // 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
614

615
616
    // default function for default scheduling
    //
gauthier's avatar
   
gauthier committed
617

618
619
620
621
    // 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
622

623
624
625
626
    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
627
	//leave out first RB for PUCCH
628
629
630
        first_rb[CC_id]++;
        break;
      }
knopp's avatar
   
knopp committed
631
    }
knopp's avatar
knopp committed
632
633
634
635
636
637

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

638
  }
639

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

642
#ifdef CBA
643
  schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, nCCE, nCCE_available, first_rb);
644
645
#endif

knopp's avatar
   
knopp committed
646

647
  stop_meas(&eNB->schedule_ulsch);
gauthier's avatar
   
gauthier committed
648

649
650
651
652
653
654
655
656
657
658
659
}



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,
660
661
662
663
664
665
666
667
668
669
670
671
672
                         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
673
  uint16_t                TBS = 0;
674
675
676
677
678
  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;

679
  int n,CC_id = 0;
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
  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
702
    if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
703
      continue;
704
    }
705
706
707

    rnti = UE_RNTI(module_idP,UE_id);

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

713
714
715
716
717
718
    // 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
719

720
721
722
723
724
725
726
727
728
      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
729
730


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

733
734
        DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
        UE_template = &UE_list->UE_template[CC_id][UE_id];
gauthier's avatar
   
gauthier committed
735

736
        if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,1) == -1 ) {
737
          LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
738
739
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
          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
745

746

knopp's avatar
   
knopp committed
747

748
#ifndef EXMIMO_IOT
749
750
751

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

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

790
	  if (tpc!=1) {
navid's avatar
navid committed
791
	    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",
792
793
794
795
		  module_idP,frameP,subframeP,harq_pid,tpc,
		  tpc_accumulated,normalized_rx_power,target_rx_power);
	  }

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

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

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

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

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

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

851
            }
852

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

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

          // Cyclic shift for DM RS
          if(cooperation_flag == 2) {
872
            if(UE_id == 1) { // For Distriibuted Alamouti, cyclic shift applied to 2nd UE
873
              cshift = 1;
874
            } else {
875
              cshift = 0;
876
877
            }
          } else {
878
            cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
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
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

          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,
For faster browsing, not all history is shown. View entire blame