eNB_scheduler_RA.c 72.5 KB
Newer Older
1 2 3 4 5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
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
 * \author  Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \email: navid.nikaein@eurecom.fr
 * \version 1.0
 * @ingroup _mac

 */

32 33 34
/* indented with: indent -kr eNB_scheduler_RA.c */


Raymond Knopp's avatar
 
Raymond Knopp committed
35
#include "assertions.h"
36
#include "platform_types.h"
Lionel Gauthier's avatar
Lionel Gauthier committed
37
#include "msc.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
38

39 40
#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_extern.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
41

42
#include "LAYER2/MAC/mac_proto.h"
43 44
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
45 46 47
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
48
#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
49

50
#include "RRC/LTE/rrc_extern.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
51 52
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"

53
#include "SCHED/sched_common.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
54 55 56 57
//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
Raymond Knopp committed
58
#include "intertask_interface.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
59 60
#endif

61
#include "SIMULATION/TOOLS/sim.h"	// for taus
Raymond Knopp's avatar
 
Raymond Knopp committed
62

63
#include "T.h"
64

65
#include "common/ran_context.h"
66
#include "LAYER2/MAC/eNB_scheduler_fairRR.h"
67 68 69

extern RAN_CONTEXT_t RC;

70 71 72 73
extern uint8_t nfapi_mode;
extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req);

void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset)
Raymond Knopp's avatar
Raymond Knopp committed
74
{
Cedric Roux's avatar
Cedric Roux committed
75
    *frameP    = (*frameP + ((*subframeP + offset) / 10)) % 1024;
76

77 78
    *subframeP = ((*subframeP + offset) % 10);
}
79

80 81 82 83 84
uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset)
{
  add_subframe(&frameP, &subframeP, offset);
  return frameP<<4|subframeP;
}
85

86 87 88 89 90 91 92 93
void subtract_subframe(uint16_t *frameP, uint16_t *subframeP, int offset)
{
  if (*subframeP < offset)
  {
    *frameP = (*frameP+1024-1)%1024;
  }
  *subframeP = (*subframeP+10-offset)%10;
}
94

95 96 97 98 99
uint16_t sfnsf_subtract_subframe(uint16_t frameP, uint16_t subframeP, int offset)
{
  subtract_subframe(&frameP, &subframeP, offset);
  return frameP<<4|subframeP;
}
100

101 102 103 104 105 106 107 108 109
void
add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP,
	 sub_frame_t subframeP)
{
    eNB_MAC_INST *mac = RC.mac[module_idP];
    COMMON_channels_t *cc = &mac->common_channels[CC_id];
    uint8_t j;
    nfapi_ul_config_request_t *ul_req;
    nfapi_ul_config_request_body_t *ul_req_body;
110
    nfapi_ul_config_request_pdu_t *ul_config_pdu;
111 112
    nfapi_hi_dci0_request_t        *hi_dci0_req;
    nfapi_hi_dci0_request_body_t   *hi_dci0_req_body;
113
    nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
114
    uint8_t sf_ahead_dl;
115
    uint8_t rvseq[4] = { 0, 2, 3, 1 };
116 117


118 119 120 121
    ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe];
    ul_req_body = &ul_req->ul_config_request_body;
    AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n",
		ra->rnti);
122

123
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
124
  if (ra->rach_resource_type > 0) {
125
    LOG_I (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n",
126
           module_idP, frameP, subframeP, CC_id, ra->rach_resource_type - 1, ra->Msg3_frame, ra->Msg3_subframe);
127
    LOG_I (MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d)\n",
128
           frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe, ra->msg3_nb_rb, ra->msg3_round);
Raymond Knopp's avatar
Raymond Knopp committed
129 130 131 132 133 134

    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));
135
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++;
136 137 138
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = narrowband_to_first_rb (cc, ra->msg34_narrowband) + ra->msg3_first_rb;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb;
Raymond Knopp's avatar
Raymond Knopp committed
139 140 141 142 143
    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;
144
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round];
145
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = 0;
Raymond Knopp's avatar
Raymond Knopp committed
146 147 148
    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;
149
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL (ra->msg3_mcs, ra->msg3_nb_rb);
150
    // Re13 fields
151
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1;
Raymond Knopp's avatar
Raymond Knopp committed
152 153
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1;
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1;
154
    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe;
155
    ul_req_body->number_of_pdus++;
156
  }                             //  if (ra->rach_resource_type>0) {         
157
  else
158
#endif
159
    {
160 161 162 163 164 165
	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->Msg3_frame,
	      ra->Msg3_subframe);

	LOG_D(MAC,
166
	      "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
167
	      frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe,
168
	      ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round, ra->rnti);
169

170
	ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus];
171

172 173 174 175 176 177 178
	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.tl.tag                         = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG;
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                         = mac->ul_handle++;
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                           = ra->rnti;
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start           = ra->msg3_first_rb;
179
	AssertFatal(ra->msg3_nb_rb > 0, "nb_rb = 0\n");
180 181 182 183 184 185 186 187 188 189 190 191
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks      = ra->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->msg3_round];
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number            = subframe2harqpid(cc, ra->Msg3_frame, ra->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->msg3_nb_rb);
192
	ul_req_body->number_of_pdus++;
193 194 195
        ul_req_body->tl.tag                                                    = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
        ul_req->sfn_sf                                                         = ra->Msg3_frame<<4|ra->Msg3_subframe;
        ul_req->header.message_id                                              = NFAPI_UL_CONFIG_REQUEST;
196
	// save UL scheduling information for preprocessor
197 198 199
	for (j = 0; j < ra->msg3_nb_rb; j++)
	    cc->vrb_map_UL[ra->msg3_first_rb + j] = 1;

200
        LOG_D(MAC, "MSG3: UL_CONFIG SFN/SF:%d number_of_pdus:%d ra->msg3_round:%d\n", NFAPI_SFNSF2DEC(ul_req->sfn_sf), ul_req_body->number_of_pdus, ra->msg3_round);
201 202

	if (ra->msg3_round != 0) {	// program HI too
203 204 205
	    sf_ahead_dl = ul_subframe2_k_phich(cc, subframeP);
	    hi_dci0_req = &mac->HI_DCI0_req[CC_id][(subframeP+sf_ahead_dl)%10];
	    hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
206
	    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];
207 208
	    memset((void *) hi_dci0_pdu, 0,
		   sizeof(nfapi_hi_dci0_request_pdu_t));
209 210 211 212
	    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.tl.tag                  = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
	    hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start    = ra->msg3_first_rb;
213
	    hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0;
214
	    hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value                = 0;
215 216
	    hi_dci0_req_body->number_of_hi++;

217 218
            hi_dci0_req_body->sfnsf                                 = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0);
            hi_dci0_req_body->tl.tag                                = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
219

220
            hi_dci0_req->sfn_sf                                     = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl);
221
            hi_dci0_req->header.message_id                          = NFAPI_HI_DCI0_REQUEST;
222 223 224 225 226 227 228 229

            if (nfapi_mode) {
              oai_nfapi_hi_dci0_req(hi_dci0_req);
              hi_dci0_req_body->number_of_hi=0;
            }

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

