eNB_scheduler_ulsch.c 55.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * 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
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * 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 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];
  int    UE_id = find_UE_id(enb_mod_idP,rntiP);
80
  int RA_id;
81
  int ii,j;
82
  eNB_MAC_INST *eNB = RC.mac[enb_mod_idP];
83
  int    harq_pid = subframe2harqpid(&eNB->common_channels[CC_idP],frameP,subframeP);
Cedric Roux's avatar
Cedric Roux committed
84

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

91 92 93
  start_meas(&eNB->rx_ulsch_sdu);

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

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

105
  if (UE_id!=-1) {
106
    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],
Cedric Roux's avatar
Cedric Roux committed
107
          rntiP,UE_id,ul_cqi);
gauthier's avatar
gauthier committed
108

109
    AssertFatal(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] < 8,
Cedric Roux's avatar
Cedric Roux committed
110 111
                "round >= 8\n");
    if (sduP!=NULL) {
112 113 114
       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
115 116 117
       /* 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;
118
       UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP]       = ul_cqi;
119 120 121 122 123 124 125
       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
126
    }
127
    else { // we've got an error
128
      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
129
                UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],ul_cqi);
130

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

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

148
    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,
149 150 151
     RA_template[RA_id].msg3_round,
     rntiP,RA_id,ul_cqi);

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

154
    if (sduP==NULL) { // we've got an error on Msg3
knopp's avatar
knopp committed
155
      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
156 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) {
        cancel_ra_proc(enb_mod_idP,CC_idP,frameP,rntiP);
160
      }
gauthier's avatar
gauthier committed
161

162 163 164 165 166 167 168 169
      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);
      }
170 171 172
      return;
    }
  }
173 174 175 176 177
  else  {
    LOG_W(MAC,"Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n",
          rntiP);
    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

Cedric Roux's avatar
Cedric Roux committed
180
  T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), 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(rntiP), 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++) {

Cedric Roux's avatar
Cedric Roux committed
194 195
    T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
      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 209
      }
      payload_ptr+=sizeof(POWER_HEADROOM_CMD);
      break;

    case CRNTI:
210
      UE_id = find_UE_id(enb_mod_idP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
knopp's avatar
knopp committed
211
      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",
212
	    frameP,subframeP,enb_mod_idP, CC_idP, rx_ces[i], i,num_ce,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1],UE_id);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
213 214 215 216 217 218 219
      if (UE_id!=-1) {
	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,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
	}
220 221
printf("TODO: deal with CRNTI\n");
abort();
Florian Kaltenberger's avatar
Florian Kaltenberger committed
222
      }
223
      crnti_rx=1;
roux's avatar
roux committed
224
      payload_ptr+=2;
225
      /*
roux's avatar
roux committed
226
      if (msg3_flagP != NULL) {
227
	*msg3_flagP = 0;
228 229
	}*/

230 231 232 233
      break;

    case TRUNCATED_BSR:
    case SHORT_BSR: {
234 235 236 237
      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
238
            enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f);
239

240
      if (crnti_rx==1)
Cedric Roux's avatar
Cedric Roux committed
241 242
        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);
243
      if (UE_id  != -1) {
244

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

Cedric Roux's avatar
Cedric Roux committed
247 248 249
        // 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]];
250

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

Cedric Roux's avatar
Cedric Roux committed
253 254 255
        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]);
256
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
257
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
258
        }
Cedric Roux's avatar
Cedric Roux committed
259 260 261 262
        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]);
263
      }
264
      else {
265

266
      }
267
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
 
knopp committed
268
    }
269
    break;
gauthier's avatar
 
gauthier committed
270

271 272 273 274 275 276 277 278
    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);
279

Cedric Roux's avatar
Cedric Roux committed
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
        // 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;
313

314
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
315
              "%u LCGID2 = %u LCGID3 = %u\n",
316
              enb_mod_idP, CC_idP,
317 318 319 320 321
              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]);
322
      if (crnti_rx==1)
knopp's avatar
knopp committed
323
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
324
              "%u LCGID2 = %u LCGID3 = %u\n",
325
              enb_mod_idP, CC_idP,
326 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 (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) {
333
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0;
334
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) {
335
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP;
336
        }
337

338
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) {
339
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0;
340
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) {
341
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP;
342
        }
343

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

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

355
        }
356 357 358 359 360 361
      }

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

    default:
362
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
363 364 365 366 367
      break;
    }
  }

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

Cedric Roux's avatar
Cedric Roux committed
370 371
    T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
      T_INT(rx_lcids[i]), T_INT(rx_lengths[i]));
372 373
    T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
      T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, rx_lengths[i]));
Cedric Roux's avatar
Cedric Roux committed
374

375 376
    switch (rx_lcids[i]) {
    case CCCH :
Cedric Roux's avatar
Cedric Roux committed
377
      if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
378 379
        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
380 381
        break;
      }
knopp's avatar
knopp committed
382
      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",
383
            enb_mod_idP,CC_idP,frameP,
384
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
385 386
      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);
387
      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
Cedric Roux's avatar
Cedric Roux committed
388
        RA_TEMPLATE *RA_template = &eNB->common_channels[CC_idP].RA_template[ii];
389

390
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n",
391
              enb_mod_idP, CC_idP, ii,
392 393
              RA_template->rnti, rntiP,
              RA_template->RA_active);
gauthier's avatar
 
gauthier committed
394

395 396
        if ((RA_template->rnti==rntiP) &&
            (RA_template->RA_active==TRUE)) {
gauthier's avatar
 
gauthier committed
397

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

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

405 406 407 408 409
            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 ) {
410
              AssertFatal(1==0,"[MAC][eNB] Max user count reached\n");
Cedric Roux's avatar
Cedric Roux committed
411
              // kill RA procedure
412
            } else
knopp's avatar
knopp committed
413
              LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
414
                    enb_mod_idP,CC_idP,frameP,RA_template->rnti,UE_id);
415
          } else {
knopp's avatar
knopp committed
416
            LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n",
417
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP);
Cedric Roux's avatar
Cedric Roux committed
418
            // kill RA procedure
419
          }
gauthier's avatar
 
gauthier committed
420

Cedric Roux's avatar
Cedric Roux committed
421 422 423 424 425 426 427 428 429 430
          mac_rrc_data_ind(
                           enb_mod_idP,
                           CC_idP,
                           frameP,subframeP,
                           rntiP,
                           CCCH,
                           (uint8_t*)payload_ptr,
                           rx_lengths[i],
                           ENB_FLAG_YES,
                           enb_mod_idP,
431 432
                           0
                           );
Cedric Roux's avatar
Cedric Roux committed
433 434


435 436 437
          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
438

Cedric Roux's avatar
Cedric Roux committed
439
          // prepare transmission of Msg4
440 441
          RA_template->generate_Msg4 = 1;
          RA_template->wait_ack_Msg4 = 0;
knopp's avatar
knopp committed
442 443 444



Cedric Roux's avatar
Cedric Roux committed
445 446 447 448
          // 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;

449 450
        } // if process is active
      } // loop on RA processes
Cedric Roux's avatar
Cedric Roux committed
451

nikaeinn's avatar
nikaeinn committed
452
      break ;
gauthier's avatar
 
gauthier committed
453

nikaeinn's avatar
nikaeinn committed
454
    case DCCH :
455 456
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
Cedric Roux's avatar
Cedric Roux committed
457

gauthier's avatar
 
gauthier committed
458

knopp's avatar
 
knopp committed
459
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
460
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
461
      for (j=0; j<32; j++) {
462
        LOG_T(MAC,"%x ",payload_ptr[j]);
463
      }
464
      LOG_T(MAC,"\n");
knopp's avatar
 
knopp committed
465
#endif
gauthier's avatar
 
gauthier committed
466

roux's avatar
roux committed
467
      if (UE_id != -1) {
Cedric Roux's avatar
Cedric Roux committed
468 469 470 471 472
        // 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;
473

roux's avatar
roux committed
474 475 476 477
          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
478 479 480 481 482 483 484 485 486 487 488
                           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);
roux's avatar
roux committed
489 490
          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
491 492


roux's avatar
roux committed
493
      } /* UE_id != -1 */
knopp's avatar
knopp committed
494

Cedric Roux's avatar
Cedric Roux committed
495 496

      // }
497 498
      break;

nikaeinn's avatar
nikaeinn committed
499 500 501
      // all the DRBS
    case DTCH:
    default :
gauthier's avatar
 
gauthier committed
502

knopp's avatar
 
knopp committed
503
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
504
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
505
      for (j=0; j<32; j++) {
506
        LOG_T(MAC,"%x ",payload_ptr[j]);
507
      }
508 509
      LOG_T(MAC,"\n");
#endif
nikaeinn's avatar
nikaeinn committed
510
      if (rx_lcids[i]  < NB_RB_MAX ) {
Cedric Roux's avatar
Cedric Roux committed
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
        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,
                             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);

            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
552
      }
553 554

      break;
knopp's avatar
 
knopp committed
555
    }
Cedric Roux's avatar
Cedric Roux committed
556

557 558 559
    payload_ptr+=rx_lengths[i];
  }

knopp's avatar
knopp committed
560
  // Program ACK for PHICH
561
  LOG_D(MAC,"Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n",rntiP,harq_pid,first_rb);
knopp's avatar
knopp committed
562
  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
563
  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
564
  memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
Cedric Roux's avatar
Cedric Roux committed
565
  hi_dci0_pdu->pdu_type                                               = NFAPI_HI_DCI0_HI_PDU_TYPE;
