diff --git a/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c index 5adc4abc40..30894909a7 100644 --- a/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/eNB_agent_scheduler_dlsch_ue.c @@ -129,6 +129,8 @@ schedule_ue_spec_default( uint8_t rballoc_sub[25]; int i; + uint32_t data_to_request; + uint32_t dci_tbs; if (UE_list->head==-1) { @@ -233,10 +235,10 @@ 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]; - 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].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; sdu_length_total=0; @@ -246,20 +248,22 @@ schedule_ue_spec_default( DevCheck(((eNB_UE_stats->DL_cqi[0] < MIN_CQI_VALUE) || (eNB_UE_stats->DL_cqi[0] > MAX_CQI_VALUE)), eNB_UE_stats->DL_cqi[0], MIN_CQI_VALUE, MAX_CQI_VALUE); */ - 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); + + mcs = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]]; + //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) { + // eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,16); + // } #endif // store stats - UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->DL_cqi[0]; + //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++) { @@ -268,7 +272,7 @@ schedule_ue_spec_default( 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", mod_id, frame, UE_id, CC_id, rnti, harq_pid, round, nb_available_rb, - eNB_UE_stats->DL_cqi[0], eNB_UE_stats->dlsch_mcs1, + eNB_UE_stats->DL_cqi[0], mcs, nCCE[CC_id], UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); @@ -338,8 +342,21 @@ schedule_ue_spec_default( case 1: case 2: default: + 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; //eNB_UE_stats->dlsch_mcs1; + 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_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->has_rb_shift = 1; + 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] = 0; @@ -357,12 +374,20 @@ schedule_ue_spec_default( } break; case 4: + dl_dci->has_res_alloc = 1; + dl_dci->res_alloc = 0; + 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->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; @@ -372,11 +397,19 @@ schedule_ue_spec_default( break; case 5: + dl_dci->has_res_alloc = 1; + dl_dci->res_alloc = 0; + 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_1D; 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_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 = 1; @@ -392,11 +425,19 @@ schedule_ue_spec_default( break; case 6: + dl_dci->has_res_alloc = 1; + dl_dci->res_alloc = 0; + 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_1D; 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_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 = 1; @@ -415,18 +456,18 @@ schedule_ue_spec_default( 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].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=eNB_UE_stats->dlsch_mcs1; + //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].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1; + //UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=eNB_UE_stats->dlsch_mcs1; + + num_ues_added += 1; } 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", mod_id, frame, CC_id, UE_id); } - - num_ues_added += 1; } else { /* This is a potentially new SDU opportunity */ @@ -434,7 +475,8 @@ schedule_ue_spec_default( // Now check RLC information to compute number of required RBs // get maximum TBS size for RLC request //TBS = mac_xface->get_TBS(eNB_UE_stats->DL_cqi[0]<<1,nb_available_rb); - TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,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 @@ -468,13 +510,19 @@ schedule_ue_spec_default( if (ta_len > 0) { ce_flags |= PROTOCOL__PRP_CE_TYPE__PRPCET_TA; } - + + + // Add the control element flags to the progran message + dl_data[num_ues_added]->ce_bitmap[0] = ce_flags; + dl_data[num_ues_added]->ce_bitmap[1] = ce_flags; header_len_dcch = 2; // 2 bytes DCCH SDU subheader + // 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, @@ -485,10 +533,30 @@ schedule_ue_spec_default( DCCH, (TBS-ta_len-header_len_dcch)); // transport block set size + //If data are available in the DCCH if (rlc_status.bytes_in_buffer > 0) { - sdu_length_total = cmin(rlc_status.bytes_in_buffer, TBS-ta_len-header_len_dcch); - // TODO: This should be replaced with the proper description of the CE - ce_flags |= PROTOCOL__PRP_CE_TYPE__PRPCET_CR; + + // Fill at most 1/3 of the remaining TB + data_to_request = 3;//cmin(3, rlc_status.bytes_in_buffer); + + 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; + rlc_pdus[0]->rlc_pdu_tb = (Protocol__PrpRlcPduTb **) malloc(sizeof(Protocol__PrpRlcPduTb *) * 2); + rlc_pdus[0]->rlc_pdu_tb[0] = (Protocol__PrpRlcPduTb *) malloc(sizeof(Protocol__PrpRlcPduTb)); + rlc_pdus[0]->rlc_pdu_tb[0]->has_logical_channel_id = 1; + rlc_pdus[0]->rlc_pdu_tb[0]->logical_channel_id = DCCH; + rlc_pdus[0]->rlc_pdu_tb[0]->has_size = 1; + rlc_pdus[0]->rlc_pdu_tb[0]->size = data_to_request; + rlc_pdus[0]->rlc_pdu_tb[1] = (Protocol__PrpRlcPduTb *) malloc(sizeof(Protocol__PrpRlcPduTb)); + rlc_pdus[0]->rlc_pdu_tb[1]->has_logical_channel_id = 1; + rlc_pdus[0]->rlc_pdu_tb[1]->logical_channel_id = DCCH; + rlc_pdus[0]->rlc_pdu_tb[1]->has_size = 1; + rlc_pdus[0]->rlc_pdu_tb[1]->size = data_to_request; + dl_data[num_ues_added]->n_rlc_pdu++; + + //Set this to the max value that we might request + sdu_length_total = data_to_request; } else { header_len_dcch = 0; sdu_length_total = 0; @@ -496,7 +564,9 @@ schedule_ue_spec_default( } // 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+2-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, rnti, @@ -505,20 +575,36 @@ schedule_ue_spec_default( 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 + (TBS-ta_len-header_len_dcch+2-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) { - // TODO: Again hypothetical flag. Need to check how to find the actual type of CE - ce_flags |= PROTOCOL__PRP_CE_TYPE__PRPCET_CA; - sdu_length_total += cmin(rlc_status.bytes_in_buffer, TBS-ta_len-header_len_dcch-sdu_length_total); header_len_dcch += 2; + + //Fill another 1/3 of the remaining TB + data_to_request = 3;//cmin(3, rlc_status.bytes_in_buffer); + + rlc_pdus[1] = (Protocol__PrpRlcPdu *) malloc(sizeof(Protocol__PrpRlcPdu)); + protocol__prp_rlc_pdu__init(rlc_pdus[1]); + rlc_pdus[1]->n_rlc_pdu_tb = 2; + 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]->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)); + rlc_pdus[1]->rlc_pdu_tb[1]->has_logical_channel_id = 1; + rlc_pdus[1]->rlc_pdu_tb[1]->logical_channel_id = DCCH+1; + rlc_pdus[1]->rlc_pdu_tb[1]->has_size = 1; + rlc_pdus[1]->rlc_pdu_tb[1]->size = data_to_request; + dl_data[num_ues_added]->n_rlc_pdu++; + + sdu_length_total += data_to_request; } } - // Add the control element flags to the progran message - dl_data[num_ues_added]->ce_bitmap = ce_flags; - // check for DTCH and update header information // here we should loop over all possible DTCH @@ -529,6 +615,8 @@ schedule_ue_spec_default( 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 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, @@ -539,36 +627,31 @@ schedule_ue_spec_default( DTCH, 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) { - //TODO: Set rlc pdu info. Hardcoded for the moment + //Fill what remains in the TB + data_to_request = 3;//cmin(3, rlc_status.bytes_in_buffer); + 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; + rlc_pdus[2]->rlc_pdu_tb = (Protocol__PrpRlcPduTb **) malloc(sizeof(Protocol__PrpRlcPduTb *) * 2); + rlc_pdus[2]->rlc_pdu_tb[0] = (Protocol__PrpRlcPduTb *) malloc(sizeof(Protocol__PrpRlcPduTb)); + rlc_pdus[2]->rlc_pdu_tb[0]->has_logical_channel_id = 1; + rlc_pdus[2]->rlc_pdu_tb[0]->logical_channel_id = DTCH; + rlc_pdus[2]->rlc_pdu_tb[0]->has_size = 1; + rlc_pdus[2]->rlc_pdu_tb[0]->size = data_to_request; + rlc_pdus[2]->rlc_pdu_tb[1] = (Protocol__PrpRlcPduTb *) malloc(sizeof(Protocol__PrpRlcPduTb)); + rlc_pdus[2]->rlc_pdu_tb[1]->has_logical_channel_id = 1; + rlc_pdus[2]->rlc_pdu_tb[1]->logical_channel_id = DTCH; + rlc_pdus[2]->rlc_pdu_tb[1]->has_size = 1; + rlc_pdus[2]->rlc_pdu_tb[1]->size = data_to_request; dl_data[num_ues_added]->n_rlc_pdu++; - 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; - rlc_pdus[0]->rlc_pdu_tb = (Protocol__PrpRlcPduTb **) malloc(sizeof(Protocol__PrpRlcPduTb *) * 2); - rlc_pdus[0]->rlc_pdu_tb[0] = (Protocol__PrpRlcPduTb *) malloc(sizeof(Protocol__PrpRlcPduTb)); - rlc_pdus[0]->rlc_pdu_tb[0]->has_logical_channel_id = 1; - rlc_pdus[0]->rlc_pdu_tb[0]->logical_channel_id = DTCH; - rlc_pdus[0]->rlc_pdu_tb[0]->has_size = 1; - rlc_pdus[0]->rlc_pdu_tb[0]->size = TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch; - rlc_pdus[0]->rlc_pdu_tb[1] = (Protocol__PrpRlcPduTb *) malloc(sizeof(Protocol__PrpRlcPduTb)); - rlc_pdus[0]->rlc_pdu_tb[1]->has_logical_channel_id = 1; - rlc_pdus[0]->rlc_pdu_tb[1]->logical_channel_id = DTCH; - rlc_pdus[0]->rlc_pdu_tb[1]->has_size = 1; - rlc_pdus[0]->rlc_pdu_tb[1]->size = TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch; - // 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++) { - dl_data[num_ues_added]->rlc_pdu[i] = rlc_pdus[i]; - } + sdu_length_total += data_to_request; - sdu_length_total += cmin(rlc_status.bytes_in_buffer, TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); - - if(cmin(rlc_status.bytes_in_buffer, TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch) < 128) { + if(data_to_request < 128) { header_len_dtch = 2; } @@ -577,41 +660,53 @@ schedule_ue_spec_default( } } + // 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++) { + dl_data[num_ues_added]->rlc_pdu[i] = rlc_pdus[i]; + } + // there is a payload - if (((sdu_length_total + header_len_dcch + header_len_dtch )> 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) { + 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 } - mcs = eNB_UE_stats->dlsch_mcs1; + int mcs2; - if (mcs==0) { + mcs2 = mcs; + + // TODO: Need to compute this and not take it from the stats + // mcs = eNB_UE_stats->dlsch_mcs1; + + if (mcs2==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(mcs,nb_rb); + TBS = mac_xface->get_TBS_DL(mcs2,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 = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb); + TBS = mac_xface->get_TBS_DL(mcs2, nb_available_rb); nb_rb = nb_available_rb; break; } - TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rb); + TBS = mac_xface->get_TBS_DL(mcs, nb_rb); } if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { @@ -647,16 +742,16 @@ schedule_ue_spec_default( } // 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 = mac_xface->get_TBS_DL(mcs,nb_rb); + 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); } // 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 = mac_xface->get_TBS_DL(mcs,nb_rb); + 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); } dl_dci->n_tbs_size = 2; @@ -664,7 +759,7 @@ schedule_ue_spec_default( dl_dci->tbs_size[0] = TBS; dl_dci->tbs_size[1] = TBS; - LOG_D(MAC,"dlsch_mcs before and after the rate matching = (%d, %d)\n",eNB_UE_stats->dlsch_mcs1, mcs); + LOG_D(MAC,"dlsch_mcs before and after the rate matching = (%d, %d)\n", mcs, mcs2); aggregation = process_ue_cqi(mod_id,UE_id); dl_dci->has_aggr_level = 1; @@ -745,7 +840,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-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_dci->ndi[0] = 1; //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] = 0; @@ -754,6 +849,9 @@ 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->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; @@ -777,7 +875,7 @@ 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-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_dci->ndi[0] = 1; //1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; dl_dci->ndi[1] = 0; dl_dci->n_rv = 2; dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); @@ -812,7 +910,7 @@ 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-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_dci->ndi[0] = 1; // 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; dl_dci->ndi[1] = 0; dl_dci->n_rv = 2; dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); @@ -846,7 +944,7 @@ schedule_ue_spec_default( dl_dci->has_rb_shift = 1; 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 = 1;//(uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_ndi); dl_dci->ndi[0] = 1; dl_dci->n_rv = 1; dl_dci->rv = (uint32_t *) malloc(sizeof(uint32_t) * dl_dci->n_rv); @@ -915,10 +1013,10 @@ 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++; @@ -942,3 +1040,436 @@ schedule_ue_spec_default( stop_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_OUT); } + +void apply_scheduling_decisions(mid_t mod_id, + uint32_t frame, + uint32_t subframe, + uint32_t *rballoc, + int *mbsfn_flag, + Protocol__ProgranMessage *dl_scheduling_info) { + + 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; + unsigned char header_len_dcch=0, header_len_dcch_tmp=0,header_len_dtch=0,header_len_dtch_tmp=0, ta_len=0; + unsigned char sdu_lcids[11],offset,num_sdus=0; + uint16_t nb_rb,nb_rb_temp,total_nb_available_rb[MAX_NUM_CCs],nb_available_rb; + uint16_t TBS,j,sdu_lengths[11],rnti,padding=0,post_padding=0; + unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; + unsigned char round = 0; + unsigned char harq_pid = 0; + void *DLSCH_dci = NULL; + DCI_PDU *DCI_pdu; + + LTE_eNB_UE_stats *eNB_UE_stats = NULL; + uint16_t sdu_length_total = 0; + int mcs; + 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]; + 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 i; + int size_bits,size_bytes; + + Protocol__PrpDlMacConfig *mac_config = dl_scheduling_info->dl_mac_config_msg; + Protocol__PrpDlData *dl_data; + Protocol__PrpDlDci *dl_dci; + + uint32_t rlc_size, n_lc, lcid; + + // Check if there is any scheduling command for UE data + if (mac_config->n_dl_ue_data > 0) { + + // For each UE-related command + for (i = 0; i < mac_config->n_dl_ue_data; i++) { + + dl_data = mac_config->dl_ue_data[i]; + dl_dci = dl_data->dl_dci; + + CC_id = dl_data->serv_cell_index; + rnti = dl_data->rnti; + 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; + + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); + + round = dl_dci->rv[0]; + harq_pid = dl_dci->harq_process; + + // Note this code is for a specific DCI format + DLSCH_dci = (void *)UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid]; + DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu; + + frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id); + + switch (frame_parms[CC_id]->N_RB_DL) { + case 6: + if (frame_parms[CC_id]->frame_type == TDD) { + if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1) { + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rv = round; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->dai = dl_dci->dai; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rballoc = dl_dci->rb_bitmap; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rah = dl_dci->rb_shift; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->mcs = dl_dci->mcs[0]; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->TPC = dl_dci->tpc; + ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->ndi = dl_dci->ndi[0]; + size_bytes = sizeof(DCI1_1_5MHz_TDD_t); + size_bits = sizeof_DCI1_1_5MHz_TDD_t; + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2A) { + //TODO + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1D) { + //TODO + } + } else { + if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1) { + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rv = round; + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rballoc = dl_dci->rb_bitmap; + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rah = dl_dci->rb_shift; + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->mcs = dl_dci->mcs[0]; + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->TPC = dl_dci->tpc; + ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->ndi = dl_dci->ndi[0]; + size_bytes = sizeof(DCI1_1_5MHz_FDD_t); + size_bits = sizeof_DCI1_1_5MHz_FDD_t; + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2A) { + //TODO + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1D) { + //TODO + } + } + break; + case 25: + if (frame_parms[CC_id]->frame_type == TDD) { + if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1) { + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rv = round; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->dai = dl_dci->dai; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rballoc = dl_dci->rb_bitmap; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rah = dl_dci->rb_shift; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs = dl_dci->mcs[0]; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->TPC = dl_dci->tpc; + ((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi = dl_dci->ndi[0]; + size_bytes = sizeof(DCI1_5MHz_TDD_t); + size_bits = sizeof_DCI1_5MHz_TDD_t; + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2A) { + //TODO + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1D) { + //TODO + } + } else { + if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1) { + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rv = round; + if (dl_dci->has_rb_bitmap) { + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rballoc = dl_dci->rb_bitmap; + } + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rah = dl_dci->rb_shift; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs = dl_dci->mcs[0]; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->TPC = dl_dci->tpc; + ((DCI1_5MHz_FDD_t*)DLSCH_dci)->ndi = dl_dci->ndi[0]; + size_bytes = sizeof(DCI1_5MHz_FDD_t); + size_bits = sizeof_DCI1_5MHz_FDD_t; + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2A) { + //TODO + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1D) { + //TODO + } + } + break; + case 50: + if (frame_parms[CC_id]->frame_type == TDD) { + if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1) { + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rv = round; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->dai = dl_dci->dai; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rballoc = dl_dci->rb_bitmap; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rah = dl_dci->rb_shift; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->mcs = dl_dci->mcs[0]; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->TPC = dl_dci->tpc; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->ndi = dl_dci->ndi[0]; + size_bytes = sizeof(DCI1_10MHz_TDD_t); + size_bits = sizeof_DCI1_10MHz_TDD_t; + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2A) { + //TODO + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1D) { + //TODO + } + } else { + if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1) { + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rv = round; + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rballoc = dl_dci->rb_bitmap; + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rah = dl_dci->rb_shift; + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->mcs = dl_dci->mcs[0]; + ((DCI1_10MHz_FDD_t*)DLSCH_dci)->TPC = dl_dci->tpc; + ((DCI1_10MHz_TDD_t*)DLSCH_dci)->ndi = dl_dci->ndi[0]; + size_bytes = sizeof(DCI1_10MHz_FDD_t); + size_bits = sizeof_DCI1_10MHz_FDD_t; + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2A) { + //TODO + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1D) { + //TODO + } + } + break; + case 100: + if (frame_parms[CC_id]->frame_type == TDD) { + if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1) { + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rv = round; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->dai = dl_dci->dai; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rballoc = dl_dci->rb_bitmap; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rah = dl_dci->rb_shift; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->mcs = dl_dci->mcs[0]; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->TPC = dl_dci->tpc; + ((DCI1_20MHz_TDD_t*)DLSCH_dci)->ndi = dl_dci->ndi[0]; + size_bytes = sizeof(DCI1_20MHz_TDD_t); + size_bits = sizeof_DCI1_20MHz_TDD_t; + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2A) { + //TODO + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1D) { + //TODO + } + } else { + if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1) { + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rv = round; + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rballoc = dl_dci->rb_bitmap; + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rah = dl_dci->rb_shift; + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->mcs = dl_dci->mcs[0]; + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->TPC = dl_dci->tpc; + ((DCI1_20MHz_FDD_t*)DLSCH_dci)->ndi = dl_dci->ndi[0]; + size_bytes = sizeof(DCI1_20MHz_FDD_t); + size_bits = sizeof_DCI1_20MHz_FDD_t; + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2A) { + //TODO + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1D) { + //TODO + } + } + break; + } + + // If this is a new transmission + if (round == 0) { + // First we have to deal with the creation of the PDU based on the message instructions + rlc_status.bytes_in_buffer = 0; + + TBS = dl_dci->tbs_size[0]; + + if (dl_data->n_ce_bitmap > 0) { + //Check if there is TA command + if (dl_data->ce_bitmap[0] & PROTOCOL__PRP_CE_TYPE__PRPCET_TA) { + ta_len = 2; + } else { + ta_len = 0; + } + } + + n_lc = dl_data->n_rlc_pdu; + num_sdus = 0; + // Go through each one of the channel commands and create SDUs + 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; + + if (rlc_size > 0) { + rlc_status = mac_rlc_status_ind( + mod_id, + rnti, + mod_id, + frame, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + rlc_size); // transport block set size + + 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); + + sdu_lengths[i] += mac_rlc_data_req( + mod_id, + rnti, + mod_id, + frame, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + (char *)&dlsch_buffer[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; + + if (lcid == DCCH || lcid == DCCH+1) { + header_len_dcch += 2; + } else if (lcid == DTCH) { + if (sdu_lengths[i] < 128) { + header_len_dtch = 2; + } else { + header_len_dtch = 3; + } + } + + 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[i]; + num_sdus++; + + } + } // 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 + } + + // 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; + + // 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); + + +#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(&eNB_mac_inst[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); + } + + //eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset+sdu_lengths[0]+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, mod_id, 3, UE_RNTI(mod_id, UE_id), + eNB->subframe,0,0); + LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", + mod_id, CC_id, frame, UE_RNTI(mod_id,UE_id), TBS); + } + + // 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].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; + + 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; + // TODO + + + } else { + // No need to create anything apart of DCI in case of retransmission + } + + //Add DCI based on format + if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_1) { + add_ue_spec_dci(DCI_pdu, + DLSCH_dci, + rnti, + size_bytes, + process_ue_cqi (mod_id, UE_id),//aggregation + size_bits, + format1, + 0); + } else if (dl_dci->format == PROTOCOL__PRP_DCI_FORMAT__PRDCIF_2A) { + add_ue_spec_dci(DCI_pdu, + DLSCH_dci, + rnti, + size_bytes, + process_ue_cqi (mod_id, UE_id),//aggregation + size_bits, + format2A, + 0); + } + } + } +} + diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 0de9253fef..329c40be05 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -59,10 +59,6 @@ //#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 @@ -89,9 +85,6 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, int mbsfn_status[MAX_NUM_CCs]; uint32_t RBalloc[MAX_NUM_CCs]; protocol_ctxt_t ctxt; - - Protocol__ProgranMessage *msg; - #ifdef EXMIMO int ret; #endif @@ -282,19 +275,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; } } else { //FDD - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); schedule_ulsch(module_idP,frameP,cooperation_flag,1,5,nCCE); } @@ -306,19 +287,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // TDD, nothing // FDD, normal UL/DLSCH if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); schedule_ulsch(module_idP,frameP,cooperation_flag,2,6,nCCE); } @@ -337,19 +306,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // no break here! case 5: - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; @@ -357,19 +314,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, break; } } else { //FDD - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); schedule_ulsch(module_idP,frameP,cooperation_flag,3,7,nCCE); @@ -396,19 +341,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // no break here! case 5: - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status); break; @@ -419,19 +352,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, if (mac_xface->lte_frame_parms->frame_type == FDD) { //FDD // schedule_RA(module_idP,frameP, subframeP, 0, nprb, nCCE); // schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8, nCCE); - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP, frameP, subframeP, nprb, nCCE, mbsfn_status); + schedule_ue_spec(module_idP, frameP, subframeP, nprb, nCCE, mbsfn_status); fill_DLSCH_dci(module_idP, frameP, subframeP, RBalloc, 1, mbsfn_status); } @@ -487,37 +408,13 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, case 5: schedule_RA(module_idP,frameP,subframeP,2,nprb,nCCE); - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status); break; case 3: case 4: - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; @@ -526,19 +423,7 @@ 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,nCCE); - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); } @@ -553,36 +438,12 @@ 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,nprb,nCCE); // 3 = Msg3 subframeP, not - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status); break; case 5: - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; @@ -591,19 +452,7 @@ 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,nCCE); - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); } @@ -623,19 +472,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // schedule_RA(module_idP,subframeP,nprb,nCCE); schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2,nCCE); - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; @@ -644,19 +481,7 @@ 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,nCCE); - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); } @@ -670,76 +495,28 @@ 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,nCCE); schedule_RA(module_idP,frameP,subframeP,7,nprb,nCCE); // 7 = Msg3 subframeP, not - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,1,mbsfn_status); break; case 3: case 4: schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3,nCCE); - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; case 6: schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4,nCCE); //schedule_RA(module_idP,frameP,subframeP,nprb,nCCE); - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; case 2: case 5: //schedule_RA(module_idP,frameP,subframeP,nprb,nCCE); - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); break; @@ -748,19 +525,7 @@ 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,nCCE); - 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, - nprb, - nCCE, - mbsfn_status, - msg); - enb_agent_mac_destroy_dl_config(msg); - } - //schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); + schedule_ue_spec(module_idP,frameP,subframeP,nprb,nCCE,mbsfn_status); fill_DLSCH_dci(module_idP,frameP,subframeP,RBalloc,0,mbsfn_status); }