eNB_scheduler_RA.c 73.3 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)
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 74
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)
{
Cedric Roux's avatar
Cedric Roux committed
75
    *frameP    = (*frameP + ((*subframeP + offset) / 10)) % 1024;
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

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

uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset)
{
  add_subframe(&frameP, &subframeP, offset);
  return frameP<<4|subframeP;
}

void subtract_subframe(uint16_t *frameP, uint16_t *subframeP, int offset)
{
  if (*subframeP < offset)
  {
    *frameP = (*frameP+1024-1)%1024;
  }
  *subframeP = (*subframeP+10-offset)%10;
}

uint16_t sfnsf_subtract_subframe(uint16_t frameP, uint16_t subframeP, int offset)
{
  subtract_subframe(&frameP, &subframeP, offset);
  return frameP<<4|subframeP;
}

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
}

242 243 244 245 246
void
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
247

248 249
  eNB_MAC_INST *mac = RC.mac[module_idP];
  COMMON_channels_t *cc = mac->common_channels;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
250

251 252 253 254 255 256
  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;
257

258 259 260 261
  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);
262

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

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

280
  if (cc[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0 &&
281
      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
      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
338
      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
            ra->Msg2_frame = frameP;
          ra->Msg2_subframe = (subframeP + 2) % 10;    // +2 is the "n+x" from Section 7.1.11  in 36.213
394
          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
        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;
434
        //      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ;
Raymond Knopp's avatar
Raymond Knopp committed
435 436 437 438

        // 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];
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
  } else
464

465
#endif
466
    {
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
}
574 575 576 577
void
generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
	      sub_frame_t subframeP, RA_t * ra)
{
Lionel Gauthier's avatar
 
Lionel Gauthier committed
578

579 580 581 582 583 584 585
  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;
586 587 588 589 590 591 592 593 594 595 596 597
  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;
598

Lionel Gauthier's avatar
 
Lionel Gauthier committed
599

600

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

606

Raymond Knopp's avatar
Raymond Knopp committed
607
  first_rb = 0;
608 609 610 611 612
  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
613 614
  int             pucchreps[4] = { 1, 1, 1, 1 };
  int             n1pucchan[4] = { 0, 0, 0, 0 };
Lionel Gauthier's avatar
 
Lionel Gauthier committed
615

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

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

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

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

654 655
    }
  }
656

657 658
#endif

Raymond Knopp's avatar
Raymond Knopp committed
659

660 661
    vrb_map = cc[CC_idP].vrb_map;

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

    UE_id = find_UE_id(module_idP, ra->rnti);
668 669 670 671 672
    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;
    }
673 674 675

    // set HARQ process round to 0 for this UE

676
    ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
677

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


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


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

    ra->harq_pid = 0;
698
    // Generate DCI + repetitions first
699
    // 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)
700 701 702 703 704 705
    // 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
706

707
    // rmax from SIB2 information
708
    rmax = 1<<p[ra->rach_resource_type - 1]->mpdcch_NumRepetition_RA_r13;
709

710 711

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

718
    if ((ra->msg4_mpdcch_repetition_cnt == 0) && (mpdcch_sf_condition (mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) {
sharma's avatar
sharma committed
719
      // Get RRCConnectionSetup for Piggyback
720 721 722
      ra->msg4_rrc_sdu_length = mac_rrc_data_req (module_idP, CC_idP, frameP, CCCH,
                                                  UE_RNTI(module_idP, UE_id), 1,        // 1 transport block
                                                  &cc[CC_idP].CCCH_pdu.payload[0], 0);  // not used in this case
723

724
      AssertFatal (ra->msg4_rrc_sdu_length > 0, "[MAC][eNB Scheduler] CCCH not allocated\n");
725 726


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

sharma's avatar
sharma committed
729
      // MPDCCH configuration for Msg4
730
      ra->msg4_mpdcch_done=0;
Raymond Knopp's avatar
Raymond Knopp committed
731 732 733
      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));
734 735
      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
736 737
      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
738
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1;   // imposed (9.1.5 in 213) for Type 2 Common search space
739
      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
740 741
      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
742
      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
743
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 0; // t-CRNTI
744 745
      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
746
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId;
Raymond Knopp's avatar
Raymond Knopp committed
747 748
      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
749
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | (ra->msg2_narrowband<<5);
sharma's avatar
sharma committed
750 751
      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
752 753
      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
754
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0;
Raymond Knopp's avatar
Raymond Knopp committed
755 756 757 758 759 760
      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
761
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 3;       // N1A_PRB=3 (36.212) => 56 bits
Raymond Knopp's avatar
Raymond Knopp committed
762 763 764 765 766 767 768 769 770 771
      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;
772
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0;
Raymond Knopp's avatar
Raymond Knopp committed
773 774 775
      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
776

777
      ra->msg4_mpdcch_repetition_cnt++;
778
      dl_req_body->number_pdu++;
779
      ra->msg4_TBsize = get_TBS_DL(dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs,
sharma's avatar
sharma committed
780
					    6);
Raymond Knopp's avatar
Raymond Knopp committed
781
    }                           //repetition_count==0 && SF condition met
782

783 784
    if ((ra->msg4_mpdcch_repetition_cnt > 0)&&
	(ra->msg4_mpdcch_done==0)) {     // we're in a stream of repetitions
sharma's avatar
sharma committed
785
      LOG_I(MAC,"SFN.SF %d.%d : msg4 mpdcch repetition number %d/%d\n",
786 787 788
	    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
789
	if (cc[CC_idP].tdd_Config == NULL) {    // FDD case
Raymond Knopp's avatar
Raymond Knopp committed
790 791
          // wait 2 subframes for PDSCH transmission
          if (subframeP > 7)
792
            ra->Msg4_frame = (frameP + 1) & 1023;
Raymond Knopp's avatar
Raymond Knopp committed
793
          else
794 795
            ra->Msg4_frame = frameP;
          ra->Msg4_subframe = (subframeP + 2) % 10;
sharma's avatar
sharma committed
796
	  LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Set Msg4 PDSCH in %d.%d\n",
797
		module_idP, CC_idP, frameP, subframeP, ra->Msg4_frame,ra->Msg4_subframe);
Raymond Knopp's avatar
Raymond Knopp committed
798 799 800
        } else {
          AssertFatal (1 == 0, "TDD case not done yet\n");
        }
sharma's avatar
sharma committed
801
      }
802 803
      else if (ra->msg4_mpdcch_done==0)
	ra->msg4_mpdcch_repetition_cnt++;
sharma's avatar
sharma committed
804 805
    }
// mpdcch_repetition_count == reps
806
    else if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) {
807

sharma's avatar
sharma committed
808
      // Program PDSCH
809

sharma's avatar
sharma committed
810
      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",
811
	     module_idP, CC_idP, frameP, subframeP, ra->rach_resource_type - 1, ra->rnti);
812 813


814
      dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
sharma's avatar
sharma committed
815 816 817
      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));
818
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP];
819
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->rnti;
sharma's avatar
sharma committed
820 821 822 823 824 825 826
      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;
827
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc[CC_idP].p_eNB == 1) ? 0 : 1;
sharma's avatar
sharma committed
828 829 830 831 832 833 834
      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;
835 836
      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
837 838
      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;
839 840
      //      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ;

sharma's avatar
sharma committed
841
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
842

843
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;
sharma's avatar
sharma committed
844 845 846
      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;
847
      dl_req_body->number_pdu++;
848

849 850

      ra->state = WAITMSG4ACK;
851

sharma's avatar
sharma committed
852
      lcid = 0;
853

854
      UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
sharma's avatar
sharma committed
855
      msg4_header = 1 + 6 + 1;        // CR header, CR CE, SDU header
856 857 858 859
      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
860 861 862
	msg4_post_padding = 0;
      } else {
	msg4_padding = 0;
863
	msg4_post_padding = ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header - 1;
sharma's avatar
sharma committed
864
      }
865

sharma's avatar
sharma committed
866
      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",
867
	     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
868 869
      DevAssert (UE_id != UE_INDEX_INVALID);  // FIXME not sure how to gracefully return
      // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
870
      offset = generate_dlsch_header ((unsigned char *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], 1,       //num_sdus
871
				      (unsigned short *) &ra->msg4_rrc_sdu_length,     //
sharma's avatar
sharma committed
872 873 874
				      &lcid,  // sdu_lcid
				      255,    // no drx
				      31,     // no timing advance
875
				      ra->cont_res_id,       // contention res id
sharma's avatar
sharma committed
876 877
				      msg4_padding,   // no padding
				      msg4_post_padding);
878

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

sharma's avatar
sharma committed
881
      // DL request
882 883
      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];
884
      TX_req->pdu_length = ra->msg4_TBsize;
885
      TX_req->pdu_index = mac->pdu_index[CC_idP]++;
sharma's avatar
sharma committed
886
      TX_req->num_segments = 1;
887
      TX_req->segments[0].segment_length = ra->msg4_TBsize;
888 889
      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++;
890

sharma's avatar
sharma committed
891
      // Program ACK/NAK for Msg4 PDSCH
sharma's avatar
sharma committed
892
      int             absSF = (frameP * 10) + subframeP;
sharma's avatar
sharma committed
893
      // see Section 10.2 from 36.213
sharma's avatar
sharma committed
894
      int             ackNAK_absSF = absSF + reps + 3;
sharma's avatar
sharma committed
895
      AssertFatal (reps == 1, "Have to handle programming of ACK when PDSCH repetitions is > 1\n");
896 897
      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];
898

sharma's avatar
sharma committed
899 900 901
      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
902 903
      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
904
      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0;
905
      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
906 907 908
      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
909
	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
910 911 912 913 914 915 916 917 918
	// 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");
      }
919
      ul_req_body->number_of_pdus++;
920
      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),
921
	 T_INT (0 /*harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], ra->msg4_TBsize));
922

sharma's avatar
sharma committed
923
      if (opt_enabled == 1) {
924
	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);
925
	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
926
      }
927 928
    }                           // Msg4 frame/subframe
  }                             // rach_resource_type > 0
929
  else
930
#endif
931 932
    {
    // This is normal LTE case
933
	LOG_I(MAC, "generate_Msg4 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);
934 935 936 937 938 939
    	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*/

940
	  // check if there's data on the CCCH to send with Msg4
941 942
	  rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 
					    UE_RNTI(module_idP,UE_id),1,	// 1 transport block
943
					    &cc[CC_idP].CCCH_pdu.payload[0], 0);	// not used in this case
944 945 946

	  if (rrc_sdu_length > 0) { 
	    LOG_D(MAC,
947 948
    	    	  "[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);
949 950 951 952 953 954 955 956
	    
	    //    	    AssertFatal(rrc_sdu_length > 0,
	    //    			"[MAC][eNB Scheduler] CCCH not allocated, rrc_sdu_length: %d\n", rrc_sdu_length);
	    
	    
	    
	    LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
		  module_idP, CC_idP, frameP, subframeP, ra->rnti);
957
	  
958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
	    /// 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;
979
	    } else if ((rrc_sdu_length + msg4_header) <= 41) {
980 981
	      ra->msg4_mcs = 7;
	      ra->msg4_TBsize = 41;
982
	    } else if ((rrc_sdu_length + msg4_header) <= 49) {
983 984
	      ra->msg4_mcs = 8;
	      ra->msg4_TBsize = 49;
985
	    } else if ((rrc_sdu_length + msg4_header) <= 57) {
986 987
	      ra->msg4_mcs = 9;
	      ra->msg4_TBsize = 57;
988
	    }
989
	    
990 991 992 993 994 995 996 997 998 999
	    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
1000
	    
1001 1002
	    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",
1003
		  frameP, subframeP, dl_req_body->number_pdu,
1004 1005 1006
		  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,
1007 1008
		  &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);
1009 1010 1011 1012 1013
	    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);
1014 1015
	    if (!CCE_allocation_infeasible(module_idP, CC_idP, 1, subframeP,
		 dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->rnti)) {
1016 1017
		dl_req_body->number_dci++;
		dl_req_body->number_pdu++;
1018 1019

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

		// 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);
1027 1028
		get_retransmission_timing(mac->common_channels[CC_idP].tdd_Config,&ra->Msg4_frame,&ra->Msg4_subframe);

1029 1030 1031 1032 1033 1034 1035
		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
1036
		ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
1037
		UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
1038 1039

		if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
1040
		    msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header;
1041 1042 1043
		    msg4_post_padding = 0;
		} else {
		    msg4_padding = 0;
1044
		    msg4_post_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1;
1045 1046 1047 1048 1049 1050 1051 1052 1053
		}

		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]
1054 1055 1056
		int num_sdus = rrc_sdu_length > 0 ? 1 : 0;							       
		offset = generate_dlsch_header((unsigned char *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], 
							       num_sdus,	//num_sdus
1057 1058 1059 1060 1061 1062 1063 1064
					       (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);

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

		// DLSCH Config
1069
		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
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
					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",
1090
		      dl_req_body->number_pdu, mac->pdu_index[CC_idP]);
1091

1092
		// Tx request
1093 1094 1095 1096 1097 1098
		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.
1099
				      DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]);
1100 1101
		mac->pdu_index[CC_idP]++;

