eNB_scheduler_ulsch.c 56.5 KB
Newer Older
1 2 3 4 5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
Cedric Roux's avatar
Cedric Roux committed
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
nikaeinn's avatar
nikaeinn committed
21 22 23

/*! \file eNB_scheduler_ulsch.c
 * \brief eNB procedures for the ULSCH transport channel
24 25 26
 * \author Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \email: navid.nikaein@eurecom.fr
nikaeinn's avatar
nikaeinn committed
27
 * \version 1.0
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
 * @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

Cedric Roux's avatar
Cedric Roux committed
58 59
#include "T.h"

60
#define ENABLE_MAC_PAYLOAD_DEBUG
61 62 63
#define DEBUG_eNB_SCHEDULER 1

// This table holds the allowable PRB sizes for ULSCH transmissions
64
uint8_t rb_table[34] = {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,64,72,75,80,81,90,96,100};
65

66
void rx_sdu(const module_id_t enb_mod_idP,
Cedric Roux's avatar
Cedric Roux committed
67 68 69 70 71 72 73 74 75
            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 uint16_t    timing_advance,
            const uint8_t     ul_cqi)
{
76
  int current_rnti = rntiP;
77 78 79
  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];
80
  int    UE_id = find_UE_id(enb_mod_idP, current_rnti);
81
  int RA_id;
82
  int ii,j;
83
  eNB_MAC_INST *eNB = RC.mac[enb_mod_idP];
84
  int    harq_pid = subframe2harqpid(&eNB->common_channels[CC_idP],frameP,subframeP);
Cedric Roux's avatar
Cedric Roux committed
85

86
  UE_list_t *UE_list= &eNB->UE_list;
87
  int crnti_rx=0;
88
  int old_buffer_info;
89
  RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&RC.mac[enb_mod_idP]->common_channels[CC_idP].RA_template[0];
knopp's avatar
knopp committed
90 91
  int first_rb = 0;

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

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) {
101
    trace_pdu(0, sduP,sdu_lenP, 0, 3, current_rnti, frameP, subframeP, 0,0);
gauthier's avatar
gauthier committed
102
    LOG_D(OPT,"[eNB %d][ULSCH] Frame %d  rnti %x  with size %d\n",
103
                      enb_mod_idP, frameP, current_rnti, sdu_lenP);
gauthier's avatar
gauthier committed
104
  }
105

106
  if (UE_id!=-1) {
107
    LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP, UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],
108
          current_rnti, UE_id,ul_cqi);
gauthier's avatar
gauthier committed
109

110
    AssertFatal(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] < 8,
Cedric Roux's avatar
Cedric Roux committed
111 112
                "round >= 8\n");
    if (sduP!=NULL) {
113 114 115
       UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer   = 0;
       UE_list->UE_sched_ctrl[UE_id].ul_failure_timer      = 0;
       UE_list->UE_sched_ctrl[UE_id].ul_scheduled         &= (~(1<<harq_pid));
Cedric Roux's avatar
Cedric Roux committed
116 117 118
       /* don't take into account TA if timer is running */
       if (UE_list->UE_sched_ctrl[UE_id].ta_timer == 0)
         UE_list->UE_sched_ctrl[UE_id].ta_update             = timing_advance;
119
       UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP]       = ul_cqi;
120 121 122 123 124 125 126
       UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0;
       first_rb =  UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid];

       if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
         UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=0;
         mac_eNB_rrc_ul_in_sync(enb_mod_idP,CC_idP,frameP,subframeP,UE_RNTI(enb_mod_idP,UE_id));
       }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
127
    }
128
    else { // we've got an error
129
      LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP,
Cedric Roux's avatar
Cedric Roux committed
130
                UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],ul_cqi);
131

knopp's avatar
knopp committed
132
      //      AssertFatal(1==0,"ulsch in error\n");
133
      if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) {
Cedric Roux's avatar
Cedric Roux committed
134 135 136
             UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pid));
             UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]=0;
             if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10)
137
            UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1;
