eNB_scheduler_RA.c 70.3 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
 */
Raymond Knopp's avatar
 
Raymond Knopp committed
21

22
/*! \file eNB_scheduler_RA.c
23
 * \brief primitives used for random access
Raymond Knopp's avatar
 
Raymond Knopp committed
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"
Raymond Knopp's avatar
 
Raymond Knopp committed
34 35
#include "PHY/defs.h"
#include "PHY/extern.h"
Lionel Gauthier's avatar
Lionel Gauthier committed
36
#include "msc.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
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
Raymond Knopp's avatar
 
Raymond Knopp committed
62

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
  COMMON_channels_t               *cc  = &eNB->common_channels[CC_id];
69
  uint8_t                         j;
70
  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) {
86 87
    LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n",
	  module_idP,frameP,subframeP,CC_id,RA_template->rach_resource_type-1,
88
	  RA_template->Msg3_frame,RA_template->Msg3_subframe);
Raymond Knopp's avatar
Raymond 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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
	  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));
    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++;
  } //  if (RA_template->rach_resource_type>0) {	 
  else
121
#endif
122
    {
123 124
      LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n",
	    module_idP,frameP,subframeP,CC_id,RA_template->Msg3_frame,RA_template->Msg3_subframe);
125
	    
Raymond Knopp's avatar
Raymond Knopp committed
126
      LOG_D(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n",
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
	    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));
      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++;
      // 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
	hi_dci0_pdu                                                         = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; 	
	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);
	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;
	
167 168
	LOG_D(MAC,"[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA (mcs %d, first rb %d, nb_rb %d,round %d)\n",
	      module_idP,RA_template->rnti,CC_id,frameP,subframeP,10,
169 170 171 172
	      1,1,
	      RA_template->msg3_round-1);
      } //       if (RA_template->msg3_round != 0) { // program HI too
    } // non-BL/CE UE case
173 174
}

175
void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template) {
Raymond Knopp's avatar
 
Raymond Knopp committed
176

177 178
  eNB_MAC_INST                    *eNB = RC.mac[module_idP];
  COMMON_channels_t               *cc  = eNB->common_channels;
179
 
180 181 182 183 184
  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;
185
  nfapi_dl_config_request_body_t *dl_req;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
186

187 188 189 190 191
  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);  

192 193 194 195 196
#ifdef Rel14
  int rmax            = 0;
  int rep             = 0; 
  int reps            = 0;
  int num_nb          = 0;
197

198
  first_rb        = 0;
199 200
  struct PRACH_ConfigSIB_v1310 *ext4_prach;
  PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
201
  PRACH_ParametersCE_r13_t *p[4]={NULL,NULL,NULL,NULL};
202

203 204 205 206 207
  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 ==  
  
208
  if (cc[CC_idP].radioResourceConfigCommon_BR) {
209

210
    ext4_prach                 = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
211 212 213 214 215 216 217 218 219 220 221
    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];
222
      break;
223
    default:
224 225
      AssertFatal(1==0,"Illegal count for prach_ParametersListCE_r13 %d\n",(int)prach_ParametersListCE_r13->list.count);
      break;
226
    }
227
  }
228 229 230 231 232 233 234 235 236 237 238 239

  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
240 241 242 243
    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; 
244 245 246 247 248
    // 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];
249
    first_rb = narrowband_to_first_rb(&cc[CC_idP],RA_template->msg2_narrowband);
250 251
    
    if ((RA_template->msg2_mpdcch_repetition_cnt == 0) &&
252
	(mpdcch_sf_condition(eNB,CC_idP,frameP,subframeP,rmax,TYPE2,-1)>0)){
253
      // MPDCCH configuration for RAR
Raymond Knopp's avatar
Raymond Knopp committed
254
      LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming MPDCCH %d repetitions\n",
255
	    module_idP,frameP,subframeP,reps);
256 257 258 259 260 261 262 263 264 265 266 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
      
      
      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));
      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++;
306 307
      RA_template->Msg2_subframe = (RA_template->Msg2_subframe+9)%10;

308
    } //repetition_count==0 && SF condition met
309
    if (RA_template->msg2_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions
310
<<<<<<< HEAD
311 312 313
      LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, MPDCCH repetition %d\n",
	    module_idP,frameP,subframeP,RA_template->msg2_mpdcch_repetition_cnt);

314 315 316 317 318 319 320 321 322 323
      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");
	}
324 325 326
      }// mpdcch_repetition_count == reps
      RA_template->msg2_mpdcch_repetition_cnt++;	      

327 328
      if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) {
	// Program PDSCH
329 330
	LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH %d\n",
	      module_idP,frameP,subframeP);
331 332 333 334 335 336 337 338
	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));
	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;
339
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2;   
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
	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                    = ; 
359 360 361 362

	// Rel10 fields
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
	// Rel13 fields
363 364 365 366 367 368 369 370
	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++;
	
	// Program UL processing for Msg3, same as regular LTE
	get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
371
	add_msg3(module_idP,CC_idP, RA_template,frameP,subframeP);
372 373
	fill_rar_br(eNB,CC_idP,RA_template,frameP,subframeP,cc[CC_idP].RAR_pdu.payload,RA_template->rach_resource_type-1);
	// DL request
Cedric Roux's avatar
Cedric Roux committed
374
	eNB->TX_req[CC_idP].sfn_sf                                            = (frameP<<4)+subframeP;
375 376 377 378 379 380 381 382 383 384 385 386
	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
387
#endif
388
    {
389

390
      if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) {
391
	LOG_I(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, RA_active %d format 1A (%d,%d))\n",
392 393 394 395 396
	      module_idP, CC_idP, frameP, subframeP,
	      RA_template->RA_active,
	      
	      RA_template->RA_dci_fmt1,
	      RA_template->RA_dci_size_bits1);
397 398

	// Allocate 4 PRBS starting in RB 0
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
	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));
	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);      
422 423

	// This checks if the above DCI allocation is feasible in current subframe
424
	if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->RA_rnti)) {
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
	  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++;
	  
	  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));
	  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++;
	  
	  // Program UL processing for Msg3
	  get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
Raymond Knopp's avatar
Raymond Knopp committed
460
	  LOG_D(MAC,"Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n",
461
		frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
462 463
	  
	  fill_rar(module_idP,CC_idP,frameP,cc[CC_idP].RAR_pdu.payload,N_RB_DL,7);
464 465
	  add_msg3(module_idP,CC_idP, RA_template,frameP,subframeP);

466
	  // DL request
Cedric Roux's avatar
Cedric Roux committed
467
	  eNB->TX_req[CC_idP].sfn_sf                                             = (frameP<<4)+subframeP;
468 469 470 471 472 473 474 475 476 477 478
	  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
}
479

480
void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t subframeP,RA_TEMPLATE *RA_template){
Lionel Gauthier's avatar
 
Lionel Gauthier committed
481

482

483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
  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;

503

504 505 506 507
#ifdef Rel14
  int rmax            = 0;
  int rep             = 0; 
  int reps            = 0;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
508

509

510 511 512 513 514 515 516 517
  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};
Lionel Gauthier's avatar
 
Lionel Gauthier committed
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 552 553 554 555 556 557 558 559 560 561 562 563
  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);
564

565 566 567
  UE_id = find_UE_id(module_idP,RA_template->rnti);
  AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n");
  
568 569
  // set HARQ process round to 0 for this UE
  
570 571
  if (cc->tdd_Config) RA_template->harq_pid = ((frameP*10)+subframeP)%10;
  else RA_template->harq_pid = ((frameP*10)+subframeP)&7;
572

573 574 575 576 577 578 579 580 581 582 583 584
  
  // 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
  
585
  AssertFatal(rrc_sdu_length>0,
586 587 588 589 590 591
	      "[MAC][eNB Scheduler] CCCH not allocated\n");
  
  
  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n",
	module_idP, CC_idP, frameP, subframeP,UE_id, rrc_sdu_length);
  
592 593
  
#ifdef Rel14
594 595 596
  if (RA_template->rach_resource_type>0) {
    
    // Generate DCI + repetitions first
597
    // 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)
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
    // 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
614 615
    first_rb = narrowband_to_first_rb(&cc[CC_idP],RA_template->msg34_narrowband);

616
    if ((RA_template->msg4_mpdcch_repetition_cnt == 0) &&
617
    (mpdcch_sf_condition(eNB,CC_idP,frameP,subframeP,rmax,TYPE2,-1)>0)){
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643
      // 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));
      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;
644
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process                                  = RA_template->harq_pid;
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686
      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++;
      
    } //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
	
Raymond Knopp's avatar
Raymond Knopp committed
687
	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",
688
	      module_idP, CC_idP, frameP, subframeP,RA_template->rach_resource_type-1,RA_template->rnti);
689

690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 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));
	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                    = ; 
717 718

	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
719 720 721 722 723 724 725 726 727
	
	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++;
	
	RA_template->generate_Msg4=0;
	RA_template->wait_ack_Msg4=1;
728

729 730
	lcid=0;
	
731
	UE_list->UE_sched_ctrl[UE_id].round[CC_idP][RA_template->harq_pid] = 0;
732 733
	msg4_header = 1+6+1;  // CR header, CR CE, SDU header
	
734 735
	if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
	  msg4_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header;
736 737 738
	  msg4_post_padding = 0;
	} else {
	  msg4_padding = 0;
739
	  msg4_post_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header -1;
740 741
	}
	
Raymond Knopp's avatar
Raymond Knopp committed
742
	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",
743
	      module_idP,CC_idP,frameP,subframeP,RA_template->msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
	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
Cedric Roux's avatar
Cedric Roux committed
761
	eNB->TX_req[CC_idP].sfn_sf                                             = (frameP<<4)+subframeP;
762 763 764 765 766 767 768
	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++;
769

770 771 772 773
	// 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;
774 775 776 777
	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]; 

778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799
	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),
800
	  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));
801 802 803 804 805 806 807 808 809 810 811 812
	
	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
813
#endif
814 815 816 817 818
    { // This is normal LTE case
      if ((RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) {	      
	LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
	      module_idP, CC_idP, frameP, subframeP,RA_template->rnti);
	
819
	/// Choose first 4 RBs for Msg4, should really check that these are free!
820 821 822 823 824 825 826 827
	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;
	
	
828
	// Compute MCS/TBS for 3 PRB (coded on 4 vrb)
829 830 831
	msg4_header = 1+6+1;  // CR header, CR CE, SDU header
	
	if ((rrc_sdu_length+msg4_header) <= 22) {
832 833
	  RA_template->msg4_mcs                       = 4;
	  RA_template->msg4_TBsize = 22;
834
	} else if ((rrc_sdu_length+msg4_header) <= 28) {
835 836
	  RA_template->msg4_mcs                       = 5;
	  RA_template->msg4_TBsize = 28;
837
	} else if ((rrc_sdu_length+msg4_header) <= 32) {
838 839
	  RA_template->msg4_mcs                       = 6;
	  RA_template->msg4_TBsize = 32;
840
	} else if ((rrc_sdu_length+msg4_header) <= 41) {
841 842
	  RA_template->msg4_mcs                       = 7;
	  RA_template->msg4_TBsize = 41;
843
	} else if ((rrc_sdu_length+msg4_header) <= 49) {
844 845
	  RA_template->msg4_mcs                       = 8;
	  RA_template->msg4_TBsize = 49;
846
	} else if ((rrc_sdu_length+msg4_header) <= 57) {
847 848
	  RA_template->msg4_mcs    = 9;
	  RA_template->msg4_TBsize = 57;
849 850
	}

851 852 853 854
	fill_nfapi_dl_dci_1A(dl_config_pdu,
			     4,                           // aggregation_level
			     RA_template->rnti,           // rnti
			     1,                           // rnti_type, CRNTI
855
			     RA_template->harq_pid,       // harq_process
856 857 858 859 860 861
			     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
862
	
863
	if (!CCE_allocation_infeasible(module_idP,CC_idP,1,
864 865
				       subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
				       RA_template->rnti)) {
866 867
	  dl_req->number_dci++;
	  dl_req->number_pdu++;
868
	  
869 870
	  RA_template->generate_Msg4=0;
	  RA_template->wait_ack_Msg4=1;
871 872 873 874 875
	  
	  // increment Absolute subframe by 8 for Msg4 retransmission
	  LOG_I(MAC,"Frame %d, Subframe %d: Preparing for Msg4 retransmission currently %d.%d\n",
		frameP,subframeP,RA_template->Msg4_frame,RA_template->Msg4_subframe);
	  if (RA_template->Msg4_subframe > 1) RA_template->Msg4_frame++;
876
	  RA_template->Msg4_frame&=1023;
877 878 879
	  RA_template->Msg4_subframe = (RA_template->Msg4_subframe+8)%10;
	  LOG_I(MAC,"Frame %d, Subframe %d: Msg4 retransmission in %d.%d\n",
		frameP,subframeP,RA_template->Msg4_frame,RA_template->Msg4_subframe);
880
	  lcid=0;
881
	  
882 883 884 885
	  // put HARQ process round to 0
	  if (cc->tdd_Config) RA_template->harq_pid = ((frameP*10)+subframeP)%10;
	  else RA_template->harq_pid = ((frameP*10)+subframeP)&7;
	  UE_list->UE_sched_ctrl[UE_id].round[CC_idP][RA_template->harq_pid] = 0;
886
	  
887 888
	  if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
	    msg4_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header;
889 890 891
	    msg4_post_padding = 0;
	  } else {
	    msg4_padding = 0;
892
	    msg4_post_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header -1;
893
	  }
894
	  
Raymond Knopp's avatar
Raymond Knopp committed
895
	  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",
896
		module_idP,CC_idP,frameP,subframeP,RA_template->msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
897 898 899 900 901 902 903 904 905 906 907
	  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);
908
	  
909 910 911
	  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);
912
	  
913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938
	  // 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

939
	  // DL request
940 941 942 943 944
	  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]); 
945

946
	  LOG_D(MAC,"Filling UCI ACK/NAK information, cce_idx %d\n",dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
947
	  // Program PUCCH1a for ACK/NAK
948 949 950 951 952 953
	  // 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);
954

955
	  
956
	  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),
957
	    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));
958
	  
959 960 961 962 963 964 965
	  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);
	  }
966
	  
967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982
	} // 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;
983

984 985
  int                             round;
  /*
986
#ifdef Rel14
987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
  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
1020

1021 1022 1023
  
  UE_id = find_UE_id(module_idP,RA_template->rnti);
  AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n");
1024

1025
  round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP][RA_template->harq_pid];
1026 1027 1028 1029 1030 1031
  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);
  
1032 1033
  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 for harq_pid %d was acknowledged (round %d)\n",
	module_idP,CC_idP,frameP,subframeP,RA_template->harq_pid,round);
1034 1035

  if (round!=8) {
1036 1037
    
#ifdef Rel14
1038 1039 1040 1041
    if (RA_template->rach_resource_type>0) {
      AssertFatal(1==0,"Msg4 Retransmissions not handled yet for BL/CE UEs\n");
    }
    else
1042
#endif 
1043 1044
      {
	if ( (RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) {	       
1045
	  
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
	  //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
1059
			       RA_template->harq_pid,       // harq_process
1060 1061 1062 1063
			       1,                           // tpc, none
			       getRIV(N_RB_DL,first_rb,4),  // resource_block_coding
			       RA_template->msg4_mcs,       // mcs
			       1,                           // ndi
1064
			       round&3,                       // rv
1065 1066
			       0);                          // vrb_flag
	  
1067
	  if (!CCE_allocation_infeasible(module_idP,CC_idP,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
1068 1069 1070
	    dl_req->number_dci++;
	    dl_req->number_pdu++;
	    
Raymond Knopp's avatar
Raymond Knopp committed
1071
	    LOG_D(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP);
1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
	    	  // 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
				    round&3,                     // 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
1097 1098
	  }
	  else
Raymond Knopp's avatar
Raymond Knopp committed
1099
	    LOG_D(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", RA_template->rnti, round, frameP, subframeP);
1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
	  
	  
	  // 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
1111
	  if (RA_template->Msg4_subframe>1) RA_template->Msg4_frame++;
1112
	  RA_template->Msg4_frame&=1023;
1113 1114 1115 1116 1117
	  RA_template->Msg4_subframe=(RA_template->Msg4_subframe+8)%10;

	  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 round %d in %d.%d)\n",
		module_idP,CC_idP,frameP,subframeP,RA_template->rnti,round,RA_template->Msg4_frame,RA_template->Msg4_subframe);

1118 1119
	} // Msg4 frame/subframe
      } // regular LTE case
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140
  } else {
    LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,CC_idP,frameP,subframeP);
    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);

1141

1142
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1143
    // skip UL component carriers if TDD
1144 1145 1146 1147 1148 1149 1150 1151 1152
    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) {

1153 1154
        LOG_I(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",
              module_idP,frameP,subframeP,CC_id,i,RA_template->generate_rar,RA_template->generate_Msg4,RA_template->wait_ack_Msg4, RA_template->rnti);
1155 1156 1157 1158 1159 1160

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


1161
      } // RA_active == TRUE
1162 1163
    } // for i=0 .. N_RA_PROC-1 
  } // CC_id
1164
  
1165 1166
  stop_meas(&eNB->schedule_ra);
}
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1167

1168

1169
// handles the event of MSG1 reception
1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181
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
		      )
1182 1183 1184 1185
{

  uint8_t i;

1186 1187 1188
  COMMON_channels_t   *cc  = &RC.mac[module_idP]->common_channels[CC_id];
  RA_TEMPLATE *RA_template = &cc->RA_template[0];

1189 1190
  struct PRACH_ConfigSIB_v1310 *ext4_prach = NULL;
  PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
1191

1192 1193 1194 1195
  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;
  }
1196
  LOG_I(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);
1197
#ifdef Rel14
Raymond Knopp's avatar
Raymond Knopp committed
1198
  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);
1199
#endif
1200

1201 1202
  if (prach_ParametersListCE_r13 && 
      prach_ParametersListCE_r13->list.count<rach_resource_type) {
1203 1204 1205 1206 1207 1208 1209
    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;
  }

1210 1211 1212
  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);

1213
  for (i=0; i<NB_RA_PROC_MAX; i++) {
1214 1215
    if (RA_template[i].RA_active==FALSE &&
        RA_template[i].wait_ack_Msg4 == 0) {
Cedric Roux's avatar
Cedric Roux committed
1216
      int loop = 0;
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
      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
1228 1229
      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
1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
      /* 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(); }
1242
      RA_template[i].RA_rnti        = ra_rnti;
1243
      RA_template[i].preamble_index = preamble_index;
1244

1245 1246 1247 1248 1249
      LOG_I(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",
            module_idP,CC_id,frameP,
	    RA_template[i].Msg2_frame,
	    RA_template[i].Msg2_subframe,
	    i,RA_template[i].rnti,
1250 1251 1252 1253 1254
            RA_template[i].RA_active);

      return;
    }
  }
Cedric Roux's avatar
Cedric Roux committed
1255 1256

  LOG_E(MAC,"[eNB %d][RAPROC] FAILURE: CC_id %d Frame %d Initiating RA procedure for preamble index %d\n",module_idP,CC_id,frameP,preamble_index);
1257
}
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1258

1259 1260 1261
void cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, rnti_t rnti)
{
  unsigned char i;
1262
  RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&RC.mac[module_idP]->common_channels[CC_id].RA_template[0];
1263

Lionel Gauthier's avatar
Lionel Gauthier committed
1264
  MSC_LOG_EVENT(MSC_PHY_ENB, "RA Cancelling procedure ue %"PRIx16" ", rnti);
1265
  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Cancelling RA procedure for UE rnti %x\n",module_idP,CC_id,frameP,rnti);
1266 1267 1268 1269 1270 1271 1272 1273 1274 1275

  for (i=0; i<NB_RA_PROC_MAX; i++) {
    if (rnti == RA_template[i].rnti) {
      RA_template[i].RA_active=FALSE;
      RA_template[i].generate_rar=0;
      RA_template[i].generate_Msg4=0;
      RA_template[i].wait_ack_Msg4=0;
      RA_template[i].timing_offset=0;
      RA_template[i].RRC_timer=20;
      RA_template[i].rnti = 0;
1276
      RA_template[i].msg3_round = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1277
    }
1278
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1279 1280
}