230 231 232 233 234 235 236 237 238 239
	    // save UL scheduling information for preprocessor
	    for (j = 0; j < ra->msg3_nb_rb; j++)
		cc->vrb_map_UL[ra->msg3_first_rb + j] = 1;

	    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->rnti, CC_id, frameP, subframeP, 10, 1, 1,
		  ra->msg3_round - 1);
	}			//       if (ra->msg3_round != 0) { // program HI too
    }				// non-BL/CE UE case
240 241
}

Raymond Knopp's avatar
Raymond Knopp committed
242
void
243 244
generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP,
	      sub_frame_t subframeP, RA_t * ra)
Raymond Knopp's avatar
Raymond Knopp committed
245 246
{

247

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
  eNB_MAC_INST *mac = RC.mac[module_idP];
  COMMON_channels_t *cc = mac->common_channels;
  
  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;
  nfapi_dl_config_request_body_t *dl_req_body;
  
  vrb_map = cc[CC_idP].vrb_map;
  dl_req_body = &mac->DL_req[CC_idP].dl_config_request_body;
  dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
  N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
  
263
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Raymond Knopp's avatar
Raymond Knopp committed
264 265 266 267
  int             rmax = 0;
  int             rep = 0;
  int             reps = 0;
  int             num_nb = 0;
268

Raymond Knopp's avatar
Raymond Knopp committed
269
  first_rb = 0;
270 271 272
  struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach;
  LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
  LTE_PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL };
273

Raymond Knopp's avatar
Raymond Knopp committed
274
  uint16_t        absSF = (10 * frameP) + subframeP;
275
  uint16_t        absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe;
Raymond Knopp's avatar
Raymond Knopp committed
276 277 278

  if (absSF > absSF_Msg2)
    return;                     // we're not ready yet, need to be to start ==  
279

280 281
  if (cc[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0 && 
      cc[CC_idP].radioResourceConfigCommon_BR) {
282

Raymond Knopp's avatar
Raymond Knopp committed
283
    ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
284
    prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
Raymond Knopp's avatar
Raymond Knopp committed
285

286 287
    switch (prach_ParametersListCE_r13->list.count) {
    case 4:
Raymond Knopp's avatar
Raymond Knopp committed
288
      p[3] = prach_ParametersListCE_r13->list.array[3];
289
    case 3:
Raymond Knopp's avatar
Raymond Knopp committed
290
      p[2] = prach_ParametersListCE_r13->list.array[2];
291
    case 2:
Raymond Knopp's avatar
Raymond Knopp committed
292
      p[1] = prach_ParametersListCE_r13->list.array[1];
293
    case 1:
Raymond Knopp's avatar
Raymond Knopp committed
294
      p[0] = prach_ParametersListCE_r13->list.array[0];
295
      break;
296
    default:
Raymond Knopp's avatar
Raymond Knopp committed
297
      AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", (int) prach_ParametersListCE_r13->list.count);
298
      break;
299

300
    }
301
  }
302

303
  if (ra->rach_resource_type > 0) {
Raymond Knopp's avatar
Raymond Knopp committed
304

305 306 307 308 309 310 311
    // 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
Raymond Knopp's avatar
Raymond Knopp committed
312

313
    // rmax from SIB2 information
Raymond Knopp's avatar
Raymond Knopp committed
314
    AssertFatal (rmax < 9, "rmax>8!\n");
315
    rmax = 1 << p[ra->rach_resource_type - 1]->mpdcch_NumRepetition_RA_r13;
316
    // choose r1 by default for RAR (Table 9.1.5-5)
Raymond Knopp's avatar
Raymond Knopp committed
317
    rep = 0;
318
    // get actual repetition count from Table 9.1.5-3
Raymond Knopp's avatar
Raymond Knopp committed
319
    reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep));
320
    // get narrowband according to higher-layer config 
321 322 323
    num_nb = p[ra->rach_resource_type - 1]->mpdcch_NarrowbandsToMonitor_r13.list.count;
    ra->msg2_narrowband = *p[ra->rach_resource_type - 1]->mpdcch_NarrowbandsToMonitor_r13.list.array[ra->preamble_index % num_nb]-1;
    first_rb = narrowband_to_first_rb (&cc[CC_idP], ra->msg2_narrowband);
Raymond Knopp's avatar
Raymond Knopp committed
324

325
    if ((ra->msg2_mpdcch_repetition_cnt == 0) && (mpdcch_sf_condition (mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) {
326
      ra->msg2_mpdcch_done = 0;
327
      // MPDCCH configuration for RAR
328
      LOG_I (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2 for CE Level %d, Programming MPDCCH %d repetitions\n", module_idP, frameP, subframeP, ra->rach_resource_type-1,reps);
Raymond Knopp's avatar
Raymond Knopp committed
329 330 331 332 333


      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));
334 335
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (ra->rach_resource_type > 1) ? 11 : 10;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = ra->msg2_narrowband;
Raymond Knopp's avatar
Raymond Knopp committed
336 337 338
      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  
339
      AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
Raymond Knopp's avatar
Raymond Knopp committed
340 341
      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
342
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24;        // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
Raymond Knopp's avatar
Raymond Knopp committed
343
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI
344 345
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = ra->RA_rnti;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (ra->rach_resource_type < 3) ? 1 : 2;
Raymond Knopp's avatar
Raymond Knopp committed
346 347 348
      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
349
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | (ra->msg2_narrowband<<5);      
350
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 0;       // adjust according to size of RAR, 208 bits with N1A_PRB=3
sharma's avatar
sharma committed
351
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 0;    // fix to 4 for now
Raymond Knopp's avatar
Raymond Knopp committed
352 353 354 355 356 357 358 359 360
      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;
361
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1;       // N1A_PRB=3 (36.212) => 56 bits
Raymond Knopp's avatar
Raymond Knopp committed
362 363 364 365 366 367 368 369 370 371
      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;
372
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0;
Raymond Knopp's avatar
Raymond Knopp committed
373 374 375
      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;
376
      ra->msg2_mpdcch_repetition_cnt++;
377
      dl_req_body->number_pdu++;
378
      ra->Msg2_subframe = (ra->Msg2_subframe + 9) % 10;
Raymond Knopp's avatar
Raymond Knopp committed
379 380

    }                           //repetition_count==0 && SF condition met
381
    if (ra->msg2_mpdcch_repetition_cnt > 0) {  // we're in a stream of repetitions
Raymond Knopp's avatar
Raymond Knopp committed
382 383


384 385 386
      if ((ra->msg2_mpdcch_repetition_cnt == reps)&&
	  (ra->msg2_mpdcch_done == 0)){    // this is the last mpdcch repetition
	ra->msg2_mpdcch_done = 1;
Raymond Knopp's avatar
Raymond Knopp committed
387 388 389
        if (cc[CC_idP].tdd_Config == NULL) {    // FDD case
          // wait 2 subframes for PDSCH transmission
          if (subframeP > 7)
390
            ra->Msg2_frame = (frameP + 1) & 1023;
Raymond Knopp's avatar
Raymond Knopp committed
391
          else
392 393 394
            ra->Msg2_frame = frameP;
          ra->Msg2_subframe = (subframeP + 2) % 10;    // +2 is the "n+x" from Section 7.1.11  in 36.213
          LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, programmed Msg2 for %d.%d\n", module_idP, frameP, subframeP, ra->Msg2_frame,ra->Msg2_subframe); 
Raymond Knopp's avatar
Raymond Knopp committed
395 396 397 398
        } else {
          AssertFatal (1 == 0, "TDD case not done yet\n");
        }
      }                         // mpdcch_repetition_count == reps
399 400 401
      else if (ra->msg2_mpdcch_done == 0) {
        LOG_I (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, MPDCCH repetition %d\n", module_idP, frameP, subframeP, ra->msg2_mpdcch_repetition_cnt);
        ra->msg2_mpdcch_repetition_cnt++;
402 403
      }

404

405
      if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) {
Raymond Knopp's avatar
Raymond Knopp committed
406
        // Program PDSCH
407
        LOG_I (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n", module_idP, frameP, subframeP);
Raymond Knopp's avatar
Raymond Knopp committed
408

409
        dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
Raymond Knopp's avatar
Raymond Knopp committed
410 411 412
        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));
413
        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP];
414
        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti;
Raymond Knopp's avatar
Raymond Knopp committed
415 416 417 418 419 420 421
        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2;
        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;
422
        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc[CC_idP].p_eNB == 1) ? 0 : 1;
Raymond Knopp's avatar
Raymond Knopp committed
423 424 425 426 427 428 429
        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;
430 431
        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc[CC_idP].mib->message.dl_Bandwidth); // ignored
        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_idP].p_eNB == 1) ? 1 : 2;
Raymond Knopp's avatar
Raymond Knopp committed
432 433 434 435 436 437 438
        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                    = ; 

        // Rel10 fields
        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
        // Rel13 fields
439
        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;;
Raymond Knopp's avatar
Raymond Knopp committed
440 441 442
        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;
443
        dl_req_body->number_pdu++;
Raymond Knopp's avatar
Raymond Knopp committed
444

445
	fill_rar_br (mac, CC_idP, ra, frameP, subframeP, cc[CC_idP].RAR_pdu.payload, ra->rach_resource_type - 1)     ; 
446
// Program UL processing for Msg3, same as regular LTE
447 448
        get_Msg3alloc (&cc[CC_idP], subframeP, frameP, &ra->Msg3_frame, &ra->Msg3_subframe);
        add_msg3 (module_idP, CC_idP, ra, frameP, subframeP);
449
	ra->state = WAITMSG3;
Raymond Knopp's avatar
Raymond Knopp committed
450
        // DL request
451 452 453
        LOG_I (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming TX Req\n", module_idP, frameP, subframeP);
        mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP;
        TX_req = &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
Raymond Knopp's avatar
Raymond Knopp committed
454
        TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble 
455
        TX_req->pdu_index = mac->pdu_index[CC_idP]++;
Raymond Knopp's avatar
Raymond Knopp committed
456 457 458
        TX_req->num_segments = 1;
        TX_req->segments[0].segment_length = 7;
        TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload;
459
        mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
460
      }
Raymond Knopp's avatar
Raymond Knopp committed
461
    }
462

Raymond Knopp's avatar
Raymond Knopp committed
463 464
  } else

465
#endif
466
    {
Raymond Knopp's avatar
Raymond Knopp committed
467

468 469 470 471 472 473 474 475 476 477 478 479
	if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) {
	    LOG_D(MAC,
		  "[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, state %d\n",
		  module_idP, CC_idP, frameP, subframeP, ra->state);

	    // Allocate 4 PRBS starting in RB 0
	    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;

480
	    memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t));
481
	    dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
482
	    dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
483
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
484 485
	    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;
486 487 488 489 490 491
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = ra->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
492
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1;
493
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0;
494 495
	    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;
496

497
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4);
498 499

	    // This checks if the above DCI allocation is feasible in current subframe
500 501
	    if (!CCE_allocation_infeasible(module_idP, CC_idP, 0, subframeP,
		 dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->RA_rnti)) {
502 503 504
		LOG_D(MAC,
		      "Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n",
		      frameP, subframeP, ra->RA_rnti);
505 506
		dl_req_body->number_dci++;
		dl_req_body->number_pdu++;
507

508
		dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
509 510 511 512 513 514 515
		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.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index                              = mac->pdu_index[CC_idP];
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = ra->RA_rnti;
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2;	// format 1A/1B/1D
516
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;	// localized
517 518 519 520 521 522 523 524
		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;
525
		//    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
526 527 528 529 530 531 532 533
		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;
534
		//    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
535
		dl_req_body->number_pdu++;
536
                mac->DL_req[CC_idP].sfn_sf = frameP<<4 | subframeP;
537 538

		// Program UL processing for Msg3
539
		get_Msg3alloc(&cc[CC_idP], subframeP, frameP,&ra->Msg3_frame, &ra->Msg3_subframe);
540 541 542 543 544 545

		LOG_D(MAC,
		      "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n",
		      frameP, subframeP, ra->Msg3_frame,
		      ra->Msg3_subframe);

546
		fill_rar(module_idP, CC_idP, ra, frameP, cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7);
547 548
		add_msg3(module_idP, CC_idP, ra, frameP, subframeP);
		ra->state = WAITMSG3;
Cedric Roux's avatar
Cedric Roux committed
549
                LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP);
550

551 552 553 554 555
                T(T_ENB_MAC_UE_DL_RAR_PDU_WITH_DATA, T_INT(module_idP),
                  T_INT(CC_idP), T_INT(ra->RA_rnti), T_INT(frameP),
                  T_INT(subframeP), T_INT(0 /*harq_pid always 0? */ ),
                  T_BUFFER(cc[CC_idP].RAR_pdu.payload, 7));

556 557 558
		// DL request
		mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP;
		TX_req =
559
		    &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
560 561 562 563 564 565 566
		TX_req->pdu_length = 7;	// This should be changed if we have more than 1 preamble 
		TX_req->pdu_index = mac->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;
		mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
567
		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
568
    		  set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti);
569
		}
570 571 572
	    }			// PDCCH CCE allocation is feasible
	}			// Msg2 frame/subframe condition
    }				// else BL/CE
573
}
Raymond Knopp's avatar
Raymond Knopp committed
574
void
575 576
generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
	      sub_frame_t subframeP, RA_t * ra)
Raymond Knopp's avatar
Raymond Knopp committed
577
{
578

579 580 581 582 583 584 585 586 587
  
  eNB_MAC_INST *mac = RC.mac[module_idP];
  COMMON_channels_t *cc = mac->common_channels;
  int16_t rrc_sdu_length;
  int UE_id = -1;
  uint16_t msg4_padding;
  uint16_t msg4_post_padding;
  uint16_t msg4_header;
  
588 589 590 591 592 593 594 595 596 597 598 599
  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=&mac->UE_list;
  nfapi_dl_config_request_t      *dl_req;
  nfapi_dl_config_request_body_t *dl_req_body;
  nfapi_ul_config_request_body_t *ul_req_body;
  uint8_t                         lcid;
  uint8_t                         offset;
600

601

602

603
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Raymond Knopp's avatar
Raymond Knopp committed
604 605 606
  int             rmax = 0;
  int             rep = 0;
  int             reps = 0;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
607

608

Raymond Knopp's avatar
Raymond Knopp committed
609
  first_rb = 0;
610 611 612 613 614
  struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach;
  struct LTE_PUCCH_ConfigCommon_v1310 *ext4_pucch;
  LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
  struct LTE_N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13;
  LTE_PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL };
Raymond Knopp's avatar
Raymond Knopp committed
615 616
  int             pucchreps[4] = { 1, 1, 1, 1 };
  int             n1pucchan[4] = { 0, 0, 0, 0 };
Lionel Gauthier's avatar
 
Lionel Gauthier committed
617

618 619
  if (cc[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0 && 
      cc[CC_idP].radioResourceConfigCommon_BR) {
620

Raymond Knopp's avatar
Raymond Knopp committed
621 622 623
    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;
624
    pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13;
Raymond Knopp's avatar
Raymond Knopp committed
625 626
    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");
627
    // check to verify CE-Level compatibility in SIB2_BR
Raymond Knopp's avatar
Raymond Knopp committed
628
    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");
629 630 631

    switch (prach_ParametersListCE_r13->list.count) {
    case 4:
Raymond Knopp's avatar
Raymond Knopp committed
632 633 634 635 636
      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);

637
    case 3:
Raymond Knopp's avatar
Raymond Knopp committed
638 639 640 641
      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);
642
    case 2:
Raymond Knopp's avatar
Raymond Knopp committed
643 644
      p[1] = prach_ParametersListCE_r13->list.array[1];
      n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1];
sharma's avatar
sharma committed
645
      AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n");
Raymond Knopp's avatar
Raymond Knopp committed
646
      pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13);
647
    case 1:
Raymond Knopp's avatar
Raymond Knopp committed
648 649
      p[0] = prach_ParametersListCE_r13->list.array[0];
      n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0];
sharma's avatar
sharma committed
650
      AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n");
Raymond Knopp's avatar
Raymond Knopp committed
651
      pucchreps[0] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13);
sharma's avatar
sharma committed
652
      break;
653
    default:
Raymond Knopp's avatar
Raymond Knopp committed
654
      AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", prach_ParametersListCE_r13->list.count);
655

656 657
    }
  }
658

659 660
#endif

Raymond Knopp's avatar
Raymond Knopp committed
661

662
    vrb_map = cc[CC_idP].vrb_map;
sharma's avatar
sharma committed
663

664 665
    dl_req        = &mac->DL_req[CC_idP];
    dl_req_body   = &dl_req->dl_config_request_body;
Cedric Roux's avatar
Cedric Roux committed
666
    dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
667
    N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
Raymond Knopp's avatar
Raymond Knopp committed
668

669
    UE_id = find_UE_id(module_idP, ra->rnti);
670 671 672 673 674
    if (UE_id < 0) {
      LOG_E(MAC,"Can't find UE for t-crnti %x, kill RA procedure for this UE\n",ra->rnti);
      cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti);
      return;
    }
675

676
    // set HARQ process round to 0 for this UE
677

678
    ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
Raymond Knopp's avatar
Raymond Knopp committed
679

680
   /* // Get RRCConnectionSetup for Piggyback
681
    rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1,	// 1 transport block
682
				      &cc[CC_idP].CCCH_pdu.payload[0], 0);	// not used in this case
683
    if(rrc_sdu_length <= 0) {
684
      LOG_D(MAC,"[MAC][eNB Scheduler] CCCH not allocated (%d)\n",rrc_sdu_length);
685 686 687 688
      return;
    }
    //AssertFatal(rrc_sdu_length > 0,
		//"[MAC][eNB Scheduler] CCCH not allocated\n");
Raymond Knopp's avatar
Raymond Knopp committed
689 690


691 692
    LOG_D(MAC,
	  "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n",
693
	  module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length);*/
694

Raymond Knopp's avatar
Raymond Knopp committed
695

696
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
697 698 699
  if (ra->rach_resource_type > 0) {

    ra->harq_pid = 0;
700
    // Generate DCI + repetitions first
701
    // 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)
702 703 704 705 706 707
    // 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
Raymond Knopp's avatar
Raymond Knopp committed
708

709
    // rmax from SIB2 information
710
    rmax = 1<<p[ra->rach_resource_type - 1]->mpdcch_NumRepetition_RA_r13;
sharma's avatar
sharma committed
711
    
712 713

    // 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
sharma's avatar
sharma committed
714
    rep = 0;
715
    // get actual repetition count from Table 9.1.5-3
Raymond Knopp's avatar
Raymond Knopp committed
716
    reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep));
717
    // get first narrowband
718
    first_rb = narrowband_to_first_rb (&cc[CC_idP], ra->msg34_narrowband);
719