138 139
      }
      else UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++;
140
      return;
141

142 143
    }
  }
144
  else if ((RA_id = find_RA_id(enb_mod_idP,CC_idP,current_rnti))!=-1) { // Check if this is an RA process for the rnti
145
    AssertFatal(eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx>1,
Cedric Roux's avatar
Cedric Roux committed
146 147
                "maxHARQ %d should be greater than 1\n",
                (int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
148

149
    LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP,
150
     RA_template[RA_id].msg3_round,
151
     current_rnti,RA_id,ul_cqi);
152

Cedric Roux's avatar
Cedric Roux committed
153
    first_rb                   = RA_template->msg3_first_rb;
knopp's avatar
knopp committed
154

155
    if (sduP==NULL) { // we've got an error on Msg3
knopp's avatar
knopp committed
156
      LOG_D(MAC,"[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",enb_mod_idP,CC_idP,RA_id,
Cedric Roux's avatar
Cedric Roux committed
157 158 159
            RA_template[RA_id].msg3_round,
            (int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
      if (RA_template[RA_id].msg3_round == eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx-1) {
160
        cancel_ra_proc(enb_mod_idP,CC_idP,frameP,current_rnti);
161
      }
gauthier's avatar
gauthier committed
162

163 164 165 166 167 168 169 170
      else {
        first_rb =  UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid];
        RA_template[RA_id].msg3_round++;
        // prepare handling of retransmission
        RA_template[RA_id].Msg3_frame += ((RA_template[RA_id].Msg3_subframe>1) ? 1 : 0);
        RA_template[RA_id].Msg3_subframe = (RA_template[RA_id].Msg3_subframe+8)%10;
        add_msg3(enb_mod_idP,CC_idP, &RA_template[RA_id],frameP,subframeP);
      }
171 172 173
      return;
    }
  }
174
  else  {
175
    LOG_W(MAC,"Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", current_rnti);
176 177
    return;
  }
178
  payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP);
gauthier's avatar
gauthier committed
179

180
  T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
181
    T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu));
182
  T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
183
    T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP));
gauthier's avatar
gauthier committed
184

185 186 187
  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;
knopp's avatar
knopp committed
188

189
  UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0;
knopp's avatar
knopp committed
190

191 192 193
  // control element
  for (i=0; i<num_ce; i++) {

194
    T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
Cedric Roux's avatar
Cedric Roux committed
195
      T_INT(rx_ces[i]));
Cedric Roux's avatar
Cedric Roux committed
196

197 198 199 200
    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;
201 202
        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);
203
        UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1;
Cedric Roux's avatar
Cedric Roux committed
204
        UE_list->UE_sched_ctrl[UE_id].phr_received = 1;
205 206 207 208
      }
      payload_ptr+=sizeof(POWER_HEADROOM_CMD);
      break;

209 210 211
    case CRNTI: {
      int old_rnti = (((uint16_t)payload_ptr[0])<<8) + payload_ptr[1];
      int old_UE_id = find_UE_id(enb_mod_idP, old_rnti);
knopp's avatar
knopp committed
212
      LOG_D(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n",
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
            enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, num_ce, old_rnti, old_UE_id);
      if (old_UE_id != -1) {
        /* TODO: if the UE did random access (followed by a MAC uplink with
         * CRNTI) because none of its scheduling request was granted, then
         * according to 36.321 5.4.4 the UE's MAC will notify RRC to release
         * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply
         * default configuration for CQI reporting and scheduling requests,
         * which basically means that the CQI requests won't work anymore and
         * that the UE won't do any scheduling request anymore as long as the
         * eNB doesn't reconfigure the UE.
         * We have to take care of this. As the code is, nothing is done and
         * the UE state in the eNB is wrong.
         */
        UE_id = old_UE_id;
        UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0;
        UE_list->UE_sched_ctrl[UE_id].ul_failure_timer    = 0;
        if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
          UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0;
          mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, old_rnti);
        }
        /* receiving CRNTI means that the current rnti has to go away */
        cancel_ra_proc(enb_mod_idP,CC_idP,frameP,current_rnti);
        current_rnti = old_rnti;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
236
      }
237
      crnti_rx=1;
roux's avatar
roux committed
238
      payload_ptr+=2;
239
      break;
240
    }
241 242 243

    case TRUNCATED_BSR:
    case SHORT_BSR: {
244 245 246 247
      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",
Cedric Roux's avatar
Cedric Roux committed
248
            enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f);
249

250
      if (crnti_rx==1)
Cedric Roux's avatar
Cedric Roux committed
251 252
        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);
253
      if (UE_id  != -1) {
254

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

Cedric Roux's avatar
Cedric Roux committed
257 258 259
        // update buffer info

        UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid]];
260

Cedric Roux's avatar
Cedric Roux committed
261
        UE_list->UE_template[CC_idP][UE_id].ul_total_buffer= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid];
262

Cedric Roux's avatar
Cedric Roux committed
263 264 265
        RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f);
        if (UE_id == UE_list->head)
          VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP]);
266
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
267
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
268
        }
Cedric Roux's avatar
Cedric Roux committed
269 270 271 272
        if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP,UE_id)) < RRC_CONNECTED)
          LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n",
                enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].ul_total_buffer,
                UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]);
273
      }
274
      else {
275

276
      }
277
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
 
knopp committed
278
    }
279
    break;
gauthier's avatar
 
gauthier committed
280

281 282 283 284 285 286 287 288
    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);
289

Cedric Roux's avatar
Cedric Roux committed
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
        // update buffer info
        old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0];
        UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0]];

        UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0];
        if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
        else
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;

        old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1];
        UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1]];
        UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1];
        if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
        else
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;

        old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2];
        UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2]];
        UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2];
        if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
        else
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;

        old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3];
        UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]];
        UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3];
        if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
        else
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;
323

324
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
325
              "%u LCGID2 = %u LCGID3 = %u\n",
326
              enb_mod_idP, CC_idP,
327 328 329 330 331
              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]);
332
      if (crnti_rx==1)
knopp's avatar
knopp committed
333
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
334
              "%u LCGID2 = %u LCGID3 = %u\n",
335
              enb_mod_idP, CC_idP,
336 337 338 339 340 341
              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]);

342
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) {
343
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0;
344
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) {
345
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP;
346
        }
347

348
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) {
349
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0;
350
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) {
351
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP;
352
        }
353

354
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0 ) {
355
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=0;
356
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) {
357
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=frameP;
358
        }
359

360
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0 ) {
361
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]= 0;
362
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) {
363 364
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]=frameP;

365
        }
366 367 368 369 370 371
      }

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

    default:
372
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
373 374 375 376 377
      break;
    }
  }

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

380
    T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
Cedric Roux's avatar
Cedric Roux committed
381
      T_INT(rx_lcids[i]), T_INT(rx_lengths[i]));
382
    T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
383
      T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, rx_lengths[i]));
Cedric Roux's avatar
Cedric Roux committed
384

385 386
    switch (rx_lcids[i]) {
    case CCCH :
Cedric Roux's avatar
Cedric Roux committed
387
      if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
388 389
        LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n",
              enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX,sdu_lenP);
Cedric Roux's avatar
Cedric Roux committed
390 391
        break;
      }
knopp's avatar
knopp committed
392
      LOG_D(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",
393
            enb_mod_idP,CC_idP,frameP,
394
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], current_rnti);
395 396
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC,1);
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC,0);
397
      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
Cedric Roux's avatar
Cedric Roux committed
398
        RA_TEMPLATE *RA_template = &eNB->common_channels[CC_idP].RA_template[ii];
399

400
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n",
401
              enb_mod_idP, CC_idP, ii,
402
              RA_template->rnti, current_rnti,
403
              RA_template->RA_active);
gauthier's avatar
 
gauthier committed
404

