flexran_agent_scheduler_dataplane.c 17.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * 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
 */ 
21

22
/*! \file flexran_agent_scheduler_dataplane.c
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
 * \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"

39
#include "LAYER2/MAC/flexran_agent_mac_proto.h"
40 41 42
#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/proto.h"
#include "LAYER2/MAC/extern.h"
43
#include "LAYER2/MAC/flexran_dci_conversions.h"
44 45 46 47 48 49 50 51 52 53 54

#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"
55
#include "flexran.pb-c.h"
56
#include "flexran_agent_extern.h"
57

58 59
#include "flexran_agent_common.h"

60 61
#include "SIMULATION/TOOLS/defs.h" // for taus

62 63 64 65
void flexran_apply_dl_scheduling_decisions(mid_t mod_id,
					   uint32_t frame,
					   uint32_t subframe,
					   int *mbsfn_flag,
66
					   Protocol__FlexranMessage *dl_scheduling_info) {
67

68
  Protocol__FlexDlMacConfig *mac_config = dl_scheduling_info->dl_mac_config_msg;
69 70 71 72 73 74 75 76 77 78 79 80 81

  // Check if there is anything to schedule for random access
  if (mac_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_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_config->n_dl_ue_data > 0) {
82 83
    flexran_apply_ue_spec_scheduling_decisions(mod_id, frame, subframe, mbsfn_flag,
					       mac_config->n_dl_ue_data, mac_config->dl_ue_data);
84 85 86 87 88
  }
  
}


89 90 91 92 93
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,
94
						Protocol__FlexDlData **dl_ue_data) {
95 96 97 98

  uint8_t               CC_id;
  int                   UE_id;
  mac_rlc_status_resp_t rlc_status;
99 100
  unsigned char         ta_len=0;
  unsigned char         header_len = 0, header_len_tmp = 0;
101
  unsigned char         sdu_lcids[11],offset,num_sdus=0;
102
  uint16_t              nb_rb;
103
  uint16_t              TBS, sdu_lengths[11],rnti,padding=0,post_padding=0;
104
  unsigned char         dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
105 106
  uint8_t         round            = 0;
  uint8_t         harq_pid         = 0;
107
  //  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs];
108 109 110 111 112
  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;
113
  //  static int32_t          tpc_accumulated=0;
114 115
  UE_sched_ctrl           *ue_sched_ctl;

116 117
  int last_sdu_header_len = 0;

118
  int i, j;
119

120 121
  Protocol__FlexDlData *dl_data;
  Protocol__FlexDlDci *dl_dci;
122 123 124 125 126

  uint32_t rlc_size, n_lc, lcid;
  
  // For each UE-related command
  for (i = 0; i < n_dl_ue_data; i++) {
127
    
128 129 130 131
    dl_data = dl_ue_data[i];
    dl_dci = dl_data->dl_dci;

    CC_id = dl_data->serv_cell_index;
132
    //    frame_parms[CC_id] = mac_xface->get_lte_frame_parms(mod_id, CC_id);
133 134 135 136 137 138 139 140 141 142
    
    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;
    
143 144 145
    //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);

146 147 148 149 150 151 152 153
    // 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) {
154
	//Check if there is TA command and set the length appropriately
155
	ta_len = (dl_data->ce_bitmap[0] & PROTOCOL__FLEX_CE_TYPE__FLPCET_TA) ? 2 : 0; 
156
      }
157

158 159
      num_sdus = 0;
      sdu_length_total = 0;
160

161 162
      n_lc = dl_data->n_rlc_pdu;
      // Go through each one of the channel commands and create SDUs
163 164
      header_len = 0;
      last_sdu_header_len = 0;
165
      for (j = 0; j < n_lc; j++) {
166
	sdu_lengths[j] = 0;
167 168
	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;
169 170
	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);
171 172 173
	if (rlc_size > 0) {
	  
	  rlc_status = mac_rlc_status_ind(mod_id,
174 175 176
	   				  rnti,
	   				  mod_id,
	   				  frame,
177
					  subframe,
178 179 180 181 182 183 184
	   				  ENB_FLAG_YES,
	   				  MBMS_FLAG_NO,
	   				  lcid,
	   				  0);

	  if (rlc_status.bytes_in_buffer > 0) {

185 186
	    if (rlc_status.bytes_in_buffer < rlc_size) {
	      rlc_size = rlc_status.bytes_in_buffer;
187 188
	    }

189 190 191 192
	    if (rlc_size <= 2) { 
	      rlc_size = 3; 
	    } 

193 194 195 196
	    rlc_status = mac_rlc_status_ind(mod_id,
					    rnti,
					    mod_id,
					    frame,
197
						subframe,
198 199 200 201
					    ENB_FLAG_YES,
					    MBMS_FLAG_NO,
					    lcid,
					    rlc_size); // transport block set size
202
	  
203
	    LOG_D(MAC, "[TEST] RLC can give %d bytes for LCID %d during second call\n", rlc_status.bytes_in_buffer, lcid);
204
	  
205 206
	    if (rlc_status.bytes_in_buffer > 0) {
	      
207
	      sdu_lengths[j] = mac_rlc_data_req(mod_id,
208 209 210 211 212 213
						rnti,
						mod_id,
						frame,
						ENB_FLAG_YES,
						MBMS_FLAG_NO,
						lcid,
214
						rlc_size, //not used
215
						(char *)&dlsch_buffer[sdu_length_total]);
216
	      
217 218 219
	      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;
220 221
	      
	      UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1;
222
	      UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[j];
223
	      
224
	      if (sdu_lengths[j] < 128) {
225
		header_len += 2;
226
		last_sdu_header_len = 2;
227 228
	      } else {
		header_len += 3;
229
		last_sdu_header_len = 3;
230 231 232
	      }
	      num_sdus++;
	    }
233 234 235 236 237
	  }
	}
      } // SDU creation end
      
      
238 239 240
      if (((sdu_length_total + header_len + ta_len) > 0)) {
	
	header_len_tmp = header_len;
241
	
242
	// If we have only a single SDU, header length becomes 1
243
	if ((num_sdus) == 1) {
244
	  //if (header_len == 2 || header_len == 3) {
245
	  header_len = 1;
246
	} else {
247
	  header_len = (header_len - last_sdu_header_len) + 1;
248 249
	}
	
250 251 252 253 254 255 256 257 258
	// 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
259
	}
260 261 262 263 264 265 266 267 268 269
		
	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;
	}

270
	// If there is nothing to schedule, just leave
271
	if ((sdu_length_total) <= 0) { 
272 273
	  harq_pid_updated[UE_id][harq_pid] = 1;
	  harq_pid_round[UE_id][harq_pid] = 0;
274
	  continue;
275
	}
276 277

	//	LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] TBS is %d and bytes are %d\n", frame, subframe, TBS, sdu_length_total);
278 279 280 281 282 283 284 285 286 287
	
	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);
288 289

	
290 291


292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
	
#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);
309
	}
310 311 312 313 314
	
	//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),
315
		    eNB->frame, eNB->subframe,0,0);
316 317 318 319 320 321 322 323 324 325 326 327 328 329
	  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;
	
330 331 332 333 334 335 336 337 338
	//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);
	}
339 340

	//	LOG_I(FLEXRAN_AGENT, "The MCS was %d\n", dl_dci->mcs[0]);
341
	
342 343 344 345 346 347
	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;
	
348
	UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes= TBS - sdu_length_total;
349 350 351 352
	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;
	
353 354
	//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);
355 356 357 358 359
      } 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;
360 361 362 363
      }
    } else {
      // No need to create anything apart of DCI in case of retransmission
      /*TODO: Must add these */
364
      //      eNB_UE_stats->dlsch_trials[round]++;
365 366 367 368 369
      //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];
    }
370

371 372
    //    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];
373

374
    //Fill the proper DCI of OAI
375
    flexran_fill_oai_dci(mod_id, CC_id, rnti, dl_dci);
376 377
  }
}
378 379
void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
		  Protocol__FlexDlDci *dl_dci) {
380 381 382 383 384

  void         *DLSCH_dci        = NULL;
  DCI_PDU      *DCI_pdu;

  unsigned char         harq_pid         = 0;
385
  //  unsigned char round = 0;
386
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs];
387
  int           size_bits = 0, size_bytes = 0;
388 389
  eNB_MAC_INST         *eNB      = &eNB_mac_inst[mod_id];
  UE_list_t            *UE_list  = &eNB->UE_list;
390
  LTE_eNB_UE_stats *eNB_UE_stats = NULL;
391 392 393

  int UE_id = find_ue(rnti, PHY_vars_eNB_g[mod_id][CC_id]);

394 395
  uint32_t format;

396
  harq_pid = dl_dci->harq_process;
397
  //  round = dl_dci->rv[0];
398 399 400 401 402 403
  
  // 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);
404 405 406 407 408 409 410 411 412

  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;
    }
  }
  
413 414 415 416
  
  switch (frame_parms[CC_id]->N_RB_DL) {
  case 6:
    if (frame_parms[CC_id]->frame_type == TDD) {
417
      if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
418
	FILL_DCI_TDD_1(DCI1_1_5MHz_TDD_t, DLSCH_dci, dl_dci);
419 420
	size_bytes = sizeof(DCI1_1_5MHz_TDD_t);
	size_bits  = sizeof_DCI1_1_5MHz_TDD_t;
421
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
422
	//TODO
423
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
424 425 426
	//TODO
      }
    } else {
427
      if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
428
	FILL_DCI_FDD_1(DCI1_1_5MHz_FDD_t, DLSCH_dci, dl_dci);
429 430
	size_bytes = sizeof(DCI1_1_5MHz_FDD_t);
	size_bits  = sizeof_DCI1_1_5MHz_FDD_t;
431
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
432
	//TODO
433
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
434 435 436 437 438 439
	  //TODO
      }
    }
    break;
  case 25:
    if (frame_parms[CC_id]->frame_type == TDD) {
440
      if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
441
	FILL_DCI_TDD_1(DCI1_5MHz_TDD_t, DLSCH_dci, dl_dci);
442 443
	size_bytes = sizeof(DCI1_5MHz_TDD_t);
	size_bits  = sizeof_DCI1_5MHz_TDD_t;
444
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
445
	//TODO
446
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
447 448 449
	//TODO
      }
    } else {
450
      if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
451
	FILL_DCI_FDD_1(DCI1_5MHz_FDD_t, DLSCH_dci, dl_dci);
452 453
	size_bytes = sizeof(DCI1_5MHz_FDD_t);
	size_bits  = sizeof_DCI1_5MHz_FDD_t;
454
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
455
	//TODO
456
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
457 458 459 460 461 462
	//TODO
      }
    }
    break;
  case 50:
    if (frame_parms[CC_id]->frame_type == TDD) {
463
      if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
464
	FILL_DCI_TDD_1(DCI1_10MHz_TDD_t, DLSCH_dci, dl_dci);
465 466
	size_bytes = sizeof(DCI1_10MHz_TDD_t);
	size_bits  = sizeof_DCI1_10MHz_TDD_t;
467
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
468
	//TODO
469
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
470 471 472
	//TODO
      }
    } else {
473
      if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
474
	FILL_DCI_FDD_1(DCI1_10MHz_FDD_t, DLSCH_dci, dl_dci);
475 476
	size_bytes = sizeof(DCI1_10MHz_FDD_t);
	size_bits  = sizeof_DCI1_10MHz_FDD_t;
477
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
478
	//TODO
479
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
480 481 482 483 484 485
	//TODO
      }
    }
    break;
  case 100:
    if (frame_parms[CC_id]->frame_type == TDD) {
486
      if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
487
	FILL_DCI_TDD_1(DCI1_20MHz_TDD_t, DLSCH_dci, dl_dci);
488 489
	size_bytes = sizeof(DCI1_20MHz_TDD_t);
	size_bits  = sizeof_DCI1_20MHz_TDD_t;
490
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
491
	//TODO
492
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
493 494 495
	//TODO
      }
    } else {
496
      if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1) {
497
	FILL_DCI_FDD_1(DCI1_20MHz_FDD_t, DLSCH_dci, dl_dci);
498 499
	size_bytes = sizeof(DCI1_20MHz_FDD_t);
	size_bits  = sizeof_DCI1_20MHz_FDD_t;
500
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A) {
501
	//TODO
502
      } else if (dl_dci->format ==  PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D) {
503 504 505 506 507 508
	//TODO
      }
    }
    break;
  }

509 510
  //Set format to the proper type
  switch(dl_dci->format) {
511
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1:
512 513
    format = format1;
    break;
514
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1A:
515 516
    format = format1A;
    break;
517
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1B:
518 519
    format = format1B;
    break;
520
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1C:
521 522
    format = format1C;
    break;
523
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D:
524 525
    format = format1E_2A_M10PRB;
    break;
526
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2:
527 528
    format  = format2;
    break;
529
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A:
530 531
    format = format2A;
    break;
532
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2B:
533 534
    format = format2B;
    break;
535
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_3:
536 537 538 539 540
    format = 3;
    break;
  default:
    /*TODO: Need to deal with unsupported DCI type*/
    return;
541
  }
542
  
543 544 545 546 547 548 549 550
  add_ue_spec_dci(DCI_pdu,
		  DLSCH_dci,
		  rnti,
		  size_bytes,
		  dl_dci->aggr_level,
		  size_bits,
		  format,
		  0);
551
}