720
    if ((ra->msg4_mpdcch_repetition_cnt == 0) && (mpdcch_sf_condition (mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) {
sharma's avatar
sharma committed
721
      // Get RRCConnectionSetup for Piggyback
722
      ra->msg4_rrc_sdu_length = mac_rrc_data_req (module_idP, CC_idP, frameP, CCCH, 1,       // 1 transport block
723
							   &cc[CC_idP].CCCH_pdu.payload[0], 0);     // not used in this case
sharma's avatar
sharma committed
724
      
725
      AssertFatal (ra->msg4_rrc_sdu_length > 0, "[MAC][eNB Scheduler] CCCH not allocated\n");
sharma's avatar
sharma committed
726 727
      
      
728
      LOG_I (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d, dl_req->num_pdu %d\n", module_idP, CC_idP, frameP, subframeP, UE_id, ra->msg4_rrc_sdu_length,dl_req_body->number_pdu);
sharma's avatar
sharma committed
729 730
      
      // MPDCCH configuration for Msg4
731
      ra->msg4_mpdcch_done=0;
Raymond Knopp's avatar
Raymond Knopp committed
732 733 734
      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));
735 736
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (ra->rach_resource_type > 1) ? 11 : 10;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = ra->msg2_narrowband;
Raymond Knopp's avatar
Raymond Knopp committed
737 738
      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
sharma's avatar
sharma committed
739
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1;   // imposed (9.1.5 in 213) for Type 2 Common search space  
740
      AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
Raymond Knopp's avatar
Raymond Knopp committed
741 742
      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
743
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24;        // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
sharma's avatar
sharma committed
744
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 0; // t-CRNTI
745 746
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = ra->rnti;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (ra->rach_resource_type < 3) ? 1 : 2;
sharma's avatar
sharma committed
747
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId;
Raymond Knopp's avatar
Raymond Knopp committed
748 749
      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
750
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | (ra->msg2_narrowband<<5);
sharma's avatar
sharma committed
751 752
      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 = 0;    // fix to 4 for now
Raymond Knopp's avatar
Raymond Knopp committed
753 754
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0;
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0;
sharma's avatar
sharma committed
755
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0;
Raymond Knopp's avatar
Raymond Knopp committed
756 757 758 759 760 761
      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;
sharma's avatar
sharma committed
762
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 3;       // N1A_PRB=3 (36.212) => 56 bits
Raymond Knopp's avatar
Raymond Knopp committed
763 764 765 766 767 768 769 770 771 772
      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;
773
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0;
Raymond Knopp's avatar
Raymond Knopp committed
774 775 776
      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;
sharma's avatar
sharma committed
777

778
      ra->msg4_mpdcch_repetition_cnt++;
779
      dl_req_body->number_pdu++;
780
      ra->msg4_TBsize = get_TBS_DL(dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs,
sharma's avatar
sharma committed
781
					    6);
Raymond Knopp's avatar
Raymond Knopp committed
782
    }                           //repetition_count==0 && SF condition met
sharma's avatar
sharma committed
783
    
784 785
    if ((ra->msg4_mpdcch_repetition_cnt > 0)&&
	(ra->msg4_mpdcch_done==0)) {     // we're in a stream of repetitions
sharma's avatar
sharma committed
786
      LOG_I(MAC,"SFN.SF %d.%d : msg4 mpdcch repetition number %d/%d\n",
787 788 789
	    frameP,subframeP,ra->msg4_mpdcch_repetition_cnt,reps);
      if (ra->msg4_mpdcch_repetition_cnt == reps) {    // this is the last mpdcch repetition
        ra->msg4_mpdcch_done = 1;
sharma's avatar
sharma committed
790
	if (cc[CC_idP].tdd_Config == NULL) {    // FDD case
Raymond Knopp's avatar
Raymond Knopp committed
791 792
          // wait 2 subframes for PDSCH transmission
          if (subframeP > 7)
793
            ra->Msg4_frame = (frameP + 1) & 1023;
Raymond Knopp's avatar
Raymond Knopp committed
794
          else
795 796
            ra->Msg4_frame = frameP;
          ra->Msg4_subframe = (subframeP + 2) % 10;
sharma's avatar
sharma committed
797
	  LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Set Msg4 PDSCH in %d.%d\n",
798
		module_idP, CC_idP, frameP, subframeP, ra->Msg4_frame,ra->Msg4_subframe);
Raymond Knopp's avatar
Raymond Knopp committed
799 800 801
        } else {
          AssertFatal (1 == 0, "TDD case not done yet\n");
        }
sharma's avatar
sharma committed
802
      }
803 804
      else if (ra->msg4_mpdcch_done==0)
	ra->msg4_mpdcch_repetition_cnt++;
sharma's avatar
sharma committed
805 806
    }
// mpdcch_repetition_count == reps
807
    else if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) {
sharma's avatar
sharma committed
808 809 810 811
      
      // Program PDSCH
      
      LOG_I (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 BR with RRC Piggyback (ce_level %d RNTI %x)\n",
812
	     module_idP, CC_idP, frameP, subframeP, ra->rach_resource_type - 1, ra->rnti);
sharma's avatar
sharma committed
813 814
      
      
815
      dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
sharma's avatar
sharma committed
816 817 818
      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));
819
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP];
820
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->rnti;
sharma's avatar
sharma committed
821 822 823 824 825 826 827
      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;
828
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc[CC_idP].p_eNB == 1) ? 0 : 1;
sharma's avatar
sharma committed
829 830 831 832 833 834 835
      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;
836 837
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc[CC_idP].mib->message.dl_Bandwidth); // ignored
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_idP].p_eNB == 1) ? 1 : 2;
sharma's avatar
sharma committed
838 839 840 841 842 843
      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_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
      
844
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;
sharma's avatar
sharma committed
845 846 847
      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;
848
      dl_req_body->number_pdu++;
sharma's avatar
sharma committed
849
      
850 851

      ra->state = WAITMSG4ACK;
sharma's avatar
sharma committed
852 853 854
      
      lcid = 0;
      
855
      UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
sharma's avatar
sharma committed
856
      msg4_header = 1 + 6 + 1;        // CR header, CR CE, SDU header
857 858 859 860
      AssertFatal((ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header)>=0,
		  "msg4_TBS %d is too small, change mcs to increase by %d bytes\n",ra->msg4_TBsize,ra->msg4_rrc_sdu_length+msg4_header-ra->msg4_TBsize);
      if ((ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header) <= 2) {
	msg4_padding = ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header;
sharma's avatar
sharma committed
861 862 863
	msg4_post_padding = 0;
      } else {
	msg4_padding = 0;
864
	msg4_post_padding = ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header - 1;
sharma's avatar
sharma committed
865 866 867
      }
      
      LOG_I (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",
868
	     module_idP, CC_idP, frameP, subframeP, ra->msg4_TBsize, ra->msg4_rrc_sdu_length, msg4_header, msg4_padding, msg4_post_padding);
sharma's avatar
sharma committed
869 870
      DevAssert (UE_id != UE_INDEX_INVALID);  // FIXME not sure how to gracefully return
      // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
871
      offset = generate_dlsch_header ((unsigned char *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], 1,       //num_sdus
872
				      (unsigned short *) &ra->msg4_rrc_sdu_length,     //
sharma's avatar
sharma committed
873 874 875
				      &lcid,  // sdu_lcid
				      255,    // no drx
				      31,     // no timing advance
876
				      ra->cont_res_id,       // contention res id
sharma's avatar
sharma committed
877 878 879
				      msg4_padding,   // no padding
				      msg4_post_padding);
      
880
      memcpy ((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0][(unsigned char) offset], &cc[CC_idP].CCCH_pdu.payload[0], ra->msg4_rrc_sdu_length);
sharma's avatar
sharma committed
881 882
      
      // DL request
883 884
      mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP;
      TX_req = &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
885
      TX_req->pdu_length = ra->msg4_TBsize;
886
      TX_req->pdu_index = mac->pdu_index[CC_idP]++;
sharma's avatar
sharma committed
887
      TX_req->num_segments = 1;
888
      TX_req->segments[0].segment_length = ra->msg4_TBsize;
889 890
      TX_req->segments[0].segment_data = mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0];
      mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
sharma's avatar
sharma committed
891 892
      
      // Program ACK/NAK for Msg4 PDSCH
sharma's avatar
sharma committed
893
      int             absSF = (frameP * 10) + subframeP;
sharma's avatar
sharma committed
894
      // see Section 10.2 from 36.213
sharma's avatar
sharma committed
895
      int             ackNAK_absSF = absSF + reps + 3;
sharma's avatar
sharma committed
896
      AssertFatal (reps == 1, "Have to handle programming of ACK when PDSCH repetitions is > 1\n");
897 898
      ul_req_body = &mac->UL_req_tmp[CC_idP][ackNAK_absSF % 10].ul_config_request_body;
      ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus];
sharma's avatar
sharma committed
899 900 901 902
      
      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
903 904
      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = ra->rnti;
      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;
sharma's avatar
sharma committed
905
      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0;
906
      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[ra->rach_resource_type - 1];
sharma's avatar
sharma committed
907 908 909
      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
910
	ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = n1pucchan[ra->rach_resource_type - 1];
