diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 45d7774afa..cfc9860477 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -217,6 +217,9 @@ typedef struct protocol_ctxt_s { sub_frame_t subframe; /*!< \brief LTE sub frame number.*/ eNB_index_t eNB_index; /*!< \brief valid for UE indicating the index of connected eNB(s) */ boolean_t configured; /*!< \brief flag indicating whether the instance is configured or not */ +#ifdef Rel14 + boolean_t brOption; +#endif } protocol_ctxt_t; // warning time hardcoded #define PROTOCOL_CTXT_TIME_MILLI_SECONDS(CtXt_h) ((CtXt_h)->frame*10+(CtXt_h)->subframe) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 14ca142c23..42c1efe12f 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -417,7 +417,10 @@ void config_sib2(int Mod_idP, void config_dedicated(int Mod_idP, int CC_idP, uint16_t rnti, - struct PhysicalConfigDedicated *physicalConfigDedicated) { + struct PhysicalConfigDedicated *physicalConfigDedicated) +{ + int UE_id = find_UE_id(Mod_idP, rnti); + eNB->UE_list.UE_template[CC_idP][UE_id].physicalConfigDedicated = physicalConfigDedicated; } diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 243215e5af..4fd8b61d2a 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -756,7 +756,7 @@ typedef struct { #ifdef Rel14 uint8_t rach_resource_type; - + struct PhysicalConfigDedicated *physicalConfigDedicated; #endif } UE_TEMPLATE; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 825d0fa8b6..3fd9857568 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -411,6 +411,955 @@ set_ul_DAI( // changes to pre-processor for eMTC +//------------------------------------------------------------------------------ +void +schedule_ue_spec_br( + module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP, + int* mbsfn_flag +) +//------------------------------------------------------------------------------ +{ + + uint8_t CC_id; + int UE_id; + unsigned char aggregation; + mac_rlc_status_resp_t rlc_status; + unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; + unsigned char header_len_dtch = 0, header_len_dtch_tmp = 0, header_len_dtch_last = 0; + unsigned char ta_len = 0; + unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; + uint16_t nb_rb, nb_rb_temp, nb_available_rb; + uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = 0, post_padding = 0; + unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; + unsigned char round = 0; + unsigned char harq_pid = 0; + eNB_UE_STATS *eNB_UE_stats = NULL; + uint16_t sdu_length_total = 0; + + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = eNB->common_channels; + UE_list_t *UE_list = &eNB->UE_list; + int continue_flag = 0; + int32_t normalized_rx_power, target_rx_power; + int32_t tpc = 1; + static int32_t tpc_accumulated = 0; + UE_sched_ctrl *ue_sched_ctl; + int mcs; + int i; + int min_rb_unit[MAX_NUM_CCs]; + int N_RB_DL[MAX_NUM_CCs]; + int total_nb_available_rb[MAX_NUM_CCs]; + int N_RBG[MAX_NUM_CCs]; + nfapi_dl_config_request_body_t *dl_req; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_pdu_t *TX_req; + int tdd_sfa; + +#if 0 + if (UE_list->head == -1) { + return; + } +#endif + + uint8_t *vrb_map; + int first_rb; + start_meas(&eNB->schedule_dlsch); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); + + + // for TDD: check that we have to act here, otherwise return + //if (cc[0].tdd_Config) { + // tdd_sfa = cc[0].tdd_Config->subframeAssignment; + // switch (subframeP) { + // case 0: + // // always continue + // break; + // case 1: + // return; + // break; + // case 2: + // return; + // break; + // case 3: + // if ((tdd_sfa != 2) && (tdd_sfa != 5)) return; + // break; + // case 4: + // if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) && (tdd_sfa != 5)) return; + // break; + // case 5: + // break; + // case 6: + // case 7: + // if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) && (tdd_sfa != 5)) return; + // break; + // case 8: + // if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) && (tdd_sfa != 5)) return; + // break; + // case 9: + // if ((tdd_sfa != 1) && (tdd_sfa != 3) && (tdd_sfa != 4) && (tdd_sfa != 6)) return; + // break; + + // } + //} + //weight = get_ue_weight(module_idP,UE_id); + aggregation = 2; + for (CC_id = 0; CC_idmessage.dl_Bandwidth); + min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); + // get number of PRBs less those used by common channels + total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; + for (i = 0; imessage.dl_Bandwidth); + + // store the global enb stats: + eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; + eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb[CC_id]; + eNB->eNB_stats[CC_id].total_available_prbs += total_nb_available_rb[CC_id]; + eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; + eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; + } + + /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); + /*start_meas(&eNB->schedule_dlsch_preprocessor); + dlsch_scheduler_pre_processor(module_idP, + frameP, + subframeP, + N_RBG, + mbsfn_flag); + stop_meas(&eNB->schedule_dlsch_preprocessor);*/ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); + + + for (CC_id = 0; CC_idDL_req[CC_id].dl_config_request_body; + + if (mbsfn_flag[CC_id]>0) + continue; + + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) + { + 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; + vrb_map[first_rb + 4] = 1; + vrb_map[first_rb + 5] = 1; + + continue_flag = 0; // reset the flag to allow allocation for the remaining UEs + rnti = UE_RNTI(module_idP, UE_id); + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + + if (rnti == NOT_A_RNTI) { + LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", UE_id, UE_list->num_UEs); + continue_flag = 1; + } + + if (eNB_UE_stats == NULL) { + LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); + continue_flag = 1; + } + + //if (continue_flag != 1) { + // switch (get_tmode(module_idP, CC_id, UE_id)) { + // case 1: + // case 2: + // case 7: + // aggregation = get_aggregation(get_bw_index(module_idP, CC_id), + // eNB_UE_stats->dl_cqi, + // format1); + // break; + // case 3: + // aggregation = get_aggregation(get_bw_index(module_idP, CC_id), + // eNB_UE_stats->dl_cqi, + // format2A); + // break; + // default: + // LOG_W(MAC, "Unsupported transmission mode %d\n", get_tmode(module_idP, CC_id, UE_id)); + // aggregation = 2; + // } + //} /* if (continue_flag != 1 */ + + if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated + CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, aggregation, rnti) + ) { + LOG_D(MAC, "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", + module_idP, frameP, UE_id, CC_id); + continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 + } + + //if (cc[CC_id].tdd_Config != NULL) { //TDD + // set_ue_dai(subframeP, + // UE_id, + // CC_id, + // cc[CC_id].tdd_Config->subframeAssignment, + // UE_list); + // // update UL DAI after DLSCH scheduling + // set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + //} + + /*if (continue_flag == 1) { + add_ue_dlsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_DL_NONE); + continue; + }*/ + + nb_available_rb = 6; // to be checked + harq_pid = ue_sched_ctl->harq_pid[CC_id]; + round = ue_sched_ctl->round[CC_id]; + UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); + UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; + UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; + + sdu_length_total = 0; + num_sdus = 0; + + /* + DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), + eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); + */ + eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->dl_cqi]; //to be checked + eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, 15); + + + // store stats + UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi = eNB_UE_stats->dl_cqi; + + // initializing the rb allocation indicator for each UE + //to be checked + for (j = 0; jUE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; + } + + LOG_D(MAC, "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", + module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, nb_available_rb, + eNB_UE_stats->dl_cqi, eNB_UE_stats->dlsch_mcs1, + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); + + + + /* process retransmission */ + + if (round > 0) { + // get freq_allocation + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + + if (nb_rb <= nb_available_rb) { + if (cc[CC_id].tdd_Config != NULL) { + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(module_idP, CC_id, rnti, UE_list->UE_template[CC_id][UE_id].DAI); + LOG_D(MAC, "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", CC_id, subframeP, UE_id, UE_list->UE_template[CC_id][UE_id].DAI); + } + + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; jUE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } + else { + nb_rb_temp = nb_rb; + j = 0; + + while ((nb_rb_temp > 0) && (jrballoc_sub_UE[CC_id][j] == 1) { + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + + if ((j == N_RBG[CC_id] - 1) && + ((N_RB_DL[CC_id] == 25) || + (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; + } + else { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; + } + } + + j = j + 1; + } + } + + nb_available_rb -= nb_rb; + /* + eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; + eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; + + for(j=0; jmu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; + } + */ + + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + default: + { + + // rmax from SIB2 information + rmax = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->mpdcch_NumRepetition_RA_r13; + // choose r3 by default for RAR (Table 9.1.5-5) + rep = 2; + // get actual repetition count from Table 9.1.5-3 + reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep)); + // get narrowband according to higher-layer config + num_nb = p[RA_template->rach_resource_type - 1]->mpdcch_NarrowbandsToMonitor_r13.list.count; + RA_template->msg2_narrowband = *p[RA_template->rach_resource_type - 1]->mpdcch_NarrowbandsToMonitor_r13.list.array[RA_template->preamble_index%num_nb]; + first_rb = RA_template->msg2_narrowband * 6; + + if ((RA_template->msg2_mpdcch_repetition_cnt == 0) && + (mpdcch_sf_condition(eNB, CC_idP, frameP, subframeP, rmax, TYPE2)>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; + dl_config_pdu->pdu_size = (uint8_t)(2 + sizeof(nfapi_dl_config_mpdcch_pdu)); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (RA_template->rach_resource_type > 1) ? 11 : 10; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = RA_template->msg2_narrowband; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space + AssertFatal(cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, + "cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = RA_template->RA_rnti; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (RA_template->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6, 0, 6); // Note: still to be checked if it should not be (getRIV(N_RB_DL,first_rb,6)) : Check nFAPI specifications and what is done L1 with this parameter + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rep; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1;// N1A_PRB=3 (36.212); => 208 bits for mcs=4, choose mcs according t message size TBD + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; + RA_template->msg2_mpdcch_repetition_cnt++; + dl_req->number_pdu++; + + } //repetition_count==0 && SF condition met + else if (RA_template->msg2_mpdcch_repetition_cnt>0) { // we're in a stream of repetitions + RA_template->msg2_mpdcch_repetition_cnt++; + if (RA_template->msg2_mpdcch_repetition_cnt == reps) { // this is the last mpdcch repetition + if (cc[CC_idP].tdd_Config == NULL) { // FDD case + // wait 2 subframes for PDSCH transmission + if (subframeP>7) RA_template->Msg2_frame = (frameP + 1) & 1023; + else RA_template->Msg2_frame = frameP; + RA_template->Msg2_subframe = (subframeP + 2) % 10; // +2 is the "n+x" from Section 7.1.11 in 36.213 + } + else { + AssertFatal(1 == 0, "TDD case not done yet\n"); + } + } // mpdcch_repetition_count == reps + if ((RA_template->Msg2_frame == frameP) && (RA_template->Msg2_subframe == subframeP)) { + // Program PDSCH + RA_template->generate_rar = 0; + + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void*)dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_idP]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = RA_template->RA_rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (RA_template->rach_resource_type < 3) ? 1 : 2;; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; + dl_req->number_pdu++; + + // Program UL processing for Msg3, same as regular LTE + get_Msg3alloc(&cc[CC_idP], subframeP, frameP, &RA_template->Msg3_frame, &RA_template->Msg3_subframe); + + + fill_rar_br(eNB, CC_idP, RA_template, frameP, subframeP, cc[CC_idP].RAR_pdu.payload, RA_template->rach_resource_type - 1); + // DL request + eNB->TX_req[CC_idP].sfn_sf = (frameP << 3) + subframeP; + TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; + TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble + TX_req->pdu_index = eNB->pdu_index[CC_idP]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = 7; + TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload; + eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++; + } + } + + } + + /*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_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), eNB_UE_stats->dl_cqi, format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : 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 = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3;*/ + + + if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, + rnti)) { + dl_req->number_dci++; + dl_req->number_pdu++; + + } + else { + // No TX request for retransmission (check if null request for FAPI) + } + } + + add_ue_dlsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_DL_SCHEDULED); + + //eNB_UE_stats->dlsch_trials[round]++; + UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1; + } + else { + LOG_D(MAC, "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", + module_idP, frameP, CC_id, UE_id); + } + } + else { /* This is a potentially new SDU opportunity */ + + rlc_status.bytes_in_buffer = 0; + // Now check RLC information to compute number of required RBs + // get maximum TBS size for RLC request + //to be checked + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); + // check first for RLC data on DCCH + // add the length for all the control elements (timing adv, drx, etc) : header + payload + + ta_len = (ue_sched_ctl->ta_update != 0) ? 2 : 0; + + header_len_dcch = 2; // 2 bytes DCCH SDU subheader + + if (TBS - ta_len - header_len_dcch > 0) { + rlc_status = mac_rlc_status_ind( + module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH, + (TBS - ta_len - header_len_dcch)); // transport block set size + + sdu_lengths[0] = 0; + + if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit + LOG_D(MAC, "[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, CC_id, TBS - header_len_dcch); + sdu_lengths[0] = mac_rlc_data_req( + module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH, + TBS, //not used + (char *)&dlsch_buffer[0]); + + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(DCCH), T_INT(sdu_lengths[0])); + + LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", module_idP, CC_id, sdu_lengths[0]); + sdu_length_total = sdu_lengths[0]; + sdu_lcids[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0]; + num_sdus = 1; +#ifdef DEBUG_eNB_SCHEDULER + LOG_T(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes :", module_idP, CC_id, sdu_lengths[0]); + + for (j = 0; j 0) { + rlc_status = mac_rlc_status_ind( + module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH + 1, + (TBS - ta_len - header_len_dcch - sdu_length_total)); // transport block set size less allocations for timing advance and + // DCCH SDU + sdu_lengths[num_sdus] = 0; + + if (rlc_status.bytes_in_buffer > 0) { + LOG_I(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, CC_id, TBS - header_len_dcch - sdu_length_total); + sdu_lengths[num_sdus] += mac_rlc_data_req( + module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH + 1, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total]); + + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); + + sdu_lcids[num_sdus] = DCCH1; + sdu_length_total += sdu_lengths[num_sdus]; + header_len_dcch += 2; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; + num_sdus++; +#ifdef DEBUG_eNB_SCHEDULER + LOG_T(MAC, "[eNB %d][DCCH1] CC_id %d Got %d bytes :", module_idP, CC_id, sdu_lengths[num_sdus]); + + for (j = 0; j= DTCH; lcid--) { + // TBD: check if the lcid is active + + header_len_dtch += 3; + header_len_dtch_last = 3; + LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP, frameP, lcid, TBS, + TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch); + + if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch); + + + if (rlc_status.bytes_in_buffer > 0) { + + LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", + module_idP, frameP, TBS - header_len_dcch - sdu_length_total - header_len_dtch, lcid, header_len_dtch); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS, //not used + (char*)&dlsch_buffer[sdu_length_total]); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(lcid), T_INT(sdu_lengths[num_sdus])); + + LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid); + sdu_lcids[num_sdus] = lcid; + sdu_length_total += sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; + if (sdu_lengths[num_sdus] < 128) { + header_len_dtch--; + header_len_dtch_last--; + } + num_sdus++; + } // no data for this LCID + else { + header_len_dtch -= 3; + } + } // no TBS left + else { + header_len_dtch -= 3; + break; + } + } + if (header_len_dtch == 0) + header_len_dtch_last = 0; + // there is at least one SDU + // if (num_sdus > 0 ){ + if ((sdu_length_total + header_len_dcch + header_len_dtch)> 0) { + + // Now compute number of required RBs for total sdu length + // Assume RAH format 2 + // adjust header lengths + header_len_dcch_tmp = header_len_dcch; + header_len_dtch_tmp = header_len_dtch; + if (header_len_dtch == 0) { + header_len_dcch = (header_len_dcch >0) ? 1 : 0;//header_len_dcch; // remove length field + } + else { + header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU + header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU + } + + mcs = eNB_UE_stats->dlsch_mcs1; + + if (mcs == 0) { + nb_rb = 4; // don't let the TBS get too small + } + else { + nb_rb = min_rb_unit[CC_id]; + } + + TBS = get_TBS_DL(mcs, nb_rb); + + while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) { + nb_rb += min_rb_unit[CC_id]; // + + if (nb_rb>nb_available_rb) { // if we've gone beyond the maximum number of RBs + // (can happen if N_RB_DL is odd) + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); + nb_rb = nb_available_rb; + break; + } + + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); + } + ///////////////////////////////////////////////////////////// + // alter the allocation of the emtc UE here + ////////////////////////////////////////////////////////////// + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; jUE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } + else { + nb_rb_temp = nb_rb; + j = 0; + + while ((nb_rb_temp > 0) && (jrballoc_sub_UE[CC_id][j] == 1) { + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + + if ((j == N_RBG[CC_id] - 1) && + ((N_RB_DL[CC_id] == 25) || + (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; + } + else { + nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; + } + } + + j = j + 1; + } + } + /////////////////////////////////// + + + // decrease mcs until TBS falls below required length + while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) { + mcs--; + TBS = get_TBS_DL(mcs, nb_rb); + } + + // if we have decreased too much or we don't have enough RBs, increase MCS + while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (((ue_sched_ctl->dl_pow_off[CC_id]>0) && (mcs<28)) + || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) && (mcs <= 15)))) { + mcs++; + TBS = get_TBS_DL(mcs, nb_rb); + } + + LOG_D(MAC, "dlsch_mcs before and after the rate matching = (%d, %d)\n", eNB_UE_stats->dlsch_mcs1, mcs); + +#ifdef DEBUG_eNB_SCHEDULER + LOG_D(MAC, "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP, CC_id, mcs, TBS, nb_rb); + // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", + // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); +#endif + + if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { + padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); + post_padding = 0; + } + else { + padding = 0; + + // adjust the header len + if (header_len_dtch == 0) { + header_len_dcch = header_len_dcch_tmp; + } + else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) + header_len_dtch = header_len_dtch_tmp; + } + + post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header + } + + + offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + num_sdus, //num_sdus + sdu_lengths, // + sdu_lcids, + 255, // no drx + ue_sched_ctl->ta_update, // timing advance + NULL, // contention res id + padding, + post_padding); + + //#ifdef DEBUG_eNB_SCHEDULER + if (ue_sched_ctl->ta_update) { + LOG_I(MAC, + "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", + module_idP, frameP, UE_id, CC_id, sdu_length_total, num_sdus, sdu_lengths[0], sdu_lcids[0], offset, + ue_sched_ctl->ta_update, padding, post_padding, mcs, TBS, nb_rb, header_len_dcch, header_len_dtch); + } + //#endif +#ifdef DEBUG_eNB_SCHEDULER + LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); + + for (i = 0; i<16; i++) { + LOG_T(MAC, "%x.", dlsch_buffer[i]); + } + + LOG_T(MAC, "\n"); +#endif + // cycle through SDUs and place in dlsch_buffer + memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); + // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); + + // fill remainder of DLSCH with random data + for (j = 0; j<(TBS - sdu_length_total - offset); j++) { + UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char)(taus() & 0xff); + } + + + if (opt_enabled == 1) { + trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + TBS, module_idP, 3, UE_RNTI(module_idP, UE_id), + eNB->frame, eNB->subframe, 0, 0); + LOG_D(OPT, "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", + module_idP, CC_id, frameP, UE_RNTI(module_idP, UE_id), TBS); + } + + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); + + UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; + + add_ue_dlsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_DL_SCHEDULED); + // store stats + eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; + eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; + + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; + UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; + + UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = TBS - sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += sdu_length_total; + UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; + UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; + + + + // do PUCCH power control + // this is the normalized RX power + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + normalized_rx_power = eNB_UE_stats->Po_PUCCH_dBm; + target_rx_power = get_target_pucch_rx_power(module_idP, CC_id) + 20; + + // this assumes accumulated tpc + // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out + int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case + ((framex10psubframe>(frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around + if (eNB_UE_stats->Po_PUCCH_update == 1) { + eNB_UE_stats->Po_PUCCH_update = 0; + + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; + + if (normalized_rx_power>(target_rx_power + 1)) { + tpc = 0; //-1 + tpc_accumulated--; + } + else if (normalized_rx_power<(target_rx_power - 1)) { + tpc = 2; //+1 + tpc_accumulated++; + } + else { + tpc = 1; //0 + } + /* + LOG_I(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP,frameP, subframeP,harq_pid,tpc, + tpc_accumulated,normalized_rx_power,target_rx_power);*/ + + } // Po_PUCCH has been updated + else { + tpc = 1; //0 + } // time to do TPC update + else { + tpc = 1; //0 + } + + //dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + //memset((void*)dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + //dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + //dl_config_pdu->pdu_size = (uint8_t)(2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), eNB_UE_stats->dl_cqi, format1); + //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : 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 = harq_pid; + //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting + //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + ////deactivate second codeword + //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + // + dl_req->number_dci++; + dl_req->number_pdu++; + + // Toggle NDI for next time + LOG_D(MAC, "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", + CC_id, frameP, subframeP, UE_id, + UE_list->UE_template[CC_id][UE_id].rnti, harq_pid, UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); + + UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; + UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; + + eNB->TX_req[CC_id].sfn_sf = (frameP << 3) + subframeP; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = TBS; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = TBS; + TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[harq_pid]; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + + } + else { // There is no data from RLC or MAC header, so don't schedule + + } + } + + + } // UE_id loop + } // CC_id loop + + + fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag); + + stop_meas(&eNB->schedule_dlsch); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); + +} //------------------------------------------------------------------------------ void diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 3d9cc64f24..e761873095 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -455,7 +455,11 @@ ue_send_sdu( rx_lengths[i], ENB_FLAG_NO, eNB_index, - 0); + 0 + #ifdef Rel14 + ,0 + #endif + ); } else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) { LOG_D(MAC,"[UE %d] Frame %d : DLSCH -> DL-DCCH%d, RRC message (eNB %d, %d bytes)\n", module_idP, frameP, rx_lcids[i],eNB_index,rx_lengths[i]); @@ -520,7 +524,11 @@ void ue_decode_si(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_i len, ENB_FLAG_NO, eNB_index, - 0); + 0 + #ifdef Rel14 + ,0 + #endif + ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT); stop_meas(&UE_mac_inst[module_idP].rx_si); if (opt_enabled == 1) { @@ -556,7 +564,11 @@ void ue_decode_p(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_in len, ENB_FLAG_NO, eNB_index, - 0); + 0 + #ifdef Rel14 + ,0 + #endif + ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_OUT); stop_meas(&UE_mac_inst[module_idP].rx_p); if (opt_enabled == 1) { @@ -659,7 +671,11 @@ void ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, uint frameP,0, // unknown subframe M_RNTI, MCCH, - payload_ptr, rx_lengths[i], 0, eNB_index, sync_area); + payload_ptr, rx_lengths[i], 0, eNB_index, sync_area + #ifdef Rel14 + ,0 + #endif + ); } else if (rx_lcids[i] == MTCH) { if (UE_mac_inst[module_idP].msi_status==1) { LOG_I(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes)\n",module_idP,frameP, sync_area, eNB_index, rx_lengths[i]); diff --git a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c index 222b9f7b41..48351355eb 100644 --- a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c +++ b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.c @@ -107,7 +107,7 @@ mac_rrc_data_req( } //------------------------------------------------------------------------------ -int8_t +/*int8_t mac_rrc_data_ind( const module_id_t module_idP, const int CC_idP, @@ -135,7 +135,7 @@ mac_rrc_data_ind( eNB_indexP, mbsfn_sync_area) ); -} +}*/ //------------------------------------------------------------------------------ void diff --git a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h index c2325f99bd..720eba88e7 100644 --- a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h +++ b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h @@ -46,7 +46,7 @@ mac_rrc_data_req( const uint8_t mbsfn_sync_areaP ); -int8_t +/*int8_t mac_rrc_data_ind( const module_id_t module_idP, const int CC_idP, @@ -59,7 +59,7 @@ mac_rrc_data_ind( const eNB_flag_t eNB_flagP, const mac_enb_index_t eNB_indexP, const uint8_t mbsfn_sync_area -); +);*/ void mac_lite_sync_ind( const module_id_t module_idP, diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index a67e86f808..9188e858c1 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -382,6 +382,9 @@ mac_rrc_data_ind( const eNB_flag_t eNB_flagP, const mac_enb_index_t eNB_indexP, const uint8_t mbsfn_sync_areaP +#ifdef Rel14 + , const boolean_t brOption +#endif ) //-------------------------------------------------------------------------- { @@ -396,6 +399,9 @@ mac_rrc_data_ind( int si_window; */ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, eNB_flagP, rntiP, frameP, sub_frameP,eNB_indexP); +#ifdef Rel14 + ctxt.brOption = brOption; +#endif if(eNB_flagP == ENB_FLAG_NO) { if(srb_idP == BCCH) { diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index f4ed3ca44d..9f70de708e 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -1917,6 +1917,7 @@ do_RRCConnectionReconfigurationComplete( return((enc_rval.encoded+7)/8); } +#ifdef Rel14 uint8_t do_RRCConnectionSetup_BR( const protocol_ctxt_t* const ctxt_pP, @@ -2245,7 +2246,7 @@ do_RRCConnectionSetup_BR( physicalConfigDedicated2->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = calloc(1, sizeof(EPDCCH_SetConfigToAddModList_r11_t)); // memset(physicalConfigDedicated2->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11, 0, sizeof()) - EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = calloc(0, sizeof(EPDCCH_SetConfig_r11_t)); + EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = calloc(1, sizeof(EPDCCH_SetConfig_r11_t)); epdcch_setconfig_r11->setConfigId_r11 = 0; epdcch_setconfig_r11->transmissionType_r11 = EPDCCH_SetConfig_r11__transmissionType_r11_localised; epdcch_setconfig_r11->resourceBlockAssignment_r11.numberPRB_Pairs_r11 = EPDCCH_SetConfig_r11__resourceBlockAssignment_r11__numberPRB_Pairs_r11_n2; @@ -2258,7 +2259,10 @@ do_RRCConnectionSetup_BR( epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11 = 0; epdcch_setconfig_r11->pucch_ResourceStartOffset_r11 = 0; epdcch_setconfig_r11->re_MappingQCL_ConfigId_r11 = NULL; + + epdcch_setconfig_r11->ext2 = calloc(1, sizeof(struct EPDCCH_SetConfig_r11_ext2)); epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 = NULL; + epdcch_setconfig_r11->ext2->mpdcch_config_r13 = calloc(1, sizeof(struct EPDCCH_SetConfig_r11_ext2_mpdcch_config_r13)); epdcch_setconfig_r11->ext2->mpdcch_config_r13->present = EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup; epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.csi_NumRepetitionCE_r13 = EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__csi_NumRepetitionCE_r13_sf1; epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 = EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off; @@ -2352,6 +2356,7 @@ do_RRCConnectionSetup_BR( return((enc_rval.encoded+7)/8); } +#endif //------------------------------------------------------------------------------ diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.h b/openair2/RRC/LITE/MESSAGES/asn1_msg.h index 2250b6815a..d16c53f7cc 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.h @@ -162,6 +162,19 @@ do_RRCConnectionSetup( SRB_ToAddModList_t** SRB_configList, struct PhysicalConfigDedicated** physicalConfigDedicated ); +#ifdef Rel14 +uint8_t +do_RRCConnectionSetup_BR( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* const ue_context_pP, + int CC_id, + uint8_t* const buffer, + const uint8_t transmission_mode, + const uint8_t Transaction_id, + SRB_ToAddModList_t** SRB_configList, + struct PhysicalConfigDedicated** physicalConfigDedicated +); +#endif /** \brief Generate an RRCConnectionReconfiguration DL-DCCH-Message (eNB). This routine configures SRBToAddMod (SRB2) and one DRBToAddMod diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LITE/proto.h index b0179bad8e..fb92b24a1c 100644 --- a/openair2/RRC/LITE/proto.h +++ b/openair2/RRC/LITE/proto.h @@ -314,6 +314,9 @@ mac_rrc_data_ind( const eNB_flag_t eNB_flagP, const mac_enb_index_t eNB_indexP, const uint8_t mbsfn_sync_areaP +#ifdef Rel14 + , const boolean_t brOption +#endif ); void mac_sync_ind( module_id_t Mod_instP, uint8_t status); diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index ffcb7c8178..29c2967004 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -3784,8 +3784,9 @@ rrc_eNB_generate_RRCConnectionSetup( ) //----------------------------------------------------------------------------- { - - bool is_mtc = false; +#ifdef Rel14 + boolean_t is_mtc = ctxt_pP->brOption; +#endif LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; SRB_ToAddModList_t **SRB_configList; SRB_ToAddMod_t *SRB1_config; @@ -3795,6 +3796,7 @@ rrc_eNB_generate_RRCConnectionSetup( T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); SRB_configList = &ue_context_pP->ue_context.SRB_configList; +#ifdef Rel14 if (is_mtc) { do_RRCConnectionSetup_BR(ctxt_pP, ue_context_pP, @@ -3804,7 +3806,9 @@ rrc_eNB_generate_RRCConnectionSetup( rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), SRB_configList, &ue_context_pP->ue_context.physicalConfigDedicated); - } else { + } else +#endif + { RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size = do_RRCConnectionSetup(ctxt_pP, ue_context_pP,