/*
 * Copyright 2017 Cisco Systems, Inc.
 * 
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 * 
 * 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.
 */

#include "mac.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vendor_ext.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <pthread.h>
#include <unistd.h>

#include <mutex>
#include <queue>
#include <list>

uint32_t rand_range(uint32_t min, uint32_t max)
{
	return ((rand() % (max + 1 - min)) + min);
}

struct mac_pdu
{
	mac_pdu() : buffer_len(1500), buffer(0), len(0)
	{
		buffer = (char*) malloc(buffer_len);
	}
	
	virtual ~mac_pdu()
	{
		free(buffer);
	}

	unsigned buffer_len;
	char* buffer;
	unsigned len;
};

class mac_private
{
		std::mutex mutex;
		std::queue<mac_pdu*> rx_buffer;

		std::queue<mac_pdu*> free_store;
	public:

		mac_private(bool _wireshark_test_mode)
			: byte_count(0), tick(0), wireshark_test_mode(_wireshark_test_mode)
		{

		}

		mac_pdu* allocate_mac_pdu()
		{
			mac_pdu* pdu = 0;
			mutex.lock();
			if(free_store.empty())
			{
				pdu = new mac_pdu();
			}
			else
			{
				pdu = free_store.front();
				free_store.pop();
			}
			mutex.unlock();
			return pdu;
		}

		void release_mac_pdu(mac_pdu* pdu)
		{
			mutex.lock();
			free_store.push(pdu);
			mutex.unlock();
		}

		

		void push_rx_buffer(mac_pdu* buff)
		{
			mutex.lock();
			rx_buffer.push(buff);
			mutex.unlock();
		}

		mac_pdu* pop_rx_buffer()
		{
			mac_pdu* buff = 0;
			mutex.lock();
			if(!rx_buffer.empty())
			{
				buff = rx_buffer.front();
				rx_buffer.pop();
			}
			mutex.unlock();
			return buff;
		}

		uint32_t byte_count;
		uint32_t tick;
		
		bool wireshark_test_mode;

};

