flexran_agent_scheduler_dataplane.c 17.5 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 "SIMULATION/TOOLS/defs.h" // for taus

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

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

  // 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) {
80 81
    flexran_apply_ue_spec_scheduling_decisions(mod_id, frame, subframe, mbsfn_flag,
					       mac_config->n_dl_ue_data, mac_config->dl_ue_data);
82 83 84 85 86
  }
  
}


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

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

114 115
  int last_sdu_header_len = 0;

116
  int i, j;
117

118 119
  Protocol__FlexDlData *dl_data;
  Protocol__FlexDlDci *dl_dci;
120 121 122 123 124

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

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

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

      if (ta_len > 0) {
	// Reset the measurement
	ue_sched_ctl->ta_timer = 20;
	eNB_UE_stats->timing_advance_update = 0;
163 164
	//	header_len = ta_len;
	//last_sdu_header_len = ta_len;
165
      }
166

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

	  if (rlc_status.bytes_in_buffer > 0) {

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

193 194 195 196 197 198 199 200
	    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
201
	  
202
	    sdu_lengths[j] = 0;
203
	  
204
	    LOG_D(MAC, "[TEST] RLC can give %d bytes for LCID %d during second call\n", rlc_status.bytes_in_buffer, lcid);
205
	  
206 207
	    if (rlc_status.bytes_in_buffer > 0) {
	      
208
	      sdu_lengths[j] = mac_rlc_data_req(mod_id,
209 210 211 212 213 214 215
						rnti,
						mod_id,
						frame,
						ENB_FLAG_YES,
						MBMS_FLAG_NO,
						lcid,
						(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
	ta_update = (ta_len > 0) ? ue_sched_ctl->ta_update : 0;
262
	
263
	// If there is nothing to schedule, just leave
264
	if ((sdu_length_total) <= 0) { 
265 266
	  harq_pid_updated[UE_id][harq_pid] = 1;
	  harq_pid_round[UE_id][harq_pid] = 0;
267
	  continue;
268
	}
269 270

	//	LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] TBS is %d and bytes are %d\n", frame, subframe, TBS, sdu_length_total);
271 272 273 274 275 276 277 278 279 280
	
	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);
281 282

	
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
	
#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);
300
	}
301 302 303 304 305
	
	//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),
306
		    eNB->frame, eNB->subframe,0,0);
307 308 309 310 311 312 313 314 315 316 317 318 319 320
	  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;
	
321 322 323 324 325 326 327 328 329
	//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);
	}
330 331

	//	LOG_I(FLEXRAN_AGENT, "The MCS was %d\n", dl_dci->mcs[0]);
332
	
333 334 335 336 337 338
	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;
	
339
	UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes= TBS - sdu_length_total;
340 341 342 343
	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;
	
344 345
	//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);
346 347 348 349
      }
    } else {
      // No need to create anything apart of DCI in case of retransmission
      /*TODO: Must add these */
350
      //      eNB_UE_stats->dlsch_trials[round]++;
351 352 353 354 355
      //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];
    }
356

357 358
    //    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];
359

360
    //Fill the proper DCI of OAI
361
    flexran_fill_oai_dci(mod_id, CC_id, rnti, dl_dci);
362 363
  }
}
364 365
void flexran_fill_oai_dci(mid_t mod_id, uint32_t CC_id, uint32_t rnti,
		  Protocol__FlexDlDci *dl_dci) {
366 367 368 369 370

  void         *DLSCH_dci        = NULL;
  DCI_PDU      *DCI_pdu;

  unsigned char         harq_pid         = 0;
371
  //  unsigned char round = 0;
372
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs];
373
  int           size_bits = 0, size_bytes = 0;
374 375
  eNB_MAC_INST         *eNB      = &eNB_mac_inst[mod_id];
  UE_list_t            *UE_list  = &eNB->UE_list;
376
  LTE_eNB_UE_stats *eNB_UE_stats = NULL;
377 378 379

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

380 381
  uint32_t format;

382
  harq_pid = dl_dci->harq_process;
383
  //  round = dl_dci->rv[0];
384 385 386 387 388 389
  
  // 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);
390 391 392 393 394 395 396 397 398

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

495 496
  //Set format to the proper type
  switch(dl_dci->format) {
497
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1:
498 499
    format = format1;
    break;
500
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1A:
501 502
    format = format1A;
    break;
503
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1B:
504 505
    format = format1B;
    break;
506
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1C:
507 508
    format = format1C;
    break;
509
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_1D:
510 511
    format = format1E_2A_M10PRB;
    break;
512
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2:
513 514
    format  = format2;
    break;
515
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2A:
516 517
    format = format2A;
    break;
518
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_2B:
519 520
    format = format2B;
    break;
521
  case PROTOCOL__FLEX_DCI_FORMAT__FLDCIF_3:
522 523 524 525 526
    format = 3;
    break;
  default:
    /*TODO: Need to deal with unsupported DCI type*/
    return;
527
  }
528
  
529 530 531 532 533 534 535 536
  add_ue_spec_dci(DCI_pdu,
		  DLSCH_dci,
		  rnti,
		  size_bytes,
		  dl_dci->aggr_level,
		  size_bits,
		  format,
		  0);
537
}