552 lines
18 KiB
C
552 lines
18 KiB
C
/*
|
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
|
* except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.openairinterface.org/?page_id=698
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*-------------------------------------------------------------------------------
|
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
* contact@openairinterface.org
|
|
*/
|
|
|
|
/*! \file flexran_agent_scheduler_dataplane.c
|
|
* \brief data plane procedures related to eNB scheduling
|
|
* \author Xenofon Foukas
|
|
* \date 2016
|
|
* \email: x.foukas@sms.ed.ac.uk
|
|
* \version 0.1
|
|
* @ingroup _mac
|
|
|
|
*/
|
|
|
|
#include "assertions.h"
|
|
#include "PHY/defs.h"
|
|
#include "PHY/extern.h"
|
|
|
|
#include "SCHED/defs.h"
|
|
#include "SCHED/extern.h"
|
|
|
|
#include "LAYER2/MAC/flexran_agent_mac_proto.h"
|
|
#include "LAYER2/MAC/defs.h"
|
|
#include "LAYER2/MAC/proto.h"
|
|
#include "LAYER2/MAC/extern.h"
|
|
#include "LAYER2/MAC/flexran_dci_conversions.h"
|
|
|
|
#include "UTIL/LOG/log.h"
|
|
#include "UTIL/LOG/vcd_signal_dumper.h"
|
|
#include "UTIL/OPT/opt.h"
|
|
#include "OCG.h"
|
|
#include "OCG_extern.h"
|
|
|
|
#include "RRC/LITE/extern.h"
|
|
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
|
|
|
#include "header.pb-c.h"
|
|
#include "flexran.pb-c.h"
|
|
#include "flexran_agent_extern.h"
|
|
|
|
#include "flexran_agent_common.h"
|
|
|
|
#include "SIMULATION/TOOLS/defs.h" // for taus
|
|
|
|
void flexran_apply_scheduling_decisions(mid_t mod_id,
|
|
uint32_t frame,
|
|
uint32_t subframe,
|
|
int *mbsfn_flag,
|
|
Protocol__FlexranMessage *dl_scheduling_info) {
|
|
|
|
Protocol__FlexDlMacConfig *mac_dl_config = dl_scheduling_info->dl_mac_config_msg;
|
|
|
|
// Check if there is anything to schedule for random access
|
|
if (mac_dl_config->n_dl_rar > 0) {
|
|
/*TODO: call the random access data plane function*/
|
|
}
|
|
|
|
// Check if there is anything to schedule for paging/broadcast
|
|
if (mac_dl_config->n_dl_broadcast > 0) {
|
|
/*TODO: call the broadcast/paging data plane function*/
|
|
}
|
|
|
|
// Check if there is anything to schedule for the UEs
|
|
if (mac_dl_config->n_dl_ue_data > 0) {
|
|
flexran_apply_ue_spec_scheduling_decisions(mod_id, frame, subframe, mbsfn_flag,
|
|
mac_dl_config->n_dl_ue_data, mac_dl_config->dl_ue_data);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
|
uint32_t frame,
|
|
uint32_t subframe,
|
|
int *mbsfn_flag,
|
|
uint32_t n_dl_ue_data,
|
|
Protocol__FlexDlData **dl_ue_data) {
|
|
|
|
uint8_t CC_id;
|
|
int UE_id;
|
|
mac_rlc_status_resp_t rlc_status;
|
|
unsigned char ta_len=0;
|
|
unsigned char header_len = 0, header_len_tmp = 0;
|
|
unsigned char sdu_lcids[11],offset,num_sdus=0;
|
|
uint16_t nb_rb;
|
|
uint16_t TBS, sdu_lengths[11],rnti,padding=0,post_padding=0;
|
|
unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
|
|
uint8_t round = 0;
|
|
uint8_t harq_pid = 0;
|
|
// LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
|
|
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
|
uint16_t sdu_length_total = 0;
|
|
short ta_update = 0;
|
|
eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id];
|
|
UE_list_t *UE_list = &eNB->UE_list;
|
|
// static int32_t tpc_accumulated=0;
|
|
UE_sched_ctrl *ue_sched_ctl;
|
|
|
|
int last_sdu_header_len = 0;
|
|
|
|
int i, j;
|
|
|
|
Protocol__FlexDlData *dl_data;
|
|
Protocol__FlexDlDci *dl_dci;
|
|
|
|
uint32_t rlc_size, n_lc, lcid;
|
|
|
|
// For each UE-related command
|
|
for (i = 0; i < n_dl_ue_data; i++) {
|
|
|
|
dl_data = dl_ue_data[i];
|
|
dl_dci = dl_data->dl_dci;
|
|
|
|
CC_id = dl_data->serv_cell_index;
|
|
// frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id);
|
|
|
|
rnti = dl_data->rnti;
|
|
UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]);
|
|
|
|
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;
|
|
|
|
//LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] Scheduling harq %d\n", frame, subframe, harq_pid);
|
|
// LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d]Now scheduling harq_pid %d (round %d)\n", frame, subframe, harq_pid, round);
|
|
|
|
// 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 and set the length appropriately
|
|
ta_len = (dl_data->ce_bitmap[0] & PROTOCOL__FLEX_CE_TYPE__FLPCET_TA) ? 2 : 0;
|
|
}
|
|
|
|
num_sdus = 0;
|
|
sdu_length_total = 0;
|
|
|
|
n_lc = dl_data->n_rlc_pdu;
|
|
// Go through each one of the channel commands and create SDUs
|
|
header_len = 0;
|
|
last_sdu_header_len = 0;
|
|
for (j = 0; j < n_lc; j++) {
|
|
sdu_lengths[j] = 0;
|
|
lcid = dl_data->rlc_pdu[j]->rlc_pdu_tb[0]->logical_channel_id;
|
|
rlc_size = dl_data->rlc_pdu[j]->rlc_pdu_tb[0]->size;
|
|
LOG_D(MAC,"[TEST] [eNB %d] [Frame %d] [Subframe %d], LCID %d, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
|
|
mod_id, frame, subframe, lcid, CC_id, rlc_size);
|
|
if (rlc_size > 0) {
|
|
|
|
rlc_status = mac_rlc_status_ind(mod_id,
|
|
rnti,
|
|
mod_id,
|
|
frame,
|
|
subframe,
|
|
ENB_FLAG_YES,
|
|
MBMS_FLAG_NO,
|
|
lcid,
|
|
0);
|
|
|
|
if (rlc_status.bytes_in_buffer > 0) {
|
|
|
|
if (rlc_status.bytes_in_buffer < rlc_size) {
|
|
rlc_size = rlc_status.bytes_in_buffer;
|
|
}
|
|
|
|
if (rlc_size <= 2) {
|
|
rlc_size = 3;
|
|
}
|
|
|
|
rlc_status = mac_rlc_status_ind(mod_id,
|
|
rnti,
|
|
mod_id,
|
|
frame,
|
|
subframe,
|
|
ENB_FLAG_YES,
|
|
MBMS_FLAG_NO,
|
|
lcid,
|
|
rlc_size); // transport block set size
|
|
|
|
LOG_D(MAC, "[TEST] RLC can give %d bytes for LCID %d during second call\n", rlc_status.bytes_in_buffer, lcid);
|
|
|
|
if (rlc_status.bytes_in_buffer > 0) {
|
|
|
|
sdu_lengths[j] = mac_rlc_data_req(mod_id,
|
|
rnti,
|
|
mod_id,
|
|
frame,
|
|
ENB_FLAG_YES,
|
|
MBMS_FLAG_NO,
|
|
lcid,
|
|
rlc_size, //not used
|
|
(char *)&dlsch_buffer[sdu_length_total]);
|
|
|
|
LOG_D(MAC,"[eNB %d][LCID %d] CC_id %d Got %d bytes from RLC\n",mod_id, lcid, CC_id, sdu_lengths[j]);
|
|
sdu_length_total += sdu_lengths[j];
|
|
sdu_lcids[j] = lcid;
|
|
|
|
UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1;
|
|
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[j];
|
|
|
|
if (sdu_lengths[j] < 128) {
|
|
header_len += 2;
|
|
last_sdu_header_len = 2;
|
|
} else {
|
|
header_len += 3;
|
|
last_sdu_header_len = 3;
|
|
}
|
|
num_sdus++;
|
|
}
|
|
}
|
|
}
|
|
} // SDU creation end
|
|
|
|
|
|
if (((sdu_length_total + header_len + ta_len) > 0)) {
|
|
|
|
header_len_tmp = header_len;
|
|
|
|
// If we have only a single SDU, header length becomes 1
|
|
if ((num_sdus) == 1) {
|
|
//if (header_len == 2 || header_len == 3) {
|
|
header_len = 1;
|
|
} else {
|
|
header_len = (header_len - last_sdu_header_len) + 1;
|
|
}
|
|
|
|
// If we need a 1 or 2 bit padding or no padding at all
|
|
if ((TBS - header_len - sdu_length_total - ta_len) <= 2
|
|
|| (TBS - header_len - sdu_length_total - ta_len) > TBS) { //protect from overflow
|
|
padding = (TBS - header_len - sdu_length_total - ta_len);
|
|
post_padding = 0;
|
|
} else { // The last sdu needs to have a length field, since we add padding
|
|
padding = 0;
|
|
header_len = header_len_tmp;
|
|
post_padding = TBS - sdu_length_total - header_len - ta_len; // 1 is for the postpadding header
|
|
}
|
|
|
|
if (ta_len > 0) {
|
|
// Reset the measurement
|
|
ta_update = flexran_get_TA(mod_id, UE_id, CC_id);
|
|
ue_sched_ctl->ta_timer = 20;
|
|
eNB_UE_stats->timing_advance_update = 0;
|
|
} else {
|
|
ta_update = 0;
|
|
}
|
|
|
|
// If there is nothing to schedule, just leave
|
|
if ((sdu_length_total) <= 0) {
|
|
harq_pid_updated[UE_id][harq_pid] = 1;
|
|
harq_pid_round[UE_id][harq_pid] = 0;
|
|
continue;
|
|
}
|
|
|
|
// LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] TBS is %d and bytes are %d\n", frame, subframe, TBS, sdu_length_total);
|
|
|
|
offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
|
|
num_sdus, //num_sdus
|
|
sdu_lengths, //
|
|
sdu_lcids,
|
|
255, // no drx
|
|
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->frame, 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].dl_cqi= eNB_UE_stats->DL_cqi[0];
|
|
|
|
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;
|
|
|
|
//nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
|
|
//Find the number of resource blocks and set them to the template for retransmissions
|
|
nb_rb = get_min_rb_unit(mod_id, CC_id);
|
|
uint16_t stats_tbs = mac_xface->get_TBS_DL(dl_dci->mcs[0], nb_rb);
|
|
|
|
while (stats_tbs < TBS) {
|
|
nb_rb += get_min_rb_unit(mod_id, CC_id);
|
|
stats_tbs = mac_xface->get_TBS_DL(dl_dci->mcs[0], nb_rb);
|
|
}
|
|
|
|
// LOG_I(FLEXRAN_AGENT, "The MCS was %d\n", dl_dci->mcs[0]);
|
|
|
|
UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb;
|
|
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb;
|
|
UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=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;
|
|
|
|
//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);
|
|
} else {
|
|
LOG_D(FLEXRAN_AGENT, "No need to schedule a dci after all. Just drop it\n");
|
|
harq_pid_updated[UE_id][harq_pid] = 1;
|
|
harq_pid_round[UE_id][harq_pid] = 0;
|
|
continue;
|
|
}
|
|
} else {
|
|
// No need to create anything apart of DCI in case of retransmission
|
|
/*TODO: Must add these */
|
|
// 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=nCCECC_id];
|
|
}
|
|
|
|
// UE_list->UE_template[CC_id][UE_id].oldNDI[dl_dci->harq_process] = dl_dci->ndi[0];
|
|
// eNB_UE_stats->dlsch_mcs1 = dl_dci->mcs[0];
|
|
|
|
//Fill the proper DCI of OAI
|
|
flexran_fill_oai_dci(mod_id, CC_id, rnti, dl_dci);
|
|
}
|
|
}
|
|
void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
|
|
Protocol__FlexDlDci *dl_dci) {
|
|
|
|
void *DLSCH_dci = NULL;
|
|
DCI_PDU *DCI_pdu;
|
|
|
|
unsigned char harq_pid = 0;
|
|
// unsigned char round = 0;
|
|
LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
|
|
int size_bits = 0, size_bytes = 0;
|
|
eNB_MAC_INST *eNB = &eNB_mac_inst[mod_id];
|
|
UE_list_t *UE_list = &eNB->UE_list;
|
|
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
|
|
|
int UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]);
|
|
|
|
uint32_t format;
|
|
|
|
harq_pid = dl_dci->harq_process;
|
|
// round = dl_dci->rv[0];
|
|
|
|
// 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);
|
|
|
|
if (dl_dci->has_tpc == 1) {
|
|
// Check if tpc has been set and reset measurement */
|
|
if ((dl_dci->tpc == 0) || (dl_dci->tpc == 2)) {
|
|
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
|
|
eNB_UE_stats->Po_PUCCH_update = 0;
|
|
}
|
|
}
|
|
|
|
|
|
switch (frame_parms[CC_id]->N_RB_DL) {
|
|
case 6:
|
|
if (frame_parms[CC_id]->frame_type == TDD) {
|
|
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
|
|
FILL_DCI_TDD_1(DCI1_1_5MHz_TDD_t, DLSCH_dci, dl_dci);
|
|
size_bytes = sizeof(DCI1_1_5MHz_TDD_t);
|
|
size_bits = sizeof_DCI1_1_5MHz_TDD_t;
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
|
|
//TODO
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
|
|
//TODO
|
|
}
|
|
} else {
|
|
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
|
|
FILL_DCI_FDD_1(DCI1_1_5MHz_FDD_t, DLSCH_dci, dl_dci);
|
|
size_bytes = sizeof(DCI1_1_5MHz_FDD_t);
|
|
size_bits = sizeof_DCI1_1_5MHz_FDD_t;
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
|
|
//TODO
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
|
|
//TODO
|
|
}
|
|
}
|
|
break;
|
|
case 25:
|
|
if (frame_parms[CC_id]->frame_type == TDD) {
|
|
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
|
|
FILL_DCI_TDD_1(DCI1_5MHz_TDD_t, DLSCH_dci, dl_dci);
|
|
size_bytes = sizeof(DCI1_5MHz_TDD_t);
|
|
size_bits = sizeof_DCI1_5MHz_TDD_t;
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
|
|
//TODO
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
|
|
//TODO
|
|
}
|
|
} else {
|
|
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
|
|
FILL_DCI_FDD_1(DCI1_5MHz_FDD_t, DLSCH_dci, dl_dci);
|
|
size_bytes = sizeof(DCI1_5MHz_FDD_t);
|
|
size_bits = sizeof_DCI1_5MHz_FDD_t;
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
|
|
//TODO
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
|
|
//TODO
|
|
}
|
|
}
|
|
break;
|
|
case 50:
|
|
if (frame_parms[CC_id]->frame_type == TDD) {
|
|
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
|
|
FILL_DCI_TDD_1(DCI1_10MHz_TDD_t, DLSCH_dci, dl_dci);
|
|
size_bytes = sizeof(DCI1_10MHz_TDD_t);
|
|
size_bits = sizeof_DCI1_10MHz_TDD_t;
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
|
|
//TODO
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
|
|
//TODO
|
|
}
|
|
} else {
|
|
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
|
|
FILL_DCI_FDD_1(DCI1_10MHz_FDD_t, DLSCH_dci, dl_dci);
|
|
size_bytes = sizeof(DCI1_10MHz_FDD_t);
|
|
size_bits = sizeof_DCI1_10MHz_FDD_t;
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
|
|
//TODO
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
|
|
//TODO
|
|
}
|
|
}
|
|
break;
|
|
case 100:
|
|
if (frame_parms[CC_id]->frame_type == TDD) {
|
|
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
|
|
FILL_DCI_TDD_1(DCI1_20MHz_TDD_t, DLSCH_dci, dl_dci);
|
|
size_bytes = sizeof(DCI1_20MHz_TDD_t);
|
|
size_bits = sizeof_DCI1_20MHz_TDD_t;
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
|
|
//TODO
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
|
|
//TODO
|
|
}
|
|
} else {
|
|
if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
|
|
FILL_DCI_FDD_1(DCI1_20MHz_FDD_t, DLSCH_dci, dl_dci);
|
|
size_bytes = sizeof(DCI1_20MHz_FDD_t);
|
|
size_bits = sizeof_DCI1_20MHz_FDD_t;
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
|
|
//TODO
|
|
} else if (dl_dci->format == PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
|
|
//TODO
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
//Set format to the proper type
|
|
switch(dl_dci->format) {
|
|
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1:
|
|
format = format1;
|
|
break;
|
|
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1A:
|
|
format = format1A;
|
|
break;
|
|
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1B:
|
|
format = format1B;
|
|
break;
|
|
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1C:
|
|
format = format1C;
|
|
break;
|
|
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D:
|
|
format = format1E_2A_M10PRB;
|
|
break;
|
|
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2:
|
|
format = format2;
|
|
break;
|
|
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A:
|
|
format = format2A;
|
|
break;
|
|
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2B:
|
|
format = format2B;
|
|
break;
|
|
case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_3:
|
|
format = 3;
|
|
break;
|
|
default:
|
|
/*TODO: Need to deal with unsupported DCI type*/
|
|
return;
|
|
}
|
|
|
|
add_ue_spec_dci(DCI_pdu,
|
|
DLSCH_dci,
|
|
rnti,
|
|
size_bytes,
|
|
dl_dci->aggr_level,
|
|
size_bits,
|
|
format,
|
|
0);
|
|
}
|