Commit 55460eaf authored by Louis Adrien Dufrene's avatar Louis Adrien Dufrene

some format for eMTC schedulers

parent 0ead4bdb
...@@ -456,1078 +456,6 @@ void getRepetition(UE_TEMPLATE * pue_template,unsigned int *maxRep , unsigned i ...@@ -456,1078 +456,6 @@ void getRepetition(UE_TEMPLATE * pue_template,unsigned int *maxRep , unsigned i
} }
/*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);
aggregation = 2;
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.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; i < N_RB_DL[CC_id]; i++)
if (cc[CC_id].vrb_map[i] != 0)
total_nb_available_rb[CC_id]--;
N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.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_id < MAX_NUM_CCs; CC_id++)
{
vrb_map = cc[CC_id].vrb_map;
LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id);
dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
if (mbsfn_flag[CC_id] > 0)
continue;
unsigned int rmax;
unsigned int narrowBandindex_index;
unsigned int first_rb, rep, reps;
// rmax from RRC connection setup
getRepetition(&UE_list->UE_template[CC_id][UE_id], &rmax, &narrowBandindex_index);
first_rb = narrowband_to_first_rb(cc,narrowBandindex_index);
if (vrb_map[first_rb] == 1) // skip scheduling emtc UEs if first RB is taken
continue ;
for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id])
{
if (UE_list->UE_template[CC_id][UE_id].rach_resource_type ==0 ) // do the following scheduling only if the UE is emtc
continue ;
//[khalid] ******** allocate here the vrb_map
// 1st check on the vrb_map[] and allocate the one that is next to them
// at the end of the scheduler make sure the right subbands coresponding to these RBs are allocated the UE in UE_template directely
// also check on the fill_DCI function
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];
//[khalid] allocate the middle RB subbands in sf 1,5 for synch signals and PBCH
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 ((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);x
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; j < N_RBG[CC_id]; j++) {
UE_list->UE_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)
{
// 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 freq_allocation
nb_rb = 6;//UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
if (nb_rb <= nb_available_rb)
{
//if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band
UE_list->UE_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) && (j < N_RBG[CC_id])) {
// if (ue_sched_ctl->rballoc_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; j<N_RBG[CC_id]; j++) {
//eNB->mu_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:
{
if ((UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt == 0) &&
(mpdcch_sf_condition(eNB, CC_id, frameP, subframeP, rmax, TYPEUESPEC,UE_id) > 0))
{
// MPDCCH configuration for RAR
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_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 = (UE_list->UE_template[CC_id][UE_id].rach_resource_type > 1) ? 11 : 10;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = narrowBandindex_index;
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_id].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_id].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 = 4; // other-RNTI
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = rnti;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (UE_list->UE_template[CC_id][UE_id].rach_resource_type < 3) ? 1 : 2;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_id].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
//[khalid] missing DCI format should be 10 for 6-1A
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 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; // 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 = (round & 3);
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = harq_pid;
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;
UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt++;
dl_req->number_pdu++;
//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;
add_ue_dlsch_info(module_idP,
CC_id,
UE_id,
subframeP,
S_DL_SCHEDULED);
} //repetition_count==0 && SF condition met
else if (UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt > 0)
{
// we're in a stream of repetitions
UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt++;
if (UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt == reps)
{
// this is the last mpdcch repetition
if (cc[CC_id].tdd_Config == NULL) { // FDD case
// wait 2 subframes for PDSCH transmission
if (subframeP > 7) UE_list->UE_template[CC_id][UE_id].Msg2_frame = (frameP + 1) & 1023;
else UE_list->UE_template[CC_id][UE_id].Msg2_frame = frameP;
UE_list->UE_template[CC_id][UE_id].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 ((UE_list->UE_template[CC_id][UE_id].Msg2_frame == frameP) && (UE_list->UE_template[CC_id][UE_id].Msg2_subframe == subframeP)) {
// Program PDSCH
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_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 4; // format 6-1A
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 = (round & 3);
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 = (UE_list->UE_template[CC_id][UE_id].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++;
}
}
}
}
}
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
TBS = 408;
// 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 < sdu_lengths[0]; j++) {
LOG_T(MAC, "%x ", dlsch_buffer[j]);
}
LOG_T(MAC, "\n");
#endif
}
else {
header_len_dcch = 0;
sdu_length_total = 0;
}
}
// check for DCCH1 and update header information (assume 2 byte sub-header)
if (TBS - ta_len - header_len_dcch - sdu_length_total > 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 < sdu_lengths[num_sdus]; j++) {
LOG_T(MAC, "%x ", dlsch_buffer[j]);
}
LOG_T(MAC, "\n");
#endif
}
}
// assume the max dtch header size, and adjust it later
header_len_dtch = 0;
header_len_dtch_last = 0; // the header length of the last mac sdu
// lcid has to be sorted before the actual allocation (similar struct as ue_list).
for (lcid = NB_RB_MAX - 1; lcid >= 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];
//}
//[khalid]: maximum MCS (7 or 15) depend on the DCI formate used from UE_list->UE_template[CC_id [UE_id].rach_resource_type
mcs = 4;
nb_rb = 6;
TBS = 408;//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);
//}
//if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band
UE_list->UE_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) && (j < N_RBG[CC_id])) {
// if (ue_sched_ctl->rballoc_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;
// }
//}
//RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
//RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id];
//for(j=0; j<N_RBG[CC_id]; j++) {
//RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];
//}
//
// 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 = 4;//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
// }
//
//
// } // Po_PUCCH has been updated
// else {
// tpc = 1; //0
// } // time to do TPC update
//else {
// tpc = 1; //0
//}
{
// 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));
if ((UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt == 0) &&
(mpdcch_sf_condition(eNB, CC_id, frameP, subframeP, rmax, TYPEUESPEC,UE_id) > 0))
{
// MPDCCH configuration for RAR
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_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 = (UE_list->UE_template[CC_id][UE_id].rach_resource_type > 1) ? 11 : 10;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = narrowBandindex_index;
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_id].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_id].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 = 4; // other-RNTI
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = rnti;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (UE_list->UE_template[CC_id][UE_id].rach_resource_type < 3) ? 1 : 2;
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_id].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 = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = harq_pid;
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;
UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt++;
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++;
} //repetition_count==0 && SF condition met
else if (UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt > 0)
{
// we're in a stream of repetitions
UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt++;
if (UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt == reps)
{
// this is the last mpdcch repetition
if (cc[CC_id].tdd_Config == NULL) { // FDD case
// wait 2 subframes for PDSCH transmission
if (subframeP > 7) UE_list->UE_template[CC_id][UE_id].Msg2_frame = (frameP + 1) & 1023;
else UE_list->UE_template[CC_id][UE_id].Msg2_frame = frameP;
UE_list->UE_template[CC_id][UE_id].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 ((UE_list->UE_template[CC_id][UE_id].Msg2_frame == frameP) && (UE_list->UE_template[CC_id][UE_id].Msg2_subframe == subframeP)) {
// Program PDSCH
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_id];
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 4; // format 6-1A
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 = (UE_list->UE_template[CC_id][UE_id].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 = 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++;
}
else { // There is no data from RLC or MAC header, so don't schedule
}
}
if (cc[CC_id].tdd_Config != NULL) { // TDD
set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP);
}
} // 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 void
schedule_ue_spec(module_id_t module_idP, schedule_ue_spec(module_id_t module_idP,
...@@ -2925,64 +1853,88 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_ ...@@ -2925,64 +1853,88 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/*
* Default DLSCH scheduler for LTE-M
*/
void void
schedule_ue_spec_br( schedule_ue_spec_br(module_id_t module_idP,
module_id_t module_idP,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP sub_frame_t subframeP)
) { //------------------------------------------------------------------------------
int CC_id = 0,UE_id; {
eNB_MAC_INST *mac = RC.mac[module_idP]; int CC_id = 0;
COMMON_channels_t *cc = mac->common_channels; int UE_id = -1;
UE_list_t *UE_list = &mac->UE_list;
UE_TEMPLATE *UE_template;
UE_sched_ctrl *ue_sched_ctl;
int32_t tpc=1;
int rvseq[4] = {0,2,3,1}; int rvseq[4] = {0,2,3,1};
mac_rlc_status_resp_t rlc_status; int mcs = 0;
unsigned char header_len_dcch=0, header_len_dcch_tmp=0; int round_DL = 0;
unsigned char header_len_dtch=0, header_len_dtch_tmp=0, header_len_dtch_last=0; int ta_update = 0;
unsigned char ta_len=0; int32_t tpc = 1;
unsigned char sdu_lcids[NB_RB_MAX],lcid,offset,num_sdus=0; int32_t normalized_rx_power = 0;
uint16_t TBS,j,sdu_lengths[NB_RB_MAX],rnti,padding=0,post_padding=0; int32_t target_rx_power = 0;
unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; uint16_t TBS = 0;
int round; uint16_t j = 0;
int ta_update; uint16_t sdu_lengths[NB_RB_MAX];
uint16_t rnti = 0;
uint16_t padding = 0;
uint16_t post_padding = 0;
uint16_t sdu_length_total = 0; uint16_t sdu_length_total = 0;
int mcs;
int32_t normalized_rx_power, target_rx_power;
nfapi_dl_config_request_pdu_t *dl_config_pdu; mac_rlc_status_resp_t rlc_status;
nfapi_ul_config_request_pdu_t *ul_config_pdu; rrc_eNB_ue_context_t *ue_contextP = NULL;
nfapi_tx_request_pdu_t *TX_req;
nfapi_dl_config_request_body_t *dl_req; unsigned char header_len_dcch = 0;
nfapi_ul_config_request_body_t *ul_req; unsigned char header_len_dcch_tmp = 0;
unsigned char header_len_dtch = 0;
unsigned char header_len_dtch_tmp = 0;
unsigned char header_len_dtch_last = 0;
unsigned char ta_len = 0;
unsigned char sdu_lcids[NB_RB_MAX];
unsigned char lcid = 0;
unsigned char offset,num_sdus=0;
unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach; eNB_MAC_INST *mac = RC.mac[module_idP];
struct LTE_PUCCH_ConfigCommon_v1310 *ext4_pucch; COMMON_channels_t *cc = mac->common_channels;
LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; UE_list_t *UE_list = &mac->UE_list;
struct LTE_N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13; UE_TEMPLATE *UE_template = NULL;
UE_sched_ctrl *ue_sched_ctl = NULL;
nfapi_dl_config_request_pdu_t *dl_config_pdu = NULL;
nfapi_ul_config_request_pdu_t *ul_config_pdu = NULL;
nfapi_tx_request_pdu_t *TX_req = NULL;
nfapi_dl_config_request_body_t *dl_req = NULL;
nfapi_ul_config_request_body_t *ul_req = NULL;
struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = NULL;
struct LTE_PUCCH_ConfigCommon_v1310 *ext4_pucch = NULL;
LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
struct LTE_N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13 = NULL;
int pucchreps[4] = { 1, 1, 1, 1 }; int pucchreps[4] = { 1, 1, 1, 1 };
int n1pucchan[4] = { 0, 0, 0, 0 }; int n1pucchan[4] = { 0, 0, 0, 0 };
uint32_t ackNAK_absSF; uint32_t ackNAK_absSF;
int first_rb; int first_rb;
dl_req = &mac->DL_req[CC_id].dl_config_request_body; dl_req = &(mac->DL_req[CC_id].dl_config_request_body);
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; dl_config_pdu = &(dl_req->dl_config_pdu_list[dl_req->number_pdu]);
if ((frameP&1) == 0) return; /* Return if frame is even */
if ((frameP & 1) == 0) {
return;
}
if (cc[CC_id].mib->message.schedulingInfoSIB1_BR_r13 ==0) return; if (cc[CC_id].mib->message.schedulingInfoSIB1_BR_r13 == 0) {
return;
}
if (cc[CC_id].radioResourceConfigCommon_BR) { if (cc[CC_id].radioResourceConfigCommon_BR) {
ext4_prach = cc[CC_id].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; ext4_prach = cc[CC_id].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
ext4_pucch = cc[CC_id].radioResourceConfigCommon_BR->ext4->pucch_ConfigCommon_v1310; ext4_pucch = cc[CC_id].radioResourceConfigCommon_BR->ext4->pucch_ConfigCommon_v1310;
prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13; pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13;
AssertFatal (prach_ParametersListCE_r13 != NULL, "prach_ParametersListCE_r13 is null\n"); 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"); AssertFatal (pucch_N1PUCCH_AN_InfoList_r13 != NULL, "pucch_N1PUCCH_AN_InfoList_r13 is null\n");
// check to verify CE-Level compatibility in SIB2_BR /* Check to verify CE-Level compatibility in SIB2_BR */
AssertFatal (prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count, "prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n"); AssertFatal (prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count, "prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n");
switch (prach_ParametersListCE_r13->list.count) { switch (prach_ParametersListCE_r13->list.count) {
...@@ -3009,29 +1961,40 @@ schedule_ue_spec_br( ...@@ -3009,29 +1961,40 @@ schedule_ue_spec_br(
} }
} }
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
int harq_pid = 0; int harq_pid = 0;
rnti = UE_RNTI(module_idP,UE_id); rnti = UE_RNTI(module_idP, UE_id);
if (rnti==NOT_A_RNTI) continue;
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; if (rnti==NOT_A_RNTI) {
UE_template = &UE_list->UE_template[CC_id][UE_id]; continue;
}
ue_sched_ctl = &(UE_list->UE_sched_ctrl[UE_id]);
UE_template = &(UE_list->UE_template[CC_id][UE_id]);
if (UE_template->rach_resource_type == 0) {
continue;
}
if (UE_template->rach_resource_type == 0) continue;
uint8_t rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); uint8_t rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
if (rrc_status < RRC_CONNECTED) continue; if (rrc_status < RRC_CONNECTED) {
continue;
}
/* CDRX LTE-M */
if (ue_sched_ctl->cdrx_configured == TRUE) {
if ((ue_sched_ctl->bypass_cdrx == FALSE) && (ue_sched_ctl->in_active_time == FALSE)) {
continue;
}
}
round = ue_sched_ctl->round[CC_id][harq_pid]; round_DL = ue_sched_ctl->round[CC_id][harq_pid];
AssertFatal (UE_template->physicalConfigDedicated != NULL, AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n");
"UE_template->physicalConfigDedicated is null\n"); AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n");
"UE_template->physicalConfigDedicated->ext4 is null\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL,
"UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup,
"UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL,
...@@ -3040,36 +2003,35 @@ schedule_ue_spec_br( ...@@ -3040,36 +2003,35 @@ schedule_ue_spec_br(
LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n");
AssertFatal(epdcch_setconfig_r11->ext2!=NULL, "epdcch_setconfig_r11->ext2 is null\n"); AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n");
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
"epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup,
"epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present==LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup,
"epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n");
AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310!=NULL, AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null");
"epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup,
AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present==LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup,
"epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n");
/* Simple scheduler for 1 repetition, 1 HARQ */
// simple scheduler for 1 repetition, 1 HARQ
if (subframeP == 5) { // MPDCCH if (subframeP == 5) { // MPDCCH
if (round_DL == 8) {
if (round == 8) {
rlc_status.bytes_in_buffer = 0; rlc_status.bytes_in_buffer = 0;
// Now check RLC information to compute number of required RBs
// get maximum TBS size for RLC request /* Now check RLC information to compute number of required RBs */
/* Get maximum TBS size for RLC request */
TBS = get_TBS_DL(9,6); TBS = get_TBS_DL(9,6);
// check first for RLC data on DCCH
// add the length for all the control elements (timing adv, drx, etc) : header + payload /* Check first for RLC data on DCCH */
/* Add the length for all the control elements (timing adv, drx, etc) : header + payload */
if (ue_sched_ctl->ta_timer == 0) { if (ue_sched_ctl->ta_timer == 0) {
ta_update = ue_sched_ctl->ta_update; ta_update = ue_sched_ctl->ta_update;
/* if we send TA then set timer to not send it for a while */ /* If we send TA then set timer to not send it for a while */
if (ta_update != 31) if (ta_update != 31)
ue_sched_ctl->ta_timer = 20; ue_sched_ctl->ta_timer = 20;
/* reset ta_update */ /* Reset ta_update */
ue_sched_ctl->ta_update = 31; ue_sched_ctl->ta_update = 31;
} else { } else {
ta_update = 31; ta_update = 31;
...@@ -3079,10 +2041,10 @@ schedule_ue_spec_br( ...@@ -3079,10 +2041,10 @@ schedule_ue_spec_br(
header_len_dcch = 2; // 2 bytes DCCH SDU subheader header_len_dcch = 2; // 2 bytes DCCH SDU subheader
if ( TBS-ta_len-header_len_dcch > 0 ) { if (TBS - ta_len-header_len_dcch > 0 ) {
LOG_I(MAC,"Calling mac_rlc_status_ind for DCCH\n"); LOG_I(MAC,"Calling mac_rlc_status_ind for DCCH\n");
rlc_status = mac_rlc_status_ind(
module_idP, rlc_status = mac_rlc_status_ind(module_idP,
rnti, rnti,
module_idP, module_idP,
frameP, frameP,
...@@ -3090,17 +2052,20 @@ schedule_ue_spec_br( ...@@ -3090,17 +2052,20 @@ schedule_ue_spec_br(
ENB_FLAG_YES, ENB_FLAG_YES,
MBMS_FLAG_NO, MBMS_FLAG_NO,
DCCH, DCCH,
(TBS-ta_len-header_len_dcch) (TBS-ta_len-header_len_dcch),
,0, 0 0,
); // transport block set size 0); // transport block set size
sdu_lengths[0]=0; sdu_lengths[0] = 0;
if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit
LOG_I(MAC,"[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", LOG_I(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, module_idP,
frameP,
CC_id,
TBS-header_len_dcch);
sdu_lengths[0] = mac_rlc_data_req(module_idP,
rnti, rnti,
module_idP, module_idP,
frameP, frameP,
...@@ -3108,14 +2073,25 @@ schedule_ue_spec_br( ...@@ -3108,14 +2073,25 @@ schedule_ue_spec_br(
MBMS_FLAG_NO, MBMS_FLAG_NO,
DCCH, DCCH,
TBS, //not used TBS, //not used
(char *)&dlsch_buffer[0] (char *)&dlsch_buffer[0],
,0, 0 0,
); 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]));
T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), LOG_I(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",
T_INT(harq_pid), T_INT(DCCH), T_INT(sdu_lengths[0])); module_idP,
CC_id,
sdu_lengths[0]);
LOG_I(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_length_total = sdu_lengths[0];
sdu_lcids[0] = DCCH; 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_pdu_tx[DCCH]+=1;
...@@ -3127,27 +2103,30 @@ schedule_ue_spec_br( ...@@ -3127,27 +2103,30 @@ schedule_ue_spec_br(
} }
} }
// check for DCCH1 and update header information (assume 2 byte sub-header) /* Check for DCCH1 and update header information (assume 2 byte sub-header) */
if (TBS-ta_len-header_len_dcch-sdu_length_total > 0 ) { if (TBS - ta_len-header_len_dcch - sdu_length_total > 0) {
rlc_status = mac_rlc_status_ind( rlc_status = mac_rlc_status_ind(module_idP,
module_idP,
rnti, rnti,
module_idP, module_idP,
frameP, frameP,
subframeP, subframeP,
ENB_FLAG_YES, ENB_FLAG_YES,
MBMS_FLAG_NO, MBMS_FLAG_NO,
DCCH+1, DCCH + 1,
(TBS-ta_len-header_len_dcch-sdu_length_total) (TBS-ta_len-header_len_dcch-sdu_length_total),
,0, 0); // transport block set size less allocations for timing advance and 0,
// DCCH SDU 0); // transport block set size less allocations for timing advance and DCCH SDU
sdu_lengths[num_sdus] = 0; sdu_lengths[num_sdus] = 0;
if (rlc_status.bytes_in_buffer > 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", 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, module_idP,
frameP,
CC_id,
TBS-header_len_dcch - sdu_length_total);
sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP,
rnti, rnti,
module_idP, module_idP,
frameP, frameP,
...@@ -3155,36 +2134,47 @@ schedule_ue_spec_br( ...@@ -3155,36 +2134,47 @@ schedule_ue_spec_br(
MBMS_FLAG_NO, MBMS_FLAG_NO,
DCCH+1, DCCH+1,
TBS, //not used TBS, //not used
(char *)&dlsch_buffer[sdu_length_total] (char *)&dlsch_buffer[sdu_length_total],
,0, 0 0,
); 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(T_ENB_MAC_UE_DL_SDU,
T_INT(harq_pid), T_INT(DCCH+1), T_INT(sdu_lengths[num_sdus])); 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_lcids[num_sdus] = DCCH1;
sdu_length_total += sdu_lengths[num_sdus]; sdu_length_total += sdu_lengths[num_sdus];
header_len_dcch += 2; 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_pdu_tx[DCCH1] += 1;
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1]+=sdu_lengths[num_sdus]; UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus];
num_sdus++; num_sdus++;
} }
} }
// assume the max dtch header size, and adjust it later /* Assume the max dtch header size, and adjust it later */
header_len_dtch=0; header_len_dtch = 0;
header_len_dtch_last=0; // the header length of the last mac sdu header_len_dtch_last = 0; // the header length of the last mac sdu
// lcid has to be sorted before the actual allocation (similar struct as ue_list).
for (lcid=NB_RB_MAX-1; lcid>=DTCH ; lcid--){ /* lcid has to be sorted before the actual allocation (similar struct as ue_list) */
// TBD: check if the lcid is active for (lcid = NB_RB_MAX-1; lcid >= DTCH ; lcid--){
/* TBD: check if the lcid is active */
header_len_dtch += 3;
header_len_dtch_last = 3;
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", LOG_D(MAC,"[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
module_idP,frameP,lcid,TBS, module_idP,
TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); 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 ? if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ?
rlc_status = mac_rlc_status_ind(module_idP, rlc_status = mac_rlc_status_ind(module_idP,
rnti, rnti,
module_idP, module_idP,
...@@ -3193,14 +2183,31 @@ schedule_ue_spec_br( ...@@ -3193,14 +2183,31 @@ schedule_ue_spec_br(
ENB_FLAG_YES, ENB_FLAG_YES,
MBMS_FLAG_NO, MBMS_FLAG_NO,
lcid, lcid,
TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch,
,0, 0); 0,
0);
if (rlc_status.bytes_in_buffer > 0) { if (rlc_status.bytes_in_buffer > 0) {
/* RRC inactivity LTE-M */
/* Reset RRC inactivity timer after uplane activity */
ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti);
if (ue_contextP != NULL) {
ue_contextP->ue_context.ue_rrc_inactivity_timer = 1;
} else {
LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n",
module_idP,
CC_id,
rnti);
}
LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", LOG_I(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); 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, sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
rnti, rnti,
module_idP, module_idP,
...@@ -3209,12 +2216,25 @@ schedule_ue_spec_br( ...@@ -3209,12 +2216,25 @@ schedule_ue_spec_br(
MBMS_FLAG_NO, MBMS_FLAG_NO,
lcid, lcid,
TBS, //not used TBS, //not used
(char*)&dlsch_buffer[sdu_length_total] (char*) &dlsch_buffer[sdu_length_total],
,0, 0); 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), 0);
T_INT(harq_pid), T_INT(lcid), T_INT(sdu_lengths[num_sdus]));
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_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
module_idP,
sdu_lengths[num_sdus],
lcid);
LOG_I(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_lcids[num_sdus] = lcid;
sdu_length_total += sdu_lengths[num_sdus]; sdu_length_total += sdu_lengths[num_sdus];
...@@ -3222,55 +2242,56 @@ schedule_ue_spec_br( ...@@ -3222,55 +2242,56 @@ schedule_ue_spec_br(
header_len_dtch--; header_len_dtch--;
header_len_dtch_last--; header_len_dtch_last--;
} }
num_sdus++; num_sdus++;
} // no data for this LCID } else { // no data for this LCID
else { header_len_dtch -= 3;
header_len_dtch-=3;
} }
} // no TBS left } else { // no TBS left
else { header_len_dtch -= 3;
header_len_dtch-=3;
break; break;
} }
} // for loop LCID
if (header_len_dtch == 0) {
header_len_dtch_last = 0;
} }
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 /* There is at least one SDU */
// Assume RAH format 2 if ((sdu_length_total + header_len_dcch + header_len_dtch) > 0) {
// adjust header lengths /* 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_dcch_tmp = header_len_dcch;
header_len_dtch_tmp = header_len_dtch; 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 if (header_len_dtch == 0) {
header_len_dcch = (header_len_dcch > 0) ? 1 : 0; // remove length field
} else { } 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_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 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 = 9; mcs = 9;
// decrease mcs until TBS falls below required length /* Decrease mcs until TBS falls below required length */
while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) { while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) {
mcs--; mcs--;
TBS = get_TBS_DL(mcs,6); TBS = get_TBS_DL(mcs,6);
} }
// if we have decreased too much or we don't have enough RBs, increase MCS /* 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)) { while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) {
mcs++; mcs++;
TBS = get_TBS_DL(mcs,6); TBS = get_TBS_DL(mcs,6);
} }
//#ifdef DEBUG_eNB_SCHEDULER LOG_I(MAC, "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n",
LOG_I(MAC,"[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", module_idP,
module_idP,CC_id,mcs,TBS,6); CC_id,
// msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", mcs,
// TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); TBS,
6);
if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { 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); padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len);
...@@ -3278,17 +2299,16 @@ schedule_ue_spec_br( ...@@ -3278,17 +2299,16 @@ schedule_ue_spec_br(
} else { } else {
padding = 0; padding = 0;
// adjust the header len /* Adjust the header len */
if (header_len_dtch==0) { if (header_len_dtch == 0) {
header_len_dcch = header_len_dcch_tmp; header_len_dcch = header_len_dcch_tmp;
} else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) } else { // if ((header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2)))
header_len_dtch = header_len_dtch_tmp; 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 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], offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
num_sdus, //num_sdus num_sdus, //num_sdus
sdu_lengths, // sdu_lengths, //
...@@ -3301,84 +2321,116 @@ schedule_ue_spec_br( ...@@ -3301,84 +2321,116 @@ schedule_ue_spec_br(
if (ta_update != 31) { if (ta_update != 31) {
LOG_D(MAC, LOG_D(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",
"[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,
module_idP,frameP, UE_id, CC_id, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset, frameP,
ta_update,padding,post_padding,mcs,TBS,6,header_len_dcch,header_len_dtch); UE_id,
CC_id,
sdu_length_total,
num_sdus,
sdu_lengths[0],
sdu_lcids[0],
offset,
ta_update,
padding,
post_padding,
mcs,
TBS,
6,
header_len_dcch,
header_len_dtch);
} }
/* 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);
/* Fill remainder of DLSCH with random data */
// cycle through SDUs and place in dlsch_buffer for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total); UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char)(taus()&0xff);
// 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) { if (opt_enabled == 1) {
trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], trace_pdu(1,
TBS, module_idP, 3, UE_RNTI(module_idP,UE_id), (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
mac->frame, mac->subframe,0,0); TBS,
module_idP,
3,
UE_RNTI(module_idP,UE_id),
mac->frame,
mac->subframe,
0,
0);
LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", 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); 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(T_ENB_MAC_UE_DL_PDU_WITH_DATA,
T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); T_INT(module_idP),
T_INT(CC_id),
// do PUCCH power control T_INT(rnti),
// this is the normalized RX power T_INT(frameP),
T_INT(subframeP),
T_INT(harq_pid),
T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS));
/* Do PUCCH power control */
/* This is the normalized RX power */
/* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */
normalized_rx_power = (5*ue_sched_ctl->pucch1_snr[CC_id]-640)/10+30; normalized_rx_power = (5 * ue_sched_ctl->pucch1_snr[CC_id]-640) / 10 + 30;
target_rx_power = mac->puCch10xSnr/10+30; target_rx_power = mac->puCch10xSnr / 10 + 30;
// this assumes accumulated tpc /* This assumes accumulated tpc */
// make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out /* 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; 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 (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case
((framex10psubframe > (frameP * 10 + subframeP)) &&
(((10240 - framex10psubframe +frameP * 10 + subframeP) >= 10)))) { // frame wrap-around
if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) {
ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; ue_sched_ctl->pucch1_cqi_update[CC_id] = 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_frame = frameP;
UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP; UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP;
if (normalized_rx_power>(target_rx_power+4)) { if (normalized_rx_power > (target_rx_power + 4)) {
tpc = 0; //-1 tpc = 0; //-1
} else if (normalized_rx_power<(target_rx_power-4)) { } else if (normalized_rx_power<(target_rx_power - 4)) {
tpc = 2; //+1 tpc = 2; //+1
} else { } else {
tpc = 1; //0 tpc = 1; //0
} }
LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n",
module_idP,frameP, subframeP,harq_pid,tpc, module_idP,
normalized_rx_power,target_rx_power); frameP,
subframeP,
} // Po_PUCCH has been updated harq_pid,
else { tpc,
tpc = 1; //0 normalized_rx_power,
} // time to do TPC update target_rx_power);
else { } else { // Po_PUCCH has been updated
tpc = 1; // 0
}
} else { // time to do TPC update
tpc = 1; //0 tpc = 1; //0
} }
// Toggle NDI in first round // Toggle NDI in first round
UE_template->oldNDI[harq_pid] = 1-UE_template->oldNDI[harq_pid]; UE_template->oldNDI[harq_pid] = 1 - UE_template->oldNDI[harq_pid];
ue_sched_ctl->round[CC_id][harq_pid] = 0; ue_sched_ctl->round[CC_id][harq_pid] = 0;
round=0; round_DL = 0;
} // if ((sdu_length_total + header_len_dcch + header_len_dtch) > 0)
} }
} if (round_DL < 8) {
/* Fill in MDPDCCH */
if (round < 8) {
// fill in MDPDCCH
memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t)); 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_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 11 : 10; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 11 : 10;
...@@ -3386,7 +2438,8 @@ schedule_ue_spec_br( ...@@ -3386,7 +2438,8 @@ schedule_ue_spec_br(
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; 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.resource_block_assignment = 0; // Note: this can be dynamic
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = epdcch_setconfig_r11->transmissionType_r11; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = epdcch_setconfig_r11->transmissionType_r11;
AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11!=NULL,
AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL,
"UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n");
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
...@@ -3401,7 +2454,7 @@ schedule_ue_spec_br( ...@@ -3401,7 +2454,7 @@ schedule_ue_spec_br(
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | ((epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1)<<5); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | ((epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1)<<5);
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 9; // adjust according to size of RAR, 208 bits with N1A_PRB=3 dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 9; // adjust according to size of RAR, 208 bits with N1A_PRB=3
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 0; // fix to 4 for now dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 0; // fix to 4 for now
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = rvseq[round&3]; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = rvseq[round_DL&3];
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = UE_template->oldNDI[harq_pid]; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = UE_template->oldNDI[harq_pid];
dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 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_length = 0;
...@@ -3428,18 +2481,25 @@ schedule_ue_spec_br( ...@@ -3428,18 +2481,25 @@ schedule_ue_spec_br(
dl_req->number_pdu++; dl_req->number_pdu++;
UE_template->mcs[harq_pid] = dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs; UE_template->mcs[harq_pid] = dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs;
} }
} } else if ((subframeP == 7) && (round_DL < 8)) { // DLSCH
else if ((subframeP == 7)&&(round<8)) { // DLSCH
int absSF = (frameP * 10) + subframeP; int absSF = (frameP * 10) + subframeP;
// Have to check that MPDCCH was generated /* Have to check that MPDCCH was generated */
LOG_I (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating DLSCH (ce_level %d RNTI %x)\n", LOG_I (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating DLSCH (ce_level %d RNTI %x)\n",
module_idP, CC_id, frameP, subframeP, UE_template->rach_resource_type - 1,rnti); module_idP,
CC_id,
frameP,
subframeP,
UE_template->rach_resource_type - 1,
rnti);
first_rb = narrowband_to_first_rb(&cc[CC_id], epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1);
first_rb = narrowband_to_first_rb (&cc[CC_id], epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1);
dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 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)); 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_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_dlsch_pdu)); dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_dlsch_pdu));
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_id]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_id];
...@@ -3464,9 +2524,7 @@ schedule_ue_spec_br( ...@@ -3464,9 +2524,7 @@ schedule_ue_spec_br(
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; 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.num_bf_vector = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (UE_template->rach_resource_type < 3) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (UE_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.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.initial_transmission_sf_io = (10 * frameP) + subframeP;
...@@ -3476,8 +2534,7 @@ schedule_ue_spec_br( ...@@ -3476,8 +2534,7 @@ schedule_ue_spec_br(
// DL request // DL request
mac->TX_req[CC_id].sfn_sf = (frameP << 4) + subframeP; mac->TX_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
TX_req = &mac->TX_req[CC_id].tx_request_body.tx_pdu_list[mac->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req = &mac->TX_req[CC_id].tx_request_body.tx_pdu_list[mac->TX_req[CC_id].tx_request_body.number_of_pdus];
TX_req->pdu_length = get_TBS_DL(UE_template->mcs[harq_pid], TX_req->pdu_length = get_TBS_DL(UE_template->mcs[harq_pid], 6);
6);
TX_req->pdu_index = mac->pdu_index[CC_id]++; TX_req->pdu_index = mac->pdu_index[CC_id]++;
TX_req->num_segments = 1; TX_req->num_segments = 1;
TX_req->segments[0].segment_length = TX_req->pdu_length; TX_req->segments[0].segment_length = TX_req->pdu_length;
...@@ -3508,18 +2565,39 @@ schedule_ue_spec_br( ...@@ -3508,18 +2565,39 @@ schedule_ue_spec_br(
} else { } else {
AssertFatal (1 == 0, "PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n"); AssertFatal (1 == 0, "PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n");
} }
ul_req->number_of_pdus++; ul_req->number_of_pdus++;
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 (0 /*harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TX_req->pdu_length)); 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 (0 /* harq_pid always 0? */ ),
T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TX_req->pdu_length));
if (opt_enabled == 1) { if (opt_enabled == 1) {
trace_pdu (1, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0], TX_req->pdu_length , UE_id, 3, rnti, frameP, subframeP, 0, 0); trace_pdu(1,
LOG_D (OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", module_idP, CC_id, frameP, rnti, TX_req->pdu_length ); (uint8_t *) mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0],
} TX_req->pdu_length,
UE_id,
3,
rnti,
frameP,
subframeP,
0,
0);
LOG_D(OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n",
module_idP,
CC_id,
frameP,
rnti,
TX_req->pdu_length);
} }
} } // end else if ((subframeP == 7) && (round_DL < 8))
} // end loop on UE_id
} }
#endif #endif
......
...@@ -1909,126 +1909,165 @@ schedule_ulsch_rnti(module_id_t module_idP, ...@@ -1909,126 +1909,165 @@ schedule_ulsch_rnti(module_id_t module_idP,
} }
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
//-----------------------------------------------------------------------------
/*
* default ULSCH scheduler for LTE-M
*/
void schedule_ulsch_rnti_emtc(module_id_t module_idP, void schedule_ulsch_rnti_emtc(module_id_t module_idP,
frame_t frameP, frame_t frameP,
sub_frame_t subframeP, sub_frame_t subframeP,
unsigned char sched_subframeP, int sched_subframeP,
int *emtc_active) int *emtc_active)
//-----------------------------------------------------------------------------
{ {
int UE_id; int UE_id = -1;
rnti_t rnti = -1; rnti_t rnti = -1;
uint8_t round = 0; uint8_t round_UL = 0;
uint8_t harq_pid = 0; uint8_t harq_pid = 0;
uint8_t status = 0; uint8_t status = 0;
uint32_t cshift,ndi; uint32_t cshift = 0;
int32_t normalized_rx_power; uint32_t ndi = 0;
int32_t target_rx_power=-90; int32_t normalized_rx_power = 0;
int n; int32_t target_rx_power = -90;
int n = 0;
int CC_id = 0; int CC_id = 0;
int N_RB_UL; int N_RB_UL = 0;
int sched_frame = frameP;
int rvidx_tab[4] = {0,2,3,1};
int tpc = 0;
int cqi_req = 0;
eNB_MAC_INST *eNB = RC.mac[module_idP]; eNB_MAC_INST *eNB = RC.mac[module_idP];
COMMON_channels_t *cc = eNB->common_channels; COMMON_channels_t *cc = eNB->common_channels;
UE_list_t *UE_list=&eNB->UE_list; UE_list_t *UE_list = &(eNB->UE_list);
UE_TEMPLATE *UE_template; UE_TEMPLATE *UE_template = NULL;
UE_sched_ctrl *UE_sched_ctrl; UE_sched_ctrl *UE_sched_ctrl = NULL;
int sched_frame=frameP;
int rvidx_tab[4] = {0,2,3,1};
int tpc=0;
int cqi_req=0;
if (sched_subframeP<subframeP) sched_frame++; if (sched_subframeP < subframeP) {
sched_frame++;
}
nfapi_hi_dci0_request_body_t *hi_dci0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; nfapi_hi_dci0_request_body_t *hi_dci0_req = &(eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body);
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = NULL;
nfapi_ul_config_request_body_t *ul_req_tmp = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body; nfapi_ul_config_request_body_t *ul_req_tmp = &(eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body);
// loop over all active UEs /* If frameP odd don't schedule */
if ((frameP&1) == 1) return; if ((frameP & 1) == 1) {
return;
}
for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) { /* Loop over all active UEs */
for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
UE_template = &(UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]);
if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].rach_resource_type == 0) continue; /* LTE-M device */
if (UE_template->rach_resource_type == 0) {
continue;
}
// don't schedule if Msg4 is not received yet /* Don't schedule if Msg4 is not received yet */
if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) { if (UE_template->configured == FALSE) {
LOG_D(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", LOG_D(MAC,"[eNB %d] frame %d subframe %d, UE %d: not configured, skipping UE scheduling \n",
module_idP,frameP,subframeP,UE_id); module_idP,
frameP,
subframeP,
UE_id);
continue; continue;
} }
rnti = UE_RNTI(module_idP,UE_id); rnti = UE_RNTI(module_idP, UE_id);
if (rnti == NOT_A_RNTI) {
LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d: no RNTI \n",
module_idP,
frameP,
subframeP,
UE_id);
if (rnti==NOT_A_RNTI) {
LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id);
continue; continue;
} }
// loop over all active UL CC_ids for this UE /* CDRX LTE-M */
for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { UE_sched_ctrl = &(UE_list->UE_sched_ctrl[UE_id]);
// This is the actual CC_id in the list if (UE_sched_ctrl->cdrx_configured == TRUE) {
if ((UE_sched_ctrl->bypass_cdrx == FALSE) && (UE_sched_ctrl->in_active_time == FALSE)) {
continue;
}
}
/* Loop over all active UL CC_ids for this UE */
for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
/* This is the actual CC_id in the list */
CC_id = UE_list->ordered_ULCCids[n][UE_id]; CC_id = UE_list->ordered_ULCCids[n][UE_id];
N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth);
UE_template = &(UE_list->UE_template[CC_id][UE_id]);
UE_template = &UE_list->UE_template[CC_id][UE_id];
UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
harq_pid = 0; harq_pid = 0;
round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; round_UL = UE_sched_ctrl->round_UL[CC_id][harq_pid];
AssertFatal(round<8,"round %d > 7 for UE %d/%x\n",round,UE_id,rnti);
AssertFatal(round_UL < 8,"round_UL %d > 7 for UE %d/%x\n",
round_UL,
UE_id,
rnti);
LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for BL/CE UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for BL/CE UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n",
module_idP,frameP,subframeP,harq_pid,UE_id,rnti,CC_id, 24,N_RB_UL); module_idP,
frameP,
subframeP,
harq_pid,
UE_id,
rnti,
CC_id,
24, // agregation level
N_RB_UL);
RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->estimated_ul_buffer; RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->estimated_ul_buffer;
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template->estimated_ul_buffer);
if ((UE_template->ul_SR >0 || round > 0 || status < RRC_CONNECTED)&&(subframeP==5))
// if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames
{
LOG_I(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n",
module_idP,harq_pid,frameP,subframeP,UE_id,rnti,round,UE_template->ul_SR,
UE_sched_ctrl->ul_inactivity_timer,
UE_sched_ctrl->ul_failure_timer, if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == 5)) {
/*
* if there is information on bsr of DCCH, DTCH,
* or if there is UL_SR,
* or if there is a packet to retransmit,
* or we want to schedule a periodic feedback every frame
*/
LOG_I(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round_UL %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n",
module_idP,
harq_pid,
frameP,
subframeP,
UE_id,
rnti,
round_UL,
UE_template->ul_SR,
UE_sched_ctrl->ul_inactivity_timer,
UE_sched_ctrl->ul_failure_timer,
UE_sched_ctrl->cqi_req_timer); UE_sched_ctrl->cqi_req_timer);
// reset the scheduling request
emtc_active[CC_id]=1; /* Reset the scheduling request */
emtc_active[CC_id] = 1;
UE_template->ul_SR = 0; UE_template->ul_SR = 0;
status = mac_eNB_get_rrc_status(module_idP,rnti); status = mac_eNB_get_rrc_status(module_idP,rnti);
/*
if (status < RRC_CONNECTED)
cqi_req = 0; cqi_req = 0;
else if (UE_sched_ctrl->cqi_req_timer>300) {
cqi_req = 1;
UE_sched_ctrl->cqi_req_timer=0;
} /* Power control: compute the expected ULSCH RX power (for the stats) */
else /* This is the normalized RX power and this should be constant (regardless of mcs) */
cqi_req = 0;
*/
cqi_req = 0;
//power control
//compute the expected ULSCH RX power (for the stats)
// this is the normalized RX power and this should be constant (regardless of mcs
normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id];
target_rx_power = 178; target_rx_power = 178;
// this assumes accumulated tpc /* This assumes accumulated tpc */
// make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */
int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe; int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe;
if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case
((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) // frame wrap-around
{ {
UE_template->pusch_tpc_tx_frame=frameP; UE_template->pusch_tpc_tx_frame = frameP;
UE_template->pusch_tpc_tx_subframe=subframeP; UE_template->pusch_tpc_tx_subframe = subframeP;
if (normalized_rx_power>(target_rx_power+4)) { if (normalized_rx_power > (target_rx_power + 4)) {
tpc = 0; //-1 tpc = 0; //-1
UE_sched_ctrl->tpc_accumulated[CC_id]--; UE_sched_ctrl->tpc_accumulated[CC_id]--;
} else if (normalized_rx_power<(target_rx_power-4)) { } else if (normalized_rx_power < (target_rx_power - 4)) {
tpc = 2; //+1 tpc = 2; //+1
UE_sched_ctrl->tpc_accumulated[CC_id]++; UE_sched_ctrl->tpc_accumulated[CC_id]++;
} else { } else {
...@@ -2037,103 +2076,116 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2037,103 +2076,116 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
} else { } else {
tpc = 1; //0 tpc = 1; //0
} }
//tpc = 1;
if (tpc != 1) {
if (tpc!=1) {
LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", LOG_D(MAC,"[eNB %d] ULSCH 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, module_idP,
UE_sched_ctrl->tpc_accumulated[CC_id],normalized_rx_power,target_rx_power); frameP,
subframeP,
harq_pid,
tpc,
UE_sched_ctrl->tpc_accumulated[CC_id],
normalized_rx_power,
target_rx_power);
} }
// new transmission /* New transmission */
if (round==0) { if (round_UL == 0) {
ndi = 1-UE_template->oldNDI_UL[harq_pid];
UE_template->oldNDI_UL[harq_pid]=ndi;
UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power;
UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power;
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=4;
UE_template->mcs_UL[harq_pid] = 4;
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=UE_template->mcs_UL[harq_pid]; /* CDRX LTE-M */
// buffer_occupancy = UE_template->ul_total_buffer; if (UE_sched_ctrl->cdrx_configured == TRUE) {
UE_sched_ctrl->drx_inactivity_timer = 1; // reset drx inactivity timer when new transmission
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) UE_sched_ctrl->drx_inactivity_timer);
}
ndi = 1 - UE_template->oldNDI_UL[harq_pid];
UE_template->oldNDI_UL[harq_pid] = ndi;
UE_template->mcs_UL[harq_pid] = 4;
UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], 6);
UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],6); UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power;
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=6; UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power;
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid]; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = 4;
// buffer_occupancy -= TBS; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid];
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += 6;
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid];
T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T(T_ENB_MAC_UE_UL_SCHEDULE,
T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(0), T_INT(6), T_INT(module_idP),
T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); T_INT(CC_id),
T_INT(rnti),
T_INT(frameP),
T_INT(subframeP),
T_INT(harq_pid),
T_INT(UE_template->mcs_UL[harq_pid]),
T_INT(0),
T_INT(6),
T_INT(UE_template->TBS_UL[harq_pid]),
T_INT(ndi));
// bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) /* Store for possible retransmission */
//store for possible retransmission
UE_template->nb_rb_ul[harq_pid] = 6; UE_template->nb_rb_ul[harq_pid] = 6;
UE_sched_ctrl->ul_scheduled |= (1 << harq_pid);
if (UE_id == UE_list->head) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, UE_sched_ctrl->ul_scheduled);
}
UE_sched_ctrl->ul_scheduled |= (1<<harq_pid); /* Adjust total UL buffer status by TBS, wait for UL sdus to do final update */
if (UE_id == UE_list->head)
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled);
// adjust total UL buffer status by TBS, wait for UL sdus to do final update
UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid]; UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid];
LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes); LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes);
/* Cyclic shift for DMRS */
// Cyclic shift for DM RS cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) /* save it for a potential retransmission */
// save it for a potential retransmission
UE_template->cshift[harq_pid] = cshift; UE_template->cshift[harq_pid] = cshift;
AssertFatal (UE_template->physicalConfigDedicated != NULL, AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n");
"UE_template->physicalConfigDedicated is null\n"); AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n");
"UE_template->physicalConfigDedicated->ext4 is null\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL,
"UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup,
"UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL,
"UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n");
LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n");
AssertFatal(epdcch_setconfig_r11->ext2!=NULL, "epdcch_setconfig_r11->ext2 is null\n"); AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n");
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
"epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup,
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL,
"epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present==LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup,
"epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n");
AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310!=NULL, AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null");
"epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup,
AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present==LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup,
"epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n");
LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n", LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS MPDCCH Narrowband %d\n",
harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,(int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); harq_pid,
frameP,
subframeP,
UE_id,
rnti,
sched_frame,
sched_subframeP,
(int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1);
UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1);
UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci + hi_dci0_req->number_of_hi]);
epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); memset((void*) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi];
memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE;
hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted
AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11!=NULL, AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL,
"UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n");
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
...@@ -2141,18 +2193,19 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2141,18 +2193,19 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; // already set above...
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000; // 0dB hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000; // 0dB
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid];
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB = 3
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0;
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13==
LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off,
"epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n");
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1-epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = 0; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = 0;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid];
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = 0; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = 0;
...@@ -2169,11 +2222,15 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2169,11 +2222,15 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
hi_dci0_req->number_of_dci++; hi_dci0_req->number_of_dci++;
LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG. Request for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS mpdcch narrowband %d\n",
LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS mpdcch narrowband %d\n", harq_pid,
harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP, frameP,
(int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); subframeP,
UE_id,
rnti,
sched_frame,
sched_subframeP,
(int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1);
fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
cqi_req, cqi_req,
...@@ -2189,19 +2246,19 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2189,19 +2246,19 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
0, // frequency_hopping_enabled_flag 0, // frequency_hopping_enabled_flag
0, // frequency_hopping_bits 0, // frequency_hopping_bits
UE_template->oldNDI_UL[harq_pid], // new_data_indication UE_template->oldNDI_UL[harq_pid], // new_data_indication
rvidx_tab[round&3], // redundancy_version rvidx_tab[round_UL&3], // redundancy_version
harq_pid, // harq_process_number harq_pid, // harq_process_number
0, // ul_tx_mode 0, // ul_tx_mode
0, // current_tx_nb 0, // current_tx_nb
0, // n_srs 0, // n_srs
UE_template->TBS_UL[harq_pid] UE_template->TBS_UL[harq_pid]
); );
fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
UE_template->rach_resource_type>2 ? 2 : 1,
1, //total_number_of_repetitions
1, //repetition_number
(frameP*10)+subframeP);
fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
UE_template->rach_resource_type > 2 ? 2 : 1,
1, // total_number_of_repetitions
1, // repetition_number
(frameP * 10) + subframeP);
ul_req_tmp->number_of_pdus++; ul_req_tmp->number_of_pdus++;
eNB->ul_handle++; eNB->ul_handle++;
...@@ -2212,57 +2269,73 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2212,57 +2269,73 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
subframeP, subframeP,
S_UL_SCHEDULED); S_UL_SCHEDULED);
LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id); LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n",
module_idP,
} CC_id,
else { // round > 0 => retransmission frameP,
T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), subframeP,
T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(0), T_INT(6), UE_id);
T_INT(round));
AssertFatal (UE_template->physicalConfigDedicated != NULL, } else { // round_UL > 0 => retransmission
"UE_template->physicalConfigDedicated is null\n"); /* In LTE-M the UL HARQ process is asynchronous */
AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION,
"UE_template->physicalConfigDedicated->ext4 is null\n"); T_INT(module_idP),
AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, T_INT(CC_id),
"UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); T_INT(rnti),
T_INT(frameP),
T_INT(subframeP),
T_INT(harq_pid),
T_INT(UE_template->mcs_UL[harq_pid]),
T_INT(0),
T_INT(6),
T_INT(round_UL));
AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup,
"UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n");
AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL,
"UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n");
LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n");
AssertFatal(epdcch_setconfig_r11->ext2!=NULL, "epdcch_setconfig_r11->ext2 is null\n"); AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n");
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
"epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup,
"epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present==LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup,
"epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n");
AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310!=NULL, AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null");
"epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup,
AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present==LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup,
"epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n");
LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n", LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n",
harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,(int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); harq_pid,
frameP,
subframeP,
UE_id,
rnti,
sched_frame,
sched_subframeP,
(int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1);
UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb(cc, epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1);
hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]);
UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, memset((void*) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1);
hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi];
memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE;
hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted
AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11!=NULL, AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL,
"UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n");
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
...@@ -2278,11 +2351,12 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2278,11 +2351,12 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0;
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13==
LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off,
"epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n");
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1-epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = rvidx_tab[round&3]; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = rvidx_tab[round_UL&3];
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid];
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = harq_pid; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = harq_pid;
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc;
...@@ -2297,6 +2371,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2297,6 +2371,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1;
hi_dci0_req->number_of_dci++; hi_dci0_req->number_of_dci++;
fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
cqi_req, cqi_req,
cc, cc,
...@@ -2311,22 +2386,22 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, ...@@ -2311,22 +2386,22 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
0, // frequency_hopping_enabled_flag 0, // frequency_hopping_enabled_flag
0, // frequency_hopping_bits 0, // frequency_hopping_bits
UE_template->oldNDI_UL[harq_pid], // new_data_indication UE_template->oldNDI_UL[harq_pid], // new_data_indication
rvidx_tab[round&3], // redundancy_version rvidx_tab[round_UL&3], // redundancy_version
harq_pid, // harq_process_number harq_pid, // harq_process_number
0, // ul_tx_mode 0, // ul_tx_mode
0, // current_tx_nb 0, // current_tx_nb
0, // n_srs 0, // n_srs
UE_template->TBS_UL[harq_pid] UE_template->TBS_UL[harq_pid]
); );
fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
UE_template->rach_resource_type>2 ? 2 : 1, UE_template->rach_resource_type>2 ? 2 : 1,
1, //total_number_of_repetitions 1, //total_number_of_repetitions
1, //repetition_number 1, //repetition_number
(frameP*10)+subframeP); (frameP * 10) + subframeP);
ul_req_tmp->number_of_pdus++; ul_req_tmp->number_of_pdus++;
eNB->ul_handle++; eNB->ul_handle++;
} }
} // UE_is_to_be_scheduled } // UE_is_to_be_scheduled
} // ULCCs } // ULCCs
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment