eNB_scheduler_RA.c 71 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
 */
21

22
/*! \file eNB_scheduler_RA.c
23
 * \brief primitives used for random access
24 25 26 27 28 29 30 31 32
 * \author  Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \email: navid.nikaein@eurecom.fr
 * \version 1.0
 * @ingroup _mac

 */

#include "assertions.h"
33
#include "platform_types.h"
34 35
#include "PHY/defs.h"
#include "PHY/extern.h"
gauthier's avatar
gauthier committed
36
#include "msc.h"
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

#include "SCHED/defs.h"
#include "SCHED/extern.h"

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/extern.h"

#include "LAYER2/MAC/proto.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

61
#include "SIMULATION/TOOLS/defs.h" // for taus
62

Cedric Roux's avatar
Cedric Roux committed
63
#include "T.h"
64

65
void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_t frameP, sub_frame_t subframeP) {
66 67

  eNB_MAC_INST                    *eNB = RC.mac[module_idP];
68 69 70
  COMMON_channels_t               *cc  = &eNB->common_channels[CC_id];
  uint8_t                         i,j;
  nfapi_ul_config_request_t      *ul_req;
71
  nfapi_ul_config_request_pdu_t  *ul_config_pdu;
72
  nfapi_ul_config_request_body_t *ul_req_body;
73 74 75
  nfapi_hi_dci0_request_body_t   *hi_dci0_req;
  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;

76
  uint8_t rvseq[4] = {0,2,3,1};
77 78


79 80 81 82
  hi_dci0_req   = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
  ul_req        = &eNB->UL_req_tmp[CC_id][RA_template->Msg3_subframe];
  ul_req_body   = &ul_req->ul_config_request_body;
  AssertFatal(RA_template->RA_active == TRUE,"RA is not active for RA %X\n",RA_template->rnti);
83

84
#ifdef Rel14
85
  if (RA_template->rach_resource_type>0) {
knopp's avatar
knopp committed
86
    LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d CE level %d is active, Msg3 in (%d,%d)\n",
87 88
	  module_idP,frameP,subframeP,CC_id,i,RA_template->rach_resource_type-1,
	  RA_template->Msg3_frame,RA_template->Msg3_subframe);
knopp's avatar
knopp committed
89
    LOG_D(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n",
90 91 92 93 94 95 96
	  frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);

    ul_config_pdu                                                                  = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; 
    
    memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
    ul_config_pdu->pdu_type                                                        = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; 
    ul_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu));
97
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag                                 = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG;
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                                 = eNB->ul_handle++;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                                   = RA_template->rnti;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start                   = narrowband_to_first_rb(cc,RA_template->msg34_narrowband)+RA_template->msg3_first_rb;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks              = RA_template->msg3_nb_rb;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type                        = 2;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms                = 0;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag         = 0;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits                 = 0;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication                    = 0;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version                     = rvseq[RA_template->msg3_round];
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number                    = ((10*RA_template->Msg3_frame)+RA_template->Msg3_subframe)&7;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                             = 0;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                          = 0;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                                  = 1;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                                   = get_TBS_UL(RA_template->msg3_mcs,
												RA_template->msg3_nb_rb);
    // Re13 fields
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type                               = RA_template->rach_resource_type>2 ? 2 : 1;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions           = 1;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number                     = 1;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io            = (RA_template->Msg3_frame*10)+RA_template->Msg3_subframe;
    ul_req_body->number_of_pdus++;
120
    ul_req_body->tl.tag                                                            = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
121 122
  } //  if (RA_template->rach_resource_type>0) {	 
  else
123
#endif
124
    {
knopp's avatar
knopp committed
125
      LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d is active, Msg3 in (%d,%d)\n",
126
	    module_idP,frameP,subframeP,CC_id,i,RA_template->Msg3_frame,RA_template->Msg3_subframe);
127
	    
knopp's avatar
knopp committed
128
      LOG_D(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n",
129 130 131 132 133 134 135
	    frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
      
      ul_config_pdu                                                                  = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; 
      
      memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
      ul_config_pdu->pdu_type                                                        = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; 
      ul_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu));
136
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag                                 = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG;
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                                 = eNB->ul_handle++;
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                                   = RA_template->rnti;
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start                   = RA_template->msg3_first_rb;
      AssertFatal(RA_template->msg3_nb_rb > 0, "nb_rb = 0\n");
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks              = RA_template->msg3_nb_rb;
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type                        = 2;
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms                = 0;
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag         = 0;
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits                 = 0;
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication                    = 0;
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version                     = rvseq[RA_template->msg3_round];
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number                    = subframe2harqpid(cc,RA_template->Msg3_frame,RA_template->Msg3_subframe);
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                             = 0;
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                          = 0;
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                                  = 1;
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                                   = get_TBS_UL(10,RA_template->msg3_nb_rb);
      ul_req_body->number_of_pdus++;
154
      ul_req_body->tl.tag                                                            = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
155 156 157 158 159
      // save UL scheduling information for preprocessor
      for (j=0;j<RA_template->msg3_nb_rb;j++) cc->vrb_map_UL[RA_template->msg3_first_rb+j]=1;
      
      
      if (RA_template->msg3_round != 0) { // program HI too
160
	hi_dci0_pdu                                                         = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi];
161 162 163
	memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
	hi_dci0_pdu->pdu_type                                               = NFAPI_HI_DCI0_HI_PDU_TYPE; 
	hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_hi_pdu);
164
	hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag                              = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
165 166 167 168 169 170 171
	hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start                = RA_template->msg3_first_rb; 
	hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms             = 0;
	hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value                            = 0;
	hi_dci0_req->number_of_hi++;
	// save UL scheduling information for preprocessor
	for (j=0;j<RA_template->msg3_nb_rb;j++) cc->vrb_map_UL[RA_template->msg3_first_rb+j]=1;
	
knopp's avatar
knopp committed
172
	LOG_D(MAC,"[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA %d (mcs %d, first rb %d, nb_rb %d,round %d)\n",
173 174 175 176 177
	      module_idP,RA_template->rnti,CC_id,frameP,subframeP,i,10,
	      1,1,
	      RA_template->msg3_round-1);
      } //       if (RA_template->msg3_round != 0) { // program HI too
    } // non-BL/CE UE case
178 179
}