405
        if ((RA_template->rnti==current_rnti) &&
406
            (RA_template->RA_active==TRUE)) {
gauthier's avatar
 
gauthier committed
407

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

410
          if (UE_id < 0) {
411
            memcpy(&RA_template->cont_res_id[0],payload_ptr,6);
knopp's avatar
knopp committed
412
            LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n",
413
                  enb_mod_idP,CC_idP,frameP,rx_lengths[i],payload_ptr-sduP);
gauthier's avatar
 
gauthier committed
414

415 416 417 418 419
            if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pid
                      #ifdef Rel14
                        ,eNB->common_channels[CC_idP].RA_template[ii].rach_resource_type
                      #endif
                      )) == -1 ) {
420
              AssertFatal(1==0,"[MAC][eNB] Max user count reached\n");
Cedric Roux's avatar
Cedric Roux committed
421
              // kill RA procedure
422
            } else
knopp's avatar
knopp committed
423
              LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
424
                    enb_mod_idP,CC_idP,frameP,RA_template->rnti,UE_id);
425
          } else {
knopp's avatar
knopp committed
426
            LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n",
427
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP);
Cedric Roux's avatar
Cedric Roux committed
428
            // kill RA procedure
429
          }
gauthier's avatar
 
gauthier committed
430

Cedric Roux's avatar
Cedric Roux committed
431 432 433 434
          mac_rrc_data_ind(
                           enb_mod_idP,
                           CC_idP,
                           frameP,subframeP,
435
                           current_rnti,
Cedric Roux's avatar
Cedric Roux committed
436 437 438 439 440
                           CCCH,
                           (uint8_t*)payload_ptr,
                           rx_lengths[i],
                           ENB_FLAG_YES,
                           enb_mod_idP,
441 442
                           0
                           );
Cedric Roux's avatar
Cedric Roux committed
443 444


445 446 447
          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
448

Cedric Roux's avatar
Cedric Roux committed
449
          // prepare transmission of Msg4
450 451
          RA_template->generate_Msg4 = 1;
          RA_template->wait_ack_Msg4 = 0;
knopp's avatar
knopp committed
452 453 454



Cedric Roux's avatar
Cedric Roux committed
455 456 457 458
          // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
          RA_template->Msg4_frame    = frameP + ((subframeP>5) ? 1 : 0);
          RA_template->Msg4_subframe = (subframeP+4)%10;

459 460
        } // if process is active
      } // loop on RA processes
Cedric Roux's avatar
Cedric Roux committed
461

nikaeinn's avatar
nikaeinn committed
462
      break ;
gauthier's avatar
 
gauthier committed
463

nikaeinn's avatar
nikaeinn committed
464
    case DCCH :
465 466
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
Cedric Roux's avatar
Cedric Roux committed
467

gauthier's avatar
 
gauthier committed
468

knopp's avatar
 
knopp committed
469
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
470
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
471
      for (j=0; j<32; j++) {
472
        LOG_T(MAC,"%x ",payload_ptr[j]);
473
      }
474
      LOG_T(MAC,"\n");
knopp's avatar
 
knopp committed
475
#endif
gauthier's avatar
 
gauthier committed
476

roux's avatar
roux committed
477
      if (UE_id != -1) {
Cedric Roux's avatar
Cedric Roux committed
478 479 480 481 482
        // adjust buffer occupancy of the correponding logical channel group
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i])
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i];
        else
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0;
483

roux's avatar
roux committed
484 485 486 487
          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(
Cedric Roux's avatar
Cedric Roux committed
488
                           enb_mod_idP,
489
                           current_rnti,
Cedric Roux's avatar
Cedric Roux committed
490 491 492 493 494 495 496 497 498
                           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);
roux's avatar
roux committed
499 500
          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];
knopp's avatar
knopp committed
501 502


roux's avatar
roux committed
503
      } /* UE_id != -1 */
knopp's avatar
knopp committed
504

Cedric Roux's avatar
Cedric Roux committed
505 506

      // }
507 508
      break;

nikaeinn's avatar
nikaeinn committed
509 510 511
      // all the DRBS
    case DTCH:
    default :