extern "C"
{
	typedef struct {
		mac_t _public;

		int rx_sock;
		int tx_sock;
		struct sockaddr_in tx_addr;

		uint32_t tx_byte_count;

		mac_private* mac;
		
	} mac_internal_t;

	mac_t* mac_create(uint8_t wireshark_test_mode)
	{
		mac_internal_t* instance = (mac_internal_t*)malloc(sizeof(mac_internal_t));
		instance->mac = new mac_private((wireshark_test_mode >= 1));
		return (mac_t*)instance;
	}
	
	void mac_destroy(mac_t* mac)
	{
		mac_internal_t* instance = (mac_internal_t*)mac;
		delete instance->mac;
		free(instance);
	}
	
	void* mac_rx_thread_start(void* ptr)
	{
		mac_internal_t* instance = (mac_internal_t*)ptr;

		while(1)
		{
			mac_pdu* pdu = instance->mac->allocate_mac_pdu();
			int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, 0, 0, 0);
			if(len > 0)
			{
				pdu->len = len;
				instance->mac->push_rx_buffer(pdu);
			}
			else
			{
				instance->mac->release_mac_pdu(pdu);
			}
		}
		return 0;
	}

	void mac_start_data(mac_t* mac, unsigned rx_port, const char* tx_address, unsigned tx_port)
	{
		mac_internal_t* instance = (mac_internal_t*)mac;

		printf("[MAC] Rx Data from %d\n", rx_port);
		printf("[MAC] Tx Data to %s.%d\n", tx_address, tx_port);

		instance->rx_sock = socket(AF_INET, SOCK_DGRAM, 0);
		
		if(instance->rx_sock < 0)
		{
			printf("[MAC] Failed to create socket\n");
			return;
		}

		struct sockaddr_in addr;
		memset(&addr, 0, sizeof(0));
		addr.sin_family = AF_INET;
		addr.sin_port = htons(rx_port);
		addr.sin_addr.s_addr = INADDR_ANY;
		
		if(bind(instance->rx_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
		{
			printf("[MAC] Failed to bind to %d\n", rx_port);
			close(instance->rx_sock);
			return;
		}

		pthread_t mac_rx_thread;
		pthread_create(&mac_rx_thread, NULL, &mac_rx_thread_start, instance);

		instance->tx_sock = socket(AF_INET, SOCK_DGRAM, 0);
		instance->tx_addr.sin_family = AF_INET;
		instance->tx_addr.sin_port = htons(tx_port);
		instance->tx_addr.sin_addr.s_addr = inet_addr(tx_address);
	}


	
	void generate_test_subframe(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf)	
	{
		//mac_internal_t* instance = (mac_internal_t*)mac;
		
		uint8_t max_num_dl_pdus = 50;
		nfapi_dl_config_request_pdu_t dl_config_pdus[max_num_dl_pdus];
		memset(&dl_config_pdus, 0, sizeof(dl_config_pdus));
		
		nfapi_dl_config_request_t dl_config_req;
		memset(&dl_config_req, 0, sizeof(dl_config_req));
		dl_config_req.header.message_id = NFAPI_DL_CONFIG_REQUEST;
		dl_config_req.header.phy_id = phy_id;
		dl_config_req.sfn_sf = sfn_sf;
		dl_config_req.dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
		
		dl_config_req.dl_config_request_body.number_pdu = rand_range(4, max_num_dl_pdus);
		
		uint16_t i = 0;
		for(i = 0; i < dl_config_req.dl_config_request_body.number_pdu; ++i)
		{
			dl_config_pdus[i].pdu_type = rand_range(0, 11);
			
			switch(dl_config_pdus[i].pdu_type)
			{
				case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE:
				{
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.dci_format = rand_range(0, 9);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = rand_range(0, 255);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level  = rand_range(0, 32);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti = rand_range(0, (uint16_t)-1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = rand_range(0, 320000);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = rand_range(0, 31);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rand_range(0, 3);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = rand_range(0, 31);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = rand_range(0, 31);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_2 = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.harq_process = rand_range(0, 31);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tpmi = rand_range(0, 15);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.pmi = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.precoding_information = rand_range(0, 63);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tpc = rand_range(0, 3);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = rand_range(0, 15);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.ngap = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transport_block_size_index = rand_range(0, 31);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.downlink_power_offset = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.allocate_prach_flag = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.preamble_index = rand_range(0, 63);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.prach_mask_index = rand_range(0, 15);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = rand_range(0, 3);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = rand_range(0, 10000);		
					
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG;
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.mcch_flag = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.mcch_change_notification = rand_range(0, 255);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.scrambling_identity = rand_range(0, 1);
					
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG;
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.carrier_indicator = rand_range(0, 7);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.srs_flag = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.srs_request = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.antenna_ports_scrambling_and_layers = rand_range(0, 15);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.n_dl_rb = rand_range(0, 100);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG;
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.harq_ack_resource_offset = rand_range(0, 3);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.pdsch_re_mapping_quasi_co_location_indicator = rand_range(0, 3);
					
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG;
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.primary_cell_type = rand_range(0, 2);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_flag = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.number_ul_dl_configurations = 2;
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_indication[0] = rand_range(1, 5);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_indication[1] = rand_range(1, 5);
					
					
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG;
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.laa_end_partial_sf_flag = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.laa_end_partial_sf_configuration = rand_range(0, 255);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.initial_lbt_sf = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.codebook_size_determination = rand_range(0, 1);
					dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.drms_table_flag = rand_range(0, 1);
					
					// if the tpm extention is present of not.
					if(rand_range(0, 1))
					{
						dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm_struct_flag = rand_range(0, 1);
						dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_prb_per_subband = rand_range(0, 8);
						dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.number_of_subbands = rand_range(0, 13);
						dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_antennas = 1; // rand_range(0, 8);
						
						for(int j = 0; j < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.number_of_subbands; ++j)
						{
							dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].subband_index = j;
							dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].scheduled_ues = 1; //rand_range(1, 4);
							
							for(int k = 0; k < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_antennas; ++k)
								for(int l = 0; l < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].scheduled_ues; ++l)
									dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].precoding_value[k][l] = rand_range(0, 65535);
						}
					}
					else
					{
						dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm_struct_flag = 0;
					}
					
				}
				break;
				
				case NFAPI_DL_CONFIG_BCH_PDU_TYPE:
				{
					dl_config_pdus[i].bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG;
					dl_config_pdus[i].bch_pdu.bch_pdu_rel8.length = rand_range(0, 42);
					dl_config_pdus[i].bch_pdu.bch_pdu_rel8.pdu_index = rand_range(0, 65535);
					dl_config_pdus[i].bch_pdu.bch_pdu_rel8.transmission_power = rand_range(0, 10000);
				}
				break;
				
				case NFAPI_DL_CONFIG_MCH_PDU_TYPE:
				{
					dl_config_pdus[i].mch_pdu.mch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG;
					dl_config_pdus[i].mch_pdu.mch_pdu_rel8.length = rand_range(0, 42);
					dl_config_pdus[i].mch_pdu.mch_pdu_rel8.pdu_index = rand_range(0, 65535);
					dl_config_pdus[i].mch_pdu.mch_pdu_rel8.rnti = 0xFFFD;
					dl_config_pdus[i].mch_pdu.mch_pdu_rel8.resource_allocation_type = 0;
					dl_config_pdus[i].mch_pdu.mch_pdu_rel8.resource_block_coding = 0;
					dl_config_pdus[i].mch_pdu.mch_pdu_rel8.modulation = rand_range(0, 8);
					dl_config_pdus[i].mch_pdu.mch_pdu_rel8.transmission_power = rand_range(0, 10000);
					dl_config_pdus[i].mch_pdu.mch_pdu_rel8.mbsfn_area_id = rand_range(0, 255);
				}
				break;
			
				case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE:
				{
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.length = rand_range(0, 42);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.pdu_index = rand_range(0, 65535);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.rnti = rand_range(1, 65535);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = rand_range(0, 5);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = rand_range(0, 32000);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.modulation = rand_range(2, 8);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rand_range(0, 3);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transport_blocks = rand_range(1, 2);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = rand_range(0, 13);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.number_of_layers = rand_range(1, 8);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 2; //rand_range(0, 13);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.codebook_index[0] = rand_range(0, 15);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.codebook_index[1] = rand_range(0, 15);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = rand_range(0, 14);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.pa = rand_range(0, 7);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.ngap = rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.nprb = rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transmission_mode = rand_range(1, 10);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 2; //rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 2; //rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].subband_index = rand_range(0, 4);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].num_antennas = 1;	
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].bf_value[0] = rand_range(0, 128);	
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].subband_index = rand_range(0, 4);	
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].num_antennas = 1;
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].bf_value[0] = rand_range(0, 128);	
					
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG;
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel9.nscid = rand_range(0, 1);	
					
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG;
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_flag = rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_resource_config_r10 = 0;
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_zero_tx_power_resource_config_bitmap_r10 = rand_range(0, 65535);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_number_nzp_configuration = 1;
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_resource_config[0] = rand_range(0, 31);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.pdsch_start = rand_range(0, 4);		
					
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG;
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.drms_config_flag = rand_range(0, 1);	
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.drms_scrambling = rand_range(0, 503);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.csi_config_flag = rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.csi_scrambling = rand_range(0, 503);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_flag = rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_atenna_ports = rand_range(1,4);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_freq_shift = rand_range(0, 5);
					
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG;
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.altcqi_table_r12 = rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.maxlayers = rand_range(1, 8);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.n_dl_harq = rand_range(0, 255);
					
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.dwpts_symbols = rand_range(3, 14);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.initial_lbt_sf = rand_range(0, 1);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.ue_type = rand_range(0, 2);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = rand_range(0, 2);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239);
					dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = rand_range(0, 1);
				}
				break;
			
				case NFAPI_DL_CONFIG_PCH_PDU_TYPE:
				{
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG;
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.length = rand_range(0, 42);
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.pdu_index = rand_range(0, 65535);
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.p_rnti = 0xFFFE;
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.resource_allocation_type = rand_range(2, 6);
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1);
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.resource_block_coding = rand_range(0, 34000);
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.mcs = 0;
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.redundancy_version = 0;
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.number_of_transport_blocks = 1;
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transport_block_to_codeword_swap_flag = 0;
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transmission_scheme = rand_range(1, 6);
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.number_of_layers = rand_range(1, 4);
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.codebook_index = 0;
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.ue_category_capacity = rand_range(0, 14);
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.pa = rand_range(0, 7);
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transmission_power = rand_range(0, 10000);
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.nprb = rand_range(0, 1);
					dl_config_pdus[i].pch_pdu.pch_pdu_rel8.ngap = rand_range(0, 1);	
					dl_config_pdus[i].pch_pdu.pch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG;
					dl_config_pdus[i].pch_pdu.pch_pdu_rel13.ue_mode = rand_range(0, 1);	
					dl_config_pdus[i].pch_pdu.pch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239);
				}
				break;
			
				case NFAPI_DL_CONFIG_PRS_PDU_TYPE:
				{
					dl_config_pdus[i].prs_pdu.prs_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG;
					dl_config_pdus[i].prs_pdu.prs_pdu_rel9.transmission_power = rand_range(0, 10000);	
					dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_bandwidth = rand_range(6, 100);
					dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_cyclic_prefix_type = rand_range(0, 1);
					dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_muting = rand_range(0, 1);
				}
				break;
	
				case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE:
				{
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG;
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_antenna_port_count_r10 = rand_range(1, 16);
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config_r10 = 0;
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.transmission_power = rand_range(0, 10000);
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_zero_tx_power_resource_config_bitmap_r10 = rand_range(0, 8);
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_number_of_nzp_configuration = 2;
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config[0] = rand_range(0, 31);
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config[1] = rand_range(0, 31);
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG;
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.csi_rs_class = rand_range(0, 2);
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.cdm_type = rand_range(0, 1);
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.num_bf_vector = 0; // set to zero as not clear how to handle bf value array
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.bf_vector[0].csi_rs_resource_index = rand_range(0, 7);
					dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.bf_vector[0].bf_value[0] = 42;
				}
				break;
	
				case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE:
				{
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG;
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.dci_format = rand_range(0, 9);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.cce_idx = rand_range(0, 255);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.aggregation_level  = rand_range(0, 32);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.rnti = rand_range(0, (uint16_t)-1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.resource_allocation_type = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.resource_block_coding = rand_range(0, 320000);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.mcs_1 = rand_range(0, 31);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.redundancy_version_1 = rand_range(0, 3);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.new_data_indicator_1 = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.mcs_2 = rand_range(0, 31);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.redundancy_version_2 = rand_range(0, 31);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.new_data_indicator_2 = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.harq_process = rand_range(0, 31);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tpmi = rand_range(0, 15);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.pmi = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.precoding_information = rand_range(0, 63);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tpc = rand_range(0, 3);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.downlink_assignment_index = rand_range(0, 15);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.ngap = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transport_block_size_index = rand_range(0, 31);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.downlink_power_offset = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.allocate_prach_flag = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.preamble_index = rand_range(0, 63);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.prach_mask_index = rand_range(0, 15);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.rnti_type = rand_range(0, 3);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transmission_power = rand_range(0, 10000);	
					
					
					
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG;
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.mcch_flag = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.mcch_change_notification = rand_range(0, 255);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.scrambling_identity = rand_range(0, 1);
					
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG;
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.carrier_indicator = rand_range(0, 7);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.srs_flag = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.srs_request = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.antenna_ports_scrambling_and_layers = rand_range(0, 15);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.n_dl_rb = rand_range(0, 100);
					
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG;
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.harq_ack_resource_offset = rand_range(0, 3);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.pdsch_re_mapping_quasi_co_location_indicator = rand_range(0, 3);
					
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG;
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.primary_cell_type = rand_range(0, 2);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_flag = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.number_ul_dl_configurations = 2;
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_indication[0] = rand_range(1, 5);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_indication[1] = rand_range(1, 5);
					
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG;
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.laa_end_partial_sf_flag = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.laa_end_partial_sf_configuration = rand_range(0, 255);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.initial_lbt_sf = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.codebook_size_determination = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.drms_table_flag = rand_range(0, 1);

					dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG;
					dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_resource_assignment_flag = rand_range(0, 1);
					dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_id = rand_range(0, 503);
					dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_start_symbol = rand_range(1, 4);
					dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb = rand_range(2, 8);
					for(int j = 0; j < dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb; ++j)
						dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_prb_index[j] = rand_range(0, 99);
					dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.subband_index = rand_range(0, 25);	
					dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.num_antennas= rand_range(1, 4);
					for(int j = 0; j < dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb; ++j)
						dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.bf_value[j] = rand_range(0, 65535);
					
	
					dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG;
					dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.dwpts_symbols = rand_range(3, 14);
					dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.initial_lbt_sf = rand_range(0, 1);
				}
				break;
				
				case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE:
				{
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG;
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = rand_range(0, 15);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = rand_range(2, 6);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = rand_range(0, 14);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = rand_range(0, 1);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = rand_range(1, 4);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = rand_range(0, 22);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = rand_range(2, 24);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = rand_range(0, 4);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.rnti = rand_range(1, 65535);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = rand_range(1, 2);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = rand_range(0, 503);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = rand_range(0, 10000);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.dci_format = rand_range(10, 12);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = rand_range(0, 0xFFFF);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mcs = rand_range(0, 15);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = rand_range(1, 8);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = rand_range(0, 3);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = rand_range(0, 1);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.harq_process = rand_range(0, 15);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = rand_range(0, 4);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpmi = rand_range(0, 15);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = rand_range(0, 1);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pmi = rand_range(0, 1);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = rand_range(0, 3);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rand_range(1, 4);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpc = rand_range(0, 3);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = rand_range(0, 4);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = rand_range(0, 15);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = rand_range(0, 63);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = rand_range(0, 15);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = rand_range(0, 3);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = rand_range(0, 1);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.srs_request = rand_range(0, 1);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = rand_range(0, 1);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = rand_range(0, 3);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = rand_range(0, 1);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = rand_range(0, 1);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = rand_range(0, 255);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = rand_range(0, 1);
					dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = rand_range(0, 8);
					for(int j = 0 ; j < dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports; ++j)
						dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.precoding_value[j] = rand_range(0, 65535);
				}
				break;
				
				case NFAPI_DL_CONFIG_NBCH_PDU_TYPE:
				{
					dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG;
					dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.length = rand_range(0, 5555);
					dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.pdu_index = rand_range(0, 65535);
					dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.transmission_power = rand_range(0, 10000);
					dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.hyper_sfn_2_lsbs = rand_range(0, 3);
				}
				break;
				
				case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE:
				{
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG;
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.length = rand_range(0, 5555);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.pdu_index = rand_range(0, 65535);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.ncce_index = rand_range(0, 1);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.aggregation_level = rand_range(1, 2);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.start_symbol = rand_range(0, 4);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.rnti_type = rand_range(0, 3);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.rnti = rand_range(1, 65535);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.scrambling_reinitialization_batch_index = rand_range(1, 4);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.dci_format = rand_range(0, 1);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.scheduling_delay = rand_range(0, 7);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.resource_assignment = rand_range(0, 7);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.repetition_number = rand_range(0, 15); 
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.mcs = rand_range(0, 13);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.new_data_indicator = rand_range(0, 1);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.harq_ack_resource = rand_range(0, 15);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.npdcch_order_indication = rand_range(0, 1);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.starting_number_of_nprach_repetitions = rand_range(0, 3);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.subcarrier_indication_of_nprach = rand_range(0, 63);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.paging_direct_indication_differentation_flag = rand_range(0, 1);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.direct_indication = rand_range(0, 255);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.dci_subframe_repetition_number  = rand_range(0, 7);
					dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.total_dci_length_including_padding = rand_range(0, 255);
				}
				break;
				
				case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE:
				{
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG;
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.length = rand_range(0, 5555);
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.pdu_index = rand_range(0, 65535);
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.start_symbol = rand_range(0, 4);
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.rnti_type = rand_range(0, 1);
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.rnti = rand_range(1, 65535);
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.resource_assignment = rand_range(0, 7);
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.repetition_number = rand_range(0, 15);
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.modulation = 2;
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.number_of_subframes_for_resource_assignment = rand_range(1, 10);
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.scrambling_sequence_initialization_cinit = rand_range(0, 65535);
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.sf_idx = rand_range(1, 10240);
					dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2);
				}
				break;
				
			};
		}


		dl_config_req.dl_config_request_body.dl_config_pdu_list = dl_config_pdus;		
		mac->dl_config_req(mac, &dl_config_req);
		
		uint8_t num_ul_pdus = 18;
		nfapi_ul_config_request_pdu_t ul_config_pdus[num_ul_pdus];
		memset(&ul_config_pdus, 0, sizeof(ul_config_pdus));
		
		nfapi_ul_config_request_t ul_config_req;
		memset(&ul_config_req, 0, sizeof(ul_config_req));
		ul_config_req.header.message_id = NFAPI_UL_CONFIG_REQUEST;
		ul_config_req.header.phy_id = phy_id;
		ul_config_req.sfn_sf = sfn_sf;
		ul_config_req.ul_config_request_body.tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
		ul_config_req.ul_config_request_body.number_of_pdus = num_ul_pdus;
		ul_config_req.ul_config_request_body.rach_prach_frequency_resources = rand_range(0, 255);
		ul_config_req.ul_config_request_body.srs_present = rand_range(0, 1);
		
		auto ul_config_ulsch_pdu_test_gen = [](nfapi_ul_config_ulsch_pdu& ulsch_pdu)
		{
			ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG;
			ulsch_pdu.ulsch_pdu_rel8.handle = rand_range(0, 50000);
			ulsch_pdu.ulsch_pdu_rel8.size = rand_range(0, 32000);
			ulsch_pdu.ulsch_pdu_rel8.rnti = rand_range(1, 65535);
			ulsch_pdu.ulsch_pdu_rel8.resource_block_start = rand_range(0, 99);
			ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = rand_range(1, 100);
			ulsch_pdu.ulsch_pdu_rel8.modulation_type = rand_range(2, 6);
			ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7);
			ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1);
			ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = rand_range(0, 3);
			ulsch_pdu.ulsch_pdu_rel8.new_data_indication = rand_range(0, 1);
			ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rand_range(0, 3);
			ulsch_pdu.ulsch_pdu_rel8.harq_process_number = rand_range(0, 15);
			ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = rand_range(0, 1);
			ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = rand_range(0, 5);
			ulsch_pdu.ulsch_pdu_rel8.n_srs = rand_range(0, 1);
			ulsch_pdu.ulsch_pdu_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG;
			ulsch_pdu.ulsch_pdu_rel10.resource_allocation_type = rand_range(0, 1);
			ulsch_pdu.ulsch_pdu_rel10.resource_block_coding = rand_range(0, 35000);
			ulsch_pdu.ulsch_pdu_rel10.transport_blocks = rand_range(1, 2);
			ulsch_pdu.ulsch_pdu_rel10.transmission_scheme = rand_range(0, 1);
			ulsch_pdu.ulsch_pdu_rel10.number_of_layers = rand_range(1, 4);
			ulsch_pdu.ulsch_pdu_rel10.codebook_index = rand_range(0, 23);
			ulsch_pdu.ulsch_pdu_rel10.disable_sequence_hopping_flag = rand_range(0, 1);		
			ulsch_pdu.ulsch_pdu_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG;
			ulsch_pdu.ulsch_pdu_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1);
			ulsch_pdu.ulsch_pdu_rel11.npusch_identity = rand_range(0, 509);
			ulsch_pdu.ulsch_pdu_rel11.dmrs_config_flag = rand_range(0, 1);
			ulsch_pdu.ulsch_pdu_rel11.ndmrs_csh_identity = rand_range(0, 509);
			ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG;
			ulsch_pdu.ulsch_pdu_rel13.ue_type = rand_range(0, 2);
			ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = rand_range(1, 2048);
			ulsch_pdu.ulsch_pdu_rel13.repetition_number = rand_range(1, 2048);
			ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239);
			ulsch_pdu.ulsch_pdu_rel13.empty_symbols_due_to_re_tunning = rand_range(0, 8);
		};
		
		auto ul_config_cqi_ri_info_test_gen = [](nfapi_ul_config_cqi_ri_information& cqi_ri_information)
		{
			cqi_ri_information.cqi_ri_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG;
			cqi_ri_information.cqi_ri_information_rel8.dl_cqi_pmi_size_rank_1 = rand_range(0, 255);
			cqi_ri_information.cqi_ri_information_rel8.dl_cqi_pmi_size_rank_greater_1 = rand_range(0, 255);
			cqi_ri_information.cqi_ri_information_rel8.ri_size = rand_range(0, 3);
			cqi_ri_information.cqi_ri_information_rel8.delta_offset_cqi = rand_range(0, 15);
			cqi_ri_information.cqi_ri_information_rel8.delta_offset_ri = rand_range(0, 15);

			cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG;
			cqi_ri_information.cqi_ri_information_rel9.report_type = 1; // rand_range(0, 1);
			cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = rand_range(0, 15);
			cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = rand_range(0, 15);
			
			if(cqi_ri_information.cqi_ri_information_rel9.report_type == 0)
			{
				cqi_ri_information.cqi_ri_information_rel9.periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size = rand_range(0, 255);
				cqi_ri_information.cqi_ri_information_rel9.periodic_cqi_pmi_ri_report.control_type = rand_range(0, 1);
			}
			else
			{
				cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1;
				cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = rand_range(0, 3);
				cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0] = rand_range(0, 255);
			}
			
			cqi_ri_information.cqi_ri_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG;
			cqi_ri_information.cqi_ri_information_rel13.report_type = rand_range(0, 1);
			
			if(cqi_ri_information.cqi_ri_information_rel13.report_type == 0)
			{
				cqi_ri_information.cqi_ri_information_rel13.periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2 = rand_range(255, 10000);
			}
		};
		
		auto ul_config_init_tx_params_test_gen = [](nfapi_ul_config_initial_transmission_parameters& initial_transmission_parameters)
		{
			initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
			initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = rand_range(0, 1);
			initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rand_range(1, 100);
		};
		
		auto ul_config_harqinfo_test_gen = [](nfapi_ul_config_ulsch_harq_information& harq_information)
		{
			harq_information.harq_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG;
			harq_information.harq_information_rel10.harq_size = rand_range(0, 21);
			harq_information.harq_information_rel10.delta_offset_harq = rand_range(0, 15);
			harq_information.harq_information_rel10.ack_nack_mode = rand_range(0, 5);
			harq_information.harq_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG;
			harq_information.harq_information_rel13.harq_size_2 = rand_range(0, 21);
			harq_information.harq_information_rel13.delta_offset_harq_2 = rand_range(0, 15);	
		};

		auto ul_config_sr_info_test_gen = [](nfapi_ul_config_sr_information& sr_info)
		{
			sr_info.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG;
			sr_info.sr_information_rel8.pucch_index = rand_range(0, 2047);
			sr_info.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG;
			sr_info.sr_information_rel10.number_of_pucch_resources = rand_range(1, 2);
			sr_info.sr_information_rel10.pucch_index_p1 = rand_range(0, 2047);
		};
		
		auto ul_config_ue_info_test_gen = [](nfapi_ul_config_ue_information& ue_information)
		{
			ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG;
			ue_information.ue_information_rel8.handle = rand_range(0, 99999);
			ue_information.ue_information_rel8.rnti = rand_range(1, 65535);
			ue_information.ue_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG;
			ue_information.ue_information_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1);
			ue_information.ue_information_rel11.npusch_identity = rand_range(0, 503);
			ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG;
			ue_information.ue_information_rel13.ue_type = rand_range(0, 2);
			ue_information.ue_information_rel13.empty_symbols = rand_range(0, 2);
			ue_information.ue_information_rel13.total_number_of_repetitions = rand_range(1, 32);
			ue_information.ue_information_rel13.repetition_number = rand_range(1, 32);
		};
		
		auto ul_config_cqi_info_test_gen = [](nfapi_ul_config_cqi_information& cqi_information)
		{
			cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG;
			cqi_information.cqi_information_rel8.pucch_index = rand_range(0, 1184);
			cqi_information.cqi_information_rel8.dl_cqi_pmi_size = rand_range(0, 255);
			cqi_information.cqi_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG;
			cqi_information.cqi_information_rel10.number_of_pucch_resource = rand_range(1, 2);
			cqi_information.cqi_information_rel10.pucch_index_p1 = rand_range(0, 1184);
			cqi_information.cqi_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG;
			cqi_information.cqi_information_rel13.csi_mode = rand_range(0, 2);
			cqi_information.cqi_information_rel13.dl_cqi_pmi_size_2 = rand_range(0, 999);
			cqi_information.cqi_information_rel13.starting_prb = rand_range(0, 109);
			cqi_information.cqi_information_rel13.n_prb = rand_range(0, 7);
			cqi_information.cqi_information_rel13.cdm_index = rand_range(0, 1);
			cqi_information.cqi_information_rel13.n_srs = rand_range(0, 1);
		};
		
		auto ul_config_harq_info_test_gen = [](nfapi_ul_config_harq_information& harq_information)
		{
			harq_information.harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG;
			harq_information.harq_information_rel10_tdd.harq_size = rand_range(0, 21);
			harq_information.harq_information_rel10_tdd.ack_nack_mode = rand_range(0, 5);
			harq_information.harq_information_rel10_tdd.number_of_pucch_resources = rand_range(0, 4);
			harq_information.harq_information_rel10_tdd.n_pucch_1_0 = rand_range(0, 2047);
			harq_information.harq_information_rel10_tdd.n_pucch_1_1 = rand_range(0, 2047);
			harq_information.harq_information_rel10_tdd.n_pucch_1_2 = rand_range(0, 2047);
			harq_information.harq_information_rel10_tdd.n_pucch_1_3 = rand_range(0, 2047);
			harq_information.harq_information_rel8_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG;
			harq_information.harq_information_rel8_fdd.n_pucch_1_0 = rand_range(0, 2047);
			harq_information.harq_information_rel8_fdd.harq_size = rand_range(1, 2);
			harq_information.harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG;
			harq_information.harq_information_rel9_fdd.harq_size = rand_range(1, 10);
			harq_information.harq_information_rel9_fdd.ack_nack_mode = rand_range(0, 4);
			harq_information.harq_information_rel9_fdd.number_of_pucch_resources = rand_range(0, 4);
			harq_information.harq_information_rel9_fdd.n_pucch_1_0 = rand_range(0, 2047);
			harq_information.harq_information_rel9_fdd.n_pucch_1_1 = rand_range(0, 2047);
			harq_information.harq_information_rel9_fdd.n_pucch_1_2 = rand_range(0, 2047);
			harq_information.harq_information_rel9_fdd.n_pucch_1_3 = rand_range(0, 2047);
			harq_information.harq_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG;
			harq_information.harq_information_rel11.num_ant_ports = rand_range(1, 2);
			harq_information.harq_information_rel11.n_pucch_2_0 = rand_range(0, 2047);
			harq_information.harq_information_rel11.n_pucch_2_1 = rand_range(0, 2047);
			harq_information.harq_information_rel11.n_pucch_2_2 = rand_range(0, 2047);
			harq_information.harq_information_rel11.n_pucch_2_3 = rand_range(0, 2047);
			harq_information.harq_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG;
			harq_information.harq_information_rel13.harq_size_2 = rand_range(0, 999);
			harq_information.harq_information_rel13.starting_prb = rand_range(0, 109);
			harq_information.harq_information_rel13.n_prb = rand_range(0, 7);
			harq_information.harq_information_rel13.cdm_index = rand_range(0, 1);
			harq_information.harq_information_rel13.n_srs = rand_range(0, 1);
		};		
		
		
		ul_config_pdus[0].pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE;
		ul_config_ulsch_pdu_test_gen(ul_config_pdus[0].ulsch_pdu);

		ul_config_pdus[1].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE;
		ul_config_ulsch_pdu_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.ulsch_pdu);
		ul_config_cqi_ri_info_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.cqi_ri_information);
		ul_config_init_tx_params_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.initial_transmission_parameters);	

		ul_config_pdus[2].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
		ul_config_ulsch_pdu_test_gen(ul_config_pdus[2].ulsch_harq_pdu.ulsch_pdu);
		ul_config_harqinfo_test_gen(ul_config_pdus[2].ulsch_harq_pdu.harq_information);
		ul_config_init_tx_params_test_gen(ul_config_pdus[2].ulsch_harq_pdu.initial_transmission_parameters);
		
		ul_config_pdus[3].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
		ul_config_ulsch_pdu_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.ulsch_pdu);		
		ul_config_cqi_ri_info_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.cqi_ri_information);	
		ul_config_harqinfo_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.harq_information);
		ul_config_init_tx_params_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters);
		
		
		ul_config_pdus[4].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
		ul_config_ue_info_test_gen(ul_config_pdus[4].uci_cqi_pdu.ue_information);
		ul_config_cqi_info_test_gen(ul_config_pdus[4].uci_cqi_pdu.cqi_information);

		ul_config_pdus[5].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE;
		ul_config_ue_info_test_gen(ul_config_pdus[5].uci_sr_pdu.ue_information);
		ul_config_sr_info_test_gen(ul_config_pdus[5].uci_sr_pdu.sr_information);

		
		ul_config_pdus[6].pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE;
		ul_config_ue_info_test_gen(ul_config_pdus[6].uci_harq_pdu.ue_information);
		ul_config_harq_info_test_gen(ul_config_pdus[6].uci_harq_pdu.harq_information);
		
		
		ul_config_pdus[7].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE;
		ul_config_ue_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.ue_information);
		ul_config_sr_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.sr_information);
		ul_config_harq_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.harq_information);
		
		ul_config_pdus[8].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE;
		ul_config_ue_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.ue_information);
		ul_config_cqi_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.cqi_information);
		ul_config_harq_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.harq_information);
		
		ul_config_pdus[9].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE;
		ul_config_ue_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.ue_information);
		ul_config_cqi_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.cqi_information);
		ul_config_sr_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.sr_information);
		
		ul_config_pdus[10].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE;
		ul_config_ue_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.ue_information);
		ul_config_cqi_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.cqi_information);
		ul_config_sr_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.sr_information);
		ul_config_harq_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.harq_information);
		
		ul_config_pdus[11].pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE;
		ul_config_pdus[11].srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG;
		ul_config_pdus[11].srs_pdu.srs_pdu_rel8.handle = rand_range(0, 9999);
		ul_config_pdus[11].srs_pdu.srs_pdu_rel8.size = rand_range(1, 999);
		ul_config_pdus[11].srs_pdu.srs_pdu_rel8.rnti = rand_range(1, 65535);
		ul_config_pdus[11].srs_pdu.srs_pdu_rel8.srs_bandwidth = rand_range(0, 3);
		ul_config_pdus[11].srs_pdu.srs_pdu_rel8.frequency_domain_position = rand_range(0, 23);
		ul_config_pdus[11].srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = rand_range(0, 3);
		ul_config_pdus[11].srs_pdu.srs_pdu_rel8.transmission_comb = rand_range(0, 3);
		ul_config_pdus[11].srs_pdu.srs_pdu_rel8.i_srs = rand_range(0, 1023);
		ul_config_pdus[11].srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = rand_range(0, 11);
		ul_config_pdus[11].srs_pdu.srs_pdu_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG;
		ul_config_pdus[11].srs_pdu.srs_pdu_rel10.antenna_port = rand_range(0, 2);
		ul_config_pdus[11].srs_pdu.srs_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG;
		ul_config_pdus[11].srs_pdu.srs_pdu_rel13.number_of_combs = rand_range(0, 1);
		
		ul_config_pdus[12].pdu_type = NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE;
		ul_config_ue_info_test_gen(ul_config_pdus[12].harq_buffer_pdu.ue_information);		
		
		ul_config_pdus[13].pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE;
		ul_config_ulsch_pdu_test_gen(ul_config_pdus[13].ulsch_uci_csi_pdu.ulsch_pdu);
		ul_config_cqi_info_test_gen(ul_config_pdus[13].ulsch_uci_csi_pdu.csi_information);
		
		ul_config_pdus[14].pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE;
		ul_config_ulsch_pdu_test_gen(ul_config_pdus[14].ulsch_uci_harq_pdu.ulsch_pdu);
		ul_config_harq_info_test_gen(ul_config_pdus[14].ulsch_uci_harq_pdu.harq_information);
		
		ul_config_pdus[15].pdu_type = NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE;
		ul_config_ulsch_pdu_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.ulsch_pdu);
		ul_config_cqi_info_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.csi_information);
		ul_config_harq_info_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.harq_information);
		
		ul_config_pdus[16].pdu_type = NFAPI_UL_CONFIG_NULSCH_PDU_TYPE;
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG;
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nulsch_format = rand_range(0, 1);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.handle = rand_range(0, 0xFFFF);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.size = rand_range(0, 65535);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.rnti = rand_range(1, 65535);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.subcarrier_indication = rand_range(0, 47);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.resource_assignment = rand_range(0, 7);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.mcs = rand_range(0, 12);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.redudancy_version = rand_range(0, 1);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.repetition_number = rand_range(0, 7);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.new_data_indication = rand_range(0, 1);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.n_srs = rand_range(0, 1);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.scrambling_sequence_initialization_cinit = rand_range(0, 65535);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.sf_idx = rand_range(0, 40960);
		
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG;
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.handle = rand_range(0, 0xFF);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.rnti = rand_range(1, 65535);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG;
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.npusch_identity = rand_range(0, 503);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG;
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.ue_type = rand_range(0, 2);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.empty_symbols = rand_range(0, 0x3);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.total_number_of_repetitions = rand_range(1, 32);
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.repetition_number = rand_range(1, 32);
		
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nb_harq_information.nb_harq_information_rel13_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG;
		ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource = rand_range(0, 15);
		
		ul_config_pdus[17].pdu_type = NFAPI_UL_CONFIG_NRACH_PDU_TYPE;
		ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG;
		ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_0 = rand_range(0, 1);
		ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_1 = rand_range(0, 1);
		ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_2 = rand_range(0, 1);
		
		ul_config_req.ul_config_request_body.ul_config_pdu_list = ul_config_pdus;	
		mac->ul_config_req(mac, &ul_config_req);
		
		
		uint8_t num_dci_pdus = 4;
		uint8_t num_hi_pdus = 1;
		nfapi_hi_dci0_request_pdu_t hi_dci0_pdus[num_dci_pdus + num_hi_pdus];
		memset(&hi_dci0_pdus, 0, sizeof(hi_dci0_pdus));
		
		nfapi_hi_dci0_request_t hi_dci0_req;
		memset(&hi_dci0_req, 0, sizeof(hi_dci0_req));
		hi_dci0_req.header.message_id = NFAPI_HI_DCI0_REQUEST;
		hi_dci0_req.header.phy_id = phy_id;
		hi_dci0_req.sfn_sf = sfn_sf;
		
		hi_dci0_req.hi_dci0_request_body.tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
		hi_dci0_req.hi_dci0_request_body.sfnsf = sfn_sf;
		hi_dci0_req.hi_dci0_request_body.number_of_dci = num_dci_pdus;
		hi_dci0_req.hi_dci0_request_body.number_of_hi = num_hi_pdus;
		
		hi_dci0_pdus[0].pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE;
		hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
		hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.resource_block_start = rand_range(0, 100);
		hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7);
		hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.hi_value = rand_range(0, 1);
		hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.i_phich = rand_range(0, 1);
		hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.transmission_power = rand_range(0, 10000);
		hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG;	
		hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.flag_tb2 = rand_range(0, 1);
		hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.hi_value_2 = rand_range(0, 1);
		
		hi_dci0_pdus[1].pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE;
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG;
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.dci_format = rand_range(0, 4);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cce_index = rand_range(0, 88);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.aggregation_level = rand_range(1, 8);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.rnti = rand_range(1, 65535);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.resource_block_start = rand_range(0, 100);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.number_of_resource_block = rand_range(0, 100);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.mcs_1 = rand_range(0, 31);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.frequency_hopping_bits = rand_range(0, 3);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.new_data_indication_1 = rand_range(0, 1);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.ue_tx_antenna_seleciton = rand_range(0, 2);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tpc = rand_range(0, 3);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cqi_csi_request = rand_range(0, 7);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.ul_index = rand_range(0, 3);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.dl_assignment_index = rand_range(1, 4);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tpc_bitmap = rand_range(0, 9999);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.transmission_power = rand_range(0, 10000);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG;
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.carrier_indicator = rand_range(0, 7);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.size_of_cqi_csi_feild = rand_range(0, 2);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.srs_flag = rand_range(0, 1);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.srs_request = rand_range(0, 1);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_allocation_flag = rand_range(0, 1);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_allocation_type = rand_range(0, 1);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_block_coding = rand_range(0, 9999);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.mcs_2 = rand_range(0, 31);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.new_data_indication_2 = rand_range(0, 1);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.number_of_antenna_ports = rand_range(0, 2);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.tpmi = rand_range(0, 63);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.n_ul_rb = rand_range(6, 100);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG;
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.pscch_resource = rand_range(0, 16);
		hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.time_resource_pattern = rand_range(0, 32);
		
		
		hi_dci0_pdus[2].pdu_type = NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE;
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG;
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.dci_format = rand_range(0, 4);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cce_index = rand_range(0, 88);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.aggregation_level = rand_range(1, 8);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.rnti = rand_range(1, 65535);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.resource_block_start = rand_range(0, 100);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.number_of_resource_block = rand_range(0, 100);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.mcs_1 = rand_range(0, 31);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.frequency_hopping_bits = rand_range(0, 3);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.new_data_indication_1 = rand_range(0, 1);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.ue_tx_antenna_seleciton = rand_range(0, 2);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tpc = rand_range(0, 3);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cqi_csi_request = rand_range(0, 7);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.ul_index = rand_range(0, 3);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.dl_assignment_index = rand_range(1, 4);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tpc_bitmap = rand_range(0, 9999);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.transmission_power = rand_range(0, 10000);		
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG;
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.carrier_indicator = rand_range(0, 7);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.size_of_cqi_csi_feild = rand_range(0, 2);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.srs_flag = rand_range(0, 1);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.srs_request = rand_range(0, 1);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_allocation_flag = rand_range(0, 1);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_allocation_type = rand_range(0, 1);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_block_coding = rand_range(0, 9999);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.mcs_2 = rand_range(0, 31);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.new_data_indication_2 = rand_range(0, 1);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.number_of_antenna_ports = rand_range(0, 2);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.tpmi = rand_range(0, 63);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255);
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.n_ul_rb = rand_range(6, 100);			
		hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_parameters_rel11.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG;
		
		hi_dci0_pdus[3].pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE;
		hi_dci0_pdus[3].mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tl.tag = NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG;

		hi_dci0_pdus[4].pdu_type = NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE;
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.tl.tag = NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG;
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.ncce_index = rand_range(0, 1);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.aggregation_level = rand_range(1, 2);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.start_symbol = rand_range(0, 4);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.rnti = rand_range(1, 65535);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.scrambling_reinitialization_batch_index = rand_range(1, 4);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.subcarrier_indication = rand_range(0, 63);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.resource_assignment = rand_range(0, 7);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.scheduling_delay = rand_range(0, 3);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.mcs = rand_range(0, 12);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.redudancy_version = rand_range(0, 1);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.repetition_number = rand_range(0, 7);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.new_data_indicator = rand_range(0, 1);
		hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.dci_subframe_repetition_number = rand_range(0, 3);
		
		hi_dci0_req.hi_dci0_request_body.hi_dci0_pdu_list = hi_dci0_pdus;
		mac->hi_dci0_req(mac, &hi_dci0_req);

		uint8_t num_tx_pdus = 2;
		nfapi_tx_request_pdu_t tx_pdus[num_tx_pdus];
		memset(&tx_pdus, 0, sizeof(tx_pdus));
		
		nfapi_tx_request_t tx_req;
		memset(&tx_req, 0, sizeof(tx_req));
		tx_req.header.message_id = NFAPI_TX_REQUEST;
		tx_req.header.phy_id = phy_id;
		tx_req.sfn_sf = sfn_sf;
		
		tx_req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
		tx_req.tx_request_body.number_of_pdus = num_tx_pdus;
		
		uint32_t data[2];
		data[0] = 0x11223344;
		data[1] = 0x55667788;
		
		tx_pdus[0].pdu_length = 8;
		tx_pdus[0].pdu_index = 1;
		tx_pdus[0].num_segments = 2;
		tx_pdus[0].segments[0].segment_length = 4;
		tx_pdus[0].segments[0].segment_data = (uint8_t*)&data[0];
		tx_pdus[0].segments[1].segment_length = 4;
		tx_pdus[0].segments[1].segment_data = (uint8_t*)&data[1];
		
		tx_pdus[1].pdu_length = 8;
		tx_pdus[1].pdu_index = 2;
		tx_pdus[1].num_segments = 2;
		tx_pdus[1].segments[0].segment_length = 4;
		tx_pdus[1].segments[0].segment_data = (uint8_t*)&data[0];
		tx_pdus[1].segments[1].segment_length = 4;
		tx_pdus[1].segments[1].segment_data = (uint8_t*)&data[1];		
		
		
		tx_req.tx_request_body.tx_pdu_list = tx_pdus;
		mac->tx_req(mac, &tx_req);
	}
	
	void generate_subframe(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf)
	{
		mac_internal_t* instance = (mac_internal_t*)mac;
				
		nfapi_dl_config_request_t dl_config_req;
		memset(&dl_config_req, 0, sizeof(dl_config_req));
		dl_config_req.header.message_id = NFAPI_DL_CONFIG_REQUEST;
		dl_config_req.header.phy_id = phy_id;
		dl_config_req.sfn_sf = sfn_sf;

		dl_config_req.dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
		dl_config_req.dl_config_request_body.number_pdu = 8;

		nfapi_dl_config_request_pdu_t pdus[8];
		memset(&pdus, 0, sizeof(pdus));
		for(int i = 0; i < 8; i++)
		{
			pdus[i].pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE;

			pdus[i].bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG;
			pdus[i].bch_pdu.bch_pdu_rel8.length = 42;
			pdus[i].bch_pdu.bch_pdu_rel8.pdu_index = i;
			pdus[i].bch_pdu.bch_pdu_rel8.transmission_power = 56;

		}

		dl_config_req.dl_config_request_body.dl_config_pdu_list = pdus;

		/*
		vendor_ext_tlv_1 ve;
		ve.tl.tag = VENDOR_EXT_TLV_1_TAG;
		ve.dummy = 999;
		dl_config_req.vendor_extension = &ve.tl;
		*/

		mac->dl_config_req(mac, &dl_config_req);	


		nfapi_ul_config_request_t ul_config_req;
		memset(&ul_config_req, 0, sizeof(ul_config_req));
		ul_config_req.header.message_id = NFAPI_UL_CONFIG_REQUEST;
		ul_config_req.header.phy_id = phy_id;
		ul_config_req.sfn_sf = sfn_sf;
		mac->ul_config_req(mac, &ul_config_req);

		nfapi_hi_dci0_request_t hi_dci0_req;
		memset(&hi_dci0_req, 0, sizeof(hi_dci0_req));
		hi_dci0_req.header.message_id = NFAPI_HI_DCI0_REQUEST;
		hi_dci0_req.header.phy_id = phy_id;
		hi_dci0_req.sfn_sf = sfn_sf;
		mac->hi_dci0_req(mac, &hi_dci0_req);



		nfapi_tx_request_t tx_req;
		memset(&tx_req, 0, sizeof(tx_req));
		tx_req.header.message_id = NFAPI_TX_REQUEST;
		tx_req.header.phy_id = phy_id;
		tx_req.sfn_sf = sfn_sf;

		nfapi_tx_request_pdu_t tx_pdus[8];

		tx_req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
		tx_req.tx_request_body.number_of_pdus = 0;
		tx_req.tx_request_body.tx_pdu_list = &tx_pdus[0];

		mac_pdu* buff = 0;
		int i = 0;
		std::list<mac_pdu*> free_list;
		do
		{
			buff = instance->mac->pop_rx_buffer();
			if(buff != 0)
			{
				if(buff->len == 0)
				{
					printf("[MAC] Buffer length = 0\n");
				}

				tx_req.tx_request_body.tx_pdu_list[i].pdu_length = buff->len;
				tx_req.tx_request_body.tx_pdu_list[i].pdu_index = i;
				tx_req.tx_request_body.tx_pdu_list[i].num_segments = 1;
				tx_req.tx_request_body.tx_pdu_list[i].segments[0].segment_length = buff->len;
				tx_req.tx_request_body.tx_pdu_list[i].segments[0].segment_data = (uint8_t*)buff->buffer;

				tx_req.tx_request_body.number_of_pdus++;
				i++;

				instance->mac->byte_count += buff->len;

				free_list.push_back(buff);
			}
		}while(buff != 0 && i < 8);

		mac->tx_req(mac, &tx_req);

		//for(int j = 0; j < tx_req.tx_request_body.number_of_pdus; ++j)
		for(mac_pdu* pdu : free_list)
		{
			instance->mac->release_mac_pdu(pdu);
			//free(tx_req.tx_request_body.tx_pdu_list[j].segments[0].segment_data);
		}
	}
	
	void mac_subframe_ind(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf)
	{

		
		//printf("[MAC] subframe indication phyid:%d sfnsf:%d\n", phy_id, sfn_sf);
		mac_internal_t* instance = (mac_internal_t*)mac;

		if(instance->mac->tick == 1000)
		{
			if(instance->mac->byte_count > 0)
			{
				printf("[MAC] Rx rate %d bytes/sec\n", instance->mac->byte_count);
				instance->mac->byte_count = 0;
			}
			instance->mac->tick = 0;
		}
		instance->mac->tick++;
		
		if(instance->mac->wireshark_test_mode)
		{
			generate_test_subframe(mac, phy_id, sfn_sf);
		}
		else
		{
			generate_subframe(mac, phy_id, sfn_sf);
		}
	}	
	
	void mac_harq_ind(mac_t* mac, nfapi_harq_indication_t* ind)
	{
	}
	void mac_crc_ind(mac_t* mac, nfapi_crc_indication_t* ind)
	{
	}
	void mac_rx_ind(mac_t* mac, nfapi_rx_indication_t* ind)
	{
		mac_internal_t* instance = (mac_internal_t*)mac;

		for(int i = 0; i < ind->rx_indication_body.number_of_pdus; ++i)
		{
			uint16_t len = ind->rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length;
			uint8_t* data = ind->rx_indication_body.rx_pdu_list[i].data;
			//printf("[MAC] sfnsf:%d len:%d\n", ind->sfn_sf,len);
			//
			instance->tx_byte_count += len;

			int sendto_result = sendto(instance->tx_sock, data, len, 0, (struct sockaddr*)&(instance->tx_addr), sizeof(instance->tx_addr));
			
			if(sendto_result < 0)
			{
				// error
			}
		}

	}
	void mac_rach_ind(mac_t* mac, nfapi_rach_indication_t* ind)
	{
	}
	void mac_srs_ind(mac_t* mac, nfapi_srs_indication_t* ind)
	{
	}
	void mac_sr_ind(mac_t* mac, nfapi_sr_indication_t* ind)
	{
	}
	void mac_cqi_ind(mac_t* mac, nfapi_cqi_indication_t* ind)
	{
	}
	void mac_lbt_dl_ind(mac_t* mac, nfapi_lbt_dl_indication_t* ind)
	{
	}
	void mac_nb_harq_ind(mac_t* mac, nfapi_nb_harq_indication_t* ind)
	{
	}
	void mac_nrach_ind(mac_t* mac, nfapi_nrach_indication_t* ind)
	{
	}
}