180
void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template) {
181

182 183
  eNB_MAC_INST                    *eNB = RC.mac[module_idP];
  COMMON_channels_t               *cc  = eNB->common_channels;
184
 
185 186 187 188 189
  uint8_t                         *vrb_map;
  int                             first_rb;
  int                             N_RB_DL;
  nfapi_dl_config_request_pdu_t   *dl_config_pdu;
  nfapi_tx_request_pdu_t          *TX_req;
190
  nfapi_dl_config_request_body_t *dl_req;
191

192 193 194 195 196
  vrb_map       = cc[CC_idP].vrb_map;
  dl_req        = &eNB->DL_req[CC_idP].dl_config_request_body;
  dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
  N_RB_DL       = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);  

197 198 199 200 201
#ifdef Rel14
  int rmax            = 0;
  int rep             = 0; 
  int reps            = 0;
  int num_nb          = 0;
202

203
  first_rb        = 0;
204 205
  struct PRACH_ConfigSIB_v1310 *ext4_prach;
  PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
206
  PRACH_ParametersCE_r13_t *p[4]={NULL,NULL,NULL,NULL};
207

208 209 210 211 212
  uint16_t absSF      = (10*frameP)+subframeP;
  uint16_t absSF_Msg2 = (10*RA_template->Msg2_frame)+RA_template->Msg2_subframe;

  if (absSF>absSF_Msg2) return; // we're not ready yet, need to be to start ==  
  
213
  if (cc[CC_idP].radioResourceConfigCommon_BR) {
214

215
    ext4_prach                 = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
216 217 218 219 220 221 222 223 224 225 226
    prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
        
    switch (prach_ParametersListCE_r13->list.count) {
    case 4:
      p[3]=prach_ParametersListCE_r13->list.array[3];
    case 3:
      p[2]=prach_ParametersListCE_r13->list.array[2];
    case 2:
      p[1]=prach_ParametersListCE_r13->list.array[1];
    case 1:
      p[0]=prach_ParametersListCE_r13->list.array[0];
227
      break;
228
    default:
229 230
      AssertFatal(1==0,"Illegal count for prach_ParametersListCE_r13 %d\n",(int)prach_ParametersListCE_r13->list.count);
      break;
231
    }
232
  }
233 234 235 236 237 238 239 240 241 242 243 244

  if (RA_template->rach_resource_type > 0) {
    
    // This uses an MPDCCH Type 2 common allocation according to Section 9.1.5 36-213
    // Parameters:
    //    p=2+4 PRB set (number of PRB pairs 3)
    //    rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3
    //    if CELevel = 0,1 => Table 9.1.5-1b for MPDCCH candidates
    //    if CELevel = 2,3 => Table 9.1.5-2b for MPDCCH candidates
    //    distributed transmission
    
    // rmax from SIB2 information
245 246 247 248
    AssertFatal(rmax<9,"rmax>8!\n");
    rmax           = 1<<p[RA_template->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13;
    // choose r1 by default for RAR (Table 9.1.5-5)
    rep            = 0; 
249 250 251 252 253
    // get actual repetition count from Table 9.1.5-3
    reps           = (rmax<=8)?(1<<rep):(rmax>>(3-rep));
    // get narrowband according to higher-layer config 
    num_nb = p[RA_template->rach_resource_type-1]->mpdcch_NarrowbandsToMonitor_r13.list.count;
    RA_template->msg2_narrowband = *p[RA_template->rach_resource_type-1]->mpdcch_NarrowbandsToMonitor_r13.list.array[RA_template->preamble_index%num_nb];
254
    first_rb = narrowband_to_first_rb(&cc[CC_idP],RA_template->msg2_narrowband);
255 256
    
    if ((RA_template->msg2_mpdcch_repetition_cnt == 0) &&
257
	(mpdcch_sf_condition(eNB,CC_idP,frameP,subframeP,rmax,TYPE2,-1)>0)){
258
      // MPDCCH configuration for RAR
knopp's avatar
knopp committed
259
      LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming MPDCCH %d repetitions\n",
260
	    module_idP,frameP,subframeP,reps);
261 262 263 264 265
      
      
      memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
      dl_config_pdu->pdu_type                                                                  = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; 
      dl_config_pdu->pdu_size                                                                  = (uint8_t)(2+sizeof(nfapi_dl_config_mpdcch_pdu));
266
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag                                        = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG;
267 268 269 270 271 272 273 274 275 276 277 278 279 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
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format                                    = (RA_template->rach_resource_type > 1) ? 11 : 10;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band                            = RA_template->msg2_narrowband;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs                           = 6;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment                     = 0; // Note: this can be dynamic
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type                       = 1; // imposed (9.1.5 in 213) for Type 2 Common search space  
      AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL,
		  "cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol                                  = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index                                    = 0;  // Note: this should be dynamic
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level                             = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type                                     = 2;  // RA-RNTI
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti                                          = RA_template->RA_rnti;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode                                       = (RA_template->rach_resource_type < 3) ? 1 : 2;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init                          = cc[CC_idP].physCellId;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io                    = (frameP*10)+subframeP;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power                            = 6000; // 0dB
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding                         = getRIV(6,0,6);  // Note: still to be checked if it should not be (getRIV(N_RB_DL,first_rb,6)) : Check nFAPI specifications and what is done L1 with this parameter
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs                                           = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels                        = 4; // fix to 4 for now
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version                            = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator                            = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process                                  = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length                                   = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi                                          = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag                                      = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi                                           = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset                          = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number                = rep; 
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc                                           = 1;// N1A_PRB=3 (36.212); => 208 bits for mcs=4, choose mcs according t message size TBD
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length              = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index                     = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag                           = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index                                = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index                              = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level                             = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request                                   = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag    = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity         = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag                = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication                             = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding            = 0; // this is not needed by OAI L1, but should be filled in
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports                    = 1;
      RA_template->msg2_mpdcch_repetition_cnt++;
      dl_req->number_pdu++;
312
      dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
313 314
      RA_template->Msg2_subframe = (RA_template->Msg2_subframe+9)%10;

315
    } //repetition_count==0 && SF condition met
316
    if (RA_template->msg2_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions
knopp's avatar
knopp committed
317
      LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, MPDCCH repetition %d\n",
318 319
	    module_idP,frameP,subframeP,RA_template->msg2_mpdcch_repetition_cnt);

320 321 322 323 324 325 326 327 328 329
      if (RA_template->msg2_mpdcch_repetition_cnt==reps) { // this is the last mpdcch repetition
	if (cc[CC_idP].tdd_Config==NULL) { // FDD case
	  // wait 2 subframes for PDSCH transmission
	  if (subframeP>7) RA_template->Msg2_frame = (frameP+1)&1023;
	  else             RA_template->Msg2_frame = frameP;
	  RA_template->Msg2_subframe               = (subframeP+2)%10; // +2 is the "n+x" from Section 7.1.11  in 36.213
	}
	else {
	  AssertFatal(1==0,"TDD case not done yet\n");
	}
330 331 332
      }// mpdcch_repetition_count == reps
      RA_template->msg2_mpdcch_repetition_cnt++;	      

333 334
      if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) {
	// Program PDSCH
knopp's avatar
knopp committed
335
	LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n",
336
	      module_idP,frameP,subframeP);
