diff --git a/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c index 7435194d33..a4fbac6de2 100644 --- a/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c @@ -86,7 +86,6 @@ schedule_ue_spec_default( //TODO uint8_t CC_id; int UE_id; - uint16_t nCCE[MAX_NUM_CCs]; int N_RBG[MAX_NUM_CCs]; unsigned char aggregation; mac_rlc_status_resp_t rlc_status; @@ -103,9 +102,8 @@ schedule_ue_spec_default( // uint8_t dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // unsigned char rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBG_MAX]; // uint16_t pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - int mcs; + int mcs, mcs_tmp; uint16_t min_rb_unit[MAX_NUM_CCs]; - short ta_update = 0; eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id]; UE_list_t *UE_list = &eNB->UE_list; LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; @@ -144,15 +142,18 @@ schedule_ue_spec_default( for (CC_id=0; CC_idget_lte_frame_parms(mod_id, CC_id); - //total_nb_available_rb[CC_id] = frame_parms[CC_id]->N_RB_DL - nb_rb_used[CC_id]; - //nCCE[CC_id] = mac_xface->get_nCCE_max(mod_id, CC_id) - nCCE_used[CC_id]; + // get number of PRBs less those used by common channels + total_nb_available_rb[CC_id] = frame_parms[CC_id]->N_RB_DL; + for (i=0;iN_RB_DL;i++) + if (eNB->common_channels[CC_id].vrb_map[i]!=0) + total_nb_available_rb[CC_id]--; + N_RBG[CC_id] = frame_parms[CC_id]->N_RBG; // 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].available_ncces = nCCE[CC_id]; eNB->eNB_stats[CC_id].dlsch_bytes_tx=0; eNB->eNB_stats[CC_id].dlsch_pdus_tx=0; } @@ -192,15 +193,17 @@ schedule_ue_spec_default( continue_flag=1; } - if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || (nCCE[CC_id] < (1<pre_nb_available_rbs[CC_id], nCCE[CC_id], aggregation); + if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated + CCE_allocation_infeasible(mod_id, CC_id, 0, subframe, aggregation, rnti) + ) { + LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", + mod_id, frame, UE_id, CC_id); //if(mac_xface->get_transmission_mode(module_idP,rnti)==5) continue_flag=1; //to next user (there might be rbs availiable for other UEs in TM5 // else // break; } - + if (frame_parms[CC_id]->frame_type == TDD) { set_ue_dai (subframe, frame_parms[CC_id]->tdd_config, @@ -233,6 +236,8 @@ schedule_ue_spec_default( nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; harq_pid = ue_sched_ctl->harq_pid[CC_id]; round = ue_sched_ctl->round[CC_id]; + + /* TODO: Must add these stats (probably in the apply_scheduling function) */ //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(mod_id, rnti); //UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; @@ -248,15 +253,18 @@ schedule_ue_spec_default( */ mcs = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]]; + + /*TODO: Must also update these stats*/ //eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]]; //eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); #ifdef EXMIMO - // if (mac_xface->get_transmission_mode(mod_id, CC_id, rnti)==5) { - // eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,16); - // } + if (mac_xface->get_transmission_mode(mod_id, CC_id, rnti)==5) { + mcs = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]]; + //eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,16); + } #endif @@ -264,14 +272,13 @@ schedule_ue_spec_default( //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->DL_cqi[0]; // initializing the rb allocation indicator for each UE - for(j=0; jN_RBG; j++) { + for(j = 0; j < frame_parms[CC_id]->N_RBG; 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, ncc %d, rrc %d)\n", + 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", mod_id, frame, UE_id, CC_id, rnti, harq_pid, round, nb_available_rb, eNB_UE_stats->DL_cqi[0], mcs, - nCCE[CC_id], UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); dl_dci = (Protocol__PrpDlDci*) malloc(sizeof(Protocol__PrpDlDci)); @@ -301,14 +308,14 @@ schedule_ue_spec_default( if (nb_rb <= nb_available_rb) { if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for(j=0; jN_RBG; j++) { // for indicating the rballoc for each sub-band + for(j = 0; j < frame_parms[CC_id]->N_RBG; 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) && (jN_RBG)) { + while((nb_rb_temp > 0) && (j < frame_parms[CC_id]->N_RBG)) { 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 == frame_parms[CC_id]->N_RBG-1) && @@ -326,8 +333,6 @@ schedule_ue_spec_default( nb_available_rb -= nb_rb; aggregation = process_ue_cqi(mod_id, UE_id); - nCCE[CC_id]-=(1<mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; @@ -344,7 +349,8 @@ schedule_ue_spec_default( dl_dci->res_alloc = 0; dl_dci->n_mcs = 1; dl_dci->mcs = (uint32_t *)malloc(sizeof(uint32_t)); - dl_dci->mcs[0] = mcs; //eNB_UE_stats->dlsch_mcs1; + dl_dci->mcs[0] = mcs; + //TODO:Need to fix tpc for retransmissions dl_dci->has_tpc = 1; dl_dci->tpc = 1; dl_dci->has_vrb_format = 1; @@ -352,7 +358,7 @@ schedule_ue_spec_default( dl_dci->has_format = 1; dl_dci->format = PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1; dl_dci->has_rb_bitmap = 1; - dl_dci->rb_bitmap = allocate_prbs_sub(UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid], UE_list->UE_template[CC_id][UE_id].rballoc_subband); + dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, UE_list->UE_template[CC_id][UE_id].rballoc_subband); dl_dci->has_rb_shift = 1; dl_dci->rb_shift = 0; dl_dci->n_ndi = 1; @@ -374,29 +380,48 @@ schedule_ue_spec_default( case 4: dl_dci->has_res_alloc = 1; dl_dci->res_alloc = 0; + dl_dci->n_mcs = 2; + dl_dci->mcs = (uint32_t *)malloc(sizeof(uint32_t) * dl_dci->n_mcs); + dl_dci->mcs[0] = mcs; + dl_dci->mcs[1] = mcs; + //TODO:Need to fix tpc for retransmissions + dl_dci->has_tpc = 1; + dl_dci->tpc = 1; dl_dci->has_vrb_format = 1; dl_dci->vrb_format = PROTOCOL__PRP_VRB_FORMAT__PRVRBF_LOCALIZED; dl_dci->has_format = 1; dl_dci->format = PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2A; + dl_dci->has_rb_bitmap = 1; + dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, UE_list->UE_template[CC_id][UE_id].rballoc_subband); + dl_dci->has_rb_shift = 1; + dl_dci->rb_shift = 0; dl_dci->n_ndi = 2; dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); dl_dci->ndi[0] = 0; dl_dci->ndi[1] = 0; - //dl_dci->has_rb_bitmap = 1; - //dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); - dl_dci->has_rb_shift = 1; - dl_dci->rb_shift = 0; - dl_dci->has_dai = 1; - dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; dl_dci->n_rv = 2; dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); dl_dci->rv[0] = round&3; dl_dci->rv[1] = round&3; - + if (frame_parms[CC_id]->frame_type == TDD) { + dl_dci->has_dai = 1; + dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d\n", + mod_id, CC_id, harq_pid, round,(UE_list->UE_template[CC_id][UE_id].DAI-1)); + } else { + LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d\n", + mod_id, CC_id, harq_pid, round); + } break; case 5: dl_dci->has_res_alloc = 1; dl_dci->res_alloc = 0; + dl_dci->n_mcs = 1; + dl_dci->mcs = (uint32_t *)malloc(sizeof(uint32_t)); + dl_dci->mcs[0] = mcs; + //TODO:Need to fix tpc for retransmissions + dl_dci->has_tpc = 1; + dl_dci->tpc = 1; dl_dci->has_vrb_format = 1; dl_dci->vrb_format = PROTOCOL__PRP_VRB_FORMAT__PRVRBF_LOCALIZED; dl_dci->has_format = 1; @@ -404,8 +429,8 @@ schedule_ue_spec_default( dl_dci->n_ndi = 1; dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); dl_dci->ndi[0] = 0; - //dl_dci->has_rb_bitmap = 1; - //dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); + dl_dci->has_rb_bitmap = 1; + dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, UE_list->UE_template[CC_id][UE_id].rballoc_subband); dl_dci->has_rb_shift = 1; dl_dci->rb_shift = 0; dl_dci->has_dai = 1; @@ -425,6 +450,12 @@ schedule_ue_spec_default( case 6: dl_dci->has_res_alloc = 1; dl_dci->res_alloc = 0; + dl_dci->n_mcs = 1; + dl_dci->mcs = (uint32_t *)malloc(sizeof(uint32_t)); + dl_dci->mcs[0] = mcs; + //TODO:Need to fix tpc for retransmissions + dl_dci->has_tpc = 1; + dl_dci->tpc = 1; dl_dci->has_vrb_format = 1; dl_dci->vrb_format = PROTOCOL__PRP_VRB_FORMAT__PRVRBF_LOCALIZED; dl_dci->has_format = 1; @@ -432,8 +463,8 @@ schedule_ue_spec_default( dl_dci->n_ndi = 1; dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); dl_dci->ndi[0] = 0; - //dl_dci->has_rb_bitmap = 1; - //dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); + dl_dci->has_rb_bitmap = 1; + dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, UE_list->UE_template[CC_id][UE_id].rballoc_subband); dl_dci->has_rb_shift = 1; dl_dci->rb_shift = 0; dl_dci->has_dai = 1; @@ -447,17 +478,18 @@ schedule_ue_spec_default( break; } - add_ue_dlsch_info(mod_id, - CC_id, - UE_id, - subframe, - S_DL_SCHEDULED); + /*We now probably don't need this*/ + /* add_ue_dlsch_info(mod_id, */ + /* CC_id, */ + /* UE_id, */ + /* subframe, */ + /* S_DL_SCHEDULED); */ //eNB_UE_stats->dlsch_trials[round]++; //UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission+=1; //UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx=nb_rb; //UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx+=nb_rb; - //UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx=nCCE[CC_id]; + //UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx=nCCECC_id]; //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; @@ -475,33 +507,12 @@ schedule_ue_spec_default( //TBS = mac_xface->get_TBS(eNB_UE_stats->DL_cqi[0]<<1,nb_available_rb); TBS = mac_xface->get_TBS_DL(mcs, nb_available_rb); dci_tbs = TBS; + // check first for RLC data on DCCH // add the length for all the control elements (timing adv, drx, etc) : header + payload - //#ifndef EXMIMO_IOT - // to be checked by RK, NN, FK - uint8_t update_TA=4; - - switch (frame_parms[CC_id]->N_RB_DL) { - case 6: - update_TA = 1; - break; - - case 25: - update_TA = 4; - break; - - case 50: - update_TA = 8; - break; - - case 100: - update_TA = 16; - break; - } - - ta_len = ((eNB_UE_stats->timing_advance_update/update_TA)!=0) ? 2 : 0; - + ta_len = (ue_sched_ctl->ta_update!=0) ? 2 : 0; + dl_data[num_ues_added]->n_ce_bitmap = 2; dl_data[num_ues_added]->ce_bitmap = (uint32_t *) malloc(sizeof(uint32_t) * 2); @@ -509,6 +520,7 @@ schedule_ue_spec_default( ce_flags |= PROTOCOL__PRP_CE_TYPE__PRPCET_TA; } + /*TODO: Add other flags if DRX and other CE are required*/ // Add the control element flags to the progran message dl_data[num_ues_added]->ce_bitmap[0] = ce_flags; @@ -519,24 +531,22 @@ schedule_ue_spec_default( // Need to see if we have space for data from this channel if ( TBS-ta_len-header_len_dcch > 0 ) { - //If we have space, we need to see how much data we can request at most (if any are available) - - rlc_status = mac_rlc_status_ind( - mod_id, - rnti, - mod_id, - frame, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH, - (TBS-ta_len-header_len_dcch)); // transport block set size + //If we have space, we need to see how much data we can request at most (if any available) + rlc_status = mac_rlc_status_ind(mod_id, + rnti, + mod_id, + frame, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH, + (dci_tbs-ta_len-header_len_dcch)); // transport block set size //If data are available in the DCCH if (rlc_status.bytes_in_buffer > 0) { - - // Fill at most 1/3 of the remaining TB - data_to_request = 3;//cmin(3, rlc_status.bytes_in_buffer); - + LOG_D(MAC, "[TEST]Have %d bytes in buffer DCCH during first call\n", rlc_status.bytes_in_buffer); + //Fill in as much as possible + data_to_request = cmin(dci_tbs-ta_len-header_len_dcch, rlc_status.bytes_in_buffer) + 1; + LOG_D(MAC, "[TEST]Will request %d \n", data_to_request); rlc_pdus[0] = (Protocol__PrpRlcPdu *) malloc(sizeof(Protocol__PrpRlcPdu)); protocol__prp_rlc_pdu__init(rlc_pdus[0]); rlc_pdus[0]->n_rlc_pdu_tb = 2; @@ -562,26 +572,25 @@ schedule_ue_spec_default( } // check for DCCH1 and update header information (assume 2 byte sub-header) - if (TBS-ta_len-header_len_dcch+2-sdu_length_total > 0 ) { + if (dci_tbs-ta_len-header_len_dcch-sdu_length_total > 0 ) { //If we have space, we need to see how much data we can request at most (if any are available) - rlc_status = mac_rlc_status_ind( - mod_id, + rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH+1, - (TBS-ta_len-header_len_dcch+2-sdu_length_total)); // transport block set size less allocations for timing advance and + (dci_tbs-ta_len-header_len_dcch-sdu_length_total)); // transport block set size less allocations for timing advance and // DCCH SDU // If data are available in DCCH1 if (rlc_status.bytes_in_buffer > 0) { header_len_dcch += 2; - - //Fill another 1/3 of the remaining TB - data_to_request = 3;//cmin(3, rlc_status.bytes_in_buffer); + + //Fill in as much as possible + data_to_request = cmin(dci_tbs-ta_len-header_len_dcch-sdu_length_total, rlc_status.bytes_in_buffer) + 1; rlc_pdus[1] = (Protocol__PrpRlcPdu *) malloc(sizeof(Protocol__PrpRlcPdu)); protocol__prp_rlc_pdu__init(rlc_pdus[1]); @@ -589,7 +598,7 @@ schedule_ue_spec_default( rlc_pdus[1]->rlc_pdu_tb = (Protocol__PrpRlcPduTb **) malloc(sizeof(Protocol__PrpRlcPduTb *) * 2); rlc_pdus[1]->rlc_pdu_tb[0] = (Protocol__PrpRlcPduTb *) malloc(sizeof(Protocol__PrpRlcPduTb)); rlc_pdus[1]->rlc_pdu_tb[0]->has_logical_channel_id = 1; - rlc_pdus[1]->rlc_pdu_tb[0]->logical_channel_id = DCCH; + rlc_pdus[1]->rlc_pdu_tb[0]->logical_channel_id = DCCH+1; rlc_pdus[1]->rlc_pdu_tb[0]->has_size = 1; rlc_pdus[1]->rlc_pdu_tb[0]->size = data_to_request; rlc_pdus[1]->rlc_pdu_tb[1] = (Protocol__PrpRlcPduTb *) malloc(sizeof(Protocol__PrpRlcPduTb)); @@ -610,27 +619,26 @@ schedule_ue_spec_default( LOG_D(MAC,"[eNB %d], Frame %d, DTCH->DLSCH, CC_id %d, Checking RLC status (rab %d, tbs %d, len %d)\n", mod_id, frame, CC_id, DTCH, TBS, - TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); + dci_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 ) { + if (dci_tbs-ta_len-header_len_dcch-sdu_length_total-header_len_dtch > 0 ) { //If we have space, we need to see how much data we can request at most (if any are available) - rlc_status = mac_rlc_status_ind( - mod_id, + rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, ENB_FLAG_YES, MBMS_FLAG_NO, DTCH, - TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); + dci_tbs-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); // If data are available in DTCH if (rlc_status.bytes_in_buffer > 0) { - + LOG_D(MAC, "[TEST] Have %d bytes in buffer DTCH during first call\n", rlc_status.bytes_in_buffer); //Fill what remains in the TB - data_to_request = 3;//cmin(3, rlc_status.bytes_in_buffer); - + data_to_request = cmin(dci_tbs-ta_len-header_len_dcch-sdu_length_total-header_len_dtch, rlc_status.bytes_in_buffer) + 1; + LOG_D(MAC, "[TEST]Will request %d \n", data_to_request); rlc_pdus[2] = (Protocol__PrpRlcPdu *) malloc(sizeof(Protocol__PrpRlcPdu)); protocol__prp_rlc_pdu__init(rlc_pdus[2]); rlc_pdus[2]->n_rlc_pdu_tb = 2; @@ -654,14 +662,14 @@ schedule_ue_spec_default( } } else { - header_len_dtch = 0; + header_len_dtch = 3; } } // Add rlc_pdus to the dl_data message dl_data[num_ues_added]->rlc_pdu = (Protocol__PrpRlcPdu **) malloc(sizeof(Protocol__PrpRlcPdu *) * dl_data[num_ues_added]->n_rlc_pdu); - for (i = 0; i< dl_data[num_ues_added]->n_rlc_pdu; i++) { + for (i = 0; i < dl_data[num_ues_added]->n_rlc_pdu; i++) { dl_data[num_ues_added]->rlc_pdu[i] = rlc_pdus[i]; } @@ -674,51 +682,48 @@ schedule_ue_spec_default( header_len_dtch_tmp = header_len_dtch; if (header_len_dtch == 0) { - header_len_dcch = (header_len_dcch >0) ? 1 : header_len_dcch; // remove length field + header_len_dcch = (header_len_dcch > 0) ? 1 : header_len_dcch; // remove length field } else { - header_len_dtch = (header_len_dtch > 0) ? 1 :header_len_dtch; // remove length field for the last SDU + header_len_dtch = (header_len_dtch > 0) ? 1 : header_len_dtch; // remove length field for the last SDU } - int mcs2; - - mcs2 = mcs; + mcs_tmp = mcs; // TODO: Need to compute this and not take it from the stats // mcs = eNB_UE_stats->dlsch_mcs1; - if (mcs2==0) { + if (mcs_tmp == 0) { nb_rb = 4; // don't let the TBS get too small } else { nb_rb=min_rb_unit[CC_id]; } - TBS = mac_xface->get_TBS_DL(mcs2,nb_rb); + TBS = mac_xface->get_TBS_DL(mcs_tmp, 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 + 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 = mac_xface->get_TBS_DL(mcs2, nb_available_rb); + TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_available_rb); nb_rb = nb_available_rb; break; } - TBS = mac_xface->get_TBS_DL(mcs, nb_rb); + TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); } if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for(j=0; jN_RBG; j++) { // for indicating the rballoc for each sub-band + for(j = 0; j < frame_parms[CC_id]->N_RBG; 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) && (jN_RBG)) { + while((nb_rb_temp > 0) && (j < frame_parms[CC_id]->N_RBG)) { 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 == frame_parms[CC_id]->N_RBG-1) && ((frame_parms[CC_id]->N_RB_DL == 25)|| (frame_parms[CC_id]->N_RB_DL == 50))) { @@ -735,44 +740,41 @@ schedule_ue_spec_default( PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - for(j=0; jN_RBG; j++) { + for(j = 0; j < frame_parms[CC_id]->N_RBG; j++) { PHY_vars_eNB_g[mod_id][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)) && (mcs2>0)) { - mcs2--; - TBS = mac_xface->get_TBS_DL(mcs2,nb_rb); + while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs_tmp > 0)) { + mcs_tmp--; + TBS = mac_xface->get_TBS_DL(mcs_tmp, 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) && (mcs2<28)) - || ( (ue_sched_ctl->dl_pow_off[CC_id]==0) && (mcs2<=15)))) { - mcs2++; - TBS = mac_xface->get_TBS_DL(mcs2,nb_rb); + while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && + ((( ue_sched_ctl->dl_pow_off[CC_id] > 0) && (mcs_tmp < 28)) || ( (ue_sched_ctl->dl_pow_off[CC_id]==0) && (mcs_tmp <= 15)))) { + mcs_tmp++; + TBS = mac_xface->get_TBS_DL(mcs_tmp, nb_rb); } - dl_dci->n_tbs_size = 2; - dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * 2); - dl_dci->tbs_size[0] = TBS; - dl_dci->tbs_size[1] = TBS; + LOG_D(MAC,"dlsch_mcs and TBS before and after the rate matching = (%d, %d) (%d, %d)\n", mcs, mcs_tmp, dci_tbs, TBS); - LOG_D(MAC,"dlsch_mcs before and after the rate matching = (%d, %d)\n", mcs, mcs2); + dci_tbs = TBS; + + mcs = mcs_tmp; aggregation = process_ue_cqi(mod_id,UE_id); dl_dci->has_aggr_level = 1; dl_dci->aggr_level = aggregation; - dl_dci->has_cce_index = 1; - // dl_dci->cce_index = nCCE_used[CC_id]; - nCCE[CC_id]-=(1<UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; - add_ue_dlsch_info(mod_id, - CC_id, - UE_id, - subframe, - S_DL_SCHEDULED); + /*Deactivate here as well*/ + /* add_ue_dlsch_info(mod_id, */ + /* CC_id, */ + /* UE_id, */ + /* subframe, */ + /* S_DL_SCHEDULED); */ if (frame_parms[CC_id]->frame_type == TDD) { UE_list->UE_template[CC_id][UE_id].DAI++; @@ -838,8 +840,8 @@ schedule_ue_spec_default( dl_dci->rb_shift = 0; dl_dci->n_ndi = 1; dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = 1; //1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_dci->n_rv = 1; + dl_dci->ndi[0] = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_dci->n_rv = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); dl_dci->rv[0] = 0; dl_dci->has_tpc = 1; @@ -848,16 +850,11 @@ schedule_ue_spec_default( dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); dl_dci->mcs[0] = mcs; dl_dci->n_tbs_size = 1; - dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t)); + dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); dl_dci->tbs_size[0] = dci_tbs; if (frame_parms[CC_id]->frame_type == TDD) { dl_dci->has_dai = 1; dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d\n", - mod_id, CC_id, harq_pid, round,(UE_list->UE_template[CC_id][UE_id].DAI-1)); - } else { - LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d\n", - mod_id, CC_id, harq_pid, round); } break; case 3: @@ -873,26 +870,25 @@ schedule_ue_spec_default( dl_dci->rb_shift = 0; dl_dci->n_ndi = 2; dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = 1; //1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_dci->ndi[1] = 0; + dl_dci->ndi[0] = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];; + dl_dci->ndi[1] = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];; dl_dci->n_rv = 2; dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); dl_dci->rv[0] = 0; - dl_dci->rv[1] = 1; + dl_dci->rv[1] = 0; dl_dci->has_tpc = 1; dl_dci->tpc = tpc; dl_dci->n_mcs = 2; dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); dl_dci->mcs[0] = mcs; - dl_dci->mcs[1] = 0; + dl_dci->mcs[1] = mcs; + dl_dci->n_tbs_size = 2; + dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); + dl_dci->tbs_size[0] = dci_tbs; + dl_dci->tbs_size[1] = dci_tbs; if (frame_parms[CC_id]->frame_type == TDD) { dl_dci->has_dai = 1; dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d\n", - mod_id, CC_id, harq_pid, round,(UE_list->UE_template[CC_id][UE_id].DAI-1)); - } else { - LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d\n", - mod_id, CC_id, harq_pid, round); } break; case 4: @@ -901,33 +897,32 @@ schedule_ue_spec_default( dl_dci->has_vrb_format = 1; dl_dci->vrb_format = PROTOCOL__PRP_VRB_FORMAT__PRVRBF_LOCALIZED; dl_dci->has_format = 1; - dl_dci->format = PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2; + dl_dci->format = PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2A; dl_dci->has_rb_bitmap = 1; dl_dci->rb_bitmap = allocate_prbs_sub(nb_rb, rballoc_sub); dl_dci->has_rb_shift = 1; dl_dci->rb_shift = 0; dl_dci->n_ndi = 2; dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = 1; // 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_dci->ndi[1] = 0; + dl_dci->ndi[0] = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];; + dl_dci->ndi[1] = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];; dl_dci->n_rv = 2; dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); dl_dci->rv[0] = 0; - dl_dci->rv[1] = round&3; + dl_dci->rv[1] = 0; dl_dci->has_tpc = 1; dl_dci->tpc = tpc; dl_dci->n_mcs = 2; dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); dl_dci->mcs[0] = mcs; - dl_dci->mcs[1] = 0; + dl_dci->mcs[1] = mcs; + dl_dci->n_tbs_size = 2; + dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); + dl_dci->tbs_size[0] = dci_tbs; + dl_dci->tbs_size[1] = dci_tbs; if (frame_parms[CC_id]->frame_type == TDD) { dl_dci->has_dai = 1; dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d\n", - mod_id, CC_id, harq_pid, round,(UE_list->UE_template[CC_id][UE_id].DAI-1)); - } else { - LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d\n", - mod_id, CC_id, harq_pid, round); } break; case 5: @@ -942,8 +937,8 @@ schedule_ue_spec_default( dl_dci->has_rb_shift = 1; dl_dci->rb_shift = 0; dl_dci->n_ndi = 1; - dl_dci->ndi = 1;//(uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = 1; + dl_dci->ndi = 1; + dl_dci->ndi[0] = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];; dl_dci->n_rv = 1; dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); dl_dci->rv[0] = round&3; @@ -952,14 +947,12 @@ schedule_ue_spec_default( dl_dci->n_mcs = 1; dl_dci->mcs = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_mcs); dl_dci->mcs[0] = mcs; + dl_dci->n_tbs_size = 1; + dl_dci->tbs_size = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_tbs_size); + dl_dci->tbs_size[0] = dci_tbs; if (frame_parms[CC_id]->frame_type == TDD) { dl_dci->has_dai = 1; dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d\n", - mod_id, CC_id, harq_pid, round,(UE_list->UE_template[CC_id][UE_id].DAI-1)); - } else { - LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d\n", - mod_id, CC_id, harq_pid, round); } if(ue_sched_ctl->dl_pow_off[CC_id] == 2) { @@ -985,7 +978,7 @@ schedule_ue_spec_default( dl_dci->rb_shift = 0; dl_dci->n_ndi = 1; dl_dci->ndi = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); - dl_dci->ndi[0] = 1; + dl_dci->ndi[0] = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];; dl_dci->n_rv = 1; dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); dl_dci->rv[0] = round&3; @@ -997,11 +990,6 @@ schedule_ue_spec_default( if (frame_parms[CC_id]->frame_type == TDD) { dl_dci->has_dai = 1; dl_dci->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d\n", - mod_id, CC_id, harq_pid, round,(UE_list->UE_template[CC_id][UE_id].DAI-1)); - } else { - LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d\n", - mod_id, CC_id, harq_pid, round); } dl_dci->has_dl_power_offset = 1; @@ -1011,14 +999,14 @@ schedule_ue_spec_default( break; } // 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, frame, subframe, 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]; + LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", + CC_id, frame, subframe, 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]; // Increase the pointer for the number of scheduled UEs num_ues_added++; - } else { // There is no data from RLC or MAC header, so don't schedule + } else { // There is no data from RLC or MAC header, so don't schedule } } @@ -1047,7 +1035,6 @@ void apply_scheduling_decisions(mid_t mod_id, uint8_t CC_id; int UE_id; - uint16_t nCCE[MAX_NUM_CCs]; int N_RBG[MAX_NUM_CCs]; unsigned char aggregation; mac_rlc_status_resp_t rlc_status; @@ -1097,7 +1084,7 @@ void apply_scheduling_decisions(mid_t mod_id, UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]); //NOTICE: Maybe later will not be required, once scheduler fully restructured - eNB_dlsch_info[mod_id][CC_id][UE_id].status = S_DL_WAITING; + //eNB_dlsch_info[mod_id][CC_id][UE_id].status = S_DL_WAITING; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); @@ -1275,6 +1262,7 @@ void apply_scheduling_decisions(mid_t mod_id, ta_len = 0; } } + n_lc = dl_data->n_rlc_pdu; num_sdus = 0; @@ -1282,7 +1270,7 @@ void apply_scheduling_decisions(mid_t mod_id, for (i = 0; i < n_lc; i++) { lcid = dl_data->rlc_pdu[i]->rlc_pdu_tb[0]->logical_channel_id; rlc_size = dl_data->rlc_pdu[i]->rlc_pdu_tb[0]->size; - + LOG_D(MAC,"[TEST]Have to check %d channels\n", n_lc); if (rlc_size > 0) { rlc_status = mac_rlc_status_ind( mod_id, @@ -1294,11 +1282,13 @@ void apply_scheduling_decisions(mid_t mod_id, lcid, rlc_size); // transport block set size - sdu_lengths[i]=0; + sdu_lengths[i] = 0; LOG_D(MAC,"[eNB %d] Frame %d, LCID %d, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", mod_id, frame, lcid, CC_id, rlc_size); + LOG_D(MAC, "[TEST] Have %d bytes in buffer DCCH during second call\n", rlc_status.bytes_in_buffer); + sdu_lengths[i] += mac_rlc_data_req( mod_id, rnti, @@ -1309,6 +1299,8 @@ void apply_scheduling_decisions(mid_t mod_id, lcid, (char *)&dlsch_buffer[sdu_lengths[i]]); + LOG_D(MAC, "[TEST] This is what I actuallty got %d\n", sdu_lengths[i]); + LOG_D(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",mod_id, CC_id, sdu_lengths[i]); sdu_length_total += sdu_lengths[i]; sdu_lcids[i] = lcid; @@ -1331,72 +1323,58 @@ void apply_scheduling_decisions(mid_t mod_id, } // SDU creation end - if (header_len_dtch==0) { - header_len_dcch = (header_len_dcch >0) ? 1 : header_len_dcch; // remove length field - } else { - header_len_dtch = (header_len_dtch > 0) ? 1 :header_len_dtch; // remove length field for the last SDU - } + if (((sdu_length_total + header_len_dcch + header_len_dtch) > 0)) { - // there is a payload - if (((sdu_length_total + header_len_dcch + header_len_dtch ) > 0)) { - 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; + 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 : header_len_dcch; // remove length field + } else { + header_len_dtch = (header_len_dtch > 0) ? 1 :header_len_dtch; // remove length field for the last SDU + } + + // there is a payload + LOG_D(MAC, "[TEST] This is the padding %d\n", TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); + if (((sdu_length_total + header_len_dcch + header_len_dtch ) > 0)) { + 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 - } - } - - uint8_t update_TA=4; - - switch (frame_parms[CC_id]->N_RB_DL) { - case 6: - update_TA = 1; - break; - - case 25: - update_TA = 4; - break; - - case 50: - update_TA = 8; - break; - - case 100: - update_TA = 16; - break; - } - - if (ta_len > 0) { - ta_update = eNB_UE_stats->timing_advance_update/update_TA; - } else { - ta_update = 0; - } - /*#else - ta_update = 0; - #endif*/ - - offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - // offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0], - num_sdus, //num_sdus - sdu_lengths, // - sdu_lcids, - 255, // no drx - ta_update, // timing advance - NULL, // contention res id - padding, - post_padding); - - + // 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 + } + } + + LOG_D(MAC, "[TEST] This is the current SDU length %d and this is the TBS %d\n", sdu_length_total, TBS); + + + if (ta_len > 0) { + ta_update = ue_sched_ctl->ta_update; + } else { + ta_update = 0; + } + + offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + // offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0], + num_sdus, //num_sdus + sdu_lengths, // + sdu_lcids, + 255, // no drx + ta_update, // timing advance + NULL, // contention res id + padding, + post_padding); + + #ifdef DEBUG_eNB_SCHEDULER LOG_T(MAC,"[eNB %d] First 16 bytes of DLSCH : \n"); @@ -1428,9 +1406,13 @@ void apply_scheduling_decisions(mid_t mod_id, 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].crnti= rnti; + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status=mac_eNB_get_rrc_status(mod_id, rnti); + UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; + UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; + 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].ncce_used = nCCE[CC_id]; UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=dl_dci->mcs[0]; UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=dl_dci->mcs[0]; UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; @@ -1441,6 +1423,10 @@ void apply_scheduling_decisions(mid_t mod_id, UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus+=1; // TODO + + } + + } else { // No need to create anything apart of DCI in case of retransmission diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 21e9337dbb..f0e0a9f84b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -59,12 +59,18 @@ //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" +//Agent-related headers +#include "ENB_APP/enb_agent_extern.h" +#include "ENB_APP/enb_agent_mac.h" + #if defined(ENABLE_ITTI) # include "intertask_interface.h" #endif #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 +//#define ENABLE_ENB_AGENT_DL_SCHEDULER + //#define DEBUG_HEADER_PARSING 1 //#define DEBUG_PACKET_TRACE 1 @@ -99,6 +105,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list; rnti_t rnti; + Protocol__ProgranMessage *msg; + LOG_D(MAC,"[eNB %d] Frame %d, Subframe %d, entering MAC scheduler (UE_list->head %d)\n",module_idP, frameP, subframeP,UE_list->head); start_meas(&eNB_mac_inst[module_idP].eNB_scheduler); @@ -252,10 +260,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, (mac_xface->lte_frame_parms->tdd_config == 6)) { //schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);//,calibration_flag); } - +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); - +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; case 1: @@ -267,12 +292,16 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, case 0: case 1: schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#endif break; case 6: schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#endif break; default: @@ -280,8 +309,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { //FDD schedule_ulsch(module_idP,frameP,cooperation_flag,1,5); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif } break; @@ -292,8 +340,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // FDD, normal UL/DLSCH if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD schedule_ulsch(module_idP,frameP,cooperation_flag,2,6); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif } break; @@ -310,8 +377,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // no break here! case 5: +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; default: @@ -320,8 +406,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } else { //FDD schedule_ulsch(module_idP,frameP,cooperation_flag,3,7); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif } break; @@ -345,9 +450,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // no break here! case 5: - +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); - fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); + fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; default: @@ -358,8 +481,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // schedule_RA(module_idP,frameP, subframeP, 0); schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status); fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif } } @@ -376,15 +518,55 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, if (mac_xface->lte_frame_parms->frame_type == FDD) { schedule_RA(module_idP,frameP,subframeP,1); schedule_ulsch(module_idP,frameP,cooperation_flag,5,9); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif } else if ((mac_xface->lte_frame_parms->tdd_config == 0) || // TDD Config 0 (mac_xface->lte_frame_parms->tdd_config == 6)) { // TDD Config 6 //schedule_ulsch(module_idP,cooperation_flag,subframeP); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#endif } else { +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif } break; @@ -402,25 +584,67 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, case 1: schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2); // schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#endif break; case 6: schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3); // schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#endif break; case 5: schedule_RA(module_idP,frameP,subframeP,2); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; case 3: case 4: +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; default: @@ -428,8 +652,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { //FDD // schedule_ulsch(module_idP,frameP,cooperation_flag,6,0); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif } break; @@ -443,13 +686,51 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, case 3: case 4: schedule_RA(module_idP,frameP,subframeP,3); // 3 = Msg3 subframeP, not +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; case 5: +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; default: @@ -457,8 +738,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { //FDD //schedule_ulsch(module_idP,frameP,cooperation_flag,7,1); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif } break; @@ -477,8 +777,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // schedule_RA(module_idP,subframeP); schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; default: @@ -486,8 +805,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { //FDD //schedule_ulsch(module_idP,frameP,cooperation_flag,8,2); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif } break; @@ -500,29 +838,105 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, case 1: schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3); schedule_RA(module_idP,frameP,subframeP,7); // 7 = Msg3 subframeP, not +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; case 3: case 4: schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; case 6: schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4); //schedule_RA(module_idP,frameP,subframeP); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; case 2: case 5: //schedule_RA(module_idP,frameP,subframeP); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif break; default: @@ -530,8 +944,27 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, } } else { //FDD // schedule_ulsch(module_idP,frameP,cooperation_flag,9,3); +#ifndef ENABLE_ENB_AGENT_DL_SCHEDULER schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status); +#else + if (mac_agent_registered[module_idP]) { + enb_agent_mac_create_empty_dl_config(module_idP, &msg); + agent_mac_xface[module_idP]->enb_agent_schedule_ue_spec( + module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + + apply_scheduling_decisions(module_idP, + frameP, + subframeP, + mbsfn_status, + msg); + enb_agent_mac_destroy_dl_config(msg); + } +#endif } break; diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index c522d5920e..faf0bf9954 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -135,7 +135,6 @@ void schedule_ue_spec(module_id_t module_idP,frame_t frameP,sub_frame_t subframe //To be used by the agent void schedule_ue_spec_default(mid_t mod_id, uint32_t frame, uint32_t subframe, - unsigned int *nb_rb_used, unsigned int *nCCE_used, int *mbsfn_flag, Protocol__ProgranMessage *dl_info); /** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure.