eNB_scheduler_RA.c 76.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
Cedric Roux's avatar
Cedric Roux committed
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
 */
21

22
/*! \file eNB_scheduler_RA.c
23
 * \brief primitives used for random access
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 */


35
#include "assertions.h"
36
#include "platform_types.h"
gauthier's avatar
gauthier committed
37
#include "msc.h"
38

39 40
#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_extern.h"
41

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

50
#include "RRC/LTE/rrc_extern.h"
51 52
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"

53
#include "SCHED/sched_common.h"
54 55 56 57
//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"

#if defined(ENABLE_ITTI)
58
#include "intertask_interface.h"
59 60
#endif

61
#include "SIMULATION/TOOLS/sim.h"	// for taus
62

Cedric Roux's avatar
Cedric Roux committed
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 (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
    if (ra->rach_resource_type > 0) {
	LOG_D(MAC,
	      "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n",
	      module_idP, frameP, subframeP, CC_id,
	      ra->rach_resource_type - 1, ra->Msg3_frame,
	      ra->Msg3_subframe);
	LOG_D(MAC,
	      "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d)\n",
	      frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe,
	      ra->msg3_nb_rb, ra->msg3_round);

	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));
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
	ul_config_pdu->pdu_type                                                = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE;
	ul_config_pdu->pdu_size                                                = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu));
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                         = mac->ul_handle++;
        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.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;
	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            = ((10 * ra->Msg3_frame) + ra->Msg3_subframe) & 7;
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                     = 0;
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                  = 0;
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                          = 1;
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                           = get_TBS_UL(ra->msg3_mcs, ra->msg3_nb_rb);
159
	// Re13 fields
160 161 162 163 164
        ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag                        = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG;
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type                       = ra->rach_resource_type > 2 ? 2 : 1;
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions   = 1;
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number             = 1;
	ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io    = (ra->Msg3_frame * 10) + ra->Msg3_subframe;
165
	ul_req_body->number_of_pdus++;
166 167 168
        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;
169 170
    }				//  if (ra->rach_resource_type>0) {  
    else
171
#endif
172
    {
173 174 175 176 177 178
	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,
179
	      "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
180
	      frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe,
181
	      ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round, ra->rnti);
182

183
	ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus];
184

185 186 187 188 189 190 191
	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;
192
	AssertFatal(ra->msg3_nb_rb > 0, "nb_rb = 0\n");
193 194 195 196 197 198 199 200 201 202 203 204
	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);
205
	ul_req_body->number_of_pdus++;
206 207 208
        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;
209
	// save UL scheduling information for preprocessor
210 211 212
	for (j = 0; j < ra->msg3_nb_rb; j++)
	    cc->vrb_map_UL[ra->msg3_first_rb + j] = 1;

213
        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);
214 215

	if (ra->msg3_round != 0) {	// program HI too
216 217 218
	    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;
219
	    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];
220 221
	    memset((void *) hi_dci0_pdu, 0,
		   sizeof(nfapi_hi_dci0_request_pdu_t));
222 223 224 225
	    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;
226
	    hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0;
227
	    hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value                = 0;
228 229
	    hi_dci0_req_body->number_of_hi++;

230 231
            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;
232

233
            hi_dci0_req->sfn_sf                                     = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl);
234
            hi_dci0_req->header.message_id                          = NFAPI_HI_DCI0_REQUEST;
235 236 237 238 239 240 241 242

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

243 244 245 246 247 248 249 250 251 252
	    // 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
253 254
}

255 256 257 258 259 260 261
void
generate_Msg2(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;
262

263 264 265 266 267 268
    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;
269

270 271 272 273
    vrb_map = cc[CC_idP].vrb_map;
    dl_req = &mac->DL_req[CC_idP].dl_config_request_body;
    dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
    N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
274

275
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
276 277 278 279 280 281 282 283 284 285 286 287 288
    int rmax = 0;
    int rep = 0;
    int reps = 0;
    int num_nb = 0;

    first_rb = 0;
    struct PRACH_ConfigSIB_v1310 *ext4_prach;
    PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
    PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL };

    uint16_t absSF = (10 * frameP) + subframeP;
    uint16_t absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe;

289 290
    LOG_D(MAC,"absSF:%d absSF_Msg2:%d ra->rach_resource_type:%d\n",absSF,absSF_Msg2,ra->rach_resource_type);

291
    if (absSF < absSF_Msg2)
292 293 294 295
	return;			// we're not ready yet, need to be to start ==  

    if (cc[CC_idP].radioResourceConfigCommon_BR) {

296 297
	ext4_prach                 = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
	prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313

	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];
	    break;
	default:
	    AssertFatal(1 == 0,
			"Illegal count for prach_ParametersListCE_r13 %d\n",
			(int) prach_ParametersListCE_r13->list.count);
	    break;
314
	}
315 316 317 318 319 320 321 322 323 324 325 326 327 328
    }

    if (ra->rach_resource_type > 0) {

	// This uses an MPDCCH Type 2 common allocation according to Section 9.1.5 36-213
	// Parameters:
	//    p=2+4 PRB set (number of PRB pairs 3)
	//    rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3
	//    if CELevel = 0,1 => Table 9.1.5-1b for MPDCCH candidates
	//    if CELevel = 2,3 => Table 9.1.5-2b for MPDCCH candidates
	//    distributed transmission

	// rmax from SIB2 information
	AssertFatal(rmax < 9, "rmax>8!\n");
329
	rmax = 1 << p[ra->rach_resource_type-1]->mpdcch_NumRepetition_RA_r13;
330 331 332 333 334
	// choose r1 by default for RAR (Table 9.1.5-5)
	rep = 0;
	// get actual repetition count from Table 9.1.5-3
	reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep));
	// get narrowband according to higher-layer config 
335 336 337
	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];
	first_rb = narrowband_to_first_rb(&cc[CC_idP], ra->msg2_narrowband);
338 339

	if ((ra->msg2_mpdcch_repetition_cnt == 0) &&
340
	    (mpdcch_sf_condition(mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) {
341 342 343 344 345 346
	    // MPDCCH configuration for RAR
	    LOG_D(MAC,
		  "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming MPDCCH %d repetitions\n",
		  module_idP, frameP, subframeP, reps);


347 348 349 350 351 352 353 354 355 356
	    memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t));
	    dl_config_pdu->pdu_type                                                                  = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE;
	    dl_config_pdu->pdu_size                                                                  = (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu));
            dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag                                        = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG;
	    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;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs                           = 6;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment                     = 0;	// Note: this can be dynamic
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type                       = 1;	// imposed (9.1.5 in 213) for Type 2 Common search space  
	    AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13!= NULL,
357
			"cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
358 359 360 361 362 363 364 365 366 367
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol                                  = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index                                    = 0;	// Note: this should be dynamic
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level                             = 16;	// OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type                                     = 2;	// RA-RNTI
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti                                          = ra->RA_rnti;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode                                       = (ra->rach_resource_type < 3) ? 1 : 2;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init                          = cc[CC_idP].physCellId;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io                    = (frameP * 10) + subframeP;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power                            = 6000;	// 0dB
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding                         = getRIV(6, 0, 6);	// Note: still to be checked if it should not be (getRIV(N_RB_DL,first_rb,6)) : Check nFAPI specifications and what is done L1 with this parameter
368
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4;	// adjust according to size of RAR, 208 bits with N1A_PRB=3
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels                        = 4;	// fix to 4 for now
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version                            = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator                            = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process                                  = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length                                   = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi                                          = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag                                      = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi                                           = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset                          = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number                = rep;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc                                           = 1;	// N1A_PRB=3 (36.212); => 208 bits for mcs=4, choose mcs according t message size TBD
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length              = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index                     = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag                           = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index                                = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index                              = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level                             = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request                                   = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag    = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity         = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag                = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication                             = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding            = 0;	// this is not needed by OAI L1, but should be filled in
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports                    = 1;
394 395
	    ra->msg2_mpdcch_repetition_cnt++;
	    dl_req->number_pdu++;
396
            dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
397 398
	    ra->Msg2_subframe = (ra->Msg2_subframe + 9) % 10;

399 400
            mac->DL_req[CC_idP].sfn_sf = sfnsf_add_subframe(ra->Msg2_frame, ra->Msg2_subframe, 4);	// nFAPI is runnning at TX SFN/SF - ie 4 ahead
            mac->DL_req[CC_idP].header.message_id = NFAPI_DL_CONFIG_REQUEST;
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
	}			//repetition_count==0 && SF condition met
	if (ra->msg2_mpdcch_repetition_cnt > 0) {	// we're in a stream of repetitions
	    LOG_D(MAC,
		  "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, MPDCCH repetition %d\n",
		  module_idP, frameP, subframeP,
		  ra->msg2_mpdcch_repetition_cnt);

	    if (ra->msg2_mpdcch_repetition_cnt == reps) {	// this is the last mpdcch repetition
		if (cc[CC_idP].tdd_Config == NULL) {	// FDD case
		    // wait 2 subframes for PDSCH transmission
		    if (subframeP > 7)
			ra->Msg2_frame = (frameP + 1) & 1023;
		    else
			ra->Msg2_frame = frameP;
		    ra->Msg2_subframe = (subframeP + 2) % 10;	// +2 is the "n+x" from Section 7.1.11  in 36.213
		} else {
		    AssertFatal(1 == 0, "TDD case not done yet\n");
		}
	    }			// mpdcch_repetition_count == reps
	    ra->msg2_mpdcch_repetition_cnt++;

	    if ((ra->Msg2_frame == frameP)
		&& (ra->Msg2_subframe == subframeP)) {
		// Program PDSCH
		LOG_D(MAC,
		      "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n",
		      module_idP, frameP, subframeP);
		ra->state = WAITMSG3;
Cedric Roux's avatar
Cedric Roux committed
429
                LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP);
430

431 432 433 434 435 436 437 438
		dl_config_pdu =  &dl_req->dl_config_pdu_list[dl_req->number_pdu];
		memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t));
		dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
		dl_config_pdu->pdu_size                                                        = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu));
                dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.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;
439
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;	// localized
440 441 442 443 444 445 446 447
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(N_RB_DL, first_rb, 6);
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation                             = 2;	//QPSK
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version                     = 0;
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks                       = 1;	// first block
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag  = 0;
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme                    = (cc->p_eNB == 1) ? 0 : 1;
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers                       = 1;
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands                     = 1;
448
		//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
449 450 451 452 453 454 455 456
		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;
457 458 459
		//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 

		// Rel10 fields
460 461
                dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG;
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
462
		// Rel13 fields
463 464 465 466 467
                dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG;
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type                               = (ra->rach_resource_type < 3) ? 1 : 2;
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type                    = 2;	// not SI message
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = (10 * frameP) + subframeP;
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag                       = 0;
468 469
		dl_req->number_pdu++;

470 471 472
                mac->DL_req[CC_idP].sfn_sf = (frameP<<4)+subframeP;
                mac->DL_req[CC_idP].header.message_id = NFAPI_DL_CONFIG_REQUEST;

Cedric Roux's avatar
Cedric Roux committed
473
                LOG_D(MAC,"DL_CONFIG SFN/SF:%d/%d MESSAGE2\n", frameP, subframeP);
474

475 476 477 478 479 480 481 482
		// Program UL processing for Msg3, same as regular LTE
		get_Msg3alloc(&cc[CC_idP], subframeP, frameP,
			      &ra->Msg3_frame, &ra->Msg3_subframe);
		add_msg3(module_idP, CC_idP, ra, frameP, subframeP);
		fill_rar_br(mac, CC_idP, ra, frameP, subframeP,
			    cc[CC_idP].RAR_pdu.payload,
			    ra->rach_resource_type - 1);
		// DL request
483 484
                mac->TX_req[CC_idP].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
                mac->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST;
485 486
		mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP;
		TX_req =
487
		    &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
488 489 490 491
		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;
492
		TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload;
493
		mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
494
		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
495
    		  set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti);
496
		}
497
	    }
498
	}
499 500

    } else
501
#endif
502
    {
503

504 505 506 507 508 509 510 511 512 513 514 515
	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;

516
	    memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t));
517
	    dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
518
	    dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
519
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
520 521
	    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;
522 523 524 525 526 527
	    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
528
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1;
529
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0;
530 531
	    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;
532

533
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4);
534 535

	    // This checks if the above DCI allocation is feasible in current subframe
536 537
	    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)) {
538 539 540 541 542 543
		LOG_D(MAC,
		      "Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n",
		      frameP, subframeP, ra->RA_rnti);
		dl_req->number_dci++;
		dl_req->number_pdu++;

544 545 546 547 548 549 550 551
		dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
		memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t));
		dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
		dl_config_pdu->pdu_size                                                        = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu));
                dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.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
552
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;	// localized
553 554 555 556 557 558 559 560
		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;
561
		//    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
562 563 564 565 566 567 568 569
		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;
570 571
		//    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
		dl_req->number_pdu++;
572
                mac->DL_req[CC_idP].sfn_sf = frameP<<4 | subframeP;
573 574

		// Program UL processing for Msg3
575
		get_Msg3alloc(&cc[CC_idP], subframeP, frameP,&ra->Msg3_frame, &ra->Msg3_subframe);
576 577 578 579 580 581

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

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

587 588 589 590 591
                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));

592 593 594
		// DL request
		mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP;
		TX_req =
595
		    &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
596 597 598 599 600 601 602
		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++;
603
		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
604
    		  set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti);
605
		}
606 607 608
	    }			// PDCCH CCE allocation is feasible
	}			// Msg2 frame/subframe condition
    }				// else BL/CE
609
}
610 611 612 613
void
generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
	      sub_frame_t subframeP, RA_t * ra)
{
614

615

616 617 618 619 620 621 622
    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;
623

624 625 626 627 628 629 630 631 632 633 634 635 636
  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;
  nfapi_ul_config_request_t      *ul_req;
  uint8_t                         lcid;
  uint8_t                         offset;
637

638

639
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
    int rmax = 0;
    int rep = 0;
    int reps = 0;


    first_rb = 0;
    struct PRACH_ConfigSIB_v1310 *ext4_prach;
    struct PUCCH_ConfigCommon_v1310 *ext4_pucch;
    PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13;
    struct N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13;
    PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL };
    int pucchreps[4] = { 1, 1, 1, 1 };
    int n1pucchan[4] = { 0, 0, 0, 0 };

    if (cc[CC_idP].radioResourceConfigCommon_BR) {

656 657 658 659 660 661
	ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
	ext4_pucch = cc[CC_idP].radioResourceConfigCommon_BR->ext4->pucch_ConfigCommon_v1310;
	prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
	pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13;
	AssertFatal(prach_ParametersListCE_r13 != NULL,"prach_ParametersListCE_r13 is null\n");
	AssertFatal(pucch_N1PUCCH_AN_InfoList_r13 != NULL,"pucch_N1PUCCH_AN_InfoList_r13 is null\n");
662
	// check to verify CE-Level compatibility in SIB2_BR
663
	AssertFatal(prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count,
664 665 666 667 668 669
		    "prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n");

	switch (prach_ParametersListCE_r13->list.count) {
	case 4:
	    p[3] = prach_ParametersListCE_r13->list.array[3];
	    n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3];
670
	    AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 != NULL,
671
			"pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n");
672
	    pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13);
673 674 675 676

	case 3:
	    p[2] = prach_ParametersListCE_r13->list.array[2];
	    n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2];
677
	    AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13!= NULL,
678
			"pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n");
679
	    pucchreps[2] =(int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13);
680 681 682
	case 2:
	    p[1] = prach_ParametersListCE_r13->list.array[1];
	    n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1];
683
	    AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL,
684
			"pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n");
685
	    pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13);
686 687 688
	case 1:
	    p[0] = prach_ParametersListCE_r13->list.array[0];
	    n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0];
689
	    AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL,
690
			"pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n");
691
	    pucchreps[0] =(int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13);
692 693 694 695 696
	default:
	    AssertFatal(1 == 0,
			"Illegal count for prach_ParametersListCE_r13 %d\n",
			prach_ParametersListCE_r13->list.count);
	}
697 698 699
    }
#endif

700 701
    vrb_map = cc[CC_idP].vrb_map;

702 703
    dl_req        = &mac->DL_req[CC_idP];
    dl_req_body   = &dl_req->dl_config_request_body;
Cedric Roux's avatar
Cedric Roux committed
704
    dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
705 706 707 708 709 710 711
    N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);

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

    // set HARQ process round to 0 for this UE

712
    ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
713

714
   /* // Get RRCConnectionSetup for Piggyback
715
    rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1,	// 1 transport block
716
				      &cc[CC_idP].CCCH_pdu.payload[0], 0);	// not used in this case
717
    if(rrc_sdu_length <= 0) {
718
      LOG_D(MAC,"[MAC][eNB Scheduler] CCCH not allocated (%d)\n",rrc_sdu_length);
719 720 721 722
      return;
    }
    //AssertFatal(rrc_sdu_length > 0,
		//"[MAC][eNB Scheduler] CCCH not allocated\n");
723 724 725 726


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


730
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762
    if (ra->rach_resource_type > 0) {

	// Generate DCI + repetitions first
	// 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)
	// Parameters:
	//    p=2+4 PRB set (number of PRB pairs 6)
	//    rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3
	//    if CELevel = 0,1 => Table 9.1.5-1b for MPDCCH candidates
	//    if CELevel = 2,3 => Table 9.1.5-2b for MPDCCH candidates
	//    distributed transmission

	// rmax from SIB2 information
	rmax = p[ra->rach_resource_type - 1]->mpdcch_NumRepetition_RA_r13;
	AssertFatal(rmax >= 4,
		    "choose rmax>=4 for enough repeititions, or reduce rep to 1 or 2\n");

	// choose r3 by default for Msg4 (this is ok from table 9.1.5-3 for rmax = >=4, if we choose rmax <4 it has to be less
	rep = 2;
	// get actual repetition count from Table 9.1.5-3
	reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep));
	// get first narrowband
	first_rb =
	    narrowband_to_first_rb(&cc[CC_idP], ra->msg34_narrowband);

	if ((ra->msg4_mpdcch_repetition_cnt == 0) &&
	    (mpdcch_sf_condition
	     (mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) {
	    // MPDCCH configuration for RAR

	    memset((void *) dl_config_pdu, 0,
		   sizeof(nfapi_dl_config_request_pdu_t));
	    dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE;
763
	    dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_mpdcch_pdu));
764
            dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG;
765 766 767
	    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->msg34_narrowband;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6;
768
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0;	// Note: this can be dynamic
769
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1;
770 771 772 773
	    AssertFatal(cc[CC_idP].
			sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13
			!= NULL,
			"cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n");
774
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
775 776 777 778
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0;	// Note: this should be dynamic
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16;	// OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 0;	// t-C-RNTI
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = ra->RA_rnti;
779
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (ra->rach_resource_type < 3) ? 1 : 2;
780
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId;	/// Check this is still N_id_cell for type2 common
781
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP;
782 783 784 785
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000;	// 0dB
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6, 0, 6);	// check if not getRIV(N_RB_DL,first_rb,6);
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4;	// adjust according to size of Msg4, 208 bits with N1A_PRB=3
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4;	// fix to 4 for now
786 787 788
	    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 = ra->harq_pid;
789 790 791 792
	    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;
793 794
	    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;
795
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1;	// N1A_PRB=3; => 208 bits
796 797 798
	    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;
799
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0;
800 801
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0;
802
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0;
803 804 805 806 807
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0;
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0;
808
	    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
809
	    dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1;
810
	    ra->msg4_mpdcch_repetition_cnt++;
811 812 813 814 815
	    dl_req_body->number_pdu++;
            dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;

            dl_req->sfn_sf = (ra->Msg4_frame<<4)+ra->Msg4_subframe;
            dl_req->header.message_id = NFAPI_DL_CONFIG_REQUEST;
816

817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
	}			//repetition_count==0 && SF condition met
	else if (ra->msg4_mpdcch_repetition_cnt > 0) {	// we're in a stream of repetitions
	    ra->msg4_mpdcch_repetition_cnt++;
	    if (ra->msg4_mpdcch_repetition_cnt == reps) {	// this is the last mpdcch repetition
		if (cc[CC_idP].tdd_Config == NULL) {	// FDD case
		    // wait 2 subframes for PDSCH transmission
		    if (subframeP > 7)
			ra->Msg4_frame = (frameP + 1) & 1023;
		    else
			ra->Msg4_frame = frameP;
		    ra->Msg4_subframe = (subframeP + 2) % 10;
		} else {
		    AssertFatal(1 == 0, "TDD case not done yet\n");
		}
	    }			// mpdcch_repetition_count == reps
832
	    if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) {
833 834 835

		// Program PDSCH

836 837 838 839 840 841 842 843 844 845 846 847 848 849
	        // 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\n");

850 851 852 853 854 855 856
		LOG_D(MAC,
		      "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 BR with RRC Piggyback (ce_level %d RNTI %x)\n",
		      module_idP, CC_idP, frameP, subframeP,
		      ra->rach_resource_type - 1, ra->rnti);

		AssertFatal(1 == 0,
			    "Msg4 generation not finished for BL/CE UE\n");
857 858
		dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
		memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t));
859
		dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
860
		dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu));
861
                dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
862
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index =  mac->pdu_index[CC_idP];
863 864 865 866 867
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->rnti;
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2;	// format 1A/1B/1D
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;	// localized
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6);	// check that this isn't getRIV(6,0,6)
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2;	//QPSK
868
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0;
869
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;	// first block
870 871 872 873
		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;
874
		//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
875
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1;
876
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4;	// 0 dB
877
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0;
878 879
		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
880 881
		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;
882 883 884
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
		//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 

885
                dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG;
886
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13;
887

888
                dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG;
889
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;
890
		dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2;	// not SI message
891 892
		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;
893 894
		dl_req_body->number_pdu++;
                dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
895

896 897 898
                mac->DL_req[CC_idP].sfn_sf = (frameP<<4)+subframeP;
                mac->DL_req[CC_idP].header.message_id = NFAPI_DL_CONFIG_REQUEST;
	
899
		ra->state = WAITMSG4ACK;
Cedric Roux's avatar
Cedric Roux committed
900
                LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG4ACK\n", module_idP, frameP, subframeP);
901 902 903

		lcid = 0;

904
		UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
905 906 907
		msg4_header = 1 + 6 + 1;	// CR header, CR CE, SDU header

		if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
908
		    msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header;
909 910 911
		    msg4_post_padding = 0;
		} else {
		    msg4_padding = 0;
912
		    msg4_post_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1;
913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931
		}

		LOG_D(MAC,
		      "[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n",
		      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);

		memcpy((void *) &mac->UE_list.
932
		       DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
933 934 935 936
		       &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length);

		// DL request
		mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP;
937 938 939
                mac->TX_req[CC_idP].tx_request_body.tl.tag  = NFAPI_TX_REQUEST_BODY_TAG;
                mac->TX_req[CC_idP].header.message_id 	    = NFAPI_TX_REQUEST;

940
		TX_req =
941
		    &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
942 943 944 945
		TX_req->pdu_length = rrc_sdu_length;
		TX_req->pdu_index = mac->pdu_index[CC_idP]++;
		TX_req->num_segments = 1;
		TX_req->segments[0].segment_length = rrc_sdu_length;
946
		TX_req->segments[0].segment_data = mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0];
947 948 949 950 951 952 953 954
		mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;

		// Program ACK/NAK for Msg4 PDSCH
		int absSF = (ra->Msg3_frame * 10) + ra->Msg3_subframe;
		// see Section 10.2 from 36.213
		int ackNAK_absSF = absSF + reps + 4;
		AssertFatal(reps > 2,
			    "Have to handle programming of ACK when PDSCH repetitions is > 2\n");
955 956 957
		ul_req = &mac->UL_req_tmp[CC_idP][ackNAK_absSF % 10];
		ul_req_body = &ul_req->ul_config_request_body;
		ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus];
958

959 960
		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));
961
                ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG;
962
		ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0;	// don't know how to use this
963
		ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = ra->rnti;
964
                ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG;
965 966 967 968
		ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;
		ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0;
		ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[ra->rach_resource_type - 1];
		ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.repetition_number = 0;
969 970 971 972 973 974

                ul_req_body->tl.tag                                                                         = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
                ul_req->sfn_sf  									    = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 4);
                ul_req->header.message_id  								    = NFAPI_UL_CONFIG_REQUEST;
                LOG_D(MAC,"UL_req_tmp[CC_idP:%d][ackNAK_absSF mod 10:%d] ra->Msg3_frame:%d ra->Msg3_subframe:%d + 4 sfn_sf:%d\n", CC_idP, ackNAK_absSF%10, ra->Msg3_frame, ra->Msg3_subframe, NFAPI_SFNSF2DEC(ul_req->sfn_sf));

975 976
		// 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
977
                  ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG;
978
		    ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.n_pucch_1_0 = n1pucchan[ra->rach_resource_type - 1];
979 980 981 982 983 984 985 986 987
		    // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case
		    // = N_ECCE_q + Delta_ARO + n1pucchan[ce_level]
		    // higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 =>
		    // Delta_ARO = 0 from Table 10.1.2.1-1
		    ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel8_fdd.harq_size = 1;	// 1-bit ACK/NAK
		} else {
		    AssertFatal(1 == 0,
				"PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n");
		}
988
		ul_req_body->number_of_pdus++;
989 990 991 992 993 994 995
		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) {
Thomas Laurent's avatar
Thomas Laurent committed
996
		    trace_pdu(DIRECTION_DOWNLINK,
997
			      (uint8_t *) mac->
Thomas Laurent's avatar
Thomas Laurent committed
998 999
			      UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0],
			      rrc_sdu_length, UE_id, WS_C_RNTI,
1000 1001 1002 1003
			      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",
1004
			  module_idP, CC_idP, frameP, UE_RNTI(module_idP,UE_id),
1005 1006
			  rrc_sdu_length);
		}
1007
		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
1008
        	  set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
1009
		}
1010 1011 1012 1013 1014
	    }			// Msg4 frame/subframe
	}			// msg4_mpdcch_repetition_count
    }				// rach_resource_type > 0 
    else
#endif
1015 1016
    {
    // This is normal LTE case
1017
	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);
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
    	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);



1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
	    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
1082

1083 1084
	    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",
1085
		  frameP, subframeP, dl_req_body->number_pdu,
1086 1087 1088
		  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,
1089 1090
		  &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);
1091 1092 1093 1094 1095
	    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);
1096 1097
	    if (!CCE_allocation_infeasible(module_idP, CC_idP, 1, subframeP,
		 dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->rnti)) {
1098 1099
		dl_req_body->number_dci++;
		dl_req_body->number_pdu++;
1100 1101

		ra->state = WAITMSG4ACK;
Cedric Roux's avatar
Cedric Roux committed
1102
                LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG4ACK\n", module_idP, frameP, subframeP);
1103 1104 1105 1106 1107 1108

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

1111 1112 1113 1114 1115 1116 1117
		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
1118
		ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
1119
		UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
1120 1121

		if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
1122
		    msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header;
1123 1124 1125
		    msg4_post_padding = 0;
		} else {
		    msg4_padding = 0;
1126
		    msg4_post_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1;
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
		}

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

1145
		memcpy((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset],
1146 1147 1148
		       &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length);

		// DLSCH Config
1149
		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
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
					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<