337 338 339 340 341 342
	RA_template->generate_rar = 0;	      
	
	dl_config_pdu                                                                  = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
	memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
	dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; 
	dl_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
343
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
344 345
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index                              = eNB->pdu_index[CC_idP];
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = RA_template->RA_rnti;
346
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2;   
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;   // localized
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(N_RB_DL,first_rb,6);
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation                             = 2; //QPSK
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version                     = 0;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks                       = 1;// first block
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag  = 0;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme                    = (cc->p_eNB==1 ) ? 0 : 1;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers                       = 1;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands                     = 1;
	//	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity                   = 1;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa                                     = 4; // 0 dB
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index               = 0;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap                                   = 0;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb                                   = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode                      = (cc->p_eNB==1 ) ? 1 : 2;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband                 = 1;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector                          = 1;
	//	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
366 367

	// Rel10 fields
368
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG;
369 370
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
	// Rel13 fields
371
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG;
372 373 374 375 376
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type                               = (RA_template->rach_resource_type < 3) ? 1 : 2;;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type                    = 2;  // not SI message
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = (10*frameP)+subframeP;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag                       = 0;
	dl_req->number_pdu++;
377
        dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
378 379 380
	
	// Program UL processing for Msg3, same as regular LTE
	get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
381
	add_msg3(module_idP,CC_idP, RA_template,frameP,subframeP);
382 383
	fill_rar_br(eNB,CC_idP,RA_template,frameP,subframeP,cc[CC_idP].RAR_pdu.payload,RA_template->rach_resource_type-1);
	// DL request
384 385 386
	eNB->TX_req[CC_idP].sfn_sf                                            = (frameP<<4)+subframeP;
        eNB->TX_req[CC_idP].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
        eNB->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST;
387 388 389 390 391 392 393 394 395 396 397 398
	TX_req                                                                = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; 		     
	TX_req->pdu_length                                                    = 7;  // This should be changed if we have more than 1 preamble 
	TX_req->pdu_index                                                     = eNB->pdu_index[CC_idP]++;
	TX_req->num_segments                                                  = 1;
	TX_req->segments[0].segment_length                                    = 7;
	TX_req->segments[0].segment_data                                      = cc[CC_idP].RAR_pdu.payload;
	eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++;
      }
    }      
    
  }		
  else
399
#endif
400
    {
401

402
      if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) {
knopp's avatar
knopp committed
403
	LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, RA_active %d format 1A (%d,%d))\n",
404 405 406 407 408
	      module_idP, CC_idP, frameP, subframeP,
	      RA_template->RA_active,
	      
	      RA_template->RA_dci_fmt1,
	      RA_template->RA_dci_size_bits1);
409 410

	// Allocate 4 PRBS starting in RB 0
411 412 413 414 415 416 417 418 419
	first_rb = 0;
	vrb_map[first_rb] = 1;
	vrb_map[first_rb+1] = 1;
	vrb_map[first_rb+2] = 1;
	vrb_map[first_rb+3] = 1;
	
	memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
	dl_config_pdu->pdu_type                                                          = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; 
	dl_config_pdu->pdu_size                                                          = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
420
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
421 422 423 424 425 426 427 428 429 430 431 432 433 434
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format                             = NFAPI_DL_DCI_FORMAT_1A;
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level                      = 4;
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                                   = RA_template->RA_rnti;
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type                              = 2;    // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power                     = 6000; // equal to RS power
	
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process                           = 0;
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc                                    = 1; // no TPC
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1                   = 1;
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                                  = 0;
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1                   = 0;
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
	
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding                  = getRIV(N_RB_DL,first_rb,4);      
435 436

	// This checks if the above DCI allocation is feasible in current subframe
437 438 439 440 441
	if (!CCE_allocation_infeasible(module_idP,CC_idP,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->RA_rnti)) {
	  LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n",
		frameP,subframeP,RA_template->RA_rnti);
	  dl_req->number_dci++;
	  dl_req->number_pdu++;
442
          dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
443 444 445 446 447
	  
	  dl_config_pdu                                                                  = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
	  memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
	  dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; 
	  dl_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
448
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index                              = eNB->pdu_index[CC_idP];
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = RA_template->RA_rnti;
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2;   // format 1A/1B/1D
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;   // localized
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(N_RB_DL,first_rb,4);
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation                             = 2; //QPSK
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version                     = 0;
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks                       = 1;// first block
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag  = 0;
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme                    = (cc->p_eNB==1 ) ? 0 : 1;
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers                       = 1;
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands                     = 1;
	  //	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity                   = 1;
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa                                     = 4; // 0 dB
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index               = 0;
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap                                   = 0;
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb                                   = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode                      = (cc->p_eNB==1 ) ? 1 : 2;
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband                 = 1;
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector                          = 1;
	  //	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
	  dl_req->number_pdu++;
472
          dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
473 474 475
	  
	  // Program UL processing for Msg3
	  get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
476