gauthier's avatar
 
gauthier committed
512

knopp's avatar
 
knopp committed
513
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
514
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
515
      for (j=0; j<32; j++) {
516
        LOG_T(MAC,"%x ",payload_ptr[j]);
517
      }
518 519
      LOG_T(MAC,"\n");
#endif
nikaeinn's avatar
nikaeinn committed
520
      if (rx_lcids[i]  < NB_RB_MAX ) {
Cedric Roux's avatar
Cedric Roux committed
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
        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]);

        if (UE_id != -1) {
          // adjust buffer occupancy of the correponding logical channel group
          LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n",
                enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id,rx_lcids[i],
                UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]],
                UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]);

          if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i])
            UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i];
          else
            UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0;
          if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) &&  (rx_lengths[i] > 0) ) {   // MAX SIZE OF transport block
            mac_rlc_data_ind(
                             enb_mod_idP,
538
                             current_rnti,
Cedric Roux's avatar
Cedric Roux committed
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
                             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);

            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];
          }
          else { /* rx_length[i] */
            UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
            LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ",
                  enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id);
          }
        }
        else {/*(UE_id != -1*/
          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);
        }
nikaeinn's avatar
nikaeinn committed
562
      }
563 564

      break;
knopp's avatar
 
knopp committed
565
    }
Cedric Roux's avatar
Cedric Roux committed
566

567 568 569
    payload_ptr+=rx_lengths[i];
  }

knopp's avatar
knopp committed
570
  // Program ACK for PHICH
571
  LOG_D(MAC,"Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n",current_rnti,harq_pid,first_rb);
knopp's avatar
knopp committed
572
  nfapi_hi_dci0_request_body_t   *hi_dci0_req = &eNB->HI_DCI0_req[CC_idP].hi_dci0_request_body;
Cedric Roux's avatar
Cedric Roux committed
573
  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi];
knopp's avatar
knopp committed
574
  memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
Cedric Roux's avatar
Cedric Roux committed
575
  hi_dci0_pdu->pdu_type                                               = NFAPI_HI_DCI0_HI_PDU_TYPE;
knopp's avatar
knopp committed
576
  hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_hi_pdu);
Cedric Roux's avatar
Cedric Roux committed
577
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start                = first_rb;
knopp's avatar
knopp committed
578 579 580
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms             = 0;
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value                            = 1;
  hi_dci0_req->number_of_hi++;
Cedric Roux's avatar
Cedric Roux committed
581

582 583
  /* 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
584 585
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
586
    /*
587 588
    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
589
        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);
590 591
        *msg3_flagP=0;
      }
592
      }*/
593
  } else {
roux's avatar
roux committed
594 595 596 597 598
    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;
    }
599 600
  }

gauthier's avatar
gauthier committed
601
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
602
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
 
knopp committed
603 604
}

605 606 607
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
  uint32_t i=0;
608

609
  if (nbytes<0) {
610
    return(0);
611
  }
612

613 614 615 616 617 618
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
619 620
}

621 622 623 624 625
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
  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;
626

627
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
628 629 630
}

unsigned char *parse_ulsch_header(unsigned char *mac_header,
gauthier's avatar
 
gauthier committed
631 632 633 634 635
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
636 637 638 639 640 641 642 643
                                  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) {

644
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
645
      not_done = 0;
646
    }
647 648 649 650 651 652 653 654

    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;

655
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
656
          length -= rx_lengths[num_sdu_cnt];
657
        }
658 659 660 661 662 663 664
      } 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
665
        }
666 667
      }

Cedric Roux's avatar
Cedric Roux committed
668
      LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n",
669 670 671 672 673 674 675 676 677 678 679 680
            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++;

681
        if (lcid==LONG_BSR) {
682
          ce_len+=3;
683
        } else if (lcid==CRNTI) {
684
          ce_len+=2;
685
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
686
          ce_len++;
687
        } else {
688
          LOG_E(MAC,"unknown CE %d \n", lcid);
689
          AssertFatal(1==0,"unknown CE");
gauthier's avatar
 
gauthier committed
690
        }