sharma's avatar
sharma committed
911 912 913 914 915 916 917 918 919
	// 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_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK
	ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.number_of_pucch_resources = 1;
      } else {
	AssertFatal (1 == 0, "PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n");
      }
920
      ul_req_body->number_of_pdus++;
921
      T (T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT (module_idP), T_INT (CC_idP), T_INT (ra->rnti), T_INT (frameP), T_INT (subframeP),
922
	 T_INT (0 /*harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], ra->msg4_TBsize));
sharma's avatar
sharma committed
923 924
      
      if (opt_enabled == 1) {
925
	trace_pdu (1, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], ra->msg4_rrc_sdu_length, UE_id, 3, UE_RNTI (module_idP, UE_id), mac->frame, mac->subframe, 0, 0);
926
	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), ra->msg4_rrc_sdu_length);
sharma's avatar
sharma committed
927 928
      }
    }                           // Msg4 frame/subframe  
Raymond Knopp's avatar
Raymond Knopp committed
929
  }                             // rach_resource_type > 0 
930
  else
931
#endif
932 933
    {
    // This is normal LTE case
934
	LOG_D(MAC, "generate_Msg4 1 ra->Msg4_frame SFN/SF: %d.%d,  frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP);
935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952
    	if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) {

    	    // 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*/

    		rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1,	// 1 transport block
    						      &cc[CC_idP].CCCH_pdu.payload[0], 0);	// not used in this case

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

    	    AssertFatal(rrc_sdu_length > 0,
    			"[MAC][eNB Scheduler] CCCH not allocated, rrc_sdu_length: %d\n", rrc_sdu_length);



953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998
	    LOG_D(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->rnti);

	    /// Choose first 4 RBs for Msg4, should really check that these are free!
	    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;


	    // Compute MCS/TBS for 3 PRB (coded on 4 vrb)
	    msg4_header = 1 + 6 + 1;	// CR header, CR CE, SDU header

	    if ((rrc_sdu_length + msg4_header) <= 22) {
		ra->msg4_mcs = 4;
		ra->msg4_TBsize = 22;
	    } else if ((rrc_sdu_length + msg4_header) <= 28) {
		ra->msg4_mcs = 5;
		ra->msg4_TBsize = 28;
	    } else if ((rrc_sdu_length + msg4_header) <= 32) {
		ra->msg4_mcs = 6;
		ra->msg4_TBsize = 32;
	    } else if ((rrc_sdu_length + msg4_header) <= 41) {
		ra->msg4_mcs = 7;
		ra->msg4_TBsize = 41;
	    } else if ((rrc_sdu_length + msg4_header) <= 49) {
		ra->msg4_mcs = 8;
		ra->msg4_TBsize = 49;
	    } else if ((rrc_sdu_length + msg4_header) <= 57) {
		ra->msg4_mcs = 9;
		ra->msg4_TBsize = 57;
	    }

	    fill_nfapi_dl_dci_1A(dl_config_pdu, 4,	// aggregation_level
				 ra->rnti,	// rnti
				 1,	// rnti_type, CRNTI
				 ra->harq_pid,	// harq_process
				 1,	// tpc, none
				 getRIV(N_RB_DL, first_rb, 4),	// resource_block_coding
				 ra->msg4_mcs,	// mcs
				 1,	// ndi
				 0,	// rv
				 0);	// vrb_flag
999

1000 1001
	    LOG_D(MAC,
		  "Frame %d, subframe %d: Msg4 DCI pdu_num %d (rnti %x,rnti_type %d,harq_pid %d, resource_block_coding (%p) %d\n",
1002
		  frameP, subframeP, dl_req_body->number_pdu,
1003 1004 1005
		  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,
1006 1007
		  &dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding,
		  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding);
1008 1009 1010 1011 1012
	    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);
1013 1014
	    if (!CCE_allocation_infeasible(module_idP, CC_idP, 1, subframeP,
		 dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->rnti)) {
1015 1016
		dl_req_body->number_dci++;
		dl_req_body->number_pdu++;
1017 1018

		ra->state = WAITMSG4ACK;
Cedric Roux's avatar
Cedric Roux committed
1019
                LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG4ACK\n", module_idP, frameP, subframeP);
1020 1021 1022 1023 1024 1025

		// increment Absolute subframe by 8 for Msg4 retransmission
		LOG_D(MAC,
		      "Frame %d, Subframe %d: Preparing for Msg4 retransmission currently %d.%d\n",
		      frameP, subframeP, ra->Msg4_frame,
		      ra->Msg4_subframe);
1026 1027
		get_retransmission_timing(mac->common_channels[CC_idP].tdd_Config,&ra->Msg4_frame,&ra->Msg4_subframe);

1028 1029 1030 1031 1032 1033 1034
		LOG_D(MAC,
		      "Frame %d, Subframe %d: Msg4 retransmission in %d.%d\n",
		      frameP, subframeP, ra->Msg4_frame,
		      ra->Msg4_subframe);
		lcid = 0;

		// put HARQ process round to 0
1035
		ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
1036
		UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
1037 1038

		if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
1039
		    msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header;
1040 1041 1042
		    msg4_post_padding = 0;
		} else {
		    msg4_padding = 0;
1043
		    msg4_post_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1;
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
		}

		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",
		      module_idP, CC_idP, frameP, subframeP,
		      ra->msg4_TBsize, rrc_sdu_length, msg4_header,
		      msg4_padding, msg4_post_padding);
		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 *) mac->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
					       31,	// no timing advance
					       ra->cont_res_id,	// contention res id
					       msg4_padding,	// no padding
					       msg4_post_padding);

1062
		memcpy((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
1063 1064 1065
		       &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length);

		// DLSCH Config
1066
		fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize, mac->pdu_index[CC_idP], ra->rnti, 2,	// resource_allocation_type : format 1A/1B/1D
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
					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
		LOG_D(MAC,
		      "Filled DLSCH config, pdu number %d, non-dci pdu_index %d\n",
1087
		      dl_req_body->number_pdu, mac->pdu_index[CC_idP]);
1088

1089
		// Tx request
1090 1091 1092 1093 1094 1095
		mac->TX_req[CC_idP].sfn_sf =
		    fill_nfapi_tx_req(&mac->TX_req[CC_idP].tx_request_body,
				      (frameP * 10) + subframeP,
				      rrc_sdu_length,
				      mac->pdu_index[CC_idP],
				      mac->UE_list.
1096
				      DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]);
1097 1098
		mac->pdu_index[CC_idP]++;

1099 1100
                dl_req->sfn_sf = mac->TX_req[CC_idP].sfn_sf;