knopp's avatar
knopp committed
477
	  LOG_D(MAC,"Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n",
478
		frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
479 480
	  
	  fill_rar(module_idP,CC_idP,frameP,cc[CC_idP].RAR_pdu.payload,N_RB_DL,7);
481 482
	  add_msg3(module_idP,CC_idP, RA_template,frameP,subframeP);

483
	  // DL request
484 485 486
	  eNB->TX_req[CC_idP].sfn_sf                                             = (frameP<<4)+subframeP;
          eNB->TX_req[CC_idP].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
          eNB->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST;
487 488 489 490 491 492 493 494 495 496 497
	  TX_req                                                                = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; 		     
	  TX_req->pdu_length                                                    = 7;  // This should be changed if we have more than 1 preamble 
	  TX_req->pdu_index                                                     = eNB->pdu_index[CC_idP]++;
	  TX_req->num_segments                                                  = 1;
	  TX_req->segments[0].segment_length                                    = 7;
	  TX_req->segments[0].segment_data                                      = cc[CC_idP].RAR_pdu.payload;
	  eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++;
	} // PDCCH CCE allocation is feasible
      } // Msg2 frame/subframe condition
    } // else BL/CE
}
498

499
void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template){
500

501

502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
  eNB_MAC_INST                    *eNB = RC.mac[module_idP];
  COMMON_channels_t               *cc  = eNB->common_channels;
  int16_t                         rrc_sdu_length;
  int                             UE_id           = -1;
  uint16_t                        msg4_padding;
  uint16_t                        msg4_post_padding;
  uint16_t                        msg4_header;

  uint8_t                         *vrb_map;
  int                             first_rb;
  int                             N_RB_DL;
  nfapi_dl_config_request_pdu_t   *dl_config_pdu;
  nfapi_ul_config_request_pdu_t   *ul_config_pdu;
  nfapi_tx_request_pdu_t          *TX_req;
  UE_list_t                       *UE_list=&eNB->UE_list;
  nfapi_dl_config_request_body_t *dl_req;
  nfapi_ul_config_request_body_t *ul_req;
  uint8_t                         lcid;
  uint8_t                         offset;
521
  int harq_pid;
522

523

524 525 526 527
#ifdef Rel14
  int rmax            = 0;
  int rep             = 0; 
  int reps            = 0;
528

529

530 531 532 533 534 535 536 537
  first_rb        = 0;
  struct PRACH_ConfigSIB_v1310 *ext4_prach;
  struct PUCCH_ConfigCommon_v1310 *ext4_pucch;
  PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
  struct N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13;
  PRACH_ParametersCE_r13_t *p[4]={NULL,NULL,NULL,NULL};
  int pucchreps[4]={1,1,1,1};
  int n1pucchan[4]={0,0,0,0};
538

539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
  if (cc[CC_idP].radioResourceConfigCommon_BR) {

    ext4_prach                    = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
    ext4_pucch                    = cc[CC_idP].radioResourceConfigCommon_BR->ext4->pucch_ConfigCommon_v1310;
    prach_ParametersListCE_r13    = &ext4_prach->prach_ParametersListCE_r13;
    pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13;
    AssertFatal(prach_ParametersListCE_r13!=NULL,"prach_ParametersListCE_r13 is null\n");
    AssertFatal(pucch_N1PUCCH_AN_InfoList_r13!=NULL,"pucch_N1PUCCH_AN_InfoList_r13 is null\n");
    // check to verify CE-Level compatibility in SIB2_BR
    AssertFatal(prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count,
		"prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n");

    switch (prach_ParametersListCE_r13->list.count) {
    case 4:
      p[3]         = prach_ParametersListCE_r13->list.array[3];
      n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3]; 
      AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13!=NULL,"pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n");
      pucchreps[3] = (int)(4<<*ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13);
      
    case 3:
      p[2]         = prach_ParametersListCE_r13->list.array[2];
      n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2]; 
      AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13!=NULL,"pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n");
      pucchreps[2] = (int)(4<<*ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13);
    case 2:
      p[1]         =prach_ParametersListCE_r13->list.array[1];
      n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1]; 
      AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13!=NULL,"pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n");
      pucchreps[1] = (int)(1<<*ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13);
    case 1:
      p[0]         = prach_ParametersListCE_r13->list.array[0];
      n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0]; 
      AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13!=NULL,"pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n");
      pucchreps[0] = (int)(1<<*ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13);
    default:
      AssertFatal(1==0,"Illegal count for prach_ParametersListCE_r13 %d\n",prach_ParametersListCE_r13->list.count);
    }
  }
#endif

  vrb_map       = cc[CC_idP].vrb_map;
  
  dl_req        = &eNB->DL_req[CC_idP].dl_config_request_body;
  dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
  N_RB_DL       = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
584

585 586 587
  UE_id = find_UE_id(module_idP,RA_template->rnti);
  AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n");
  
588 589 590 591 592
  // set HARQ process round to 0 for this UE
  
  if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
  else harq_pid = ((frameP*10)+subframeP)&7;

593 594 595 596 597 598 599 600 601 602 603 604
  
  // Get RRCConnectionSetup for Piggyback
  rrc_sdu_length = mac_rrc_data_req(module_idP,
				    CC_idP,
				    frameP,
				    CCCH,
				    1, // 1 transport block
				    &cc[CC_idP].CCCH_pdu.payload[0],
				    ENB_FLAG_YES,
				    module_idP,
				    0); // not used in this case
  
605
  AssertFatal(rrc_sdu_length>0,
606 607 608
	      "[MAC][eNB Scheduler] CCCH not allocated\n");
  
  
knopp's avatar
knopp committed
609
  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n",
610 611
	module_idP, CC_idP, frameP, subframeP,UE_id, rrc_sdu_length);
  
612 613
  