691
      }
knopp's avatar
 
knopp committed
692
    }
693
  }
694

695 696 697 698
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
699 700
}

701 702 703 704 705 706 707 708 709 710 711 712 713
/* This function is called by PHY layer when it schedules some
 * uplink for a random access message 3.
 * The MAC scheduler has to skip the RBs used by this message 3
 * (done below in schedule_ulsch).
 */
void set_msg3_subframe(module_id_t Mod_id,
                       int CC_id,
                       int frame,
                       int subframe,
                       int rnti,
                       int Msg3_frame,
                       int Msg3_subframe)
{
714
  eNB_MAC_INST *eNB=RC.mac[Mod_id];
715 716 717 718 719 720 721 722 723
  int i;
  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].rnti == rnti) {
      eNB->common_channels[CC_id].RA_template[i].Msg3_subframe = Msg3_subframe;
      break;
    }
  }
}
724

725

Cedric Roux's avatar
Cedric Roux committed
726 727 728 729
void schedule_ulsch(module_id_t module_idP,
                    frame_t frameP,
                    sub_frame_t subframeP)
{
730 731
  uint16_t first_rb[MAX_NUM_CCs],i;
  int CC_id;
732
  eNB_MAC_INST *eNB=RC.mac[module_idP];
733
  COMMON_channels_t *cc;
gauthier's avatar
 
gauthier committed
734

735
  start_meas(&eNB->schedule_ulsch);
gauthier's avatar
 
gauthier committed
736

737 738 739 740 741 742 743 744 745 746
  int sched_subframe = (subframeP+4)%10;

  cc = &eNB->common_channels[0];
  int tdd_sfa;
  // for TDD: check subframes where we have to act and return if nothing should be done now
  if (cc->tdd_Config) {
    tdd_sfa = cc->tdd_Config->subframeAssignment;
    switch (subframeP) {
    case 0:
      if ((tdd_sfa == 0)||
Cedric Roux's avatar
Cedric Roux committed
747 748
          (tdd_sfa == 3)||
          (tdd_sfa == 6)) sched_subframe = 4;
749 750 751 752
      else return;
      break;
    case 1:
      if ((tdd_sfa==0)||
Cedric Roux's avatar
Cedric Roux committed
753
          (tdd_sfa==1)) sched_subframe = 7;
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791
      else if (tdd_sfa==6) sched_subframe = 8;
      break;
    default:
      return;

    case 2: // Don't schedule UL in subframe 2 for TDD
      return;
    case 3:
      if (tdd_sfa==2) sched_subframe = 7;
      else return;
      break;
    case 4:
      if (tdd_sfa==1) sched_subframe = 8;
      else return;
      break;
    case 5:
      if (tdd_sfa==0)      sched_subframe = 9;
      else if (tdd_sfa==6) sched_subframe = 3;
      else return;
      break;
    case 6:
      if (tdd_sfa==1)      sched_subframe = 2;
      else if (tdd_sfa==6) sched_subframe = 3;
      else return;
      break;
    case 7:
      return;
    case 8:
      if ((tdd_sfa>=2) || (tdd_sfa<=5)) sched_subframe=2;
      else return;
      break;
    case 9:
      if ((tdd_sfa==1) || (tdd_sfa==3) || (tdd_sfa==4)) sched_subframe=3;
      else if (tdd_sfa==6) sched_subframe=4;
      else return;
      break;
    }
  }
792
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
gauthier's avatar
 
gauthier committed
793

794 795


796
    //leave out first RB for PUCCH
797
    first_rb[CC_id] = 1;
gauthier's avatar
 
gauthier committed
798

799 800 801 802
    // 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
803

804 805
    // default function for default scheduling
    //
gauthier's avatar
 
gauthier committed
806

807 808 809 810
    // 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
811

Cedric Roux's avatar
Cedric Roux committed
812

813
    for (i=0; i<NB_RA_PROC_MAX; i++) {
knopp's avatar