eNB_scheduler_RA.c 72 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 (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
  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);
  
262
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Raymond Knopp's avatar
Raymond Knopp committed
263 264 265 266
  int             rmax = 0;
  int             rep = 0;
  int             reps = 0;
  int             num_nb = 0;
267

Raymond Knopp's avatar
Raymond Knopp committed
268
  first_rb = 0;
269 270
  struct PRACH_ConfigSIB_v1310 *ext4_prach;
  PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
Raymond Knopp's avatar
Raymond Knopp committed
271
  PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL };
272

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

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

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

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

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

301
  if (ra->rach_resource_type > 0) {
Raymond Knopp's avatar
Raymond Knopp committed
302

303 304 305 306 307 308 309
    // 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
310

311
    // rmax from SIB2 information
Raymond Knopp's avatar
Raymond Knopp committed
312
    AssertFatal (rmax < 9, "rmax>8!\n");
313
    rmax = 1 << p[ra->rach_resource_type - 1]->mpdcch_NumRepetition_RA_r13;
314
    // choose r1 by default for RAR (Table 9.1.5-5)
Raymond Knopp's avatar
Raymond Knopp committed
315
    rep = 0;
316
    // get actual repetition count from Table 9.1.5-3
Raymond Knopp's avatar
Raymond Knopp committed
317
    reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep));
318
    // get narrowband according to higher-layer config 
319 320 321
    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
322

323
    if ((ra->msg2_mpdcch_repetition_cnt == 0) && (mpdcch_sf_condition (mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) {
324
      ra->msg2_mpdcch_done = 0;
325
      // MPDCCH configuration for RAR
326
      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
327 328 329 330 331


      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));
332 333
      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
334 335 336
      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  
337
      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
338 339
      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
340
      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
341
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI
342 343
      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
344 345 346
      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
347
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | (ra->msg2_narrowband<<5);      
348
      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
349
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 0;    // fix to 4 for now
Raymond Knopp's avatar
Raymond Knopp committed
350 351 352 353 354 355 356 357 358
      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;
359
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1;       // N1A_PRB=3 (36.212) => 56 bits
Raymond Knopp's avatar
Raymond Knopp committed
360 361 362 363 364 365 366 367 368 369
      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;
370
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0;
Raymond Knopp's avatar
Raymond Knopp committed
371 372 373
      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;
374
      ra->msg2_mpdcch_repetition_cnt++;
375
      dl_req_body->number_pdu++;
376
      ra->Msg2_subframe = (ra->Msg2_subframe + 9) % 10;
Raymond Knopp's avatar
Raymond Knopp committed
377 378

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


382 383 384
      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
385 386 387
        if (cc[CC_idP].tdd_Config == NULL) {    // FDD case
          // wait 2 subframes for PDSCH transmission
          if (subframeP > 7)
388
            ra->Msg2_frame = (frameP + 1) & 1023;
Raymond Knopp's avatar
Raymond Knopp committed
389
          else
390 391 392
            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
393 394 395 396
        } else {
          AssertFatal (1 == 0, "TDD case not done yet\n");
        }
      }                         // mpdcch_repetition_count == reps
397 398 399
      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++;
400 401
      }

402

403
      if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) {
Raymond Knopp's avatar
Raymond Knopp committed
404
        // Program PDSCH
405
        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
406

407
        dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
Raymond Knopp's avatar
Raymond Knopp committed
408 409 410
        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));
411
        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP];
412
        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti;
Raymond Knopp's avatar
Raymond Knopp committed
413 414 415 416 417 418 419
        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;
420
        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
421 422 423 424 425 426 427
        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;
428 429
        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
430 431 432 433 434 435 436
        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
437
        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;;
Raymond Knopp's avatar
Raymond Knopp committed
438 439 440
        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;
441
        dl_req_body->number_pdu++;
Raymond Knopp's avatar
Raymond Knopp committed
442

443
	fill_rar_br (mac, CC_idP, ra, frameP, subframeP, cc[CC_idP].RAR_pdu.payload, ra->rach_resource_type - 1)     ; 
444
// Program UL processing for Msg3, same as regular LTE
445 446
        get_Msg3alloc (&cc[CC_idP], subframeP, frameP, &ra->Msg3_frame, &ra->Msg3_subframe);
        add_msg3 (module_idP, CC_idP, ra, frameP, subframeP);
447
	ra->state = WAITMSG3;
Raymond Knopp's avatar
Raymond Knopp committed
448
        // DL request
449 450 451
        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
452
        TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble 
453
        TX_req->pdu_index = mac->pdu_index[CC_idP]++;
Raymond Knopp's avatar
Raymond Knopp committed
454 455 456
        TX_req->num_segments = 1;
        TX_req->segments[0].segment_length = 7;
        TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload;
457
        mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
458
      }
Raymond Knopp's avatar
Raymond Knopp committed
459
    }
460

Raymond Knopp's avatar
Raymond Knopp committed
461 462
  } else

463
#endif
464
    {
Raymond Knopp's avatar
Raymond Knopp committed
465

466 467 468 469 470 471 472 473 474 475 476 477
	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;

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

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

	    // This checks if the above DCI allocation is feasible in current subframe
498 499
	    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)) {
500 501 502
		LOG_D(MAC,
		      "Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n",
		      frameP, subframeP, ra->RA_rnti);
503 504
		dl_req_body->number_dci++;
		dl_req_body->number_pdu++;
505

506
		dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
507 508 509 510 511 512 513
		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
514
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;	// localized
515 516 517 518 519 520 521 522
		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;
523
		//    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
524 525 526 527 528 529 530 531
		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;
532
		//    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
533
		dl_req_body->number_pdu++;
534
                mac->DL_req[CC_idP].sfn_sf = frameP<<4 | subframeP;
535 536

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

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

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

		// DL request
		mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP;
		TX_req =
552
		    &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
553 554 555 556 557 558 559
		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++;
560
		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
561
    		  set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti);
562
		}
563 564 565
	    }			// PDCCH CCE allocation is feasible
	}			// Msg2 frame/subframe condition
    }				// else BL/CE
566
}
Raymond Knopp's avatar
Raymond Knopp committed
567
void
568 569
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
570
{
571

572 573 574 575 576 577 578 579 580
  
  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;
  
581 582 583 584 585 586 587 588 589 590 591 592
  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;
593

594

595
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Raymond Knopp's avatar
Raymond Knopp committed
596 597 598
  int             rmax = 0;
  int             rep = 0;
  int             reps = 0;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
599

600

Raymond Knopp's avatar
Raymond Knopp committed
601
  first_rb = 0;
602 603 604 605
  struct PRACH_ConfigSIB_v1310 *ext4_prach;
  struct PUCCH_ConfigCommon_v1310 *ext4_pucch;
  PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
  struct N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13;
Raymond Knopp's avatar
Raymond Knopp committed
606 607 608
  PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL };
  int             pucchreps[4] = { 1, 1, 1, 1 };
  int             n1pucchan[4] = { 0, 0, 0, 0 };
Lionel Gauthier's avatar
 
Lionel Gauthier committed
609

610 611
  if (cc[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0 && 
      cc[CC_idP].radioResourceConfigCommon_BR) {
612

Raymond Knopp's avatar
Raymond Knopp committed
613 614 615
    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;
616
    pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13;
Raymond Knopp's avatar
Raymond Knopp committed
617 618
    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");
619
    // check to verify CE-Level compatibility in SIB2_BR
Raymond Knopp's avatar
Raymond Knopp committed
620
    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");
621 622 623

    switch (prach_ParametersListCE_r13->list.count) {
    case 4:
Raymond Knopp's avatar
Raymond Knopp committed
624 625 626 627 628
      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);

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

650 651
#endif

Raymond Knopp's avatar
Raymond Knopp committed
652

653
    vrb_map = cc[CC_idP].vrb_map;
sharma's avatar
sharma committed
654

655 656
    dl_req        = &mac->DL_req[CC_idP];
    dl_req_body   = &dl_req->dl_config_request_body;
Cedric Roux's avatar
Cedric Roux committed
657
    dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
658
    N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
Raymond Knopp's avatar
Raymond Knopp committed
659

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

663
    // set HARQ process round to 0 for this UE
664

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

667
   /* // Get RRCConnectionSetup for Piggyback
668
    rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1,	// 1 transport block
669
				      &cc[CC_idP].CCCH_pdu.payload[0], 0);	// not used in this case
670
    if(rrc_sdu_length <= 0) {
671
      LOG_D(MAC,"[MAC][eNB Scheduler] CCCH not allocated (%d)\n",rrc_sdu_length);
672 673 674 675
      return;
    }
    //AssertFatal(rrc_sdu_length > 0,
		//"[MAC][eNB Scheduler] CCCH not allocated\n");
Raymond Knopp's avatar
Raymond Knopp committed
676 677


678 679
    LOG_D(MAC,
	  "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n",
680
	  module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length);*/
681

Raymond Knopp's avatar
Raymond Knopp committed
682

683
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
684 685 686
  if (ra->rach_resource_type > 0) {

    ra->harq_pid = 0;
687
    // Generate DCI + repetitions first
688
    // 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)
689 690 691 692 693 694
    // 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
695

696
    // rmax from SIB2 information
697
    rmax = 1<<p[ra->rach_resource_type - 1]->mpdcch_NumRepetition_RA_r13;
sharma's avatar
sharma committed
698
    
699 700

    // 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
701
    rep = 0;
702
    // get actual repetition count from Table 9.1.5-3
Raymond Knopp's avatar
Raymond Knopp committed
703
    reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep));
704
    // get first narrowband
705
    first_rb = narrowband_to_first_rb (&cc[CC_idP], ra->msg34_narrowband);
706

707
    if ((ra->msg4_mpdcch_repetition_cnt == 0) && (mpdcch_sf_condition (mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) {
sharma's avatar
sharma committed
708
      // Get RRCConnectionSetup for Piggyback
709
      ra->msg4_rrc_sdu_length = mac_rrc_data_req (module_idP, CC_idP, frameP, CCCH, 1,       // 1 transport block
710
							   &cc[CC_idP].CCCH_pdu.payload[0], 0);     // not used in this case
sharma's avatar
sharma committed
711
      
712
      AssertFatal (ra->msg4_rrc_sdu_length > 0, "[MAC][eNB Scheduler] CCCH not allocated\n");
sharma's avatar
sharma committed
713 714
      
      
715
      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
716 717
      
      // MPDCCH configuration for Msg4
718
      ra->msg4_mpdcch_done=0;
Raymond Knopp's avatar
Raymond Knopp committed
719 720 721
      memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t));
      dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE;
      dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
722 723
      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
724 725
      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
726
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1;   // imposed (9.1.5 in 213) for Type 2 Common search space  
727
      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
728 729
      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
730
      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
731
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 0; // t-CRNTI
732 733
      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
734
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId;
Raymond Knopp's avatar
Raymond Knopp committed
735 736
      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
737
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | (ra->msg2_narrowband<<5);
sharma's avatar
sharma committed
738 739
      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
740 741
      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
742
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0;
Raymond Knopp's avatar
Raymond Knopp committed
743 744 745 746 747 748
      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
749
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 3;       // N1A_PRB=3 (36.212) => 56 bits
Raymond Knopp's avatar
Raymond Knopp committed
750 751 752 753 754 755 756 757 758 759
      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;
760
      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0;
Raymond Knopp's avatar
Raymond Knopp committed
761 762 763
      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
764

765
      ra->msg4_mpdcch_repetition_cnt++;
766
      dl_req_body->number_pdu++;
767
      ra->msg4_TBsize = get_TBS_DL(dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs,
sharma's avatar
sharma committed
768
					    6);
Raymond Knopp's avatar
Raymond Knopp committed
769
    }                           //repetition_count==0 && SF condition met
sharma's avatar
sharma committed
770
    
771 772
    if ((ra->msg4_mpdcch_repetition_cnt > 0)&&
	(ra->msg4_mpdcch_done==0)) {     // we're in a stream of repetitions
sharma's avatar
sharma committed
773
      LOG_I(MAC,"SFN.SF %d.%d : msg4 mpdcch repetition number %d/%d\n",
774 775 776
	    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
777
	if (cc[CC_idP].tdd_Config == NULL) {    // FDD case
Raymond Knopp's avatar
Raymond Knopp committed
778 779
          // wait 2 subframes for PDSCH transmission
          if (subframeP > 7)
780
            ra->Msg4_frame = (frameP + 1) & 1023;
Raymond Knopp's avatar
Raymond Knopp committed
781
          else
782 783
            ra->Msg4_frame = frameP;
          ra->Msg4_subframe = (subframeP + 2) % 10;
sharma's avatar
sharma committed
784
	  LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Set Msg4 PDSCH in %d.%d\n",
785
		module_idP, CC_idP, frameP, subframeP, ra->Msg4_frame,ra->Msg4_subframe);
Raymond Knopp's avatar
Raymond Knopp committed
786 787 788
        } else {
          AssertFatal (1 == 0, "TDD case not done yet\n");
        }
sharma's avatar
sharma committed
789
      }
790 791
      else if (ra->msg4_mpdcch_done==0)
	ra->msg4_mpdcch_repetition_cnt++;
sharma's avatar
sharma committed
792 793
    }
// mpdcch_repetition_count == reps
794
    else if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) {
sharma's avatar
sharma committed
795 796 797 798
      
      // 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",
799
	     module_idP, CC_idP, frameP, subframeP, ra->rach_resource_type - 1, ra->rnti);
sharma's avatar
sharma committed
800 801
      
      
802
      dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
sharma's avatar
sharma committed
803 804 805
      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));
806
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP];
807
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->rnti;
sharma's avatar
sharma committed
808 809 810 811 812 813 814
      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;
815
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc[CC_idP].p_eNB == 1) ? 0 : 1;
sharma's avatar
sharma committed
816 817 818 819 820 821 822
      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;
823 824
      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
825 826 827 828 829 830
      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;
      
831
      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;
sharma's avatar
sharma committed
832 833 834
      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;
835
      dl_req_body->number_pdu++;
sharma's avatar
sharma committed
836
      
837 838

      ra->state = WAITMSG4ACK;
sharma's avatar
sharma committed
839 840 841
      
      lcid = 0;
      
842
      UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
sharma's avatar
sharma committed
843
      msg4_header = 1 + 6 + 1;        // CR header, CR CE, SDU header
844 845 846 847
      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
848 849 850
	msg4_post_padding = 0;
      } else {
	msg4_padding = 0;
851
	msg4_post_padding = ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header - 1;
sharma's avatar
sharma committed
852 853 854
      }
      
      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",
855
	     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
856 857
      DevAssert (UE_id != UE_INDEX_INVALID);  // FIXME not sure how to gracefully return
      // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0]
858
      offset = generate_dlsch_header ((unsigned char *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], 1,       //num_sdus
859
				      (unsigned short *) &ra->msg4_rrc_sdu_length,     //
sharma's avatar
sharma committed
860 861 862
				      &lcid,  // sdu_lcid
				      255,    // no drx
				      31,     // no timing advance
863
				      ra->cont_res_id,       // contention res id
sharma's avatar
sharma committed
864 865 866
				      msg4_padding,   // no padding
				      msg4_post_padding);
      
867
      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
868 869
      
      // DL request
870 871
      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];
872
      TX_req->pdu_length = ra->msg4_TBsize;
873
      TX_req->pdu_index = mac->pdu_index[CC_idP]++;
sharma's avatar
sharma committed
874
      TX_req->num_segments = 1;
875
      TX_req->segments[0].segment_length = ra->msg4_TBsize;
876 877
      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
878 879
      
      // Program ACK/NAK for Msg4 PDSCH
sharma's avatar
sharma committed
880
      int             absSF = (frameP * 10) + subframeP;
sharma's avatar
sharma committed
881
      // see Section 10.2 from 36.213
sharma's avatar
sharma committed
882
      int             ackNAK_absSF = absSF + reps + 3;
sharma's avatar
sharma committed
883
      AssertFatal (reps == 1, "Have to handle programming of ACK when PDSCH repetitions is > 1\n");
884 885
      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
886 887 888 889
      
      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
890 891
      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
892
      ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0;
893
      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
894 895 896
      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
897
	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
898 899 900 901 902 903 904 905 906
	// 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");
      }
907
      ul_req_body->number_of_pdus++;
908
      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),
909
	 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
910 911
      
      if (opt_enabled == 1) {
912
	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);
913
	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
914 915
      }
    }                           // Msg4 frame/subframe  
Raymond Knopp's avatar
Raymond Knopp committed
916
  }                             // rach_resource_type > 0 
917
  else
Raymond Knopp's avatar
Raymond Knopp committed
918

919
#endif
920 921
    {
    // This is normal LTE case
922
	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);
923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940
    	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);



941 942 943 944 945 946 947 948 949 950 951 952 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
	    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
987

988 989
	    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",
990
		  frameP, subframeP, dl_req_body->number_pdu,
991 992 993
		  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,
994 995
		  &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);
996 997 998 999 1000
	    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);
1001 1002
	    if (!CCE_allocation_infeasible(module_idP, CC_idP, 1, subframeP,
		 dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->rnti)) {
1003 1004
		dl_req_body->number_dci++;
		dl_req_body->number_pdu++;
1005 1006

		ra->state = WAITMSG4ACK;
Cedric Roux's avatar
Cedric Roux committed
1007
                LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG4ACK\n", module_idP, frameP, subframeP);
1008 1009 1010 1011 1012 1013

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

1016 1017 1018 1019 1020 1021 1022
		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
1023
		ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
1024
		UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
1025 1026

		if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
1027
		    msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header;
1028 1029 1030
		    msg4_post_padding = 0;
		} else {
		    msg4_padding = 0;
1031
		    msg4_post_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1;
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049
		}

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

1050
		memcpy((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
1051 1052 1053
		       &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length);

		// DLSCH Config
1054
		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
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074
					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",
1075
		      dl_req_body->number_pdu, mac->pdu_index[CC_idP]);
1076

1077
		// Tx request
1078 1079 1080 1081 1082 1083
		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.
1084
				      DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]);
1085 1086
		mac->pdu_index[CC_idP]++;

1087 1088
                dl_req->sfn_sf = mac->TX_req[CC_idP].sfn_sf;

1089 1090 1091 1092 1093 1094 1095 1096
		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,
1097
				      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
1098 1099 1100 1101 1102 1103 1104 1105 1106


		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
1107
		    trace_pdu(DIRECTION_DOWNLINK,
1108
			      (uint8_t *) mac->
laurent's avatar
laurent committed
1109 1110
			      UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
			      rrc_sdu_length, UE_id,  WS_C_RNTI,
1111 1112 1113 1114 1115 1116 1117 1118
			      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);
		}
1119
		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
1120
        	  set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
1121
		}
1122 1123 1124
	    }			// CCE Allocation feasible
	}			// msg4 frame/subframe
    }				// else rach_resource_type
1125 1126
}

Raymond Knopp's avatar
Raymond Knopp committed
1127
void
1128 1129
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
1130 1131
{

1132 1133 1134 1135 1136 1137 1138 1139
    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;
1140 1141
    nfapi_dl_config_request_t *dl_req;
    nfapi_dl_config_request_body_t *dl_req_body;
1142 1143 1144

    int round;
    /*
1145
       #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 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
       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;

1187 1188 1189
    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];
1190 1191 1192
    N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);

    LOG_D(MAC,
1193 1194
	  "[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);
1195 1196 1197

    if (round != 8) {

1198
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1199 1200 1201 1202
	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
1203
#endif
1204 1205 1206 1207 1208 1209 1210
	{
	    if ((ra->Msg4_frame == frameP)
		&& (ra->Msg4_subframe == subframeP)) {

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

1211 1212
                dl_req->sfn_sf = frameP<<4 | subframeP;

1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233
		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)) {
1234 1235 1236
		    dl_req_body->number_dci++;
		    dl_req_body->number_pdu++;
                    dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
1237 1238 1239 1240 1241

		    LOG_D(MAC,
			  "msg4 retransmission for rnti %x (round %d) fsf %d/%d\n",
			  ra->rnti, round, frameP, subframeP);
		    // DLSCH Config
1242
                    //DJP - fix this pdu_index = -1
1243
		    LOG_D(MAC, "check_Msg4_retransmission() before fill_nfapi_dlsch_config() with pdu_index = -1 \n");
1244
		    fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize,
1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
					    -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
1266 1267 1268
		    if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
	       	      set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
		    }
1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284
		} 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
1285
		get_retransmission_timing(mac->common_channels[CC_idP].tdd_Config,&ra->Msg4_frame,&ra->Msg4_subframe);
1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298

		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
1299
        LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:IDLE\n", module_idP, frameP, subframeP);
1300 1301
	UE_id = find_UE_id(module_idP, ra->rnti);
	DevAssert(UE_id != -1);
1302
	mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE;
1303
        cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti);
1304
    }
Raymond Knopp's avatar
Raymond Knopp committed
1305
}
1306

Raymond Knopp's avatar
Raymond Knopp committed
1307
void
1308
schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
1309 1310
{

1311 1312 1313 1314 1315
    int CC_id;
    eNB_MAC_INST *mac = RC.mac[module_idP];
    COMMON_channels_t *cc = mac->common_channels;
    RA_t *ra;
    uint8_t i;
1316

1317

1318
    start_meas(&mac->schedule_ra);
1319

1320 1321 1322 1323
    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;
1324

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

1327
	    ra = (RA_t *) & cc[CC_id].ra[i];
1328

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

1331 1332
	    if (ra->state == MSG2)
		generate_Msg2(module_idP, CC_id, frameP, subframeP, ra);
1333
	    else if (ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP )
1334 1335 1336 1337
		generate_Msg4(module_idP, CC_id, frameP, subframeP, ra);
	    else if (ra->state == WAITMSG4ACK)
		check_Msg4_retransmission(module_idP, CC_id, frameP,
					  subframeP, ra);
1338

1339 1340
	}			// for i=0 .. N_RA_PROC-1 
    }				// CC_id
1341

1342
    stop_meas(&mac->schedule_ra);
Raymond Knopp's avatar
Raymond Knopp committed
1343

1344
}
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1345

1346

1347
// handles the event of MSG1 reception
Raymond Knopp's avatar
Raymond Knopp committed
1348
void
1349 1350 1351 1352 1353 1354
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
1355
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1356
		 , uint8_t rach_resource_type
1357
#endif
1358
    )
1359 1360
{

1361
    uint8_t i;
1362

1363 1364
    COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id];
    RA_t *ra = &cc->ra[0];
1365

1366
    static uint8_t failure_cnt = 0;
1367

1368
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1369

1370 1371
    struct PRACH_ConfigSIB_v1310 *ext4_prach = NULL;
    PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
1372
  
1373

1374 1375 1376 1377 1378 1379 1380

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

1383
#endif /* #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */
1384

Cedric Roux's avatar
Cedric Roux committed
1385
    LOG_D(MAC,
1386 1387
	  "[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);
1388
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1389 1390 1391
    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);
1392
#endif
1393

1394 1395 1396
    uint16_t msg2_frame = frameP;
    uint16_t msg2_subframe = subframeP;
    int offset;
Raymond Knopp's avatar
Raymond Knopp committed
1397

1398
#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0))
1399

1400 1401 1402 1403 1404 1405 1406 1407 1408
    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;
    }

1409
#endif /* #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */
1410

1411 1412
    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);
1413 1414 1415 1416 1417 1418 1419 1420 1421

    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;
1422
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1423 1424 1425
	    ra[i].rach_resource_type = rach_resource_type;
	    ra[i].msg2_mpdcch_repetition_cnt = 0;
	    ra[i].msg4_mpdcch_repetition_cnt = 0;
1426
#endif
1427

1428

1429

1430 1431 1432
            //TODO Fill in other TDD config. What about nfapi_mode?
            if(cc->tdd_Config!=NULL){
              switch(cc->tdd_Config->subframeAssignment){
1433
                default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort();
1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444
                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;
            }
1445 1446 1447 1448 1449 1450 1451 1452 1453 1454

            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 */
1455
	    do {
1456
#if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode
1457
	        static int drnti[MAX_MOBILES_PER_ENB] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 };
1458 1459
	        int j = 0;
		int nb_ue = 0;
1460
		for (j = 0; j < MAX_MOBILES_PER_ENB; j++) {
1461 1462 1463 1464 1465 1466
		    if (UE_RNTI(module_idP, j) > 0) {
		        nb_ue++;
		    } else {
		        break;
		    }
		}
1467 1468
		if (nb_ue >= MAX_MOBILES_PER_ENB) {
		    printf("No more free RNTI available, increase MAX_MOBILES_PER_ENB\n");
1469 1470 1471
		    abort();
		}
		ra[i].rnti = drnti[nb_ue];
1472
#else	
1473
		ra[i].rnti = taus();
1474
#endif
1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
		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;
1491
	    failure_cnt = 0;
1492 1493 1494 1495 1496 1497 1498
	    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;
	}
1499
    }
Cedric Roux's avatar
Cedric Roux committed
1500

1501 1502 1503
    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);
1504 1505 1506
  
    failure_cnt++;
    if(failure_cnt > 20) {
naoi's avatar
naoi committed
1507
      LOG_E(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Clear Random access information\n", module_idP, CC_id, frameP);
1508 1509 1510
      clear_ra_proc(module_idP, CC_id, frameP);
    }
  
1511
}
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1512

Raymond Knopp's avatar
Raymond Knopp committed
1513
void
1514 1515
cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP,
	       rnti_t rnti)
1516
{
1517 1518
    unsigned char i;
    RA_t *ra = (RA_t *) & RC.mac[module_idP]->common_channels[CC_id].ra[0];
1519

1520 1521 1522 1523 1524
    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);
1525

1526 1527 1528 1529 1530 1531 1532
    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;
1533
    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);
1534
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1535 1536
    }
}
1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549

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;
1550
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1551
}