#ifdef Rel14
614 615 616
  if (RA_template->rach_resource_type>0) {
    
    // Generate DCI + repetitions first
617
    // This uses an MPDCCH Type 2 allocation according to Section 9.1.5 36-213, Type2 common allocation according to Table 7.1-8 (36-213)
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
    // Parameters:
    //    p=2+4 PRB set (number of PRB pairs 6)
    //    rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3
    //    if CELevel = 0,1 => Table 9.1.5-1b for MPDCCH candidates
    //    if CELevel = 2,3 => Table 9.1.5-2b for MPDCCH candidates
    //    distributed transmission
    
    // rmax from SIB2 information
    rmax           = p[RA_template->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13;
    AssertFatal(rmax>=4,"choose rmax>=4 for enough repeititions, or reduce rep to 1 or 2\n");

    // choose r3 by default for Msg4 (this is ok from table 9.1.5-3 for rmax = >=4, if we choose rmax <4 it has to be less
    rep            = 2; 
    // get actual repetition count from Table 9.1.5-3
    reps           = (rmax<=8)?(1<<rep):(rmax>>(3-rep));
    // get first narrowband
634 635
    first_rb = narrowband_to_first_rb(&cc[CC_idP],RA_template->msg34_narrowband);

636
    if ((RA_template->msg4_mpdcch_repetition_cnt == 0) &&
637
    (mpdcch_sf_condition(eNB,CC_idP,frameP,subframeP,rmax,TYPE2,-1)>0)){
638 639 640 641 642
      // MPDCCH configuration for RAR
      
      memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
      dl_config_pdu->pdu_type                                                                  = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; 
      dl_config_pdu->pdu_size                                                                  = (uint8_t)(2+sizeof(nfapi_dl_config_mpdcch_pdu));
643
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag                                        = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG;
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format                                    = (RA_template->rach_resource_type > 1) ? 11 : 10;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band                            = RA_template->msg34_narrowband;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs                           = 6;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment                     = 0; // Note: this can be dynamic
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type                       = 1;
      AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!=NULL,
		  "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol                                  = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index                                    = 0;  // Note: this should be dynamic
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level                             = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type                                     = 0;  // t-C-RNTI
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti                                          = RA_template->RA_rnti;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode                                       = (RA_template->rach_resource_type < 3) ? 1 : 2;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init                          = cc[CC_idP].physCellId;  /// Check this is still N_id_cell for type2 common
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io                    = (frameP*10)+subframeP;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power                            = 6000; // 0dB
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding                         = getRIV(6,0,6);// check if not getRIV(N_RB_DL,first_rb,6);
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs                                           = 4; // adjust according to size of Msg4, 208 bits with N1A_PRB=3
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels                        = 4; // fix to 4 for now
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version                            = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator                            = 0;
665
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process                                  = harq_pid;
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length                                   = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi                                          = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag                                      = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi                                           = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset                          = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number                = rep; 
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc                                           = 1;// N1A_PRB=3; => 208 bits
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length              = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index                     = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag                           = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index                                = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index                              = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level                             = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request                                   = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag    = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity         = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag                = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication                             = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding            = 0; // this is not needed by OAI L1, but should be filled in
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports                    = 1;
      RA_template->msg4_mpdcch_repetition_cnt++;
      dl_req->number_pdu++;
689
      dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
      
    } //repetition_count==0 && SF condition met
    else if (RA_template->msg4_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions
      RA_template->msg4_mpdcch_repetition_cnt++;	      
      if (RA_template->msg4_mpdcch_repetition_cnt==reps) { // this is the last mpdcch repetition
	if (cc[CC_idP].tdd_Config==NULL) { // FDD case
	  // wait 2 subframes for PDSCH transmission
	  if (subframeP>7) RA_template->Msg4_frame = (frameP+1)&1023;
	  else             RA_template->Msg4_frame = frameP;
	  RA_template->Msg4_subframe               = (subframeP+2)%10; 
	}
	else {
	  AssertFatal(1==0,"TDD case not done yet\n");
	}
      } // mpdcch_repetition_count == reps
      if ((RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) {
	
	// Program PDSCH
	
knopp's avatar
knopp committed
709
	LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 BR with RRC Piggyback (ce_level %d RNTI %x)\n",
710
	      module_idP, CC_idP, frameP, subframeP,RA_template->rach_resource_type-1,RA_template->rnti);
711

712 713 714 715 716
	AssertFatal(1==0,"Msg4 generation not finished for BL/CE UE\n");
	dl_config_pdu                                                                  = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
	memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
	dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; 
	dl_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
717
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index                              = eNB->pdu_index[CC_idP];
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = RA_template->rnti;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2;   // format 1A/1B/1D
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;   // localized
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(N_RB_DL,first_rb,6);  // check that this isn't getRIV(6,0,6)
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation                             = 2; //QPSK
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version                     = 0;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks                       = 1;// first block
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag  = 0;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme                    = (cc->p_eNB==1 ) ? 0 : 1;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers                       = 1;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands                     = 1;
	//	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity                   = 1;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa                                     = 4; // 0 dB
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index               = 0;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap                                   = 0;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb                                   = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode                      = (cc->p_eNB==1 ) ? 1 : 2;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband                 = 1;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector                          = 1;
	//	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
740

741
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG;
742
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
743
	
744
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG;
745 746 747 748 749
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type                               = (RA_template->rach_resource_type < 3) ? 1 : 2;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type                    = 2;  // not SI message
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = (10*frameP)+subframeP;
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag                       = 0;
	dl_req->number_pdu++;
750
        dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
751 752 753
	
	RA_template->generate_Msg4=0;
	RA_template->wait_ack_Msg4=1;
754

755 756
	lcid=0;
	
757
	UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid] = 0;
758 759
	msg4_header = 1+6+1;  // CR header, CR CE, SDU header
	
760 761
	if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
	  msg4_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header;
762 763 764
	  msg4_post_padding = 0;
	} else {
	  msg4_padding = 0;
765
	  msg4_post_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header -1;
766 767
	}
	
knopp's avatar
knopp committed
768
	LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
769
	      module_idP,CC_idP,frameP,subframeP,RA_template->msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787
	DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return
	// CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
	offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
				       1,                           //num_sdus
				       (unsigned short*)&rrc_sdu_length,             //
				       &lcid,                       // sdu_lcid
				       255,                         // no drx
				       0,                           // no timing advance
				       RA_template->cont_res_id,  // contention res id
				       msg4_padding,                // no padding
				       msg4_post_padding);
	
	memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
	       &cc[CC_idP].CCCH_pdu.payload[0],
	       rrc_sdu_length);
	
	// DL request
	eNB->TX_req[CC_idP].sfn_sf                                             = (frameP<<3)+subframeP;
788 789
        eNB->TX_req[CC_idP].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
        eNB->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST;
790 791 792 793 794 795 796
	TX_req                                                                = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; 		     	      
	TX_req->pdu_length                                                    = rrc_sdu_length;
	TX_req->pdu_index                                                     = eNB->pdu_index[CC_idP]++;
	TX_req->num_segments                                                  = 1;
	TX_req->segments[0].segment_length                                    = rrc_sdu_length;
	TX_req->segments[0].segment_data                                      = eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0];
	eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++;
797

798 799 800 801
	// Program ACK/NAK for Msg4 PDSCH
	int absSF = (RA_template->Msg3_frame*10)+RA_template->Msg3_subframe;
	// see Section 10.2 from 36.213
	int ackNAK_absSF = absSF + reps + 4;
802 803 804 805
	AssertFatal(reps>2,"Have to handle programming of ACK when PDSCH repetitions is > 2\n");
	ul_req        = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF%10].ul_config_request_body;
	ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 

806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827
	ul_config_pdu->pdu_type                                                                     = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; 
	ul_config_pdu->pdu_size                                                                     = (uint8_t)(2+sizeof(nfapi_ul_config_uci_harq_pdu));
	ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle                       = 0; // don't know how to use this
	ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti                         = RA_template->rnti;
	ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type                     = (RA_template->rach_resource_type < 3) ? 1 : 2;
	ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols               = 0;
	ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[RA_template->rach_resource_type-1];
	ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.repetition_number           = 0;
	// Note need to keep sending this across reptitions!!!! Not really for PUCCH, to ask small-cell forum, we'll see for the other messages, maybe parameters change across repetitions and FAPI has to provide for that
	if (cc[CC_idP].tdd_Config==NULL) { // FDD case
	  ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.n_pucch_1_0   = n1pucchan[RA_template->rach_resource_type-1];
	  // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case
	  // = N_ECCE_q + Delta_ARO + n1pucchan[ce_level]
	  // higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 =>
	  // Delta_ARO = 0 from Table 10.1.2.1-1
	  ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.harq_size     = 1;  // 1-bit ACK/NAK
	}
	else {
	  AssertFatal(1==0,"PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n");
	}
	ul_req->number_of_pdus++;
	T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_idP), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP),
828
	  T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->msg4_TBsize));
829 830 831 832 833 834 835 836 837 838 839 840
	
	if (opt_enabled==1) {
	  trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
		    rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id),
		    eNB->frame, eNB->subframe,0,0);
	  LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n",
		module_idP, CC_idP, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length);
	}
      } // Msg4 frame/subframe
    } // msg4_mpdcch_repetition_count
  } // rach_resource_type > 0 
  else
841
#endif
842 843
    { // This is normal LTE case
      if ((RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) {	      
knopp's avatar
knopp committed
844
	LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
845 846
	      module_idP, CC_idP, frameP, subframeP,RA_template->rnti);
	
847
	/// Choose first 4 RBs for Msg4, should really check that these are free!
848 849 850 851 852 853 854 855
	first_rb=0;
	
	vrb_map[first_rb] = 1;
	vrb_map[first_rb+1] = 1;
	vrb_map[first_rb+2] = 1;
	vrb_map[first_rb+3] = 1;
	
	
856
	// Compute MCS/TBS for 3 PRB (coded on 4 vrb)
857 858 859
	msg4_header = 1+6+1;  // CR header, CR CE, SDU header
	
	if ((rrc_sdu_length+msg4_header) <= 22) {
860 861
	  RA_template->msg4_mcs                       = 4;
	  RA_template->msg4_TBsize = 22;
862
	} else if ((rrc_sdu_length+msg4_header) <= 28) {
863 864
	  RA_template->msg4_mcs                       = 5;
	  RA_template->msg4_TBsize = 28;
865
	} else if ((rrc_sdu_length+msg4_header) <= 32) {
866 867
	  RA_template->msg4_mcs                       = 6;
	  RA_template->msg4_TBsize = 32;
868
	} else if ((rrc_sdu_length+msg4_header) <= 41) {
869 870
	  RA_template->msg4_mcs                       = 7;
	  RA_template->msg4_TBsize = 41;
871
	} else if ((rrc_sdu_length+msg4_header) <= 49) {
872 873
	  RA_template->msg4_mcs                       = 8;
	  RA_template->msg4_TBsize = 49;
874
	} else if ((rrc_sdu_length+msg4_header) <= 57) {
875 876
	  RA_template->msg4_mcs    = 9;
	  RA_template->msg4_TBsize = 57;
877 878
	}

879 880 881 882 883 884 885 886 887 888 889
	fill_nfapi_dl_dci_1A(dl_config_pdu,
			     4,                           // aggregation_level
			     RA_template->rnti,           // rnti
			     1,                           // rnti_type, CRNTI
			     harq_pid,                    // harq_process
			     1,                           // tpc, none
			     getRIV(N_RB_DL,first_rb,4),  // resource_block_coding
			     RA_template->msg4_mcs,       // mcs
			     1,                           // ndi
			     0,                           // rv
			     0);                          // vrb_flag
890 891 892 893
	
	if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
	  dl_req->number_dci++;
	  dl_req->number_pdu++;
894
          dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
895
	  
896 897
	  RA_template->generate_Msg4=0;
	  RA_template->wait_ack_Msg4=1;
898 899 900
	  RA_template->Msg4_frame++;
	  RA_template->Msg4_frame&=1023;

901
	  lcid=0;
902
	  
903
	  // put HARQ process 0 round to IDLE
904 905 906
	  if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
	  else harq_pid = ((frameP*10)+subframeP)&7;
	  UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid] = 0;
907
	  
908 909
	  if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
	    msg4_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header;
910 911 912
	    msg4_post_padding = 0;
	  } else {
	    msg4_padding = 0;
913
	    msg4_post_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header -1;
914
	  }
915
	  
knopp's avatar
knopp committed
916
	  LOG_D(MAC,"[eNB %d][RAPROC] CC_idP %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
917
		module_idP,CC_idP,frameP,subframeP,RA_template->msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
918 919 920 921 922 923 924 925 926 927 928
	  DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return
	  // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
	  offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
					 1,                           //num_sdus
					 (unsigned short*)&rrc_sdu_length,             //
					 &lcid,                       // sdu_lcid
					 255,                         // no drx
					 0,                           // no timing advance
					 RA_template->cont_res_id,  // contention res id
					 msg4_padding,                // no padding
					 msg4_post_padding);
929
	  
930 931 932
	  memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
		 &cc[CC_idP].CCCH_pdu.payload[0],
		 rrc_sdu_length);
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
	  // DLSCH Config
	  fill_nfapi_dlsch_config(eNB,
				  dl_req,
				  RA_template->msg4_TBsize,
				  eNB->pdu_index[CC_idP]++,
				  RA_template->rnti,
				  2,                           // resource_allocation_type : format 1A/1B/1D
				  0,                           // virtual_resource_block_assignment_flag : localized
				  getRIV(N_RB_DL,first_rb,4),  // resource_block_coding : RIV, 4 PRB
				  2,                           // modulation: QPSK
				  0,                           // redundancy version
				  1,                           // transport_blocks
				  0,                           // transport_block_to_codeword_swap_flag (0)
				  (cc->p_eNB==1 ) ? 0 : 1,     // transmission_scheme
				  1,                           // number of layers
				  1,                           // number of subbands
				  //0,                         // codebook index 
				  1,                           // ue_category_capacity
				  4,                           // pa: 0 dB
				  0,                           // delta_power_offset_index
				  0,                           // ngap
				  1,                           // NPRB = 3 like in DCI
				  (cc->p_eNB==1 ) ? 1 : 2,     // transmission mode
				  1,                           // num_bf_prb_per_subband
				  1);                          // num_bf_vector

960
	  // DL request
961 962 963 964 965
	  eNB->TX_req[CC_idP].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_idP].tx_request_body,
							 (frameP*10)+subframeP,
							 rrc_sdu_length,
							 &eNB->pdu_index[CC_idP],
							 eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); 
966
          eNB->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST;
967

968
	  // Program PUCCH1a for ACK/NAK
969 970 971 972 973 974
	  // Program ACK/NAK for Msg4 PDSCH
	  fill_nfapi_uci_acknak(module_idP,
				CC_idP,
				RA_template->rnti,
				(frameP*10)+subframeP,
				dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
975

976
	  
977
	  T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_idP), T_INT(RA_template->rnti), T_INT(frameP), T_INT(subframeP),
978
	    T_INT(0 /*harq_pid always 0?*/), T_BUFFER(&eNB->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], RA_template->msg4_TBsize));
979
	  
980 981 982 983 984 985 986
	  if (opt_enabled==1) {
	    trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
		      rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id),
		      eNB->frame, eNB->subframe,0,0);
	    LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n",
		  module_idP, CC_idP, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length);
	  }
987
	  
988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003
	} // CCE Allocation feasible
      } // msg4 frame/subframe
    } // else rach_resource_type
}

void check_Msg4_retransmission(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template) {
 
  eNB_MAC_INST                    *eNB = RC.mac[module_idP];
  COMMON_channels_t               *cc  = eNB->common_channels;
  int                             UE_id           = -1;
  uint8_t                         *vrb_map;
  int                             first_rb;
  int                             N_RB_DL;
  nfapi_dl_config_request_pdu_t   *dl_config_pdu;
  UE_list_t                       *UE_list=&eNB->UE_list;
  nfapi_dl_config_request_body_t *dl_req;
1004

1005
  int                             round,harq_pid;
1006
  /*
1007
#ifdef Rel14
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
  COMMON_channels_t               *cc  = eNB->common_channels;

  int rmax            = 0;
  int rep             = 0; 
  int reps            = 0;

  first_rb        = 0;
  struct PRACH_ConfigSIB_v1310 *ext4_prach;
  PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
  PRACH_ParametersCE_r13_t *p[4];

  if (cc[CC_idP].radioResourceConfigCommon_BR) {

    ext4_prach                 = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
    prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
        
    switch (prach_ParametersListCE_r13->list.count) {
    case 4:
      p[3]=prach_ParametersListCE_r13->list.array[3];
    case 3:
      p[2]=prach_ParametersListCE_r13->list.array[2];
    case 2:
      p[1]=prach_ParametersListCE_r13->list.array[1];
    case 1:
      p[0]=prach_ParametersListCE_r13->list.array[0];
    default:
      AssertFatal(1==0,"Illegal count for prach_ParametersListCE_r13 %d\n",prach_ParametersListCE_r13->list.count);
    }
  }
#endif
  */

  // check HARQ status and retransmit if necessary
1041

1042 1043 1044
  
  UE_id = find_UE_id(module_idP,RA_template->rnti);
  AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n");
1045 1046 1047 1048
  if (cc[CC_idP].tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
  else harq_pid = ((frameP*10)+subframeP)&7;

  round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid];
1049 1050 1051 1052 1053 1054
  vrb_map       = cc[CC_idP].vrb_map;
  
  dl_req        = &eNB->DL_req[CC_idP].dl_config_request_body;
  dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
  N_RB_DL       = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
  
knopp's avatar
knopp committed
1055
  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 was acknowledged (round %d)\n",
1056 1057 1058
	module_idP,CC_idP,frameP,subframeP,round);

  if (round!=8) {
1059 1060
    
#ifdef Rel14
1061 1062 1063 1064
    if (RA_template->rach_resource_type>0) {
      AssertFatal(1==0,"Msg4 Retransmissions not handled yet for BL/CE UEs\n");
    }
    else
1065
#endif 
1066 1067
      {
	if ( (RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) {	       
1068
	  
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
	  //RA_template->wait_ack_Msg4++;
	  // we have to schedule a retransmission
	  
	  first_rb=0;
	  vrb_map[first_rb] = 1;
	  vrb_map[first_rb+1] = 1;
	  vrb_map[first_rb+2] = 1;
	  vrb_map[first_rb+3] = 1;
	  
	  fill_nfapi_dl_dci_1A(dl_config_pdu,
			       4,                           // aggregation_level
			       RA_template->rnti,           // rnti
			       1,                           // rnti_type, CRNTI
			       0,                           // harq_process
			       1,                           // tpc, none
			       getRIV(N_RB_DL,first_rb,4),  // resource_block_coding
			       RA_template->msg4_mcs,       // mcs
			       1,                           // ndi
			       round,                       // rv
			       0);                          // vrb_flag
	  
	  if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
	    dl_req->number_dci++;
	    dl_req->number_pdu++;
1093
            dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
1094
	    
knopp's avatar
knopp committed
1095
	    LOG_D(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP);
1096 1097
	  }
	  else
knopp's avatar
knopp committed
1098
	    LOG_D(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", RA_template->rnti, round, frameP, subframeP);
1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115
	  LOG_W(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n",
		module_idP,CC_idP,frameP,subframeP,RA_template->rnti);
	  
	  
	  // Program PUCCH1a for ACK/NAK
	  

	  fill_nfapi_uci_acknak(module_idP,CC_idP,
				RA_template->rnti,
				(frameP*10)+subframeP,
				dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
	  
	  // prepare frame for retransmission
	  RA_template->Msg4_frame++;
	  RA_template->Msg4_frame&=1023;
	} // Msg4 frame/subframe
      } // regular LTE case
1116
  } else {
knopp's avatar
knopp committed
1117
    LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,CC_idP,frameP,subframeP);
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136
    RA_template->wait_ack_Msg4=0;
    RA_template->RA_active=FALSE;
    UE_id = find_UE_id(module_idP,RA_template->rnti);
    DevAssert( UE_id != -1 );
    eNB->UE_list.UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured=TRUE;
  }
} 

void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP)
{

  int                             CC_id;
  eNB_MAC_INST                    *eNB = RC.mac[module_idP];
  COMMON_channels_t               *cc  = eNB->common_channels;
  RA_TEMPLATE                     *RA_template;
  uint8_t                         i;

  start_meas(&eNB->schedule_ra);

1137

1138
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1139
    // skip UL component carriers if TDD
1140 1141 1142 1143 1144 1145 1146 1147 1148
    if (is_UL_sf(&cc[CC_id],subframeP)==1) continue;


    for (i=0; i<NB_RA_PROC_MAX; i++) {

      RA_template = (RA_TEMPLATE *)&cc[CC_id].RA_template[i];

      if (RA_template->RA_active == TRUE) {

knopp's avatar
knopp committed
1149
        LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n",
1150
              module_idP,frameP,subframeP,CC_id,i,RA_template->generate_rar,RA_template->generate_Msg4,RA_template->wait_ack_Msg4, RA_template->rnti);
1151 1152 1153 1154 1155 1156

        if      (RA_template->generate_rar == 1)  generate_Msg2(module_idP,CC_id,frameP,subframeP,RA_template);
	else if (RA_template->generate_Msg4 == 1) generate_Msg4(module_idP,CC_id,frameP,subframeP,RA_template);
 	else if (RA_template->wait_ack_Msg4==1)   check_Msg4_retransmission(module_idP,CC_id,frameP,subframeP,RA_template);


1157
      } // RA_active == TRUE
1158 1159
    } // for i=0 .. N_RA_PROC-1 
  } // CC_id
1160
  
1161 1162
  stop_meas(&eNB->schedule_ra);
}
1163

1164

1165
// handles the event of MSG1 reception
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177
void initiate_ra_proc(module_id_t module_idP, 
		      int CC_id,
		      frame_t frameP, 
		      sub_frame_t subframeP,
		      uint16_t preamble_index,
		      int16_t timing_offset,
		      uint16_t ra_rnti
#ifdef Rel14
		      ,
		      uint8_t rach_resource_type
#endif
		      )
1178 1179 1180 1181
{

  uint8_t i;

1182 1183 1184
  COMMON_channels_t   *cc  = &RC.mac[module_idP]->common_channels[CC_id];
  RA_TEMPLATE *RA_template = &cc->RA_template[0];

1185 1186
  struct PRACH_ConfigSIB_v1310 *ext4_prach = NULL;
  PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
1187

1188 1189 1190 1191
  if (cc->radioResourceConfigCommon_BR && cc->radioResourceConfigCommon_BR->ext4) {
    ext4_prach=cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
    prach_ParametersListCE_r13= &ext4_prach->prach_ParametersListCE_r13;
  }
knopp's avatar
knopp committed
1192
  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  Initiating RA procedure for preamble index %d\n",module_idP,CC_id,frameP,subframeP,preamble_index);
1193
#ifdef Rel14
knopp's avatar
knopp committed
1194
  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  PRACH resource type %d\n",module_idP,CC_id,frameP,subframeP,rach_resource_type);
1195
#endif
1196

1197 1198
  if (prach_ParametersListCE_r13 && 
      prach_ParametersListCE_r13->list.count<rach_resource_type) {
1199 1200 1201 1202 1203 1204 1205
    LOG_E(MAC,"[eNB %d][RAPROC] CC_id %d Received impossible PRACH resource type %d, only %d CE levels configured\n",
	  module_idP,CC_id,
	  rach_resource_type,
	  (int)prach_ParametersListCE_r13->list.count);
    return;
  }

1206 1207 1208
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC,1);
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC,0);

1209
  for (i=0; i<NB_RA_PROC_MAX; i++) {
1210 1211
    if (RA_template[i].RA_active==FALSE &&
        RA_template[i].wait_ack_Msg4 == 0) {
Cedric Roux's avatar
Cedric Roux committed
1212
      int loop = 0;
1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223
      RA_template[i].RA_active          = TRUE;
      RA_template[i].generate_rar       = 1;
      RA_template[i].generate_Msg4      = 0;
      RA_template[i].wait_ack_Msg4      = 0;
      RA_template[i].timing_offset      = timing_offset;
      RA_template[i].preamble_subframe  = subframeP;
#ifdef Rel14
      RA_template[i].rach_resource_type = rach_resource_type;
      RA_template[i].msg2_mpdcch_repetition_cnt = 0;		      
      RA_template[i].msg4_mpdcch_repetition_cnt = 0;		      
#endif
1224 1225
      RA_template[i].Msg2_frame         = frameP+((subframeP>5)?1:0);
      RA_template[i].Msg2_subframe      = (subframeP+4)%10;
Cedric Roux's avatar
Cedric Roux committed
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237
      /* TODO: find better procedure to allocate RNTI */
      do {
        RA_template[i].rnti = taus();
        loop++;
      } while (loop != 100 &&
               /* TODO: this is not correct, the rnti may be in use without
                * being in the MAC yet. To be refined.
                */
               !(find_UE_id(module_idP, RA_template[i].rnti) == -1 &&
                 /* 1024 and 60000 arbirarily chosen, not coming from standard */
                 RA_template[i].rnti >= 1024 && RA_template[i].rnti < 60000));
      if (loop == 100) { printf("%s:%d:%s: FATAL ERROR! contact the authors\n", __FILE__, __LINE__, __FUNCTION__); abort(); }
1238
      RA_template[i].RA_rnti        = ra_rnti;
1239
      RA_template[i].preamble_index = preamble_index;
knopp's avatar
knopp committed
1240
      LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation in Frame %d, subframe %d for process %d, rnti %x, RA_active %d\n",
1241 1242 1243 1244
            module_idP,CC_id,frameP,
	    RA_template[i].Msg2_frame,
	    RA_template[i].Msg2_subframe,
	    i,RA_template[i].rnti,