eNB_scheduler_RA.c 81.1 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
extern uint8_t nfapi_mode;
66
extern uint8_t sf_ahead;
67
extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req);
68

69
void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset)
70 71 72 73 74 75
{
    *frameP    = *frameP + ((*subframeP + offset) / 10);

    *subframeP = ((*subframeP + offset) % 10);
}

76
uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset)
77 78 79 80 81
{
  add_subframe(&frameP, &subframeP, offset);
  return frameP<<4|subframeP;
}

82
void subtract_subframe(uint16_t *frameP, uint16_t *subframeP, int offset)
83 84 85 86 87 88 89 90
{
  if (*subframeP < offset)
  {
    *frameP = (*frameP+1024-1)%1024;
  }
  *subframeP = (*subframeP+10-offset)%10;
}

91
uint16_t sfnsf_subtract_subframe(uint16_t frameP, uint16_t subframeP, int offset)
92 93 94 95 96
{
  subtract_subframe(&frameP, &subframeP, offset);
  return frameP<<4|subframeP;
}

97
void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_t frameP, sub_frame_t subframeP) {
98 99

  eNB_MAC_INST                    *eNB = RC.mac[module_idP];
100
  COMMON_channels_t               *cc  = &eNB->common_channels[CC_id];
knopp's avatar
knopp committed
101
  uint8_t                         j;
102
  nfapi_ul_config_request_t      *ul_req;
103
  nfapi_ul_config_request_pdu_t  *ul_config_pdu;
104
  nfapi_ul_config_request_body_t *ul_req_body;
105 106
  nfapi_hi_dci0_request_t        *hi_dci0_req = &eNB->HI_DCI0_req[CC_id];
  nfapi_hi_dci0_request_body_t   *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
107 108
  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;

109
  uint8_t rvseq[4] = {0,2,3,1};
110 111


112 113 114
  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);
115

116
#ifdef Rel14
117
  if (RA_template->rach_resource_type>0) {
knopp's avatar
knopp committed
118 119
    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,
120
	  RA_template->Msg3_frame,RA_template->Msg3_subframe);
121 122
    LOG_D(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d)\n",
	  frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe,RA_template->msg3_nb_rb,RA_template->msg3_round);
123 124 125 126 127 128

    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));
129
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag                                 = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG;
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
    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
147
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag                                = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG;
148 149 150 151
    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;
152

153
    ul_req_body->number_of_pdus++;
154
    ul_req_body->tl.tag                                                            = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
155

156
    ul_req->sfn_sf = RA_template->Msg3_frame<<4|RA_template->Msg3_subframe; //sfnsf_add_subframe(RA_template->Msg3_frame, RA_template->Msg3_subframe, 0);
157
    ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST;
158 159
  } //  if (RA_template->rach_resource_type>0) {	 
  else
160
#endif
161
    {
knopp's avatar
knopp committed
162 163
      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);
164
	    
165 166 167
      LOG_D(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d)\n",
	    frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe,
	    RA_template->msg3_nb_rb,RA_template->msg3_first_rb,RA_template->msg3_round);
168 169 170 171 172 173
      
      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));
174
      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag                                 = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG;
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
      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++;
192
      ul_req_body->tl.tag                                                            = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
193
      ul_req->sfn_sf = sfnsf_add_subframe(RA_template->Msg3_frame, RA_template->Msg3_subframe, 0);
194
      ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST;
195 196 197
      // 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;
      
198
      LOG_D(MAC, "MSG3: UL_CONFIG SFN/SF:%d number_of_pdus:%d RA_template->msg3_round:%d\n", NFAPI_SFNSF2DEC(ul_req->sfn_sf), ul_req_body->number_of_pdus, RA_template->msg3_round);
199 200
      
      if (RA_template->msg3_round != 0) { // program HI too
201
	hi_dci0_pdu                                                         = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci+hi_dci0_req_body->number_of_hi];
202 203 204
	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);
205
	hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag                              = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
206 207 208
	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;
209
	hi_dci0_req_body->number_of_hi++;
210
	hi_dci0_req_body->sfnsf = sfnsf_add_subframe(RA_template->Msg3_frame, RA_template->Msg3_subframe, 0);
211
        hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
212

213 214 215
        hi_dci0_req->sfn_sf = sfnsf_add_subframe(RA_template->Msg3_frame, RA_template->Msg3_subframe, 4);
        hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;

216 217 218
        oai_nfapi_hi_dci0_req(hi_dci0_req);
        hi_dci0_req_body->number_of_hi=0;

219
        LOG_D(MAC, "MSG3: HI_DCI0 SFN/SF:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req_body->number_of_dci, hi_dci0_req_body->number_of_hi);
220

221 222 223
	// 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
224 225
	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,
226 227 228 229
	      1,1,
	      RA_template->msg3_round-1);
      } //       if (RA_template->msg3_round != 0) { // program HI too
    } // non-BL/CE UE case
230 231
}

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

234 235
  eNB_MAC_INST                    *eNB = RC.mac[module_idP];
  COMMON_channels_t               *cc  = eNB->common_channels;
236
 
237 238 239 240 241
  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;
242
  nfapi_dl_config_request_body_t *dl_req;
243

244 245 246 247 248
  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);  

249 250 251 252 253
#ifdef Rel14
  int rmax            = 0;
  int rep             = 0; 
  int reps            = 0;
  int num_nb          = 0;
254

255
  first_rb        = 0;
256 257
  struct PRACH_ConfigSIB_v1310 *ext4_prach;
  PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
258
  PRACH_ParametersCE_r13_t *p[4]={NULL,NULL,NULL,NULL};
259

260 261 262 263 264
  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 ==  
  
265
  if (cc[CC_idP].radioResourceConfigCommon_BR) {
266

267
    ext4_prach                 = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
268 269 270 271 272 273 274 275 276 277 278
    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];
279
      break;
280
    default:
281 282
      AssertFatal(1==0,"Illegal count for prach_ParametersListCE_r13 %d\n",(int)prach_ParametersListCE_r13->list.count);
      break;
283
    }
284
  }
285

286 287 288 289 290 291 292
  LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, RA_template->rach_resource_type:%d frameP:%d/%d RA_template:Msg2:%d/%d\n",module_idP,frameP,subframeP,RA_template->rach_resource_type,
  frameP,
  subframeP,
  RA_template->Msg2_frame, 
  RA_template->Msg2_subframe
  );

293 294 295 296 297 298 299 300 301 302 303
  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
304 305 306 307
    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; 
308 309 310 311 312
    // 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];
313
    first_rb = narrowband_to_first_rb(&cc[CC_idP],RA_template->msg2_narrowband);
314 315
    
    if ((RA_template->msg2_mpdcch_repetition_cnt == 0) &&
316
	(mpdcch_sf_condition(eNB,CC_idP,frameP,subframeP,rmax,TYPE2,-1)>0)){
317
      // MPDCCH configuration for RAR
knopp's avatar
knopp committed
318
      LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming MPDCCH %d repetitions\n",
319
	    module_idP,frameP,subframeP,reps);
320 321 322 323 324
      
      
      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));
325
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag                                        = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG;
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
      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++;
371
      dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
372 373
      RA_template->Msg2_subframe = (RA_template->Msg2_subframe+9)%10;

374 375 376
      eNB->DL_req[CC_idP].sfn_sf = sfnsf_add_subframe(RA_template->Msg2_frame, RA_template->Msg2_subframe, 4);	// nFAPI is runnning at TX SFN/SF - ie 4 ahead
      eNB->DL_req[CC_idP].header.message_id = NFAPI_DL_CONFIG_REQUEST;

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

382 383 384 385 386 387 388 389 390 391
      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");
	}
392 393 394
      }// mpdcch_repetition_count == reps
      RA_template->msg2_mpdcch_repetition_cnt++;	      

395 396
      if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) {
	// Program PDSCH
knopp's avatar
knopp committed
397
	LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n",
398
	      module_idP,frameP,subframeP);
399 400 401 402 403 404
	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));
405
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
406 407
	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;
408
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2;   
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
	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                    = ; 
428 429

	// Rel10 fields
430
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG;
431 432
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
	// Rel13 fields
433
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG;
434 435 436 437 438
	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++;
439
        dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
440 441 442

        eNB->DL_req[CC_idP].sfn_sf = (frameP<<4)+subframeP;
        eNB->DL_req[CC_idP].header.message_id = NFAPI_DL_CONFIG_REQUEST;
443
	
444 445
        LOG_E(MAC,"DL_CONFIG SFN/SF:%d/%d MESSAGE2\n", frameP, subframeP);

446 447
	// Program UL processing for Msg3, same as regular LTE
	get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
448
	add_msg3(module_idP,CC_idP, RA_template,frameP,subframeP);
449 450
	fill_rar_br(eNB,CC_idP,RA_template,frameP,subframeP,cc[CC_idP].RAR_pdu.payload,RA_template->rach_resource_type-1);
	// DL request
451 452 453
	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;
454 455 456 457 458 459 460
	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++;
461 462

        LOG_E(MAC,"TX_REQ SFN/SF:%d/%d MESSAGE2\n", frameP, subframeP);
463 464 465 466 467
      }
    }      
    
  }		
  else
468
#endif
469
    {
470

471
      if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) {
472 473 474
  struct timespec t;
  clock_gettime(CLOCK_MONOTONIC, &t);
	LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, RA_active %d format 1A (%d,%d)) t:%ld.%09ld\n",
475 476 477
	      module_idP, CC_idP, frameP, subframeP,
	      RA_template->RA_active,
	      RA_template->RA_dci_fmt1,
478
	      RA_template->RA_dci_size_bits1, t.tv_sec,t.tv_nsec);
479 480

	// Allocate 4 PRBS starting in RB 0
481 482 483 484 485 486 487 488 489
	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));
490
	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
491 492 493 494 495 496 497 498 499 500 501 502 503 504
	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);      
505 506

	// This checks if the above DCI allocation is feasible in current subframe
507
	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)) {
508 509
	  LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x pdu_index:%d\n",
		frameP,subframeP,RA_template->RA_rnti, eNB->pdu_index[CC_idP]);
510 511
	  dl_req->number_dci++;
	  dl_req->number_pdu++;
512
          dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
513 514 515 516 517
	  
	  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));
518
	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
	  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++;
542
          dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
543
	  
544 545 546 547 548
          eNB->DL_req[CC_idP].sfn_sf = (frameP<<4)+subframeP;
          eNB->DL_req[CC_idP].header.message_id = NFAPI_DL_CONFIG_REQUEST;

          LOG_E(MAC,"DL_CONFIG SFN/SF:%d/%d MESSAGE2\n", frameP, subframeP);

549 550
	  // Program UL processing for Msg3
	  get_Msg3alloc(&cc[CC_idP],subframeP,frameP,&RA_template->Msg3_frame,&RA_template->Msg3_subframe);
551

knopp's avatar
knopp committed
552
	  LOG_D(MAC,"Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n",
553
		frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
554 555
	  
	  fill_rar(module_idP,CC_idP,frameP,cc[CC_idP].RAR_pdu.payload,N_RB_DL,7);
556 557
	  add_msg3(module_idP,CC_idP, RA_template,frameP,subframeP);

558
	  // DL request
559 560 561
	  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;
562 563 564 565 566 567 568
	  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++;
569 570 571

          LOG_E(MAC,"TX_REQ SFN/SF:%d/%d MESSAGE2\n", frameP, subframeP);

572 573 574 575
	} // PDCCH CCE allocation is feasible
      } // Msg2 frame/subframe condition
    } // else BL/CE
}
576

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

579

580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
  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;
595 596
  nfapi_dl_config_request_t      *dl_req;
  nfapi_dl_config_request_body_t *dl_req_body;
597 598
  nfapi_ul_config_request_body_t *ul_req_body;
  nfapi_ul_config_request_t      *ul_req;
599 600
  uint8_t                         lcid;
  uint8_t                         offset;
601

602

603 604 605 606
#ifdef Rel14
  int rmax            = 0;
  int rep             = 0; 
  int reps            = 0;
607

608

609 610 611 612 613 614 615 616
  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};
617

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 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659
  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;
  
660 661 662
  dl_req        = &eNB->DL_req[CC_idP];
  dl_req_body   = &dl_req->dl_config_request_body;
  dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; 
663
  N_RB_DL       = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
664

665 666 667
  UE_id = find_UE_id(module_idP,RA_template->rnti);
  AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n");
  
668 669
  // set HARQ process round to 0 for this UE
  
670 671
  if (cc->tdd_Config) RA_template->harq_pid = ((RA_template->Msg4_frame*10)+RA_template->Msg4_subframe)%10;
  else RA_template->harq_pid = ((RA_template->Msg4_frame*10)+RA_template->Msg4_subframe)&7;
672

673 674 675 676 677 678 679 680 681 682 683
  // 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
  
684
  AssertFatal(rrc_sdu_length>0,
685 686 687
	      "[MAC][eNB Scheduler] CCCH not allocated\n");
  
  
688 689
  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d MSG4:SFN/SF:%d%d UE_id %d, rrc_sdu_length %d\n",
	module_idP, CC_idP, frameP, subframeP,RA_template->Msg4_frame,RA_template->Msg4_subframe,UE_id, rrc_sdu_length);
690
  
691 692
  
#ifdef Rel14
693 694 695
  if (RA_template->rach_resource_type>0) {
    
    // Generate DCI + repetitions first
696
    // 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)
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
    // 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
713 714
    first_rb = narrowband_to_first_rb(&cc[CC_idP],RA_template->msg34_narrowband);

715
    if ((RA_template->msg4_mpdcch_repetition_cnt == 0) &&
716
    (mpdcch_sf_condition(eNB,CC_idP,RA_template->Msg4_frame,RA_template->Msg4_subframe,rmax,TYPE2,-1)>0)){
717 718 719 720 721
      // 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));
722
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag                                        = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG;
723 724 725 726 727 728 729 730 731 732 733 734 735 736
      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
737
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io                    = (RA_template->Msg4_frame*10)+RA_template->Msg4_subframe;
738 739 740 741 742 743
      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;
744
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process                                  = RA_template->harq_pid;
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
      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++;
767 768
      dl_req_body->number_pdu++;
      dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
769
      
770
      dl_req->sfn_sf = (RA_template->Msg4_frame<<4)+RA_template->Msg4_subframe;
771
      dl_req->header.message_id = NFAPI_DL_CONFIG_REQUEST;
772

773 774 775 776 777 778
    } //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
779
	  if (RA_template->Msg4_subframe>7) RA_template->Msg4_frame = (frameP+1)&1023;
780
	  else             RA_template->Msg4_frame = frameP;
781
	  RA_template->Msg4_subframe               = (RA_template->Msg4_subframe+2)%10; 
782 783 784 785 786 787 788 789 790
	}
	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
791
	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",
792
	      module_idP, CC_idP, frameP, subframeP,RA_template->rach_resource_type-1,RA_template->rnti);
793

794
	AssertFatal(1==0,"Msg4 generation not finished for BL/CE UE\n");
795
	dl_config_pdu                                                                  = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; 
796 797 798
	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));
799
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821
	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                    = ; 
822

823
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG;
824
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
825
	
826
	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG;
827 828 829 830
	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;
831 832
	dl_req_body->number_pdu++;
        dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
833 834 835

	eNB->DL_req[CC_idP].sfn_sf = (frameP<<4)+subframeP;
	eNB->DL_req[CC_idP].header.message_id = NFAPI_DL_CONFIG_REQUEST;
836
	
837 838
        LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d DL_CONFIG frame:%d subframe:%d\n", module_idP,CC_idP,frameP,subframeP);

839 840
	RA_template->generate_Msg4=0;
	RA_template->wait_ack_Msg4=1;
841

842 843
	lcid=0;
	
844
	UE_list->UE_sched_ctrl[UE_id].round[CC_idP][RA_template->harq_pid] = 0;
845 846
	msg4_header = 1+6+1;  // CR header, CR CE, SDU header
	
847 848
	if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
	  msg4_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header;
849 850 851
	  msg4_post_padding = 0;
	} else {
	  msg4_padding = 0;
852
	  msg4_post_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header -1;
853 854
	}
	
knopp's avatar
knopp committed
855
	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",
856
	      module_idP,CC_idP,frameP,subframeP,RA_template->msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
857 858 859 860 861 862 863
	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
Cedric Roux's avatar
Cedric Roux committed
864
				       31,                          // no timing advance
865 866 867 868 869 870 871 872
				       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);
	
873
	// Tx request
874 875 876 877
	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;

878 879 880 881 882 883 884
	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++;
885

886 887 888 889
	// 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;
890
	AssertFatal(reps>2,"Have to handle programming of ACK when PDSCH repetitions is > 2\n");
891

892 893 894
	ul_req             = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF%10];
	ul_req_body        = &ul_req->ul_config_request_body;
	ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; 
895

896 897
	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));
898
	ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag                       = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG;
899 900
	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;
901
	ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.tl.tag			    = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG;
902 903 904 905
	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;
906 907 908

	ul_req_body->tl.tag                                                                         = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;

909
	ul_req->sfn_sf  									    = sfnsf_add_subframe(RA_template->Msg3_frame, RA_template->Msg3_subframe, 4);
910 911
	ul_req->header.message_id  								    = NFAPI_UL_CONFIG_REQUEST;

912 913
        LOG_D(MAC,"UL_req_tmp[CC_idP:%d][ackNAK_absSF mod 10:%d] RA_template->Msg3_frame:%d RA_template->Msg3_subframe:%d + 4 sfn_sf:%d\n", CC_idP, ackNAK_absSF%10, RA_template->Msg3_frame, RA_template->Msg3_subframe, NFAPI_SFNSF2DEC(ul_req->sfn_sf));

914 915
	// 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
916
          ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG;
917 918 919 920 921 922 923 924 925 926
	  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");
	}
927
	ul_req_body->number_of_pdus++;
928
	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),
929
	  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));
930 931 932 933 934 935 936 937 938 939 940 941
	
	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
942
#endif
943
    { // This is normal LTE case
944
      if (1){     // || (RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) {	      
945
	LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
946 947
	      module_idP, CC_idP, frameP, subframeP,RA_template->rnti);
	
948
	/// Choose first 4 RBs for Msg4, should really check that these are free!
949 950 951 952 953 954 955 956
	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;
	
	
957
	// Compute MCS/TBS for 3 PRB (coded on 4 vrb)
958 959 960
	msg4_header = 1+6+1;  // CR header, CR CE, SDU header
	
	if ((rrc_sdu_length+msg4_header) <= 22) {
961 962
	  RA_template->msg4_mcs                       = 4;
	  RA_template->msg4_TBsize = 22;
963
	} else if ((rrc_sdu_length+msg4_header) <= 28) {
964 965
	  RA_template->msg4_mcs                       = 5;
	  RA_template->msg4_TBsize = 28;
966
	} else if ((rrc_sdu_length+msg4_header) <= 32) {
967 968
	  RA_template->msg4_mcs                       = 6;
	  RA_template->msg4_TBsize = 32;
969
	} else if ((rrc_sdu_length+msg4_header) <= 41) {
970 971
	  RA_template->msg4_mcs                       = 7;
	  RA_template->msg4_TBsize = 41;
972
	} else if ((rrc_sdu_length+msg4_header) <= 49) {
973 974
	  RA_template->msg4_mcs                       = 8;
	  RA_template->msg4_TBsize = 49;
975
	} else if ((rrc_sdu_length+msg4_header) <= 57) {
976 977
	  RA_template->msg4_mcs    = 9;
	  RA_template->msg4_TBsize = 57;
978 979
	}

980 981 982 983
	fill_nfapi_dl_dci_1A(dl_config_pdu,
			     4,                           // aggregation_level
			     RA_template->rnti,           // rnti
			     1,                           // rnti_type, CRNTI
984
			     RA_template->harq_pid,       // harq_process
985 986 987 988 989 990
			     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
991 992 993
  struct timespec t;
  clock_gettime(CLOCK_MONOTONIC, &t);
    LOG_D(MAC,"Frame %d, subframe %d: Msg4 SFN/SF:%d%d DCI pdu_num %d (rnti %x,rnti_type %d,harq_pid %d, resource_block_coding (%p) %d t:%ld.%09ld\n",
994 995
		  frameP,
	      subframeP,
996
              RA_template->Msg4_frame, RA_template->Msg4_subframe,
997
          dl_req_body->number_pdu,
998 999 1000 1001
          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti,
          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type,
          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process,
          &dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding,
1002
          dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding,t.tv_sec,t.tv_nsec);
1003 1004 1005
    AssertFatal(dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding < 8192,
				"resource_block_coding %u < 8192\n",
                dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding);	
1006
	if (!CCE_allocation_infeasible(module_idP,CC_idP,1,
1007
				       RA_template->Msg4_subframe,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
1008
				       RA_template->rnti)) {
1009 1010 1011 1012
	  dl_req_body->number_dci++;
	  dl_req_body->number_pdu++;
          dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;

1013
          dl_req->sfn_sf = RA_template->Msg4_frame<<4|RA_template->Msg4_subframe;
1014
          dl_req->header.message_id = NFAPI_DL_CONFIG_REQUEST;
1015
	  
1016 1017
	  RA_template->generate_Msg4=0;
	  RA_template->wait_ack_Msg4=1;
1018
	  
1019 1020 1021
          uint16_t orig_Msg4_frame    = RA_template->Msg4_frame;
          uint16_t orig_Msg4_subframe = RA_template->Msg4_subframe;

1022
	  // increment Absolute subframe by 8 for Msg4 retransmission
1023
	  LOG_D(MAC,"Frame %d, Subframe %d: Preparing for Msg4 retransmission currently %d.%d\n",
1024
		frameP,subframeP,RA_template->Msg4_frame,RA_template->Msg4_subframe);
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039

	  //if (RA_template->Msg4_subframe > 1) RA_template->Msg4_frame++;
	  //RA_template->Msg4_frame&=1023;
	  //RA_template->Msg4_subframe = (RA_template->Msg4_subframe+8)%10;

          // Expect +8 for TX->UL:ACK
          uint16_t retrans_frame = RA_template->Msg4_frame;
          uint16_t retrans_subframe = RA_template->Msg4_subframe;

          add_subframe(&retrans_frame, &retrans_subframe, 8+sf_ahead);

          RA_template->Msg4_frame = retrans_frame;
          RA_template->Msg4_subframe = retrans_subframe;

          LOG_D(MAC,"Frame %d, Subframe %d: Msg4 retransmission in %d.%d\n",
1040
		frameP,subframeP,RA_template->Msg4_frame,RA_template->Msg4_subframe);
1041
	  lcid=0;
1042
	  
1043 1044
          // DJP - FIXME TODO TDD broken
          //
1045
	  // put HARQ process round to 0
1046 1047 1048
	  if (cc->tdd_Config) RA_template->harq_pid = ((RA_template->Msg4_frame*10)+RA_template->Msg4_subframe)%10;
	  else RA_template->harq_pid = dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process;
	  //else RA_template->harq_pid = ((RA_template->Msg4_frame*10)+RA_template->Msg4_subframe)&7;
1049
	  UE_list->UE_sched_ctrl[UE_id].round[CC_idP][RA_template->harq_pid] = 0;
1050
	  
1051 1052
	  if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
	    msg4_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header;
1053 1054 1055
	    msg4_post_padding = 0;
	  } else {
	    msg4_padding = 0;
1056
	    msg4_post_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header -1;
1057
	  }
1058
	  
1059 1060
	  LOG_D(MAC,"[eNB %d][RAPROC] CC_idP %d Frame %d subframeP %d Msg4 : SFN/SF:%d%d TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
		module_idP,CC_idP,frameP,subframeP,orig_Msg4_frame,orig_Msg4_subframe,RA_template->msg4_TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding);
1061 1062 1063 1064 1065 1066 1067
	  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
Cedric Roux's avatar
Cedric Roux committed
1068
					 31,                          // no timing advance
1069 1070 1071
					 RA_template->cont_res_id,  // contention res id
					 msg4_padding,                // no padding
					 msg4_post_padding);
1072
	  
1073 1074 1075
	  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);
1076