knopp's avatar
knopp committed
566
  hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_hi_pdu);
Cedric Roux's avatar
Cedric Roux committed
567
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start                = first_rb;
knopp's avatar
knopp committed
568 569 570
  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
571

572 573
  /* 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
574 575
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
576
    /*
577 578
    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
579
        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);
580 581
        *msg3_flagP=0;
      }
582
      }*/
583
  } else {
roux's avatar
roux committed
584 585 586 587 588
    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;
    }
589 590
  }

gauthier's avatar
gauthier committed
591
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
592
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
 
knopp committed
593 594
}

595 596 597
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
  uint32_t i=0;
598

599
  if (nbytes<0) {
600
    return(0);
601
  }
602

603 604 605 606 607 608
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
609 610
}

611 612 613 614 615
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;
616

617
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
618 619 620
}

unsigned char *parse_ulsch_header(unsigned char *mac_header,
gauthier's avatar
 
gauthier committed
621 622 623 624 625
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
626 627 628 629 630 631 632 633
                                  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) {

634
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
635
      not_done = 0;
636
    }
637 638 639 640 641 642 643 644

    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;

645
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
646
          length -= rx_lengths[num_sdu_cnt];
647
        }
648 649 650 651 652 653 654
      } 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
655
        }
656 657
      }

Cedric Roux's avatar
Cedric Roux committed
658
      LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n",
659 660 661 662 663 664 665 666 667 668 669 670
            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++;

671
        if (lcid==LONG_BSR) {
672
          ce_len+=3;
673
        } else if (lcid==CRNTI) {
674
          ce_len+=2;
675
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
676
          ce_len++;
677
        } else {
678
          LOG_E(MAC,"unknown CE %d \n", lcid);
679
          AssertFatal(1==0,"unknown CE");
gauthier's avatar
 
gauthier committed
680
        }
681
      }
knopp's avatar
 
knopp committed
682
    }
683
  }
684

685 686 687 688
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
689 690
}

691 692 693 694 695 696 697 698 699 700 701 702 703
/* 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)
{
704
  eNB_MAC_INST *eNB=RC.mac[Mod_id];
705 706 707 708 709 710 711 712 713
  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;
    }
  }
}
714

715

Cedric Roux's avatar
Cedric Roux committed
716 717 718 719
void schedule_ulsch(module_id_t module_idP,
                    frame_t frameP,
                    sub_frame_t subframeP)
{
720 721
  uint16_t first_rb[MAX_NUM_CCs],i;
  int CC_id;
722
  eNB_MAC_INST *eNB=RC.mac[module_idP];
723
  COMMON_channels_t *cc;
gauthier's avatar
 
gauthier committed
724

725
  start_meas(&eNB->schedule_ulsch);
gauthier's avatar
 
gauthier committed
726

727 728 729 730 731 732 733 734 735 736
  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
737 738
          (tdd_sfa == 3)||
          (tdd_sfa == 6)) sched_subframe = 4;
739 740 741 742
      else return;
      break;
    case 1:
      if ((tdd_sfa==0)||
Cedric Roux's avatar
Cedric Roux committed
743
          (tdd_sfa==1)) sched_subframe = 7;
744 745 746 747 748 749 750 751 752 753 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
      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;
    }
  }
782
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
gauthier's avatar
 
gauthier committed
783

784 785


786
    //leave out first RB for PUCCH
787
    first_rb[CC_id] = 1;
gauthier's avatar
 
gauthier committed
788

789 790 791 792
    // 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
793

794 795
    // default function for default scheduling
    //
gauthier's avatar
 
gauthier committed
796

797 798 799 800
    // 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
801

Cedric Roux's avatar
Cedric Roux committed
802

803
    for (i=0; i<NB_RA_PROC_MAX; i++) {
804 805 806 807 808
      if ((cc->RA_template[i].RA_active == TRUE) &&
          (cc->RA_template[i].generate_rar == 0) &&
          (cc->RA_template[i].generate_Msg4 == 0) &&
          (cc->RA_template[i].wait_ack_Msg4 == 0) &&
          (cc->RA_template[i].Msg3_subframe == sched_subframe)) {
809
        first_rb[CC_id]++;
Cedric Roux's avatar
Cedric Roux committed
810
        //    cc->RA_template[i].Msg3_subframe = -1;
811 812
        break;
      }
knopp's avatar
 
knopp committed
813
    }
814
  }
815

816
  schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe,first_rb);
gauthier's avatar
 
gauthier committed
817

818
  stop_meas(&eNB->schedule_ulsch);
819 820 821 822 823
}

void schedule_ulsch_rnti(module_id_t   module_idP,
                         frame_t       frameP,
                         sub_frame_t   subframeP,
824
                         unsigned char sched_subframeP,