1101 1102 1103 1104 1105 1106 1107 1108
		LOG_D(MAC, "Filling UCI ACK/NAK information, cce_idx %d\n",
		      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
		// Program PUCCH1a for ACK/NAK
		// Program ACK/NAK for Msg4 PDSCH
		fill_nfapi_uci_acknak(module_idP,
				      CC_idP,
				      ra->rnti,
				      (frameP * 10) + subframeP,
1109
				      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
1110 1111 1112 1113 1114 1115 1116 1117 1118


		T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP),
		  T_INT(CC_idP), T_INT(ra->rnti), T_INT(frameP),
		  T_INT(subframeP), T_INT(0 /*harq_pid always 0? */ ),
		  T_BUFFER(&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id].
			   payload[0], ra->msg4_TBsize));

		if (opt_enabled == 1) {
laurent's avatar
laurent committed
1119
		    trace_pdu(DIRECTION_DOWNLINK,
1120
			      (uint8_t *) mac->
laurent's avatar
laurent committed
1121 1122
			      UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
			      rrc_sdu_length, UE_id,  WS_C_RNTI,
1123 1124 1125 1126 1127 1128 1129 1130
			      UE_RNTI(module_idP, UE_id), mac->frame,
			      mac->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);
		}
1131
		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
1132
        	  set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
1133
		}
1134 1135 1136
	    }			// CCE Allocation feasible
	}			// msg4 frame/subframe
    }				// else rach_resource_type
1137 1138
}

Raymond Knopp's avatar
Raymond Knopp committed
1139
void
1140 1141
check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
			  frame_t frameP, sub_frame_t subframeP, RA_t * ra)
Raymond Knopp's avatar
Raymond Knopp committed
1142 1143
{

1144 1145 1146 1147 1148 1149 1150 1151
    eNB_MAC_INST *mac = RC.mac[module_idP];
    COMMON_channels_t *cc = mac->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 = &mac->UE_list;
1152 1153
    nfapi_dl_config_request_t *dl_req;
    nfapi_dl_config_request_body_t *dl_req_body;
1154 1155 1156

    int round;
    /*
1157
       #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198
       COMMON_channels_t               *cc  = mac->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


    UE_id = find_UE_id(module_idP, ra->rnti);
    AssertFatal(UE_id >= 0, "Can't find UE for t-crnti\n");

    round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid];
    vrb_map = cc[CC_idP].vrb_map;

1199 1200 1201
    dl_req = &mac->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];
1202 1203 1204
    N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);

    LOG_D(MAC,
1205 1206
	  "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 for harq_pid %d was acknowledged (round %d), UE_id: %d \n",
	  module_idP, CC_idP, frameP, subframeP, ra->harq_pid, round, UE_id);
1207 1208 1209

    if (round != 8) {

1210
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1211 1212 1213 1214
	if (ra->rach_resource_type > 0) {
	    AssertFatal(1 == 0,
			"Msg4 Retransmissions not handled yet for BL/CE UEs\n");
	} else
Raymond Knopp's avatar
Raymond Knopp committed
1215
#endif
1216 1217 1218 1219 1220 1221 1222
	{
	    if ((ra->Msg4_frame == frameP)
		&& (ra->Msg4_subframe == subframeP)) {

		//ra->wait_ack_Msg4++;
		// we have to schedule a retransmission

1223 1224
                dl_req->sfn_sf = frameP<<4 | subframeP;

1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245
		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->rnti,	// rnti
				     1,	// rnti_type, CRNTI
				     ra->harq_pid,	// harq_process
				     1,	// tpc, none
				     getRIV(N_RB_DL, first_rb, 4),	// resource_block_coding
				     ra->msg4_mcs,	// mcs
				     1,	// ndi
				     round & 3,	// rv
				     0);	// vrb_flag

		if (!CCE_allocation_infeasible
		    (module_idP, CC_idP, 1, subframeP,
		     dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
		     aggregation_level, ra->rnti)) {
1246 1247 1248
		    dl_req_body->number_dci++;
		    dl_req_body->number_pdu++;
                    dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
1249 1250 1251 1252 1253

		    LOG_D(MAC,
			  "msg4 retransmission for rnti %x (round %d) fsf %d/%d\n",
			  ra->rnti, round, frameP, subframeP);
		    // DLSCH Config
1254
                    //DJP - fix this pdu_index = -1
1255
		    LOG_D(MAC, "check_Msg4_retransmission() before fill_nfapi_dlsch_config() with pdu_index = -1 \n");
1256
		    fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize,
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277
					    -1
					    /* retransmission, no pdu_index */
					    , ra->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
1278 1279 1280
		    if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
	       	      set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
		    }
1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296
		} else
		    LOG_D(MAC,
			  "msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n",
			  ra->rnti, round, frameP, subframeP);


		// Program PUCCH1a for ACK/NAK


		fill_nfapi_uci_acknak(module_idP, CC_idP,
				      ra->rnti,
				      (frameP * 10) + subframeP,
				      dl_config_pdu->dci_dl_pdu.
				      dci_dl_pdu_rel8.cce_idx);

		// prepare frame for retransmission
1297
		get_retransmission_timing(mac->common_channels[CC_idP].tdd_Config,&ra->Msg4_frame,&ra->Msg4_subframe);
1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310

		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->rnti,
		      round, ra->Msg4_frame, ra->Msg4_subframe);

	    }			// Msg4 frame/subframe
	}			// regular LTE case
    } else {
	LOG_D(MAC,
	      "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",
	      module_idP, CC_idP, frameP, subframeP);
	ra->state = IDLE;
Cedric Roux's avatar
Cedric Roux committed
1311
        LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:IDLE\n", module_idP, frameP, subframeP);
1312 1313
	UE_id = find_UE_id(module_idP, ra->rnti);
	DevAssert(UE_id != -1);
1314
	mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE;
1315
        cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti);
1316
    }
Raymond Knopp's avatar
Raymond Knopp committed
1317
}
1318

Raymond Knopp's avatar
Raymond Knopp committed
1319
void
1320
schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
1321 1322
{

1323 1324 1325 1326 1327
    int CC_id;
    eNB_MAC_INST *mac = RC.mac[module_idP];
    COMMON_channels_t *cc = mac->common_channels;
    RA_t *ra;
    uint8_t i;
1328

1329

1330
    start_meas(&mac->schedule_ra);
1331

1332 1333 1334 1335
    for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
	// skip UL component carriers if TDD
	if (is_UL_sf(&cc[CC_id], subframeP) == 1)
	    continue;
1336

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

1339
	    ra = (RA_t *) & cc[CC_id].ra[i];
1340

1341
            //LOG_D(MAC,"RA[state:%d]\n",ra->state);
1342

1343 1344
	    if (ra->state == MSG2)
		generate_Msg2(module_idP, CC_id, frameP, subframeP, ra);
1345
		else if (ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP )
1346 1347 1348 1349
		generate_Msg4(module_idP, CC_id, frameP, subframeP, ra);
	    else if (ra->state == WAITMSG4ACK)
		check_Msg4_retransmission(module_idP, CC_id, frameP,
					  subframeP, ra);
1350

1351 1352
	}			// for i=0 .. N_RA_PROC-1 
    }				// CC_id
1353

1354
    stop_meas(&mac->schedule_ra);
Raymond Knopp's avatar
Raymond Knopp committed
1355

1356
}
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1357

1358

1359
// handles the event of MSG1 reception
Raymond Knopp's avatar
Raymond Knopp committed
1360
void
1361 1362 1363 1364 1365 1366
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
1367
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1368
		 , uint8_t rach_resource_type
1369
#endif
1370
    )
1371 1372
{

1373
    uint8_t i;
1374

1375 1376
    COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id];
    RA_t *ra = &cc->ra[0];
1377
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1378 1379


1380 1381
    struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = NULL;
    LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
1382
  
1383

1384 1385 1386 1387 1388 1389 1390

    if (cc->mib->message.schedulingInfoSIB1_BR_r13>0) {
      AssertFatal(cc->radioResourceConfigCommon_BR != NULL,"radioResourceConfigCommon_BR is null\n");
      AssertFatal(cc->radioResourceConfigCommon_BR->ext4 != NULL, "radioResourceConfigCommon_BR->ext4 is null\n");
      ext4_prach = cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
      AssertFatal(ext4_prach!=NULL,"ext4_prach is null\n");
      prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
1391
    }
1392

1393
#endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */
1394

Cedric Roux's avatar
Cedric Roux committed
1395
    LOG_D(MAC,
1396 1397
	  "[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);
1398
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1399 1400 1401
    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);
1402
#endif
1403

1404 1405 1406
    uint16_t msg2_frame = frameP;
    uint16_t msg2_subframe = subframeP;
    int offset;
Raymond Knopp's avatar
Raymond Knopp committed
1407

1408 1409
    static uint8_t failure_cnt = 0 ;

1410
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
1411

1412 1413 1414 1415 1416 1417 1418 1419 1420
    if (prach_ParametersListCE_r13 &&
	prach_ParametersListCE_r13->list.count < rach_resource_type) {
	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;
    }

1421
#endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */
1422

1423 1424
    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);
1425 1426 1427 1428 1429 1430 1431 1432 1433

    for (i = 0; i < NB_RA_PROC_MAX; i++) {
	if (ra[i].state == IDLE) {
	    int loop = 0;
	    LOG_D(MAC, "Frame %d, Subframe %d: Activating RA process %d\n",
		  frameP, subframeP, i);
	    ra[i].state = MSG2;
	    ra[i].timing_offset = timing_offset;
	    ra[i].preamble_subframe = subframeP;
1434
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1435 1436 1437
	    ra[i].rach_resource_type = rach_resource_type;
	    ra[i].msg2_mpdcch_repetition_cnt = 0;
	    ra[i].msg4_mpdcch_repetition_cnt = 0;
1438
#endif
1439

1440

1441

1442 1443 1444
            //TODO Fill in other TDD config. What about nfapi_mode?
            if(cc->tdd_Config!=NULL){
              switch(cc->tdd_Config->subframeAssignment){
1445
                default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort();
1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456
                case 1 :
                  offset = 6;
                  break;
              }
            }else{//FDD
                // DJP - this is because VNF is 2 subframes ahead of PNF and TX needs 4 subframes
                if (nfapi_mode)
                  offset = 7;
                else
                  offset = 5;
            }
1457 1458 1459 1460 1461 1462 1463 1464 1465 1466

            add_subframe(&msg2_frame, &msg2_subframe, offset);

            ra[i].Msg2_frame         = msg2_frame;
            ra[i].Msg2_subframe      = msg2_subframe;

            LOG_D(MAC,"%s() Msg2[%04d%d] SFN/SF:%04d%d offset:%d\n", __FUNCTION__,ra[i].Msg2_frame,ra[i].Msg2_subframe,frameP,subframeP,offset);

            ra[i].Msg2_subframe = (subframeP + offset) % 10;
            /* TODO: find better procedure to allocate RNTI */
1467
	    do {
1468
#if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode
1469
	        static int drnti[MAX_MOBILES_PER_ENB] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 };
1470 1471
	        int j = 0;
		int nb_ue = 0;
1472
		for (j = 0; j < MAX_MOBILES_PER_ENB; j++) {
1473 1474 1475 1476 1477 1478
		    if (UE_RNTI(module_idP, j) > 0) {
		        nb_ue++;
		    } else {
		        break;
		    }
		}
1479 1480
		if (nb_ue >= MAX_MOBILES_PER_ENB) {
		    printf("No more free RNTI available, increase MAX_MOBILES_PER_ENB\n");
1481 1482 1483
		    abort();
		}
		ra[i].rnti = drnti[nb_ue];
1484
#else	
1485
		ra[i].rnti = taus();
1486
#endif
1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502
		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[i].rnti) == -1 &&
		     /* 1024 and 60000 arbirarily chosen, not coming from standard */
		     ra[i].rnti >= 1024 && ra[i].rnti < 60000));
	    if (loop == 100) {
		printf("%s:%d:%s: FATAL ERROR! contact the authors\n",
		       __FILE__, __LINE__, __FUNCTION__);
		abort();
	    }
	    ra[i].RA_rnti = ra_rnti;
	    ra[i].preamble_index = preamble_index;
1503
	    failure_cnt = 0;
1504 1505 1506 1507 1508 1509 1510
	    LOG_D(MAC,
		  "[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation in Frame %d, subframe %d for process %d, rnti %x, state %d\n",
		  module_idP, CC_id, frameP, ra[i].Msg2_frame,
		  ra[i].Msg2_subframe, i, ra[i].rnti, ra[i].state);

	    return;
	}
1511
    }
Cedric Roux's avatar
Cedric Roux committed
1512

1513 1514 1515
    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);
1516 1517 1518
  
    failure_cnt++;
    if(failure_cnt > 20) {
naoi's avatar
naoi committed
1519
      LOG_E(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Clear Random access information\n", module_idP, CC_id, frameP);
1520 1521 1522
      clear_ra_proc(module_idP, CC_id, frameP);
    }
  
1523
}
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1524

Raymond Knopp's avatar
Raymond Knopp committed
1525
void
1526 1527
cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP,
	       rnti_t rnti)
1528
{
1529 1530
    unsigned char i;
    RA_t *ra = (RA_t *) & RC.mac[module_idP]->common_channels[CC_id].ra[0];
1531

1532 1533 1534 1535 1536
    MSC_LOG_EVENT(MSC_PHY_ENB, "RA Cancelling procedure ue %" PRIx16 " ",
		  rnti);
    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);
1537

1538 1539 1540 1541 1542 1543 1544
    for (i = 0; i < NB_RA_PROC_MAX; i++) {
	if (rnti == ra[i].rnti) {
	  ra[i].state = IDLE;
	  ra[i].timing_offset = 0;
	  ra[i].RRC_timer = 20;
	  ra[i].rnti = 0;
	  ra[i].msg3_round = 0;
1545
    LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Canceled RA procedure for UE rnti %x\n", module_idP, CC_id, frameP, rnti);
1546
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1547 1548
    }
}
1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561

void clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP)
{
  unsigned char i;
  RA_t *ra = (RA_t *) & RC.mac[module_idP]->common_channels[CC_id].ra[0];

  for (i = 0; i < NB_RA_PROC_MAX; i++) {
    LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra[i].rnti);
    ra[i].state = IDLE;
    ra[i].timing_offset = 0;
    ra[i].RRC_timer = 20;
    ra[i].rnti = 0;
    ra[i].msg3_round = 0;
1562
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1563
}