1102 1103
                dl_req->sfn_sf = mac->TX_req[CC_idP].sfn_sf;

1104 1105 1106 1107 1108 1109 1110 1111
		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,
1112
				      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
1113 1114 1115 1116 1117 1118 1119 1120 1121


		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
1122
		    trace_pdu(DIRECTION_DOWNLINK,
1123
			      (uint8_t *) mac->
laurent's avatar
laurent committed
1124 1125
			      UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
			      rrc_sdu_length, UE_id,  WS_C_RNTI,
1126 1127 1128 1129 1130 1131 1132 1133
			      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);
		}
1134
		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
1135
        	  set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
1136
		}
1137
	    }			// CCE Allocation feasible
1138 1139 1140 1141 1142 1143
	  }
	  else {
	    LOG_I(MAC,
		     "eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Delaying Msg4 for RRC Piggyback (RNTI %x)\n",
		     module_idP, CC_idP, frameP, subframeP, ra->rnti);
	    ra->Msg4_subframe ++;
Raymond Knopp's avatar
Raymond Knopp committed
1144 1145 1146
	    ra->Msg4_delay_cnt++;
	    if (ra->Msg4_delay_cnt==10) cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti);

1147 1148 1149 1150 1151 1152
	    if (ra->Msg4_subframe == 10) {
	      ra->Msg4_frame++;
	      ra->Msg4_frame&=1023;
	      ra->Msg4_subframe = 0;
	    }
	  }
1153 1154
	}			// msg4 frame/subframe
    }				// else rach_resource_type
1155 1156
}

1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
void
check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
			  frame_t frameP, sub_frame_t subframeP, RA_t * ra)
{

    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;
1170 1171
    nfapi_dl_config_request_t *dl_req;
    nfapi_dl_config_request_body_t *dl_req_body;
1172 1173 1174

    int round;
    /*
1175
       #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216
       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;

1217 1218 1219
    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];
1220 1221 1222
    N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);

    LOG_D(MAC,
1223 1224
	  "[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);
1225 1226 1227

    if (round != 8) {

1228
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1229 1230 1231 1232
	if (ra->rach_resource_type > 0) {
	    AssertFatal(1 == 0,
			"Msg4 Retransmissions not handled yet for BL/CE UEs\n");
	} else
1233
#endif
1234 1235 1236 1237 1238 1239 1240
	{
	    if ((ra->Msg4_frame == frameP)
		&& (ra->Msg4_subframe == subframeP)) {

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

1241 1242
                dl_req->sfn_sf = frameP<<4 | subframeP;

1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
		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)) {
1264 1265 1266
		    dl_req_body->number_dci++;
		    dl_req_body->number_pdu++;
                    dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
1267 1268 1269 1270 1271

		    LOG_D(MAC,
			  "msg4 retransmission for rnti %x (round %d) fsf %d/%d\n",
			  ra->rnti, round, frameP, subframeP);
		    // DLSCH Config
1272
                    //DJP - fix this pdu_index = -1
1273
		    LOG_D(MAC, "check_Msg4_retransmission() before fill_nfapi_dlsch_config() with pdu_index = -1 \n");
1274
		    fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize,
1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295
					    -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
1296 1297 1298
		    if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
	       	      set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
		    }
1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314
		} 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
1315
		get_retransmission_timing(mac->common_channels[CC_idP].tdd_Config,&ra->Msg4_frame,&ra->Msg4_subframe);
1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328

		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
1329
        LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:IDLE\n", module_idP, frameP, subframeP);
1330 1331
	UE_id = find_UE_id(module_idP, ra->rnti);
	DevAssert(UE_id != -1);
1332
	mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE;
1333
        cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti);
1334
    }
1335
}
1336

1337 1338 1339
void
schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{
1340

1341 1342 1343 1344 1345
    int CC_id;
    eNB_MAC_INST *mac = RC.mac[module_idP];
    COMMON_channels_t *cc = mac->common_channels;
    RA_t *ra;
    uint8_t i;
1346

1347

1348
    start_meas(&mac->schedule_ra);
1349

1350 1351 1352 1353
    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;
1354

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

1357
	    ra = (RA_t *) & cc[CC_id].ra[i];
1358

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

1361 1362
	    if (ra->state == MSG2)
		generate_Msg2(module_idP, CC_id, frameP, subframeP, ra);
1363
		else if (ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP )
1364 1365 1366 1367
		generate_Msg4(module_idP, CC_id, frameP, subframeP, ra);
	    else if (ra->state == WAITMSG4ACK)
		check_Msg4_retransmission(module_idP, CC_id, frameP,
					  subframeP, ra);
1368

1369 1370
	}			// for i=0 .. N_RA_PROC-1 
    }				// CC_id
1371

1372
    stop_meas(&mac->schedule_ra);
Raymond Knopp's avatar
Raymond Knopp committed
1373

1374
}
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1375

1376

1377
// handles the event of MSG1 reception
1378 1379 1380 1381 1382 1383 1384
void
initiate_ra_proc(module_id_t module_idP,
		 int CC_id,
		 frame_t frameP,
		 sub_frame_t subframeP,
		 uint16_t preamble_index,
		 int16_t timing_offset, uint16_t ra_rnti
1385
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1386
		 , uint8_t rach_resource_type
1387
#endif
1388
    )
1389 1390
{

1391
    uint8_t i;
1392

1393 1394
    COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id];
    RA_t *ra = &cc->ra[0];
1395
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1396

1397

1398 1399
    struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = NULL;
    LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
1400
  
1401

1402 1403 1404 1405 1406 1407 1408

    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;
1409
    }
1410

1411
#endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */
1412

Cedric Roux's avatar
Cedric Roux committed
1413
    LOG_D(MAC,
1414 1415
	  "[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);
1416
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1417 1418 1419
    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);
1420
#endif
1421

1422 1423 1424 1425
    uint16_t msg2_frame = frameP;
    uint16_t msg2_subframe = subframeP;
    int offset;

1426 1427
    static uint8_t failure_cnt = 0 ;

1428
#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0))
1429

1430 1431 1432 1433 1434 1435 1436 1437 1438
    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;
    }

1439
#endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */
1440

1441 1442
    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);
1443 1444 1445 1446 1447 1448 1449

    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;
Raymond Knopp's avatar
Raymond Knopp committed
1450
	    ra[i].Msg4_delay_cnt=0;
1451 1452
	    ra[i].timing_offset = timing_offset;
	    ra[i].preamble_subframe = subframeP;
1453
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1454 1455 1456
	    ra[i].rach_resource_type = rach_resource_type;
	    ra[i].msg2_mpdcch_repetition_cnt = 0;
	    ra[i].msg4_mpdcch_repetition_cnt = 0;
1457
#endif
1458

1459

1460

1461 1462 1463
            //TODO Fill in other TDD config. What about nfapi_mode?
            if(cc->tdd_Config!=NULL){
              switch(cc->tdd_Config->subframeAssignment){
1464
                default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort();
1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475
                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;
            }
1476 1477 1478 1479 1480 1481 1482 1483 1484 1485

            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 */
1486
	    do {
1487
#if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode
1488
	        static int drnti[MAX_MOBILES_PER_ENB] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 };
1489 1490
	        int j = 0;
		int nb_ue = 0;
1491
		for (j = 0; j < MAX_MOBILES_PER_ENB; j++) {
1492 1493 1494 1495 1496 1497
		    if (UE_RNTI(module_idP, j) > 0) {
		        nb_ue++;
		    } else {
		        break;
		    }
		}
1498 1499
		if (nb_ue >= MAX_MOBILES_PER_ENB) {
		    printf("No more free RNTI available, increase MAX_MOBILES_PER_ENB\n");
1500 1501 1502
		    abort();
		}
		ra[i].rnti = drnti[nb_ue];
1503
#else	
1504
		ra[i].rnti = taus();
1505
#endif
1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521
		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;
1522
	    failure_cnt = 0;
1523 1524 1525 1526 1527 1528 1529
	    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;
	}
1530
    }
Cedric Roux's avatar
Cedric Roux committed
1531

1532 1533 1534
    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);
1535 1536 1537
  
    failure_cnt++;
    if(failure_cnt > 20) {
naoi's avatar
naoi committed
1538
      LOG_E(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Clear Random access information\n", module_idP, CC_id, frameP);
1539 1540 1541
      clear_ra_proc(module_idP, CC_id, frameP);
    }
  
1542
}
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1543

1544 1545 1546
void
cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP,
	       rnti_t rnti)
1547
{
1548 1549 1550 1551 1552 1553 1554 1555 1556 1557
    unsigned char i;
    RA_t *ra = (RA_t *) & RC.mac[module_idP]->common_channels[CC_id].ra[0];

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

    for (i = 0; i < NB_RA_PROC_MAX; i++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1558 1559 1560 1561 1562 1563 1564 1565
      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;
        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);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1566 1567
    }
}
1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582

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