diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 9b365261725e9229c8063e93d1dc5eb8595ad895..401198df515f216fbeafdbff7683a6169bdce4f5 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -28,6 +28,7 @@ cmake_minimum_required (VERSION 2.8)
 ################################################
 set (OPENAIR_DIR     $ENV{OPENAIR_DIR})
 set (NFAPI_DIR       $ENV{NFAPI_DIR})
+set (NFAPI_USER_DIR  ${OPENAIR_DIR}/nfapi)
 set (OPENAIR1_DIR    ${OPENAIR_DIR}/openair1)
 set (OPENAIR2_DIR    ${OPENAIR_DIR}/openair2)
 set (OPENAIR3_DIR    ${OPENAIR_DIR}/openair3)
@@ -738,7 +739,12 @@ else()
   include_directories("${OPENAIR2_DIR}/UTIL")
   include_directories("${OPENAIR2_DIR}/UTIL/LOG")
 endif()
-include_directories("${NFAPI_DIR}")
+include_directories("${NFAPI_DIR}/nfapi/public_inc")
+include_directories("${NFAPI_DIR}/common/public_inc")
+include_directories("${NFAPI_DIR}/pnf/public_inc")
+include_directories("${NFAPI_DIR}/nfapi/inc")
+include_directories("${NFAPI_DIR}/sim_common/inc")
+include_directories("${NFAPI_DIR}/pnf_sim/inc")
 include_directories("${OPENAIR1_DIR}")
 include_directories("${OPENAIR2_DIR}/NAS")
 include_directories("${OPENAIR2_DIR}")
@@ -980,6 +986,58 @@ set(SCHED_SRC
 )
 add_library(SCHED_LIB ${SCHED_SRC})
 
+# nFAPI
+#################################
+set(NFAPI_COMMON_SRC
+  ${NFAPI_DIR}/common/src/debug.c
+)
+add_library(NFAPI_COMMON_LIB ${NFAPI_COMMON_SRC})
+
+include_directories(${NFAPI_DIR}/common/public_inc)
+
+set(NFAPI_SRC
+  ${NFAPI_DIR}/nfapi/src/nfapi.c
+  ${NFAPI_DIR}/nfapi/src/nfapi_p4.c
+  ${NFAPI_DIR}/nfapi/src/nfapi_p5.c
+  ${NFAPI_DIR}/nfapi/src/nfapi_p7.c
+)
+add_library(NFAPI_LIB ${NFAPI_SRC})
+
+include_directories(${NFAPI_DIR}/nfapi/public_inc)
+include_directories(${NFAPI_DIR}/nfapi/inc)
+
+set(NFAPI_PNF_SRC
+  ${NFAPI_DIR}/pnf/src/pnf.c
+  ${NFAPI_DIR}/pnf/src/pnf_interface.c
+  ${NFAPI_DIR}/pnf/src/pnf_p7.c
+  ${NFAPI_DIR}/pnf/src/pnf_p7_interface.c
+)
+add_library(NFAPI_PNF_LIB ${NFAPI_PNF_SRC})
+
+include_directories(${NFAPI_DIR}/pnf/public_inc)
+include_directories(${NFAPI_DIR}/pnf/inc)
+
+set(NFAPI_VNF_SRC
+  ${NFAPI_DIR}/vnf/src/vnf.c
+  ${NFAPI_DIR}/vnf/src/vnf_interface.c
+  ${NFAPI_DIR}/vnf/src/vnf_p7.c
+  ${NFAPI_DIR}/vnf/src/vnf_p7_interface.c
+)
+add_library(NFAPI_VNF_LIB ${NFAPI_VNF_SRC})
+
+include_directories(${NFAPI_DIR}/vnf/public_inc)
+include_directories(${NFAPI_DIR}/vnf/inc)
+
+# nFAPI user defined code
+#############################
+set(NFAPI_USER_SRC
+${NFAPI_USER_DIR}/nfapi.c
+${NFAPI_USER_DIR}/nfapi_pnf.c
+${NFAPI_USER_DIR}/nfapi_vnf.c
+)
+add_library(NFAPI_USER_LIB ${NFAPI_USER_SRC})
+include_directories(${NFAPI_USER_DIR})
+
 # Layer 1
 #############################
 set(PHY_SRC
@@ -1175,6 +1233,8 @@ add_library(L2
   ${ENB_APP_SRC})
 #  ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c)
 
+include_directories(${NFAPI_USER_DIR})
+
 if (FLEXRAN_AGENT_SB_IF)
 
 #Test for adding a shared library
@@ -1588,6 +1648,13 @@ add_library(OPENAIR0_LIB
   ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
 )
 
+include_directories("${NFAPI_DIR}/nfapi/public_inc")
+include_directories("${NFAPI_DIR}/common/public_inc")
+include_directories("${NFAPI_DIR}/pnf/public_inc")
+include_directories("${NFAPI_DIR}/nfapi/inc")
+include_directories("${NFAPI_DIR}/sim_common/inc")
+include_directories("${NFAPI_DIR}/pnf_sim/inc")
+
 # System packages that are required
 # We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/
 # or cmake provide a generic interface to pkg-config that widely used
@@ -1643,6 +1710,26 @@ endif()
 add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}")
 add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}")
 
+#pkg_search_module(NFAPI nfapi)
+#if(NOT ${NFAPI_FOUND})
+  #message( FATAL_ERROR "PACKAGE nfapi not found: some targets will fail. Run build_oai -I again!")
+#else()
+  #include_directories(${NFAPI_INCLUDE_DIRS})
+  #message( "PACKAGE nfapi!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
+  #message( "${NFAPI_INCLUDE_DIR}")
+  #message( "${NFAPI_COMMON_INCLUDE_DIR}")
+  #message( "${NFAPI_VNF_INCLUDE_DIR}")
+  #message( "${NFAPI_PNF_INCLUDE_DIR}")
+  #message( "XXX")
+  #message( "${NFAPI_LIBRARY}")
+  #message( "${NFAPI_COMMON_LIBRARY}")
+  #message( "${NFAPI_PNF_LIBRARY}")
+  #message( "XXX")
+  #message( "${NFAPI_LIBRARIES}")
+  #message( "XXX")
+#endif()
+
+
 pkg_search_module(XPM xpm)
 if(NOT ${XPM_FOUND})
   message("PACKAGE xpm not found: some targets will fail")
@@ -1682,6 +1769,12 @@ if (${T_TRACER})
   set (T_LIB "rt")
 endif (${T_TRACER})
 
+#if (${NFAPI_DIR})
+#set (NFAPI_PNF_LIB "nfapi_pnf")
+#set (NFAPI_LIB "nfapi")
+#set (NFAPI_COMMON_LIB "nfapi_common")
+#endif (${NFAPI_DIR})
+#
 #Some files in the T directory are generated.
 #This rule and the following deal with it.
 add_custom_command (
@@ -1740,6 +1833,9 @@ add_executable(lte-softmodem
 target_link_libraries (lte-softmodem -ldl 
   -Wl,--start-group
   RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7
+  NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB
+  NFAPI_USER_LIB
+  z
   -Wl,--end-group )
 
 target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES})
@@ -1858,22 +1954,44 @@ add_executable(oaisim
   ${T_SOURCE}
 )
 
+#add_library( imp_nfapi STATIC IMPORTED)
+#set_property(TARGET imp_nfapi PROPERTY IMPORTED_LOCATION ${NFAPI_DIR}/libnfapi.a)
+#set_property(TARGET imp_nfapi PROPERTY IMPORTED_IMPLIB ${NFAPI_DIR}/libnfapi.a)
+#target_link_libraries(oaisim imp_nfapi)
+
+#add_library( imp_nfapi_common STATIC IMPORTED)
+#set_property(TARGET imp_nfapi_common PROPERTY IMPORTED_LOCATION ${NFAPI_DIR}/common/libnfapi_common.a)
+#set_property(TARGET imp_nfapi_common PROPERTY IMPORTED_IMPLIB ${NFAPI_DIR}/common/libnfapi_common.a)
+#target_link_libraries(oaisim imp_nfapi_common)
+
+#add_library( imp_nfapi_pnf STATIC IMPORTED)
+#set_property(TARGET imp_nfapi_pnf PROPERTY IMPORTED_LOCATION ${NFAPI_DIR}/pnf/libnfapi_pnf.a)
+#set_property(TARGET imp_nfapi_pnf PROPERTY IMPORTED_IMPLIB ${NFAPI_DIR}/pnf/libnfapi_pnf.a)
+#target_link_libraries(oaisim imp_nfapi_pnf)
+
+#
+#add_library (imp_nfapi_common STATIC IMPORTED)
+#set_target_properties(imp_nfapi_common PROPERTIES IMPORTED_LOCATION ${NFAPI_DIR}/common/libnfapi_common.a
+#set_target_properties(oaisim PROPERTIES LINK_FLAGS ${NFAPI_DIR}/nfapi/libnfapi.a ${NFAPI_DIR}/pnf/libnfapi_pnf.a ${NFAPI_DIR}/common/libnfapi_common.a)
+
+
 
 target_include_directories(oaisim PUBLIC  ${OPENAIR_TARGETS}/SIMU/USER)
 target_link_libraries (oaisim
   -Wl,-ldl,--start-group
   RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} LIB_NAS_UE SIMU SECU_OSA ${ITTI_LIB}  ${MIH_LIB}
+  NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB
+  NFAPI_USER_LIB
   -Wl,--end-group )
 
 target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES})
-target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES}  ${NETTLE_LIBRARIES} sctp 
-  ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES})
+target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES}  ${NETTLE_LIBRARIES} sctp z
+  ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES} )
 #Force link with forms, regardless XFORMS option
 target_link_libraries (oaisim forms)
 target_link_libraries (oaisim ${T_LIB})
 
 
-
 # A all in one network simulator
 ################
 add_executable(oaisim_nos1
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 8ed9726e0fc5c7aec937ecae7e771da7c4bb2c83..2877133306447530ea33812699242a0ffa2579b5 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -187,7 +187,7 @@ function main() {
             GDB=1
             CMAKE_BUILD_TYPE="Debug"
             echo_info "Will Compile with gdb symbols and disable compiler optimization"
-            CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=Debug"
+            CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=Debug --trace-expand"
             shift;;
        --eNB)
             eNB=1
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index a57040449c7223d191be4df7c928ed036b4e5d62..8157d8b705bfbbe3ad36179de24463a10fa35680 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -205,6 +205,7 @@ install_protobuf_c_from_source(){
     rm -rf /tmp/protobuf-c
     git clone https://github.com/protobuf-c/protobuf-c.git
     cd protobuf-c
+	git checkout 2a46af42784abf86804d536f6e0122d47cfeea45
     ./autogen.sh
     ./configure
     echo "Compiling protobuf-c"
diff --git a/nfapi/nfapi.c b/nfapi/nfapi.c
new file mode 100644
index 0000000000000000000000000000000000000000..4bae644c5f740c6e980ecd71e38f6709da7cc781
--- /dev/null
+++ b/nfapi/nfapi.c
@@ -0,0 +1,693 @@
+
+//#include "fapi_stub.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/time.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>
+
+#if 0
+#if 0
+//DJP
+#include <mutex>
+#include <queue>
+#include <list>
+#endif
+
+//DJP struct phy_pdu
+typedef struct
+{
+#if 0
+	phy_pdu() : buffer_len(1500), buffer(0), len(0)
+	{
+		buffer = (char*) malloc(buffer_len);
+	}
+	
+	virtual ~phy_pdu()
+	{
+		free(buffer);
+	}
+#endif
+
+	unsigned buffer_len;
+	char* buffer;
+	unsigned len;
+} phy_pdu;
+
+// DJP class fapi_private 
+typedef struct
+{
+		//std::mutex mutex;
+		//std::queue<phy_pdu*> rx_buffer;
+
+		//std::queue<phy_pdu*> free_store;
+#if 0
+	public:
+
+		fapi_private()
+			: byte_count(0), tick(0), first_dl_config(false)
+		{
+		}
+
+		phy_pdu* allocate_phy_pdu()
+		{
+			phy_pdu* pdu = 0;
+			mutex.lock();
+			if(free_store.empty())
+			{
+				pdu = new phy_pdu();
+			}
+			else
+			{
+				pdu = free_store.front();
+				free_store.pop();
+			}
+			mutex.unlock();
+			return pdu;
+		}
+
+		void release_phy_pdu(phy_pdu* pdu)
+		{
+			mutex.lock();
+			free_store.push(pdu);
+			mutex.unlock();
+		}
+
+		bool rx_buffer_empty()
+		{
+			bool empty;
+			mutex.lock();
+			empty = rx_buffer.empty();
+			mutex.unlock();
+
+			return empty;
+		}
+		
+
+		void push_rx_buffer(phy_pdu* buff)
+		{
+			mutex.lock();
+			rx_buffer.push(buff);
+			mutex.unlock();
+		}
+
+		phy_pdu* pop_rx_buffer()
+		{
+			phy_pdu* buff = 0;
+			mutex.lock();
+			if(!rx_buffer.empty())
+			{
+				buff = rx_buffer.front();
+				rx_buffer.pop();
+			}
+			mutex.unlock();
+			return buff;
+		}
+#endif
+
+		uint32_t byte_count;
+		uint32_t tick;
+		uint8_t first_dl_config;
+
+} fapi_private ;
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+	typedef struct fapi_internal
+	{
+		fapi_t _public;
+
+		fapi_cb_t callbacks;
+
+		uint8_t state;
+		fapi_config_t config;
+
+		int rx_sock;
+		int tx_sock;
+		struct sockaddr_in tx_addr;
+
+		uint32_t tx_byte_count;
+		uint32_t tick;
+		
+		fapi_private* fapi;
+
+	} fapi_internal_t;
+#if defined(__cplusplus)
+}
+#endif
+
+#if 0
+//DJP
+void send_uplink_indications(fapi_internal_t* instance, uint16_t sfn_sf)
+{
+	fapi_harq_ind_t harq_ind;
+	(instance->callbacks.fapi_harq_ind)(&(instance->_public), &harq_ind);
+
+	fapi_crc_ind_t crc_ind;
+	crc_ind.header.message_id = FAPI_CRC_INDICATION;
+	crc_ind.header.length = 0; //??;
+	crc_ind.sfn_sf = sfn_sf;
+	crc_ind.body.number_of_crcs = 1;
+	crc_ind.body.pdus[0].rx_ue_info.handle = 0; //??
+	crc_ind.body.pdus[0].rx_ue_info.rnti = 0; //??
+	crc_ind.body.pdus[0].rel8_pdu.crc_flag = 1;
+
+	(instance->callbacks.fapi_crc_ind)(&(instance->_public), &crc_ind);
+
+	if(!instance->fapi->rx_buffer_empty())
+	{
+		fapi_rx_ulsch_ind_t rx_ind;
+		memset(&rx_ind, 0, sizeof(rx_ind));
+		rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION;
+		rx_ind.sfn_sf = sfn_sf;
+
+
+		phy_pdu* buff = 0;
+		int i = 0;
+		std::list<phy_pdu*> free_list;
+		do
+		{
+			buff = instance->fapi->pop_rx_buffer();
+			if(buff != 0)
+			{
+				if(buff->len == 0)
+				{
+					printf("[FAPI] Buffer length = 0\n");
+				}
+
+				rx_ind.body.pdus[i].rx_ue_info.handle = 0xDEADBEEF;
+				rx_ind.body.pdus[i].rx_ue_info.rnti = 0x4242;
+
+				rx_ind.body.pdus[i].rel8_pdu.length = buff->len;
+				//rx_ind.pdus[i].rel8_pdu.data_offset;
+				//rx_ind.pdus[i].rel8_pdu.ul_cqi;
+				//rx_ind.pdus[i].rel8_pdu.timing_advance;
+
+				rx_ind.body.data[i] = buff->buffer;
+
+				rx_ind.body.number_of_pdus++;
+				i++;
+
+				instance->fapi->byte_count += buff->len;
+
+				free_list.push_back(buff);
+			}
+		}while(buff != 0 && i < 8);
+
+		(instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind);
+
+		for(phy_pdu* pdu : free_list)
+		{
+			instance->fapi->release_phy_pdu(pdu);
+			//free(tx_req.tx_request_body.tx_pdu_list[j].segments[0].segment_data);
+		}
+	}
+	else
+	{
+		fapi_rx_ulsch_ind_t rx_ind;
+		memset(&rx_ind, 0, sizeof(rx_ind));
+		rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION;
+		rx_ind.sfn_sf = sfn_sf;
+		(instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind);
+	}
+
+	
+	fapi_rx_cqi_ind_t cqi_ind;
+	cqi_ind.sfn_sf = sfn_sf;
+	(instance->callbacks.fapi_rx_cqi_ind)(&(instance->_public), &cqi_ind);
+
+	fapi_rx_sr_ind_t sr_ind;
+	sr_ind.sfn_sf = sfn_sf;
+	(instance->callbacks.fapi_rx_sr_ind)(&(instance->_public), &sr_ind);
+
+	fapi_rach_ind_t rach_ind;
+	rach_ind.sfn_sf = sfn_sf;
+	(instance->callbacks.fapi_rach_ind)(&(instance->_public), &rach_ind);
+
+	fapi_srs_ind_t srs_ind;
+	srs_ind.sfn_sf = sfn_sf;
+	(instance->callbacks.fapi_srs_ind)(&(instance->_public), &srs_ind);
+	/*
+	nfapi_lbt_dl_indication_t lbt_ind;
+	memset(&lbt_ind, 0, sizeof(lbt_ind));
+	lbt_ind.header.message_id = NFAPI_LBT_DL_INDICATION;
+	lbt_ind.header.phy_id = config->phy_id;
+	lbt_ind.sfn_sf = sfn_sf;
+	nfapi_pnf_p7_lbt_dl_ind(config, &lbt_ind);
+
+	vendor_ext_p7_ind ve_p7_ind;
+	memset(&ve_p7_ind, 0, sizeof(ve_p7_ind));
+	ve_p7_ind.header.message_id = P7_VENDOR_EXT_IND;
+	ve_p7_ind.header.phy_id = config->phy_id;
+	ve_p7_ind.error_code = NFAPI_MSG_OK;
+	nfapi_pnf_p7_vendor_extension(config, &(ve_p7_ind.header));
+	*/
+	
+	fapi_nb_harq_ind_t nb_harq_ind;
+	nb_harq_ind.sfn_sf = sfn_sf;
+	(instance->callbacks.fapi_nb_harq_ind)(&(instance->_public), &nb_harq_ind);
+
+	fapi_nrach_ind_t nrach_ind;
+	nrach_ind.sfn_sf = sfn_sf;
+	(instance->callbacks.fapi_nrach_ind)(&(instance->_public), &nrach_ind);
+
+}
+#endif
+
+#if 0
+void* fapi_thread_start(void* ptr)
+{
+	set_thread_priority(81);
+
+	fapi_internal_t* instance = (fapi_internal_t*)ptr;
+	uint16_t sfn_sf_dec = 0;
+	uint32_t last_tv_usec = 0;
+	uint32_t last_tv_sec = 0;
+
+	uint32_t millisec;
+	uint32_t last_millisec = -1;
+	uint16_t catchup = 0;
+
+	while(1)
+	{
+		// get the time
+		struct timeval sf_start;
+		(void)gettimeofday(&sf_start, NULL);
+		
+		uint16_t sfn_sf = ((((sfn_sf_dec) / 10) << 4) | (((sfn_sf_dec) - (((sfn_sf_dec) / 10) * 10)) & 0xF));
+		// increment the sfn/sf - for the next subframe
+		sfn_sf_dec++;
+		if(sfn_sf_dec > 10239)
+			sfn_sf_dec = 0;
+
+	
+		fapi_subframe_ind_t ind;
+		ind.sfn_sf = sfn_sf;
+
+		if(instance->fapi->first_dl_config)
+		{
+			//DJP send_uplink_indications(instance, sfn_sf);
+		}
+
+		if(instance->tick == 1000)
+		{
+			if(instance->tx_byte_count > 0)
+			{
+				printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count);
+				instance->tx_byte_count = 0;
+			}
+			
+			instance->tick = 0;
+		}
+
+		instance->tick++;
+
+		(instance->callbacks.fapi_subframe_ind)(&(instance->_public), &ind);
+
+		{
+			//DJP phy_pdu* pdu = instance->fapi->allocate_phy_pdu();
+			phy_pdu* pdu = (phy_pdu*)malloc(sizeof(phy_pdu));
+			int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, MSG_DONTWAIT, 0, 0);
+			if(len > 0)
+			{
+				pdu->len = len;
+				//DJP instance->fapi->push_rx_buffer(pdu);
+			}
+			else
+			{
+				//DJP instance->fapi->release_phy_pdu(pdu);
+			}
+		}
+		
+
+		if(catchup)
+		{
+			catchup--;
+		}
+		else
+		{
+			struct timespec now_ts;
+			struct timespec sleep_ts;
+			struct timespec sleep_rem_ts;
+
+			// get the current time
+			clock_gettime(CLOCK_MONOTONIC, &now_ts);
+
+
+			// determine how long to sleep before the start of the next 1ms
+			sleep_ts.tv_sec = 0;
+			sleep_ts.tv_nsec = 1e6 - (now_ts.tv_nsec % 1000000);
+
+			int nanosleep_result = nanosleep(&sleep_ts, &sleep_rem_ts);
+
+			if(nanosleep_result != 0)
+				printf("*** nanosleep failed or was interrupted\n");
+
+
+			clock_gettime(CLOCK_MONOTONIC, &now_ts);
+			millisec = now_ts.tv_nsec / 1e6;
+
+			if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec)
+			{
+				printf("*** missing millisec %d %d\n", last_millisec, millisec);
+				catchup = millisec - last_millisec - 1;
+			}
+
+			last_millisec = millisec;
+		}
+	}
+}
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+#if 0
+	fapi_t* fapi_create(fapi_cb_t* callbacks, fapi_config_t* config)
+	{
+		fapi_internal_t* instance = (fapi_internal_t*)calloc(1, sizeof(fapi_internal_t));
+		instance->callbacks = *callbacks;
+		instance->config = *config;
+		instance->state = 0;
+
+		// DJP instance->fapi = new fapi_private();
+		instance->fapi = (fapi_t*)malloc(sizeof(fapi_private));
+
+		return (fapi_t*)instance;
+	}
+#endif
+	
+#if 0
+	void fapi_destroy(fapi_t* fapi)
+	{
+		fapi_internal_t* instance = (fapi_internal_t*)fapi;
+		
+		//DJP delete instance->fapi;
+		free(instance);
+	}
+#endif
+
+#if 0
+	void* fapi_rx_thread_start(void* ptr)
+	{
+		set_thread_priority(60);
+
+		fapi_internal_t* instance = (fapi_internal_t*)ptr;
+
+		while(1)
+		{
+			//DJP phy_pdu* pdu = instance->fapi->allocate_phy_pdu();
+			phy_pdu* pdu = (phy_pdu*)malloc(sizeof(phy_pdu));
+			int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, 0, 0, 0);
+			if(len > 0)
+			{
+				pdu->len = len;
+				//instance->fapi->push_rx_buffer(pdu);
+			}
+			else
+			{
+				//instance->fapi->release_phy_pdu(pdu);
+			}
+
+		}
+	}
+#endif
+
+#if 0
+	void fapi_start_data(fapi_t* fapi, unsigned rx_port, const char* tx_address, unsigned tx_port)
+	{
+		fapi_internal_t* instance = (fapi_internal_t*)fapi;
+
+		printf("[FAPI] Rx Data from %d\n", rx_port);
+		printf("[FAPI] 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("[FAPI] Failed to create socket\n");
+			return;
+		}
+
+		struct sockaddr_in addr;
+		memset(&addr, 0, sizeof(addr));
+		addr.sin_family = AF_INET;
+		addr.sin_port = htons(rx_port);
+		addr.sin_addr.s_addr = INADDR_ANY;
+		
+		int bind_result = bind(instance->rx_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
+		
+		if(bind_result == -1)
+		{
+			printf("[FAPI] Failed to bind to port %d\n", rx_port);
+			close(instance->rx_sock);
+			return ;
+		}
+
+		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);
+	}
+#endif
+
+
+	void fill_tlv(fapi_tlv_t tlvs[], uint8_t count, uint8_t tag, uint8_t len, uint16_t value)
+	{
+		tlvs[count].tag = tag;
+		tlvs[count].value = value;
+		tlvs[count].length = len;
+	}
+
+#if 0
+	int fapi_param_request(fapi_t* fapi, fapi_param_req_t* req)
+	{
+		fapi_internal_t* instance = (fapi_internal_t*)fapi;
+			
+		fapi_param_resp_t resp;
+		resp.header.message_id = FAPI_PARAM_RESPONSE;
+
+		resp.error_code = FAPI_MSG_OK;
+
+		resp.number_of_tlvs = 0;
+		fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_STATE_TAG, 2, instance->state);
+#if 0
+//DJP
+		if(instance->state == 0)
+		{
+			if(instance->config.duplex_mode == 0)
+			{
+				// -- TDD
+				// Downlink Bandwidth Support
+				// Uplink Bandwidth Support
+				// Downlink Modulation Support
+				// Uplink Modulation Support
+				// PHY Antenna Capability
+				// Release Capability
+				// MBSFN Capability
+			}
+			else if(instance->config.duplex_mode == 1)
+			{
+				// -- FDD
+				// Downlink Bandwidth Support
+				fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.dl_channel_bw_support);
+				// Uplink Bandwidth Support
+				fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.ul_channel_bw_support);
+				// Downlink Modulation Support
+				// Uplink Modulation Support
+				// PHY Antenna Capability
+				// Release Capability
+				// MBSFN Capability
+				// LAA Capability
+			}
+		}
+		else
+		{
+			if(instance->config.duplex_mode == 0)
+			{
+				// -- TDD
+				// Downlink Bandwidth Support
+				// Uplink Bandwidth Support
+				// Downlink Modulation Support
+				// Uplink Modulation Support
+				// PHY Antenna Capability
+				// Release Capability
+				// MBSFN Capability
+				// Duplexing Mode
+				// PCFICH Power Offset
+				// P-B
+				// DL Cyclic Prefix Type
+				// UL Cyclic Prefix Type
+				// RF Config
+				// PHICH Config
+				// SCH Config
+				// PRACH Config
+				// PUSCH Config
+				// PUCCH Config
+				// SRS Config
+				// Uplink Reference Signal Config
+				// TDD Frame Structure Config
+				// Data Report Mode
+			}
+			else if(instance->config.duplex_mode == 1)
+			{
+				// FDD
+				// Downlink Bandwidth Support
+				// Uplink Bandwidth Support
+				// Downlink Modulation Support
+				// Uplink Modulation Support
+				// PHY Antenna Capability
+				// Release Capability
+				// MBSFN Capability
+				// LAA Capability
+				// Duplexing Mode
+				// PCFICH Power Offset
+				// P-B
+				// DL Cyclic Prefix Type
+				// UL Cyclic Prefix Type
+				// RF Config
+				// PHICH Config
+				// SCH Config
+				// PRACH Config
+				// PUSCH Config
+				// PUCCH Config
+				// SRS Config
+				// Uplink Reference Signal Config
+				// Data Report Mode
+			}
+		}
+#endif
+
+
+		//todo fill
+		(instance->callbacks.fapi_param_response)(fapi, &resp);
+
+		return 0;
+	}
+#endif
+
+#if 0
+	int fapi_config_request(fapi_t* fapi, fapi_config_req_t* req)
+	{
+		fapi_internal_t* instance = (fapi_internal_t*)fapi;
+			
+		fapi_config_resp_t resp;
+		resp.header.message_id = FAPI_CONFIG_RESPONSE;
+		resp.error_code = FAPI_MSG_OK;
+
+		(instance->callbacks.fapi_config_response)(fapi, &resp);
+		return 0;
+	}
+#endif
+
+#if 0
+	int fapi_start_request(fapi_t* fapi, fapi_start_req_t* req)
+	{
+		fapi_internal_t* instance = (fapi_internal_t*)fapi;
+			
+		pthread_t fapi_thread;
+		pthread_create(&fapi_thread, NULL, &fapi_thread_start, instance);
+		
+		return 0;
+	}                
+#endif
+
+#if 0
+	int fapi_dl_config_request(fapi_t* fapi, fapi_dl_config_req_t* req)
+	{
+		fapi_internal_t* instance = (fapi_internal_t*)fapi;
+
+		//DJP instance->fapi->first_dl_config = true;
+		instance->fapi->first_dl_config = 1;
+
+		return 0;
+	}
+#endif
+
+#if 0
+	int fapi_ul_config_request(fapi_t* fapi, fapi_ul_config_req_t* req)
+	{
+		fapi_internal_t* instance = (fapi_internal_t*)fapi;
+
+		return 0;
+	}
+#endif
+#if 0
+	int fapi_hi_dci0_request(fapi_t* fapi, fapi_hi_dci0_req_t* req)
+	{
+		fapi_internal_t* instance = (fapi_internal_t*)fapi;
+
+		return 0;
+	}
+#endif
+#if 0
+	int fapi_tx_request(fapi_t* fapi, fapi_tx_req_t* req)
+	{
+		fapi_internal_t* instance = (fapi_internal_t*)fapi;
+
+		for(int i = 0; i < req->body.number_of_pdus; ++i)
+		{
+			uint16_t len = req->body.pdus[i].pdu_length;
+			uint32_t* data = req->body.pdus[i].tlvs[0].value;
+			//printf("[FAPI] sfnsf:%d len:%d\n", req->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 == -1)
+			{
+				// error
+			}
+		}
+
+		return 0;
+	}
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif
+
+
+
+void set_thread_priority(int priority)
+{
+	//printf("%s(priority:%d)\n", __FUNCTION__, priority);
+	
+	pthread_attr_t ptAttr;
+	
+	struct sched_param schedParam;
+	schedParam.__sched_priority = priority; //79;
+	if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0)
+	{
+		printf("Failed to set scheduler to SCHED_RR\n");
+	}
+
+	if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0)
+	{
+		printf("Failed to set pthread sched policy SCHED_RR\n");
+	}
+
+	pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED);
+
+	struct sched_param thread_params;
+	thread_params.sched_priority = 20;
+	if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0)
+	{
+		printf("failed to set sched param\n");
+	}
+}
+
diff --git a/nfapi/nfapi_pnf.c b/nfapi/nfapi_pnf.c
new file mode 100644
index 0000000000000000000000000000000000000000..7009833ecca5db031b7ed2f3afae3bb9f08d2804
--- /dev/null
+++ b/nfapi/nfapi_pnf.c
@@ -0,0 +1,1985 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "debug.h"
+#include "nfapi_pnf_interface.h"
+#include "nfapi.h"
+#include "nfapi_pnf.h"
+#include "common/ran_context.h"
+//#include "openair1/PHY/vars.h"
+extern RAN_CONTEXT_t RC;
+
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <assert.h>
+#include <arpa/inet.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include <vendor_ext.h>
+#include "fapi_stub.h"
+
+#if 0
+#include "pool.h"
+
+#include <mutex>
+#include <list>
+#include <queue>
+#include <map>
+#include <vector>
+#include <algorithm>
+#include <stdlib.h>
+#endif
+
+#define NUM_P5_PHY 2
+
+uint16_t phy_antenna_capability_values[] = { 1, 2, 4, 8, 16 };
+
+nfapi_pnf_param_response_t g_pnf_param_resp;
+
+
+nfapi_pnf_p7_config_t *p7_config_g = NULL;
+
+void* pnf_allocate(size_t size)
+{
+  //DJP
+  //return (void*)memory_pool::allocate(size);
+  return malloc(size);
+}
+
+void pnf_deallocate(void* ptr)
+{
+  //DJP
+  //memory_pool::deallocate((uint8_t*)ptr);
+  free(ptr);
+}
+
+
+//class udp_data
+//DJP
+typedef struct 
+{
+  //public:
+  uint8_t enabled;
+  uint32_t rx_port;
+  uint32_t tx_port;
+  //std::string tx_addr;
+  char tx_addr[80];
+}udp_data;
+
+//class phy_info
+//DJP
+typedef struct 
+{
+#if 0
+  public:
+
+    phy_info()
+      : first_subframe_ind(0), fapi(0),
+      dl_ues_per_subframe(0), ul_ues_per_subframe(0), 
+      timing_window(0), timing_info_mode(0), timing_info_period(0)
+  {
+    index = 0;
+    id = 0;
+
+    local_port = 0;
+    remote_addr = 0;
+    remote_port = 0;
+
+    duplex_mode = 0;
+    dl_channel_bw_support = 0;
+    ul_channel_bw_support = 0;
+    num_dl_layers_supported = 0;
+    num_ul_layers_supported = 0;
+    release_supported = 0;
+    nmm_modes_supported = 0;
+  }
+#endif
+
+    uint16_t index;
+    uint16_t id;
+    //std::vector<uint8_t> rfs;
+    //std::vector<uint8_t> excluded_rfs;
+    uint8_t rfs[2];
+    uint8_t excluded_rfs[2];
+
+    udp_data udp;
+
+    //std::string local_addr;
+    char local_addr[80];
+    int local_port;
+
+    char* remote_addr;
+    int remote_port;
+
+    uint8_t duplex_mode;
+    uint16_t dl_channel_bw_support;
+    uint16_t ul_channel_bw_support;
+    uint8_t num_dl_layers_supported;
+    uint8_t num_ul_layers_supported;
+    uint16_t release_supported;
+    uint8_t nmm_modes_supported;
+
+    uint8_t dl_ues_per_subframe;
+    uint8_t ul_ues_per_subframe;
+
+    uint8_t first_subframe_ind;
+
+    // timing information recevied from the vnf
+    uint8_t timing_window;
+    uint8_t timing_info_mode;
+    uint8_t timing_info_period;
+
+    //fapi_t* fapi;
+
+}phy_info;
+
+//class rf_info
+//DJP
+typedef struct 
+{
+  //public:
+  uint16_t index;
+  uint16_t band;
+  int16_t max_transmit_power;
+  int16_t min_transmit_power;
+  uint8_t num_antennas_supported;
+  uint32_t min_downlink_frequency;
+  uint32_t max_downlink_frequency;
+  uint32_t max_uplink_frequency;
+  uint32_t min_uplink_frequency;
+}rf_info;
+
+
+//class pnf_info
+//DJP
+typedef struct 
+{
+#if 0
+  public:
+
+    pnf_info() 
+      : release(13), wireshark_test_mode(0),
+      max_total_power(0), oui(0)
+
+  {
+    release = 0;
+
+    sync_mode = 0;
+    location_mode = 0;
+    dl_config_timing = 0;
+    ul_config_timing = 0;
+    tx_timing = 0;
+    hi_dci0_timing = 0;
+
+    max_phys = 0;
+    max_total_bw = 0;
+    max_total_dl_layers = 0;
+    max_total_ul_layers = 0;
+    shared_bands = 0;
+    shared_pa = 0;
+
+  }
+#endif
+
+    int release;
+    //DJPstd::vector<phy_info> phys;
+    //std::vector<rf_info> rfs;
+    phy_info phys[2];
+    rf_info rfs[2];
+
+    uint8_t sync_mode;
+    uint8_t location_mode;
+    uint8_t location_coordinates[6];
+    uint32_t dl_config_timing;
+    uint32_t ul_config_timing;
+    uint32_t tx_timing;
+    uint32_t hi_dci0_timing;
+
+    uint16_t max_phys;
+    uint16_t max_total_bw;
+    uint16_t max_total_dl_layers;
+    uint16_t max_total_ul_layers;
+    uint8_t shared_bands;
+    uint8_t shared_pa;
+    int16_t max_total_power;
+    uint8_t oui;
+
+    uint8_t wireshark_test_mode;
+
+}pnf_info;
+
+// DJP struct pnf_phy_user_data_t
+typedef struct 
+{
+  uint16_t phy_id;
+  nfapi_pnf_config_t* config;
+  phy_info* phy;
+  nfapi_pnf_p7_config_t* p7_config;
+}pnf_phy_user_data_t;
+
+//DJP int read_pnf_xml(pnf_info& pnf, const char* xml_file)
+int read_pnf_xml(pnf_info* pnf, const char* xml_file)
+{
+#if 0
+  try
+  {
+    std::ifstream input(xml_file);
+
+    using boost::property_tree::ptree;
+    ptree pt;
+
+    read_xml(input, pt);
+
+    pnf.wireshark_test_mode = pt.get<unsigned>("pnf.wireshark_test_mode", 0);
+
+
+    pnf.sync_mode = pt.get<unsigned>("pnf.sync_mode");
+    pnf.location_mode= pt.get<unsigned>("pnf.location_mode");
+    //pnf.sync_mode = pt.get<unsigned>("pnf.location_coordinates");
+
+    pnf.dl_config_timing= pt.get<unsigned>("pnf.dl_config_timing");
+    pnf.ul_config_timing = pt.get<unsigned>("pnf.ul_config_timing");
+    pnf.tx_timing = pt.get<unsigned>("pnf.tx_timing");
+    pnf.hi_dci0_timing = pt.get<unsigned>("pnf.hi_dci0_timing");
+
+    pnf.max_phys = pt.get<unsigned>("pnf.max_phys");
+    pnf.max_total_bw = pt.get<unsigned>("pnf.max_total_bandwidth");
+    pnf.max_total_dl_layers = pt.get<unsigned>("pnf.max_total_num_dl_layers");
+    pnf.max_total_ul_layers = pt.get<unsigned>("pnf.max_total_num_ul_layers");
+
+    pnf.shared_bands = pt.get<unsigned>("pnf.shared_bands");
+    pnf.shared_pa = pt.get<unsigned>("pnf.shared_pas");
+
+    pnf.max_total_power = pt.get<signed>("pnf.maximum_total_power");
+
+    //"oui");
+
+    for(const auto& v : pt.get_child("pnf.phys"))
+    {
+      if(v.first == "phy")
+      {
+        phy_info phy;
+
+
+
+        phy.index = v.second.get<unsigned>("index");
+        phy.local_port = v.second.get<unsigned>("port");
+        phy.local_addr = v.second.get<std::string>("address");
+        phy.duplex_mode = v.second.get<unsigned>("duplex_mode");
+
+        phy.dl_channel_bw_support = v.second.get<unsigned>("downlink_channel_bandwidth_support");
+        phy.ul_channel_bw_support = v.second.get<unsigned>("uplink_channel_bandwidth_support");
+        phy.num_dl_layers_supported = v.second.get<unsigned>("number_of_dl_layers");
+        phy.num_ul_layers_supported = v.second.get<unsigned>("number_of_ul_layers");
+        phy.release_supported = v.second.get<unsigned>("3gpp_release_supported");
+        phy.nmm_modes_supported = v.second.get<unsigned>("nmm_modes_supported");
+
+        for(const auto& v2 : v.second.get_child("rfs"))
+        {
+          if(v2.first == "index")
+            phy.rfs.push_back(v2.second.get_value<unsigned>());
+        }
+        for(const auto& v2 : v.second.get_child("excluded_rfs"))
+        {
+          if(v2.first == "index")
+            phy.excluded_rfs.push_back(v2.second.get_value<unsigned>());
+        }
+
+        boost::optional<const boost::property_tree::ptree&> d = v.second.get_child_optional("data.udp");
+        if(d.is_initialized())
+        {
+          phy.udp.enabled = true;
+          phy.udp.rx_port = d.get().get<unsigned>("rx_port");
+          phy.udp.tx_port = d.get().get<unsigned>("tx_port");
+          phy.udp.tx_addr = d.get().get<std::string>("tx_addr");
+        }
+        else
+        {
+          phy.udp.enabled = false;
+        }
+
+        phy.dl_ues_per_subframe = v.second.get<unsigned>("dl_ues_per_subframe");
+        phy.ul_ues_per_subframe = v.second.get<unsigned>("ul_ues_per_subframe");
+
+        pnf.phys.push_back(phy);
+      }
+    }	
+    for(const auto& v : pt.get_child("pnf.rfs"))
+    {
+      if(v.first == "rf")
+      {
+        rf_info rf;
+
+        rf.index = v.second.get<unsigned>("index");
+        rf.band = v.second.get<unsigned>("band");
+        rf.max_transmit_power = v.second.get<signed>("max_transmit_power");
+        rf.min_transmit_power = v.second.get<signed>("min_transmit_power");
+        rf.num_antennas_supported = v.second.get<unsigned>("num_antennas_supported");
+        rf.min_downlink_frequency = v.second.get<unsigned>("min_downlink_frequency");
+        rf.max_downlink_frequency = v.second.get<unsigned>("max_downlink_frequency");
+        rf.min_uplink_frequency = v.second.get<unsigned>("max_uplink_frequency");
+        rf.max_uplink_frequency = v.second.get<unsigned>("min_uplink_frequency");
+
+        pnf.rfs.push_back(rf);
+      }
+    }	
+  }
+  catch(std::exception& e)
+  {
+    printf("%s", e.what());
+    return -1;
+  }
+  catch(boost::exception& e)
+  {
+    printf("%s", boost::diagnostic_information(e).c_str());
+    return -1;
+  }
+
+#endif
+
+#if 0
+  pnf->phys[0].udp.enabled = 1;
+  pnf->phys[0].udp.rx_port = 50000; //DJP d.get().get<unsigned>("rx_port");
+  pnf->phys[0].udp.tx_port = 50001; //DJP d.get().get<unsigned>("tx_port");
+  strcpy(pnf->phys[0].udp.tx_addr, "127.0.0.2"); //DJP d.get().get<std::string>("tx_addr");
+  printf("%s() DJP HARD CODED PHY UDP address port to %s rx:%d tx:%d\n", 
+      __FUNCTION__, pnf->phys[0].udp.tx_addr, pnf->phys[0].udp.rx_port, pnf->phys[0].udp.tx_port);
+#endif
+
+  return 0;
+}
+
+void pnf_sim_trace(nfapi_trace_level_t level, const char* message, ...)
+{
+  va_list args;
+  va_start(args, message);
+  vprintf(message, args);
+  va_end(args);
+}
+
+void pnf_set_thread_priority(int priority)
+{
+  //printf("%s(priority:%d)\n", __FUNCTION__, priority);
+
+  pthread_attr_t ptAttr;
+
+  struct sched_param schedParam;
+  schedParam.__sched_priority = priority; //79;
+  if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0)
+  {
+    printf("failed to set SCHED_RR\n");
+  }
+
+  if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0)
+  {
+    printf("failed to set pthread SCHED_RR %d\n", errno);
+  }
+
+  pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED);
+
+  struct sched_param thread_params;
+  thread_params.sched_priority = 20;
+  if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0)
+  {
+    printf("failed to set sched param\n");
+  }
+}
+
+void* pnf_p7_thread_start(void* ptr)
+{
+  NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P7 THREAD %s\n", __FUNCTION__);
+
+  pnf_set_thread_priority(79);
+
+  nfapi_pnf_p7_config_t* config = (nfapi_pnf_p7_config_t*)ptr;
+  nfapi_pnf_p7_start(config);
+
+  return 0;
+}
+
+
+
+int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req)
+{
+  printf("[PNF] pnf param request\n");
+
+  nfapi_pnf_param_response_t resp;
+  memset(&resp, 0, sizeof(resp));
+  resp.header.message_id = NFAPI_PNF_PARAM_RESPONSE;
+  resp.error_code = NFAPI_MSG_OK;
+
+  pnf_info* pnf = (pnf_info*)(config->user_data);
+
+  resp.pnf_param_general.tl.tag = NFAPI_PNF_PARAM_GENERAL_TAG;
+  resp.pnf_param_general.nfapi_sync_mode = pnf->sync_mode;
+  resp.pnf_param_general.location_mode = pnf->location_mode;
+  //uint8_t location_coordinates[NFAPI_PNF_PARAM_GENERAL_LOCATION_LENGTH];
+  resp.pnf_param_general.dl_config_timing = pnf->dl_config_timing;
+  resp.pnf_param_general.tx_timing = pnf->tx_timing;
+  resp.pnf_param_general.ul_config_timing = pnf->ul_config_timing;
+  resp.pnf_param_general.hi_dci0_timing = pnf->hi_dci0_timing;
+  resp.pnf_param_general.maximum_number_phys = pnf->max_phys;
+  resp.pnf_param_general.maximum_total_bandwidth = pnf->max_total_bw;
+  resp.pnf_param_general.maximum_total_number_dl_layers = pnf->max_total_dl_layers;
+  resp.pnf_param_general.maximum_total_number_ul_layers = pnf->max_total_ul_layers;
+  resp.pnf_param_general.shared_bands = pnf->shared_bands;
+  resp.pnf_param_general.shared_pa = pnf->shared_pa;
+  resp.pnf_param_general.maximum_total_power = pnf->max_total_power;
+  //uint8_t oui[NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH];
+
+  resp.pnf_phy.tl.tag = NFAPI_PNF_PHY_TAG;
+  //DJP resp.pnf_phy.number_of_phys = pnf->phys.size();
+  resp.pnf_phy.number_of_phys = 1;
+
+  //for(int i = 0; i < pnf->phys.size(); ++i)
+  for(int i = 0; i < 1; ++i)
+  {
+    resp.pnf_phy.phy[i].phy_config_index = pnf->phys[i].index; 
+    resp.pnf_phy.phy[i].downlink_channel_bandwidth_supported = pnf->phys[i].dl_channel_bw_support;
+    resp.pnf_phy.phy[i].uplink_channel_bandwidth_supported = pnf->phys[i].ul_channel_bw_support;
+    resp.pnf_phy.phy[i].number_of_dl_layers_supported = pnf->phys[i].num_dl_layers_supported;
+    resp.pnf_phy.phy[i].number_of_ul_layers_supported = pnf->phys[i].num_ul_layers_supported;
+    resp.pnf_phy.phy[i].maximum_3gpp_release_supported = pnf->phys[i].release_supported;
+    resp.pnf_phy.phy[i].nmm_modes_supported = pnf->phys[i].nmm_modes_supported;
+
+    //DJP resp.pnf_phy.phy[i].number_of_rfs = pnf->phys[i].rfs.size();
+    resp.pnf_phy.phy[i].number_of_rfs = 2;
+    //for(int j = 0; j < pnf->phys[i].rfs.size(); ++j)
+    for(int j = 0; j < 1; ++j)
+    {
+      resp.pnf_phy.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j];
+    }
+
+    //DJP resp.pnf_phy.phy[i].number_of_rf_exclusions = pnf->phys[i].excluded_rfs.size();
+    resp.pnf_phy.phy[i].number_of_rf_exclusions = 0;
+    //DJP for(int j = 0; j < pnf->phys[i].excluded_rfs.size(); ++j)
+    for(int j = 0; j < 0; ++j)
+    {
+      resp.pnf_phy.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j];
+    }
+  }
+
+
+  resp.pnf_rf.tl.tag = NFAPI_PNF_RF_TAG;
+  //DJPresp.pnf_rf.number_of_rfs = pnf->rfs.size();
+  resp.pnf_rf.number_of_rfs = 2;
+
+  //for(int i = 0; i < pnf->rfs.size(); ++i)
+  for(int i = 0; i < 2; ++i)
+  {
+    resp.pnf_rf.rf[i].rf_config_index = pnf->rfs[i].index; 
+    resp.pnf_rf.rf[i].band = pnf->rfs[i].band;
+    resp.pnf_rf.rf[i].maximum_transmit_power = pnf->rfs[i].max_transmit_power; 
+    resp.pnf_rf.rf[i].minimum_transmit_power = pnf->rfs[i].min_transmit_power;
+    resp.pnf_rf.rf[i].number_of_antennas_suppported = pnf->rfs[i].num_antennas_supported;
+    resp.pnf_rf.rf[i].minimum_downlink_frequency = pnf->rfs[i].min_downlink_frequency;
+    resp.pnf_rf.rf[i].maximum_downlink_frequency = pnf->rfs[i].max_downlink_frequency;
+    resp.pnf_rf.rf[i].minimum_uplink_frequency = pnf->rfs[i].min_uplink_frequency;
+    resp.pnf_rf.rf[i].maximum_uplink_frequency = pnf->rfs[i].max_uplink_frequency;
+  }
+
+  if(pnf->release >= 10)
+  {
+    resp.pnf_phy_rel10.tl.tag = NFAPI_PNF_PHY_REL10_TAG;
+    //DJPresp.pnf_phy_rel10.number_of_phys = pnf->phys.size();
+    resp.pnf_phy_rel10.number_of_phys = 1;
+
+    //for(int i = 0; i < pnf->phys.size(); ++i)
+    for(int i = 0; i < 1; ++i)
+    {
+      resp.pnf_phy_rel10.phy[i].phy_config_index = pnf->phys[i].index; 
+      resp.pnf_phy_rel10.phy[i].transmission_mode_7_supported = 0;
+      resp.pnf_phy_rel10.phy[i].transmission_mode_8_supported = 1;
+      resp.pnf_phy_rel10.phy[i].two_antenna_ports_for_pucch = 0;
+      resp.pnf_phy_rel10.phy[i].transmission_mode_9_supported = 1;
+      resp.pnf_phy_rel10.phy[i].simultaneous_pucch_pusch = 0;
+      resp.pnf_phy_rel10.phy[i].four_layer_tx_with_tm3_and_tm4 = 1;
+
+    }
+  }
+
+  if(pnf->release >= 11)
+  {
+    resp.pnf_phy_rel11.tl.tag = NFAPI_PNF_PHY_REL11_TAG;
+    //DJP resp.pnf_phy_rel11.number_of_phys = pnf->phys.size();
+    resp.pnf_phy_rel11.number_of_phys = 1;
+
+    //DJP for(int i = 0; i < pnf->phys.size(); ++i)
+    for(int i = 0; i < 1; ++i)
+    {
+      resp.pnf_phy_rel11.phy[i].phy_config_index = pnf->phys[i].index; 
+      resp.pnf_phy_rel11.phy[i].edpcch_supported = 0;
+      resp.pnf_phy_rel11.phy[i].multi_ack_csi_reporting = 1;
+      resp.pnf_phy_rel11.phy[i].pucch_tx_diversity = 0;
+      resp.pnf_phy_rel11.phy[i].ul_comp_supported = 1;
+      resp.pnf_phy_rel11.phy[i].transmission_mode_5_supported = 0;
+    }
+  }
+
+  if(pnf->release >= 12)
+  {
+    resp.pnf_phy_rel12.tl.tag = NFAPI_PNF_PHY_REL12_TAG;
+    //DJP resp.pnf_phy_rel12.number_of_phys = pnf->phys.size();
+    resp.pnf_phy_rel12.number_of_phys = 1;
+
+    //DJP for(int i = 0; i < pnf->phys.size(); ++i)
+    for(int i = 0; i < 1; ++i)
+    {
+      resp.pnf_phy_rel12.phy[i].phy_config_index = pnf->phys[i].index; 
+      resp.pnf_phy_rel12.phy[i].csi_subframe_set = 0;
+      resp.pnf_phy_rel12.phy[i].enhanced_4tx_codebook = 2; // yes this is invalid
+      resp.pnf_phy_rel12.phy[i].drs_supported = 0;
+      resp.pnf_phy_rel12.phy[i].ul_64qam_supported = 1;
+      resp.pnf_phy_rel12.phy[i].transmission_mode_10_supported = 0;
+      resp.pnf_phy_rel12.phy[i].alternative_bts_indices = 1;
+    }
+  }
+
+  if(pnf->release >= 13)
+  {
+    resp.pnf_phy_rel13.tl.tag = NFAPI_PNF_PHY_REL13_TAG;
+    //DJP resp.pnf_phy_rel13.number_of_phys = pnf->phys.size();
+    resp.pnf_phy_rel13.number_of_phys = 1;
+
+    //for(int i = 0; i < pnf->phys.size(); ++i)
+    for(int i = 0; i < 1; ++i)
+    {
+      resp.pnf_phy_rel13.phy[i].phy_config_index = pnf->phys[i].index; 
+      resp.pnf_phy_rel13.phy[i].pucch_format4_supported = 0;
+      resp.pnf_phy_rel13.phy[i].pucch_format5_supported = 1;
+      resp.pnf_phy_rel13.phy[i].more_than_5_ca_support = 0;
+      resp.pnf_phy_rel13.phy[i].laa_supported = 1;
+      resp.pnf_phy_rel13.phy[i].laa_ending_in_dwpts_supported = 0;
+      resp.pnf_phy_rel13.phy[i].laa_starting_in_second_slot_supported = 1;
+      resp.pnf_phy_rel13.phy[i].beamforming_supported = 0;
+      resp.pnf_phy_rel13.phy[i].csi_rs_enhancement_supported = 1;
+      resp.pnf_phy_rel13.phy[i].drms_enhancement_supported = 0;
+      resp.pnf_phy_rel13.phy[i].srs_enhancement_supported = 1;
+    }
+
+    resp.pnf_phy_rel13_nb_iot.tl.tag = NFAPI_PNF_PHY_REL13_NB_IOT_TAG;
+    //DJP resp.pnf_phy_rel13_nb_iot.number_of_phys = pnf->phys.size();		
+    resp.pnf_phy_rel13_nb_iot.number_of_phys = 1;
+
+    //for(int i = 0; i < pnf->phys.size(); ++i)
+    for(int i = 0; i < 1; ++i)
+    {
+      resp.pnf_phy_rel13_nb_iot.phy[i].phy_config_index = pnf->phys[i].index; 
+
+      //DJP resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rfs = pnf->phys[i].rfs.size();
+      resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rfs = 1;
+      //DJP for(int j = 0; j < pnf->phys[i].rfs.size(); ++j)
+      for(int j = 0; j < 1; ++j)
+      {
+        resp.pnf_phy_rel13_nb_iot.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j];
+      }
+
+      //DJP resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rf_exclusions = pnf->phys[i].excluded_rfs.size();
+      resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rf_exclusions = 1;
+      //DJP for(int j = 0; j < pnf->phys[i].excluded_rfs.size(); ++j)
+      for(int j = 0; j < 1; ++j)
+      {
+        resp.pnf_phy_rel13_nb_iot.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j];
+      }
+
+      resp.pnf_phy_rel13_nb_iot.phy[i].number_of_dl_layers_supported = pnf->phys[i].num_dl_layers_supported;
+      resp.pnf_phy_rel13_nb_iot.phy[i].number_of_ul_layers_supported = pnf->phys[i].num_ul_layers_supported;
+      resp.pnf_phy_rel13_nb_iot.phy[i].maximum_3gpp_release_supported = pnf->phys[i].release_supported;
+      resp.pnf_phy_rel13_nb_iot.phy[i].nmm_modes_supported = pnf->phys[i].nmm_modes_supported;
+
+    }
+  }
+
+
+  nfapi_pnf_pnf_param_resp(config, &resp);
+
+  return 0;
+}
+
+int pnf_config_request(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req)
+{
+  printf("[PNF] pnf config request\n");
+
+  pnf_info* pnf = (pnf_info*)(config->user_data);
+
+#if 0
+  for(int i = 0; i < req->pnf_phy_rf_config.number_phy_rf_config_info; ++i)
+  {
+    auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item)
+        { return item.index == req->pnf_phy_rf_config.phy_rf_config[i].phy_config_index; });
+
+    if(found != pnf->phys.end())
+    {
+      phy_info& phy = (*found);
+      phy.id = req->pnf_phy_rf_config.phy_rf_config[i].phy_id;
+      printf("[PNF] pnf config request assigned phy_id %d to phy_config_index %d\n", phy.id, req->pnf_phy_rf_config.phy_rf_config[i].phy_config_index);
+    }
+    else
+    {
+      // did not find the phy
+      printf("[PNF] pnf config request did not find phy_config_index %d\n", req->pnf_phy_rf_config.phy_rf_config[i].phy_config_index);
+    }
+
+  }
+#endif
+  //DJP
+  phy_info *phy = pnf->phys;
+  phy->id = req->pnf_phy_rf_config.phy_rf_config[0].phy_id;
+  printf("[PNF] pnf config request assigned phy_id %d to phy_config_index %d\n", phy->id, req->pnf_phy_rf_config.phy_rf_config[0].phy_config_index);
+  //DJP
+
+  nfapi_pnf_config_response_t resp;
+  memset(&resp, 0, sizeof(resp));
+  resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE;
+  resp.error_code = NFAPI_MSG_OK;
+  nfapi_pnf_pnf_config_resp(config, &resp);
+  printf("[PNF] Sent pnf_config_resp\n");
+
+  return 0;
+}
+
+int fapi_param_response(fapi_t* fapi, fapi_param_resp_t* resp)
+{
+  printf("[PNF] fapi param response\n");
+  pnf_phy_user_data_t* data = (pnf_phy_user_data_t*)(fapi->user_data);
+
+  nfapi_param_response_t nfapi_resp;
+
+  printf("[PNF] fapi param response phy_id:%d number_of_tlvs:%u\n", data->phy_id, resp->number_of_tlvs);
+
+  memset(&nfapi_resp, 0, sizeof(nfapi_resp));
+  nfapi_resp.header.message_id = NFAPI_PARAM_RESPONSE;
+  nfapi_resp.header.phy_id = data->phy_id;
+  nfapi_resp.error_code = resp->error_code;
+
+  for(int i = 0; i < resp->number_of_tlvs; ++i)
+  {
+    switch(resp->tlvs[i].tag)
+    {
+      case FAPI_PHY_STATE_TAG:
+        nfapi_resp.l1_status.phy_state.tl.tag = NFAPI_L1_STATUS_PHY_STATE_TAG;
+        nfapi_resp.l1_status.phy_state.value = resp->tlvs[i].value;
+        nfapi_resp.num_tlv++;
+        break;
+
+      case FAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG:
+        nfapi_resp.phy_capabilities.dl_bandwidth_support.tl.tag = NFAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG;
+        nfapi_resp.phy_capabilities.dl_bandwidth_support.value = resp->tlvs[i].value;
+        nfapi_resp.num_tlv++;
+        printf("%s() DL BW support %d\n", __FUNCTION__, nfapi_resp.phy_capabilities.dl_bandwidth_support.value);
+        break;
+
+      case FAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG:
+        nfapi_resp.phy_capabilities.ul_bandwidth_support.tl.tag = NFAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG;
+        nfapi_resp.phy_capabilities.ul_bandwidth_support.value = resp->tlvs[i].value;
+        nfapi_resp.num_tlv++;
+        break;
+      default:
+        printf("%s() %s:%d Unhandled TLV:%d\n", __FUNCTION__, __FILE__, __LINE__, resp->tlvs[i].tag);
+        break;
+    }
+  }
+
+  {
+    //if(phy->state == NFAPI_PNF_PHY_IDLE)
+    //if(nfapi_resp.l1_status.phy_state.value == NFAPI_PNF_PHY_IDLE)
+    {
+      // -- NFAPI
+      // Downlink UEs per Subframe
+      nfapi_resp.nfapi_config.dl_ue_per_sf.tl.tag = NFAPI_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG;
+      nfapi_resp.nfapi_config.dl_ue_per_sf.value = data->phy->dl_ues_per_subframe;
+      nfapi_resp.num_tlv++;
+      // Uplink UEs per Subframe
+      nfapi_resp.nfapi_config.ul_ue_per_sf.tl.tag = NFAPI_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG;
+      nfapi_resp.nfapi_config.ul_ue_per_sf.value = data->phy->ul_ues_per_subframe;
+      nfapi_resp.num_tlv++;
+      // nFAPI RF Bands
+      nfapi_resp.nfapi_config.rf_bands.tl.tag = NFAPI_PHY_RF_BANDS_TAG;
+      nfapi_resp.nfapi_config.rf_bands.number_rf_bands = 2;
+      nfapi_resp.nfapi_config.rf_bands.rf_band[0] = 23;
+      nfapi_resp.nfapi_config.rf_bands.rf_band[1] = 7;
+
+      // P7 PNF Address IPv4
+      nfapi_resp.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG;
+      struct sockaddr_in pnf_p7_sockaddr;
+      //DJP pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(data->phy->local_addr.c_str());
+
+      //DJP
+      strcpy(data->phy->local_addr, "192.168.1.74");
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DJP HARD CODED IP ADDRESS to %s\n", __FUNCTION__, data->phy->local_addr);
+      data->phy->local_port = 32123;
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DJP HARD CODED PORT to %d\n", __FUNCTION__, data->phy->local_port);
+
+
+
+
+      pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(data->phy->local_addr);
+      memcpy(&(nfapi_resp.nfapi_config.p7_pnf_address_ipv4.address[0]), &pnf_p7_sockaddr.sin_addr.s_addr, 4);
+      nfapi_resp.num_tlv++;
+      // P7 PNF Address IPv6
+      // P7 PNF Port
+      nfapi_resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NFAPI_P7_PNF_PORT_TAG;
+      nfapi_resp.nfapi_config.p7_pnf_port.value = data->phy->local_port;
+      nfapi_resp.num_tlv++;
+      // NMM GSM Frequency Bands
+      nfapi_resp.nfapi_config.nmm_gsm_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG;
+      nfapi_resp.nfapi_config.nmm_gsm_frequency_bands.number_of_rf_bands = 1;
+      nfapi_resp.nfapi_config.nmm_gsm_frequency_bands.bands[0] = 23;
+      nfapi_resp.num_tlv++;
+      // NMM UMTS Frequency Bands
+      nfapi_resp.nfapi_config.nmm_umts_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG;
+      nfapi_resp.nfapi_config.nmm_umts_frequency_bands.number_of_rf_bands = 1;
+      nfapi_resp.nfapi_config.nmm_umts_frequency_bands.bands[0] = 23;
+      nfapi_resp.num_tlv++;
+      // NMM LTE Frequency Bands
+      nfapi_resp.nfapi_config.nmm_lte_frequency_bands.tl.tag = NFAPI_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG;
+      nfapi_resp.nfapi_config.nmm_lte_frequency_bands.number_of_rf_bands = 1;
+      nfapi_resp.nfapi_config.nmm_lte_frequency_bands.bands[0] = 23;
+      nfapi_resp.num_tlv++;
+      // NMM Uplink RSSI supported
+      nfapi_resp.nfapi_config.nmm_uplink_rssi_supported.tl.tag = NFAPI_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG;
+      nfapi_resp.nfapi_config.nmm_uplink_rssi_supported.value = 1;
+      nfapi_resp.num_tlv++;
+
+    }
+  }
+
+  nfapi_pnf_param_resp(data->config, &nfapi_resp);
+
+  return 0;
+}
+
+void nfapi_send_pnf_start_resp(nfapi_pnf_config_t* config, uint16_t phy_id)
+{
+  printf("Sending NFAPI_START_RESPONSE config:%p phy_id:%d\n", config, phy_id);
+
+  nfapi_start_response_t start_resp;
+  memset(&start_resp, 0, sizeof(start_resp));
+  start_resp.header.message_id = NFAPI_START_RESPONSE;
+  start_resp.header.phy_id = phy_id;
+  start_resp.error_code = NFAPI_MSG_OK;
+
+  nfapi_pnf_start_resp(config, &start_resp);
+}
+
+int pnf_start_request(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req)
+{
+  printf("Received NFAPI_PNF_START_REQUEST\n");
+
+  pnf_info* pnf = (pnf_info*)(config->user_data);
+
+  // start all phys that have been configured
+  //for(phy_info& phy : pnf->phys)
+  phy_info* phy = pnf->phys;
+  if(phy->id != 0)
+  {
+    //auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item)
+    //		{ return item.id == req->header.phy_id; });
+    //
+    //	if(found != pnf->phys.end())
+    //	{
+    //		phy_info& phy = (*found);
+    //}
+
+    nfapi_pnf_start_response_t resp;
+    memset(&resp, 0, sizeof(resp));
+    resp.header.message_id = NFAPI_PNF_START_RESPONSE;
+    resp.error_code = NFAPI_MSG_OK;
+    nfapi_pnf_pnf_start_resp(config, &resp);
+    printf("[PNF] Sent NFAPI_PNF_START_RESP\n");
+  }
+  return 0;
+}
+
+int pnf_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_stop_request_t* req)
+{
+  printf("[PNF] Received NFAPI_PNF_STOP_REQ\n");
+
+  nfapi_pnf_stop_response_t resp;
+  memset(&resp, 0, sizeof(resp));
+  resp.header.message_id = NFAPI_PNF_STOP_RESPONSE;
+  resp.error_code = NFAPI_MSG_OK;
+  nfapi_pnf_pnf_stop_resp(config, &resp);
+  printf("[PNF] Sent NFAPI_PNF_STOP_REQ\n");
+
+  return 0;
+}
+
+int param_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req)
+{
+  printf("[PNF] Received NFAPI_PARAM_REQUEST phy_id:%d\n", req->header.phy_id);
+
+  //pnf_info* pnf = (pnf_info*)(config->user_data);
+
+  nfapi_param_response_t nfapi_resp;
+
+  memset(&nfapi_resp, 0, sizeof(nfapi_resp));
+  nfapi_resp.header.message_id = NFAPI_PARAM_RESPONSE;
+  nfapi_resp.header.phy_id = req->header.phy_id;
+  nfapi_resp.error_code = 0; // DJP - what value???
+
+  char local_addr[80];
+  struct sockaddr_in pnf_p7_sockaddr;
+
+  strcpy(local_addr, "192.168.1.74"); // DJP - hard code alert FIXME TODO
+
+  pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(local_addr);
+  nfapi_resp.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG;
+  memcpy(nfapi_resp.nfapi_config.p7_pnf_address_ipv4.address, &pnf_p7_sockaddr.sin_addr.s_addr, 4);
+  nfapi_resp.num_tlv++;
+
+  // P7 PNF Port
+  nfapi_resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NFAPI_P7_PNF_PORT_TAG;
+  nfapi_resp.nfapi_config.p7_pnf_port.value = 32123; // DJP - hard code alert!!!! FIXME TODO
+  nfapi_resp.num_tlv++;
+
+  nfapi_pnf_param_resp(config, &nfapi_resp);
+
+  printf("[PNF] Sent NFAPI_PARAM_RESPONSE phy_id:%d number_of_tlvs:%u\n", req->header.phy_id, nfapi_resp.num_tlv);
+#if 0
+  //DJP
+  auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item)
+      { return item.id == req->header.phy_id; });
+
+  if(found != pnf->phys.end())
+#endif
+  {
+    //DJP phy_info& phy_info = (*found);
+    //phy_info *phy_info = pnf->phys;
+
+  }
+#if 0
+  else
+  {
+    // did not find the phy
+  }
+#endif
+
+  printf("[PNF] param request .. exit\n");
+
+  return 0;
+}
+
+// From MAC config.c
+extern uint32_t from_earfcn(int eutra_bandP,uint32_t dl_earfcn);
+extern int32_t get_uldl_offset(int eutra_bandP);
+
+int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req)
+{
+  printf("[PNF] Received NFAPI_CONFIG_REQ phy_id:%d\n", req->header.phy_id);
+
+  pnf_info* pnf = (pnf_info*)(config->user_data);
+  uint8_t num_tlv = 0;
+
+#if 0
+  //DJP
+  auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item)
+      { return item.id == req->header.phy_id; });
+
+  if(found != pnf->phys.end())
+  {
+    phy_info& phy_info = (*found);
+  }
+#endif
+  //DJP 
+  phy_info* phy_info = pnf->phys;
+
+  if(req->nfapi_config.timing_window.tl.tag == NFAPI_NFAPI_TIMING_WINDOW_TAG)
+  {
+    phy_info->timing_window = req->nfapi_config.timing_window.value;
+    num_tlv++;
+  }
+
+  if(req->nfapi_config.timing_info_mode.tl.tag == NFAPI_NFAPI_TIMING_INFO_MODE_TAG)
+  {
+    printf("timing info mode provided\n");
+    phy_info->timing_info_mode = req->nfapi_config.timing_info_mode.value;
+    num_tlv++;
+  }
+  else 
+  {
+    phy_info->timing_info_mode = 0;
+    printf("NO timing info mode provided\n");
+  }
+
+  if(req->nfapi_config.timing_info_period.tl.tag == NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG)
+  {
+    printf("timing info period provided\n");
+    phy_info->timing_info_period = req->nfapi_config.timing_info_period.value;
+    num_tlv++;
+  }
+  else 
+  {
+    phy_info->timing_info_period = 0;
+  }
+
+  if(req->rf_config.dl_channel_bandwidth.tl.tag == NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG)
+  {
+    phy_info->dl_channel_bw_support = req->rf_config.dl_channel_bandwidth.value;
+    RC.eNB[0][0]->frame_parms.N_RB_DL = req->rf_config.dl_channel_bandwidth.value;
+    num_tlv++;
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG N_RB_DL:%u\n", __FUNCTION__, RC.eNB[0][0]->frame_parms.N_RB_DL);
+  }
+  else
+  {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() Missing NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG\n", __FUNCTION__);
+  }
+
+  if(req->rf_config.ul_channel_bandwidth.tl.tag == NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG)
+  {
+    phy_info->ul_channel_bw_support = req->rf_config.ul_channel_bandwidth.value;
+    RC.eNB[0][0]->frame_parms.N_RB_UL = req->rf_config.ul_channel_bandwidth.value;
+    num_tlv++;
+  }
+
+  if(req->nfapi_config.rf_bands.tl.tag == NFAPI_NFAPI_RF_BANDS_TAG)
+  {
+    pnf->rfs[0].band = req->nfapi_config.rf_bands.rf_band[0];
+    RC.eNB[0][0]->frame_parms.eutra_band = req->nfapi_config.rf_bands.rf_band[0];
+    num_tlv++;
+  }
+
+  if(req->nfapi_config.earfcn.tl.tag == NFAPI_NFAPI_EARFCN_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.dl_CarrierFreq = from_earfcn(RC.eNB[0][0]->frame_parms.eutra_band, req->nfapi_config.earfcn.value); // DJP - TODO FIXME - hard coded to first rf
+    RC.eNB[0][0]->frame_parms.ul_CarrierFreq = RC.eNB[0][0]->frame_parms.dl_CarrierFreq - (get_uldl_offset(RC.eNB[0][0]->frame_parms.eutra_band) * 1e5);
+    num_tlv++;
+
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() earfcn:%u dl_carrierFreq:%u ul_CarrierFreq:%u band:%u N_RB_DL:%u\n", 
+        __FUNCTION__, req->nfapi_config.earfcn.value, RC.eNB[0][0]->frame_parms.dl_CarrierFreq, RC.eNB[0][0]->frame_parms.ul_CarrierFreq, pnf->rfs[0].band, RC.eNB[0][0]->frame_parms.N_RB_DL);
+  }
+
+  if (req->subframe_config.duplex_mode.tl.tag == NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.frame_type = req->subframe_config.duplex_mode.value==0 ? TDD : FDD;
+    num_tlv++;
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() frame_type:%d\n", __FUNCTION__, RC.eNB[0][0]->frame_parms.frame_type);
+  }
+  if (req->subframe_config.dl_cyclic_prefix_type.tl.tag == NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.Ncp = req->subframe_config.dl_cyclic_prefix_type.value;
+    num_tlv++;
+  }
+
+  if (req->subframe_config.ul_cyclic_prefix_type.tl.tag == NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.Ncp_UL = req->subframe_config.ul_cyclic_prefix_type.value;
+    num_tlv++;
+  }
+
+  RC.eNB[0][0]->frame_parms.num_MBSFN_config = 0; // DJP - hard code alert
+
+  if (req->sch_config.physical_cell_id.tl.tag == NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.Nid_cell = req->sch_config.physical_cell_id.value;
+    num_tlv++;
+  }
+
+  if (req->rf_config.tx_antenna_ports.tl.tag == NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.nb_antennas_tx = req->rf_config.tx_antenna_ports.value;
+    RC.eNB[0][0]->frame_parms.nb_antenna_ports_eNB = 1;
+    num_tlv++;
+  }
+
+  if (req->rf_config.rx_antenna_ports.tl.tag == NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.nb_antennas_rx = req->rf_config.rx_antenna_ports.value;
+    num_tlv++;
+  }
+
+  if (req->rf_config.rx_antenna_ports.tl.tag == NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.nb_antennas_rx = req->rf_config.rx_antenna_ports.value;
+    num_tlv++;
+  }
+
+  RC.eNB[0][0]->frame_parms.nushift = 0;
+
+  if (req->phich_config.phich_resource.tl.tag == NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.phich_config_common.phich_resource = req->phich_config.phich_resource.value;
+    num_tlv++;
+  }
+
+  if (req->phich_config.phich_duration.tl.tag == NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.phich_config_common.phich_duration = req->phich_config.phich_duration.value;
+    num_tlv++;
+  }
+
+  if (req->phich_config.phich_power_offset.tl.tag == NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG)
+  {
+    LOG_E(PHY, "%s() NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG tag:%d not supported\n", __FUNCTION__, req->phich_config.phich_power_offset.tl.tag);
+    //RC.eNB[0][0]->frame_parms.phich_config_common.phich_power_offset = req->phich_config.
+    num_tlv++;
+  }
+
+  // UL RS Config
+  if (req->uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag == NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = req->uplink_reference_signal_config.cyclic_shift_1_for_drms.value;
+    num_tlv++;
+  }
+
+  if (req->uplink_reference_signal_config.uplink_rs_hopping.tl.tag == NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = req->uplink_reference_signal_config.uplink_rs_hopping.value;
+    num_tlv++;
+  }
+
+  if (req->uplink_reference_signal_config.group_assignment.tl.tag == NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = req->uplink_reference_signal_config.group_assignment.value;
+    num_tlv++;
+  }
+
+  if (req->pusch_config.hopping_mode.tl.tag == NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG) { }  // DJP - not being handled?
+
+  RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; // DJP - not being handled
+
+  if (req->prach_config.configuration_index.tl.tag == NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex=req->prach_config.configuration_index.value;
+    num_tlv++;
+  }
+
+  if (req->prach_config.root_sequence_index.tl.tag == NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.prach_config_common.rootSequenceIndex=req->prach_config.root_sequence_index.value;
+    num_tlv++;
+  }
+
+  if (req->prach_config.zero_correlation_zone_configuration.tl.tag == NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=req->prach_config.zero_correlation_zone_configuration.value;
+    num_tlv++;
+  }
+
+  if (req->prach_config.high_speed_flag.tl.tag == NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag=req->prach_config.high_speed_flag.value;
+    num_tlv++;
+  }
+
+  if (req->prach_config.frequency_offset.tl.tag == NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG)
+  {
+    RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset=req->prach_config.frequency_offset.value;
+    num_tlv++;
+  }
+
+  printf("[PNF] CONFIG_REQUEST[num_tlv:%d] TLVs processed:%d\n", req->num_tlv, num_tlv);
+
+  // DJP - commented out 19/9/17
+  //init_frame_parms(&RC.eNB[0][0]->frame_parms,1);
+  //init_lte_top(&RC.eNB[0][0]->frame_parms);
+
+  printf("[PNF] Simulating PHY CONFIG - DJP\n");
+  PHY_Config_t phy_config;
+  phy_config.Mod_id = 0;
+  phy_config.CC_id=0;
+  phy_config.cfg = req;
+
+  phy_config_request(&phy_config);
+
+  dump_frame_parms(&RC.eNB[0][0]->frame_parms);
+
+  phy_info->remote_port = req->nfapi_config.p7_vnf_port.value;
+
+  struct sockaddr_in vnf_p7_sockaddr;
+  memcpy(&vnf_p7_sockaddr.sin_addr.s_addr, &(req->nfapi_config.p7_vnf_address_ipv4.address[0]), 4);
+  phy_info->remote_addr = inet_ntoa(vnf_p7_sockaddr.sin_addr);
+
+  printf("[PNF] %d vnf p7 %s:%d timing %d %d %d\n", phy_info->id, phy_info->remote_addr, phy_info->remote_port, 
+      phy_info->timing_window, phy_info->timing_info_mode, phy_info->timing_info_period);
+
+  nfapi_config_response_t nfapi_resp;
+  memset(&nfapi_resp, 0, sizeof(nfapi_resp));
+  nfapi_resp.header.message_id = NFAPI_CONFIG_RESPONSE;
+  nfapi_resp.header.phy_id = phy_info->id;
+  nfapi_resp.error_code = 0; // DJP - some value resp->error_code;
+  nfapi_pnf_config_resp(config, &nfapi_resp);
+  printf("[PNF] Sent NFAPI_CONFIG_RESPONSE phy_id:%d\n", phy_info->id);
+
+  return 0;
+}
+
+nfapi_p7_message_header_t* pnf_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t* msg_size)
+{
+  if(message_id == P7_VENDOR_EXT_REQ)
+  {
+    (*msg_size) = sizeof(vendor_ext_p7_req);
+    return (nfapi_p7_message_header_t*)malloc(sizeof(vendor_ext_p7_req));
+  }
+
+  return 0;
+}
+
+void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t* header)
+{
+  free(header);
+}
+
+int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req)
+{
+#if 0
+  printf("[PNF] dl config request sfn_sf:%d(%d) pdcch:%u dci:%u pdu:%d pdsch_rnti:%d pcfich:%u - DO  NOTHING\n", 
+      req->sfn_sf, 
+      NFAPI_SFNSF2DEC(req->sfn_sf), 
+      req->dl_config_request_body.number_pdcch_ofdm_symbols, 
+      req->dl_config_request_body.number_dci,
+      req->dl_config_request_body.number_pdu,
+      req->dl_config_request_body.number_pdsch_rnti,
+      req->dl_config_request_body.transmission_power_pcfich
+      );
+#endif
+
+  if (RC.ru == 0)
+  {
+    return -1;
+  }
+
+  if (RC.eNB == 0)
+  {
+    return -2;
+  }
+
+  if (RC.eNB[0][0] == 0)
+  {
+    return -3;
+  }
+
+  if (RC.eNB[0][0] == 0)
+  {
+    return -3;
+  }
+
+  //int sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
+  //int sf = NFAPI_SFNSF2SF(req->sfn_sf);
+
+  //struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
+  //int num_pdcch_symbols = eNB->pdcch_vars[sf&1].num_pdcch_symbols;
+
+
+
+  if(req->vendor_extension)
+    free(req->vendor_extension);
+
+  return 0;
+}
+
+int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req)
+{
+  //printf("[PNF] ul config request\n");
+  //phy_info* phy = (phy_info*)(pnf_p7->user_data);
+
+  return 0;
+}
+
+int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req)
+{
+  //printf("[PNF] hi dci0 request\n");
+  //phy_info* phy = (phy_info*)(pnf_p7->user_data);
+
+  return 0;
+}
+
+
+void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe);
+void pdsch_procedures(PHY_VARS_eNB *eNB,
+		      eNB_rxtx_proc_t *proc,
+		      int harq_pid,
+		      LTE_eNB_DLSCH_t *dlsch, 
+		      LTE_eNB_DLSCH_t *dlsch1,
+		      LTE_eNB_UE_stats *ue_stats,
+		      int ra_flag);
+
+//int  __attribute__((optimize("O0"))) pnf_phy_tx_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req)
+int  pnf_phy_tx_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req)
+{
+  if (RC.ru == 0)
+  {
+    return -1;
+  }
+
+  if (RC.eNB == 0)
+  {
+    return -2;
+  }
+
+  if (RC.eNB[0][0] == 0)
+  {
+    return -3;
+  }
+
+  if (RC.eNB[0][0] == 0)
+  {
+    return -3;
+  }
+
+  {
+    uint16_t sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
+    uint16_t sf = NFAPI_SFNSF2SF(req->sfn_sf);
+    LTE_DL_FRAME_PARMS *fp = &RC.ru[0]->frame_parms;
+    //int ONE_SUBFRAME_OF_SAMPLES = fp->ofdm_symbol_size*fp->symbols_per_tti;
+    //int ONE_SUBFRAME_OF_SAMPLES = fp->symbols_per_tti;
+    //int ONE_SUBFRAME_OF_SAMPLES = fp->ofdm_symbol_size*fp->symbols_per_tti*sizeof(int32_t);
+    //int offset = sf * ONE_SUBFRAME_OF_SAMPLES;
+    struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
+    //int aa;
+
+    // clear the transmit data array for the current subframe
+#if 0
+    for (aa=0; aa<fp->nb_antenna_ports_eNB; aa++) {      
+      memset(&eNB->common_vars.txdataF[aa][offset], 0, ONE_SUBFRAME_OF_SAMPLES);
+    }
+#endif
+
+    if (
+        0 
+        //&& NFAPI_SFNSF2DEC(req->sfn_sf) % 500 == 0
+       )
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn_sf:%u first_carrier_offset:%d pdus:%u RC.ru:%p RC.eNB:%p RC.eNB[0][0]:%p RC.eNB[0][0]->pbch_pdu:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), fp->first_carrier_offset, req->tx_request_body.number_of_pdus, RC.ru, RC.eNB, RC.eNB[0][0], RC.eNB[0][0]->pbch_pdu);
+
+    for(int i = 0; i < req->tx_request_body.number_of_pdus; ++i)
+    {
+      // DJP - TODO FIXME - work out if BCH (common_var)s or DLSCH (common.txdata)
+
+      for(int j=0; j < req->tx_request_body.tx_pdu_list[i].num_segments; ++j)
+      {
+        // DJP - hack - assume tx_req segment of length 3 = bch
+        if (req->tx_request_body.tx_pdu_list[i].segments[0].segment_length == 3)
+        {
+          eNB->pbch_pdu[2] = req->tx_request_body.tx_pdu_list[i].segments[j].segment_data[0];
+          eNB->pbch_pdu[1] = req->tx_request_body.tx_pdu_list[i].segments[j].segment_data[1];
+          eNB->pbch_pdu[0] = req->tx_request_body.tx_pdu_list[i].segments[j].segment_data[2];
+
+	  eNB->pbch_configured=1;
+
+          if (
+          1 
+          //&& NFAPI_SFNSF2DEC(req->sfn_sf) % 500 == 0
+          )
+            NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() [PDU:%u] len:%u pdu_index:%u num_segments:%u segment[0]_length:%u pbch_pdu:%x %x %x\n", 
+                __FUNCTION__, i, req->tx_request_body.tx_pdu_list[i].pdu_length, req->tx_request_body.tx_pdu_list[i].pdu_index, req->tx_request_body.tx_pdu_list[i].num_segments,
+                req->tx_request_body.tx_pdu_list[i].segments[0].segment_length,
+                eNB->pbch_pdu[0],
+                eNB->pbch_pdu[1],
+                eNB->pbch_pdu[2]);
+
+        }
+        else
+        {
+          int num_dci = 1;	// DJP -HACK!!!!
+          int frame = sfn;
+          int subframe = sf;
+          int num_pdcch_symbols = 1; // DJP HARD CODe HACK -  this is zero - eNB->pdcch_vars[subframe&1].num_pdcch_symbols;
+
+	  if (num_dci > 0)
+	    LOG_E(PHY,"SFN/SF:%d/%d num_dci:%d num_pdcch_symbols:%d\n", frame, subframe, num_dci, num_pdcch_symbols);
+
+	  generate_dci_top(num_pdcch_symbols,
+	      num_dci,
+	      &eNB->pdcch_vars[subframe&1].dci_alloc[0],
+	      0,
+	      AMP,
+	      fp,
+	      eNB->common_vars.txdataF,
+	      subframe);
+        }
+      }
+    }
+
+#if 0
+    {
+      int sched_sfn = sf==0?sfn-1:sfn-0;
+      int sched_sf = sf==0?9:sf-1;
+
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn_sf:%u sfn:%u sf:%u SCHED:%d/%d calling common_signal_procedures\n",
+          __FUNCTION__, 
+          NFAPI_SFNSF2DEC(req->sfn_sf), 
+          sfn, sf,
+          sched_sfn, sched_sf
+          );
+
+      common_signal_procedures(eNB, sched_sfn, sched_sf);
+
+    }
+#else
+      common_signal_procedures(eNB, sfn, sf);
+#endif
+
+    // Now scan UE specific DLSCH
+    for (int UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++)
+    {
+      LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[(uint8_t)UE_id][0]; 
+      LTE_eNB_DLSCH_t *dlsch1 = eNB->dlsch[(uint8_t)UE_id][1]; 
+
+      if ((dlsch0)&&
+          (dlsch0->rnti>0) &&
+          (dlsch0->active == 1)) {
+
+        // get harq_pid
+        uint8_t harq_pid = dlsch0->harq_ids[sf];
+        AssertFatal(harq_pid>=0,"harq_pid is negative\n");
+        // generate pdsch
+        pdsch_procedures(eNB,
+            &eNB->proc.proc_rxtx[sf&1],
+            harq_pid,
+            dlsch0,
+            dlsch1,
+            &eNB->UE_stats[(uint32_t)UE_id],
+            0);
+      }
+
+      else if ((dlsch0)&&
+          (dlsch0->rnti>0)&&
+          (dlsch0->active == 0)) {
+
+        // clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later)
+        dlsch0->subframe_tx[sf]=0;
+      }
+    }
+
+    if (0 && NFAPI_SFNSF2DEC(req->sfn_sf) % 500 == 0)
+    {
+      int32_t *txdataF = eNB->common_vars.txdataF[0];
+
+      char *buf = malloc(fp->ofdm_symbol_size * fp->symbols_per_tti * 3);
+      char *pbuf = buf;
+
+      for (int i=0;i<10;i++)
+      {
+        buf[0]='\0';
+        pbuf = buf;
+
+        for (int j=0;j<fp->ofdm_symbol_size;j++)
+        {
+          for (int k=0;k<fp->symbols_per_tti;k++)
+          {
+            pbuf += sprintf(pbuf, "%2x ", txdataF[(i*fp->symbols_per_tti)+j]);
+          }
+        }
+        NFAPI_TRACE(NFAPI_TRACE_INFO, "%s", buf);
+
+      }
+      free(buf);
+    }
+
+    return 0;
+  }
+}
+
+int pnf_phy_lbt_dl_config_req(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req)
+{
+  //printf("[PNF] lbt dl config request\n");
+  return 0;
+}
+
+int pnf_phy_vendor_ext(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg)
+{
+  if(msg->message_id == P7_VENDOR_EXT_REQ)
+  {
+    //vendor_ext_p7_req* req = (vendor_ext_p7_req*)msg;
+    //printf("[PNF] vendor request (1:%d 2:%d)\n", req->dummy1, req->dummy2);
+  }
+  else
+  {
+    printf("[PNF] unknown vendor ext\n");
+  }
+  return 0;
+}
+
+int pnf_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* codex)
+{
+  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if(header->message_id == P7_VENDOR_EXT_IND)
+  {
+    vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)(header);
+    if(!push16(ind->error_code, ppWritePackedMsg, end))
+      return 0;
+
+    return 1;
+  }
+  return -1;
+}
+
+int pnf_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t* codec)
+{
+  if(header->message_id == P7_VENDOR_EXT_REQ)
+  {
+    //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+    vendor_ext_p7_req* req = (vendor_ext_p7_req*)(header);
+    if(!(pull16(ppReadPackedMessage, &req->dummy1, end) &&
+	  pull16(ppReadPackedMessage, &req->dummy2, end)))
+      return 0;
+    return 1;
+  }
+  return -1;
+}
+
+int pnf_phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t* end, void** ve, nfapi_p7_codec_config_t* config)
+{
+  //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_phy_unpack_vendor_extension_tlv\n");
+
+  switch(tl->tag)
+  {
+    case VENDOR_EXT_TLV_1_TAG:
+      *ve = malloc(sizeof(vendor_ext_tlv_1));
+      if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_1*)(*ve))->dummy, end))
+	return 0;
+
+      return 1;
+      break;
+  }
+
+  return -1;
+}
+
+int pnf_phy_pack_vendor_extention_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p7_codec_config_t* config)
+{
+  //printf("%s\n", __FUNCTION__);
+  (void)ve;
+  (void)ppWritePackedMsg;
+  return -1;
+}
+
+int pnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* config)
+{
+  //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_sim_unpack_vendor_extension_tlv\n");
+
+  switch(tl->tag)
+  {
+    case VENDOR_EXT_TLV_2_TAG:
+      *ve = malloc(sizeof(vendor_ext_tlv_2));
+      if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_2*)(*ve))->dummy, end))
+	return 0;
+
+      return 1;
+      break;
+  }
+
+  return -1;
+}
+
+int pnf_sim_pack_vendor_extention_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+  //printf("%s\n", __FUNCTION__);
+  (void)ve;
+  (void)ppWritePackedMsg;
+  return -1;
+}
+
+int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req)
+{
+  printf("[PNF] Received NFAPI_START_REQ phy_id:%d\n", req->header.phy_id);
+
+  pnf_info* pnf = (pnf_info*)(config->user_data);
+
+#if 0
+  //DJP
+  auto found = std::find_if(pnf->phys.begin(), pnf->phys.end(), [&](phy_info& item)
+      { return item.id == req->header.phy_id; });
+
+  if(found != pnf->phys.end())
+#endif
+  {
+    //DJP phy_info& phy_info = (*found);
+    phy_info* phy_info = pnf->phys;
+
+    nfapi_pnf_p7_config_t* p7_config = nfapi_pnf_p7_config_create();
+
+    p7_config->phy_id = phy->phy_id;
+
+    p7_config->remote_p7_port = phy_info->remote_port;
+    p7_config->remote_p7_addr = phy_info->remote_addr;
+    p7_config->local_p7_port = 32123; // DJP - good grief cannot seem to get the right answer phy_info->local_port;
+    //DJP p7_config->local_p7_addr = (char*)phy_info->local_addr.c_str();
+    p7_config->local_p7_addr = phy_info->local_addr;
+
+    printf("[PNF] P7 remote:%s:%d local:%s:%d\n", p7_config->remote_p7_addr, p7_config->remote_p7_port, p7_config->local_p7_addr, p7_config->local_p7_port);
+
+    p7_config->user_data = phy_info;
+
+    p7_config->malloc = &pnf_allocate;
+    p7_config->free = &pnf_deallocate;
+    p7_config->codec_config.allocate = &pnf_allocate;
+    p7_config->codec_config.deallocate = &pnf_deallocate;
+
+    p7_config->trace = &pnf_sim_trace;
+
+    phy->user_data = p7_config;
+
+    p7_config->subframe_buffer_size = phy_info->timing_window;
+    if(phy_info->timing_info_mode & 0x1)
+    {
+      p7_config->timing_info_mode_periodic = 1;
+      p7_config->timing_info_period = phy_info->timing_info_period;
+    }
+
+    if(phy_info->timing_info_mode & 0x2)
+    {
+      p7_config->timing_info_mode_aperiodic = 1;
+    }
+
+    p7_config->dl_config_req = &pnf_phy_dl_config_req;
+    p7_config->ul_config_req = &pnf_phy_ul_config_req;
+    p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req;
+    p7_config->tx_req = &pnf_phy_tx_req;
+    p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req;
+
+    p7_config->vendor_ext = &pnf_phy_vendor_ext;
+
+    p7_config->allocate_p7_vendor_ext = &pnf_phy_allocate_p7_vendor_ext;
+    p7_config->deallocate_p7_vendor_ext = &pnf_phy_deallocate_p7_vendor_ext;
+
+    p7_config->codec_config.unpack_p7_vendor_extension = &pnf_phy_unpack_p7_vendor_extension;
+    p7_config->codec_config.pack_p7_vendor_extension = &pnf_phy_pack_p7_vendor_extension;
+    p7_config->codec_config.unpack_vendor_extension_tlv = &pnf_phy_unpack_vendor_extension_tlv;
+    p7_config->codec_config.pack_vendor_extension_tlv = &pnf_phy_pack_vendor_extention_tlv;
+
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating P7 thread %s\n", __FUNCTION__);
+    pthread_t p7_thread;
+    pthread_create(&p7_thread, NULL, &pnf_p7_thread_start, p7_config);
+
+    //((pnf_phy_user_data_t*)(phy_info->fapi->user_data))->p7_config = p7_config;
+
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Calling l1_north_init_eNB() %s\n", __FUNCTION__);
+    l1_north_init_eNB();
+
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] DJP - HACK - Set p7_config global ready for subframe ind%s\n", __FUNCTION__);
+    p7_config_g = p7_config;
+
+    printf("[PNF] MARKING RC.eNB[0][0]->configured=1 %s()\n", __FUNCTION__);
+    RC.eNB[0][0]->configured = 1;
+
+    // DJP - INIT PHY RELATED STUFF - this should be separate i think but is not currently...
+    {
+      printf("[PNF] %s() Calling phy_init_lte_eNB() and setting nb_antennas_rx = 1\n", __FUNCTION__);
+      printf("[PNF] %s() TBD create frame_parms from NFAPI message\n", __FUNCTION__);
+
+      phy_init_lte_eNB(RC.eNB[0][0],0,0);
+      RC.eNB[0][0]->frame_parms.nb_antennas_rx = 1;
+      for (int ce_level=0;ce_level<4;ce_level++)
+	RC.eNB[0][0]->prach_vars.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*));
+#ifdef Rel14
+      for (int ce_level=0;ce_level<4;ce_level++)
+	RC.eNB[0][0]->prach_vars_br.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*));
+#endif
+    }
+
+    while(sync_var<0)
+    {
+      usleep(5000000);
+      printf("[PNF] waiting for OAI to be started\n");
+    }
+
+    printf("[PNF] Sending PNF_START_RESP\n");
+    nfapi_send_pnf_start_resp(config, p7_config->phy_id);
+
+    printf("[PNF] Sending first P7 subframe ind\n");
+    nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // DJP - SFN_SF set to zero - correct???
+  }
+
+  return 0;
+}
+
+int measurement_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_measurement_request_t* req)
+{
+  nfapi_measurement_response_t resp;
+  memset(&resp, 0, sizeof(resp));
+  resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE;
+  resp.header.phy_id = req->header.phy_id;
+  resp.error_code = NFAPI_MSG_OK;
+  nfapi_pnf_measurement_resp(config, &resp);
+  return 0;
+}
+
+int rssi_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_rssi_request_t* req)
+{
+  nfapi_rssi_response_t resp;
+  memset(&resp, 0, sizeof(resp));
+  resp.header.message_id = NFAPI_RSSI_RESPONSE;
+  resp.header.phy_id = req->header.phy_id;
+  resp.error_code = NFAPI_P4_MSG_OK;
+  nfapi_pnf_rssi_resp(config, &resp);
+
+  nfapi_rssi_indication_t ind;
+  memset(&ind, 0, sizeof(ind));
+  ind.header.message_id = NFAPI_RSSI_INDICATION;
+  ind.header.phy_id = req->header.phy_id;
+  ind.error_code = NFAPI_P4_MSG_OK;
+  ind.rssi_indication_body.tl.tag = NFAPI_RSSI_INDICATION_TAG;
+  ind.rssi_indication_body.number_of_rssi = 1;
+  ind.rssi_indication_body.rssi[0] = -42;
+  nfapi_pnf_rssi_ind(config, &ind);
+  return 0;
+}
+
+int cell_search_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_cell_search_request_t* req)
+{
+  nfapi_cell_search_response_t resp;
+  memset(&resp, 0, sizeof(resp));
+  resp.header.message_id = NFAPI_CELL_SEARCH_RESPONSE;
+  resp.header.phy_id = req->header.phy_id;
+  resp.error_code = NFAPI_P4_MSG_OK;
+  nfapi_pnf_cell_search_resp(config, &resp);
+
+  nfapi_cell_search_indication_t ind;
+  memset(&ind, 0, sizeof(ind));
+  ind.header.message_id = NFAPI_CELL_SEARCH_INDICATION;
+  ind.header.phy_id = req->header.phy_id;
+  ind.error_code = NFAPI_P4_MSG_OK;
+
+  switch(req->rat_type)
+  {
+    case NFAPI_RAT_TYPE_LTE:
+      {
+        ind.lte_cell_search_indication.tl.tag = NFAPI_LTE_CELL_SEARCH_INDICATION_TAG;
+        ind.lte_cell_search_indication.number_of_lte_cells_found = 1;
+        ind.lte_cell_search_indication.lte_found_cells[0].pci = 123;
+        ind.lte_cell_search_indication.lte_found_cells[0].rsrp = 123;
+        ind.lte_cell_search_indication.lte_found_cells[0].rsrq = 123;
+        ind.lte_cell_search_indication.lte_found_cells[0].frequency_offset = 123;
+      }
+      break;
+    case NFAPI_RAT_TYPE_UTRAN:
+      {
+        ind.utran_cell_search_indication.tl.tag = NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG;
+        ind.utran_cell_search_indication.number_of_utran_cells_found = 1;
+        ind.utran_cell_search_indication.utran_found_cells[0].psc = 89;
+        ind.utran_cell_search_indication.utran_found_cells[0].rscp = 89;
+        ind.utran_cell_search_indication.utran_found_cells[0].ecno = 89;
+        ind.utran_cell_search_indication.utran_found_cells[0].frequency_offset = -89;
+
+      }
+      break;
+    case NFAPI_RAT_TYPE_GERAN:
+      {
+        ind.geran_cell_search_indication.tl.tag = NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG;
+        ind.geran_cell_search_indication.number_of_gsm_cells_found = 1;
+        ind.geran_cell_search_indication.gsm_found_cells[0].bsic = 23;
+        ind.geran_cell_search_indication.gsm_found_cells[0].rxlev = 23;
+        ind.geran_cell_search_indication.gsm_found_cells[0].rxqual = 23;
+        ind.geran_cell_search_indication.gsm_found_cells[0].frequency_offset = -23;
+        ind.geran_cell_search_indication.gsm_found_cells[0].sfn_offset = 230;
+
+      }
+      break;
+  }
+
+  ind.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG;
+  ind.pnf_cell_search_state.length = 3;
+
+  nfapi_pnf_cell_search_ind(config, &ind);	
+
+  return 0;
+}
+
+int broadcast_detect_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_broadcast_detect_request_t* req)
+{
+  nfapi_broadcast_detect_response_t resp;
+  memset(&resp, 0, sizeof(resp));
+  resp.header.message_id = NFAPI_BROADCAST_DETECT_RESPONSE;
+  resp.header.phy_id = req->header.phy_id;
+  resp.error_code = NFAPI_P4_MSG_OK;
+  nfapi_pnf_broadcast_detect_resp(config, &resp);
+
+  nfapi_broadcast_detect_indication_t ind;
+  memset(&ind, 0, sizeof(ind));
+  ind.header.message_id = NFAPI_BROADCAST_DETECT_INDICATION;
+  ind.header.phy_id = req->header.phy_id;
+  ind.error_code = NFAPI_P4_MSG_OK;
+
+  switch(req->rat_type)
+  {
+    case NFAPI_RAT_TYPE_LTE:
+      {
+        ind.lte_broadcast_detect_indication.tl.tag = NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG;
+        ind.lte_broadcast_detect_indication.number_of_tx_antenna = 1;
+        ind.lte_broadcast_detect_indication.mib_length = 4;
+        //ind.lte_broadcast_detect_indication.mib...
+        ind.lte_broadcast_detect_indication.sfn_offset = 77;
+
+      }
+      break;
+    case NFAPI_RAT_TYPE_UTRAN:
+      {
+        ind.utran_broadcast_detect_indication.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG;
+        ind.utran_broadcast_detect_indication.mib_length = 4;
+        //ind.utran_broadcast_detect_indication.mib...
+        // ind.utran_broadcast_detect_indication.sfn_offset; DJP - nonsense line
+
+      }
+      break;
+  }
+
+  ind.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG;
+  ind.pnf_cell_broadcast_state.length = 3;
+
+  nfapi_pnf_broadcast_detect_ind(config, &ind);	
+
+  return 0;
+}
+
+int system_information_schedule_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_schedule_request_t* req)
+{
+  nfapi_system_information_schedule_response_t resp;
+  memset(&resp, 0, sizeof(resp));
+  resp.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE;
+  resp.header.phy_id = req->header.phy_id;
+  resp.error_code = NFAPI_P4_MSG_OK;
+  nfapi_pnf_system_information_schedule_resp(config, &resp);
+
+  nfapi_system_information_schedule_indication_t ind;
+  memset(&ind, 0, sizeof(ind));
+  ind.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION;
+  ind.header.phy_id = req->header.phy_id;
+  ind.error_code = NFAPI_P4_MSG_OK;
+
+  ind.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG;
+  ind.lte_system_information_indication.sib_type = 3;
+  ind.lte_system_information_indication.sib_length = 5;
+  //ind.lte_system_information_indication.sib...
+
+  nfapi_pnf_system_information_schedule_ind(config, &ind);		
+
+  return 0;
+}
+
+int system_information_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_request_t* req)
+{
+  nfapi_system_information_response_t resp;
+  memset(&resp, 0, sizeof(resp));
+  resp.header.message_id = NFAPI_SYSTEM_INFORMATION_RESPONSE;
+  resp.header.phy_id = req->header.phy_id;
+  resp.error_code = NFAPI_P4_MSG_OK;
+  nfapi_pnf_system_information_resp(config, &resp);
+
+  nfapi_system_information_indication_t ind;
+  memset(&ind, 0, sizeof(ind));
+  ind.header.message_id = NFAPI_SYSTEM_INFORMATION_INDICATION;
+  ind.header.phy_id = req->header.phy_id;
+  ind.error_code = NFAPI_P4_MSG_OK;
+
+  switch(req->rat_type)
+  {
+    case NFAPI_RAT_TYPE_LTE:
+      {
+        ind.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG;
+        ind.lte_system_information_indication.sib_type = 1;
+        ind.lte_system_information_indication.sib_length = 3;
+        //ind.lte_system_information_indication.sib...
+      }
+      break;
+    case NFAPI_RAT_TYPE_UTRAN:
+      {
+        ind.utran_system_information_indication.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG;
+        ind.utran_system_information_indication.sib_length = 3;
+        //ind.utran_system_information_indication.sib...
+
+      }
+      break;
+    case NFAPI_RAT_TYPE_GERAN:
+      {
+        ind.geran_system_information_indication.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG;
+        ind.geran_system_information_indication.si_length = 3;
+        //ind.geran_system_information_indication.si...
+
+      }
+      break;
+  }
+
+  nfapi_pnf_system_information_ind(config, &ind);		
+
+  return 0;
+}
+
+int nmm_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nmm_stop_request_t* req)
+{
+  nfapi_nmm_stop_response_t resp;
+  memset(&resp, 0, sizeof(resp));
+  resp.header.message_id = NFAPI_NMM_STOP_RESPONSE;
+  resp.header.phy_id = req->header.phy_id;
+  resp.error_code = NFAPI_P4_MSG_OK;
+  nfapi_pnf_nmm_stop_resp(config, &resp);
+  return 0;
+}
+
+int vendor_ext(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg)
+{
+  NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 %s %p\n", __FUNCTION__, msg);
+
+  switch(msg->message_id)
+  {
+    case P5_VENDOR_EXT_REQ:
+      {
+        vendor_ext_p5_req* req = (vendor_ext_p5_req*)msg;
+        NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 Vendor Ext Req (%d %d)\n", req->dummy1, req->dummy2);
+        // send back the P5_VENDOR_EXT_RSP
+        vendor_ext_p5_rsp rsp;
+        memset(&rsp, 0, sizeof(rsp));
+        rsp.header.message_id = P5_VENDOR_EXT_RSP;
+        rsp.error_code = NFAPI_MSG_OK;
+        nfapi_pnf_vendor_extension(config, &rsp.header, sizeof(vendor_ext_p5_rsp));
+      }
+      break;
+  }
+
+  return 0;
+}
+
+nfapi_p4_p5_message_header_t* pnf_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t* msg_size)
+{
+  if(message_id == P5_VENDOR_EXT_REQ)
+  {
+    (*msg_size) = sizeof(vendor_ext_p5_req);
+    return (nfapi_p4_p5_message_header_t*)malloc(sizeof(vendor_ext_p5_req));
+  }
+
+  return 0;
+}
+
+void pnf_sim_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t* header)
+{
+  free(header);
+}
+
+int pnf_sim_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if(header->message_id == P5_VENDOR_EXT_RSP)
+  {
+    vendor_ext_p5_rsp* rsp = (vendor_ext_p5_rsp*)(header);
+    return (!push16(rsp->error_code, ppWritePackedMsg, end));
+  }
+  return 0;
+}
+
+int pnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t* codec)
+{
+  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if(header->message_id == P5_VENDOR_EXT_REQ)
+  {
+    vendor_ext_p5_req* req = (vendor_ext_p5_req*)(header);
+    return (!(pull16(ppReadPackedMessage, &req->dummy1, end) &&
+          pull16(ppReadPackedMessage, &req->dummy2, end)));
+
+    //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s (%d %d)\n", __FUNCTION__, req->dummy1, req->dummy2);
+  }
+  return 0;
+}
+
+/*------------------------------------------------------------------------------*/
+static pnf_info pnf;
+static pthread_t pnf_start_pthread;
+
+void* pnf_start_thread(void* ptr)
+{
+  NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] IN PNF NFAPI start thread %s\n", __FUNCTION__);
+
+  nfapi_pnf_config_t *config = (nfapi_pnf_config_t*)ptr;
+
+  nfapi_pnf_start(config);
+
+  return (void*)0;
+}
+
+void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, int pnf_p7_port, int vnf_p7_port)
+{
+  char *xml_file = 0;
+
+  //DJP if(read_pnf_xml(pnf, argv[3]) < 0)
+  if(read_pnf_xml(&pnf, xml_file) < 0)
+  {
+    printf("Failed to read xml file>\n");
+    return ;
+  }
+
+  nfapi_pnf_config_t* config = nfapi_pnf_config_create();
+
+  config->vnf_ip_addr = vnf_ip_addr;
+  config->vnf_p5_port = vnf_p5_port;
+
+  pnf.phys[0].udp.enabled = 1;
+  pnf.phys[0].udp.rx_port = pnf_p7_port;
+  pnf.phys[0].udp.tx_port = vnf_p7_port;
+  strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr);
+
+  printf("%s() VNF:%s:%d PNF_PHY[UDP:tx_addr:%s:%d rx:%d]\n", 
+      __FUNCTION__, 
+      config->vnf_ip_addr, config->vnf_p5_port, 
+      pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port,
+      pnf.phys[0].udp.rx_port);
+
+  config->pnf_param_req = &pnf_param_request;
+  config->pnf_config_req = &pnf_config_request;
+  config->pnf_start_req = &pnf_start_request;
+  config->pnf_stop_req = &pnf_stop_request;
+  config->param_req = &param_request;
+  config->config_req = &config_request;
+  config->start_req = &start_request;
+
+  config->measurement_req = &measurement_request;
+  config->rssi_req = &rssi_request;
+  config->cell_search_req = &cell_search_request;
+  config->broadcast_detect_req = &broadcast_detect_request;
+  config->system_information_schedule_req = &system_information_schedule_request;
+  config->system_information_req = &system_information_request;
+  config->nmm_stop_req = &nmm_stop_request;
+
+  config->vendor_ext = &vendor_ext;
+
+  config->trace = &pnf_sim_trace;
+
+  config->user_data = &pnf;
+
+  // To allow custom vendor extentions to be added to nfapi
+  config->codec_config.unpack_vendor_extension_tlv = &pnf_sim_unpack_vendor_extension_tlv;
+  config->codec_config.pack_vendor_extension_tlv = &pnf_sim_pack_vendor_extention_tlv;
+
+  config->allocate_p4_p5_vendor_ext = &pnf_sim_allocate_p4_p5_vendor_ext;
+  config->deallocate_p4_p5_vendor_ext = &pnf_sim_deallocate_p4_p5_vendor_ext;
+
+  config->codec_config.unpack_p4_p5_vendor_extension = &pnf_sim_unpack_p4_p5_vendor_extension;
+  config->codec_config.pack_p4_p5_vendor_extension = &pnf_sim_pack_p4_p5_vendor_extension;
+
+  NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating PNF NFAPI start thread %s\n", __FUNCTION__);
+  pthread_create(&pnf_start_pthread, NULL, &pnf_start_thread, config);
+}
+
+void oai_subframe_ind(uint16_t frame, uint16_t subframe)
+{
+  //TODO FIXME - HACK - DJP - using a global to bodge it in 
+
+  if (p7_config_g != NULL && sync_var==0)
+  {
+    uint16_t sfn = subframe>=9?frame+1:frame;
+    uint16_t sf = subframe>=9?0:subframe+1;
+    uint16_t sfn_sf = sfn<<4 | sf;
+
+    if ((frame % 100 == 0) && subframe==0)
+    {
+      struct timespec ts;
+
+      clock_gettime(CLOCK_MONOTONIC, &ts);
+
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (frame:%u subframe:%u) sfn_sf:%u sfn_sf(DEC):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, frame, subframe, sfn_sf, NFAPI_SFNSF2DEC(sfn_sf));
+    }
+
+    int subframe_ret = nfapi_pnf_p7_subframe_ind(p7_config_g, p7_config_g->phy_id, sfn_sf);
+
+    if (subframe_ret)
+    {
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s(frame:%u subframe:%u) sfn_sf:%u sfn_sf(DEC):%u - PROBLEM with pnf_p7_subframe_ind()\n", __FUNCTION__, frame, subframe, sfn_sf, NFAPI_SFNSF2DEC(sfn_sf));
+    }
+  }
+  else
+  {
+  }
+}
diff --git a/nfapi/nfapi_pnf.h b/nfapi/nfapi_pnf.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b97536f58bc8b3900e24b2cb26d951b916f5e1c
--- /dev/null
+++ b/nfapi/nfapi_pnf.h
@@ -0,0 +1,6 @@
+#if !defined(NFAPI_PNF_H__)
+#define NFAPI_PNF_H__
+
+void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, int pnf_p7_port, int vnf_p7_port);
+
+#endif
diff --git a/nfapi/nfapi_vnf.c b/nfapi/nfapi_vnf.c
new file mode 100644
index 0000000000000000000000000000000000000000..a4310819fc9284ce6ceb5829b5dcd3cba8946781
--- /dev/null
+++ b/nfapi/nfapi_vnf.c
@@ -0,0 +1,1595 @@
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "nfapi_interface.h"
+#include "nfapi_vnf_interface.h"
+#include "nfapi.h"
+#include "vendor_ext.h"
+
+#include "nfapi_vnf.h"
+
+
+#include "common/ran_context.h"
+//#include "openair1/PHY/vars.h"
+extern RAN_CONTEXT_t RC;
+
+typedef struct 
+{
+	//public:
+		uint8_t enabled;
+		uint32_t rx_port;
+		uint32_t tx_port;
+		//std::string tx_addr;
+		char tx_addr[80];
+} udp_data;
+
+//class phy_info
+//DJP
+typedef struct 
+{
+#if 0
+	public:
+
+		phy_info()
+			: first_subframe_ind(0), fapi(0),
+			  dl_ues_per_subframe(0), ul_ues_per_subframe(0), 
+			  timing_window(0), timing_info_mode(0), timing_info_period(0)
+		{
+			index = 0;
+			id = 0;
+
+			local_port = 0;
+			remote_addr = 0;
+			remote_port = 0;
+	
+			duplex_mode = 0;
+			dl_channel_bw_support = 0;
+			ul_channel_bw_support = 0;
+			num_dl_layers_supported = 0;
+			num_ul_layers_supported = 0;
+			release_supported = 0;
+			nmm_modes_supported = 0;
+		}
+#endif
+
+		uint16_t index;
+		uint16_t id;
+		//std::vector<uint8_t> rfs;
+		//std::vector<uint8_t> excluded_rfs;
+		uint8_t rfs[2];
+		uint8_t excluded_rfs[2];
+
+		udp_data udp;
+
+		//std::string local_addr;
+		char local_addr[80];
+		int local_port;
+
+		char* remote_addr;
+		int remote_port;
+
+		uint8_t duplex_mode;
+		uint16_t dl_channel_bw_support;
+		uint16_t ul_channel_bw_support;
+		uint8_t num_dl_layers_supported;
+		uint8_t num_ul_layers_supported;
+		uint16_t release_supported;
+		uint8_t nmm_modes_supported;
+
+		uint8_t dl_ues_per_subframe;
+		uint8_t ul_ues_per_subframe;
+
+		uint8_t first_subframe_ind;
+
+		// timing information recevied from the vnf
+		uint8_t timing_window;
+		uint8_t timing_info_mode;
+		uint8_t timing_info_period;
+
+    // DJP
+		//fapi_t* fapi;
+
+} phy_info;
+
+//class rf_info
+//DJP
+typedef struct 
+{
+	//public:
+		uint16_t index;
+		uint16_t band;
+		int16_t max_transmit_power;
+		int16_t min_transmit_power;
+		uint8_t num_antennas_supported;
+		uint32_t min_downlink_frequency;
+		uint32_t max_downlink_frequency;
+		uint32_t max_uplink_frequency;
+		uint32_t min_uplink_frequency;
+} rf_info;
+
+
+//class pnf_info
+//DJP
+typedef struct 
+{
+#if 0
+	public:
+
+		pnf_info() 
+		: release(13), wireshark_test_mode(0),
+		  max_total_power(0), oui(0)
+					
+		{
+			release = 0;
+	
+			sync_mode = 0;
+			location_mode = 0;
+			dl_config_timing = 0;
+			ul_config_timing = 0;
+			tx_timing = 0;
+			hi_dci0_timing = 0;
+	
+			max_phys = 0;
+			max_total_bw = 0;
+			max_total_dl_layers = 0;
+			max_total_ul_layers = 0;
+			shared_bands = 0;
+			shared_pa = 0;
+			
+		}
+#endif
+
+		int release;
+		//DJPstd::vector<phy_info> phys;
+		//std::vector<rf_info> rfs;
+		phy_info phys[2];
+		rf_info rfs[2];
+
+		uint8_t sync_mode;
+		uint8_t location_mode;
+		uint8_t location_coordinates[6];
+		uint32_t dl_config_timing;
+		uint32_t ul_config_timing;
+		uint32_t tx_timing;
+		uint32_t hi_dci0_timing;
+
+		uint16_t max_phys;
+		uint16_t max_total_bw;
+		uint16_t max_total_dl_layers;
+		uint16_t max_total_ul_layers;
+		uint8_t shared_bands;
+		uint8_t shared_pa;
+		int16_t max_total_power;
+		uint8_t oui;
+		
+		uint8_t wireshark_test_mode;
+
+} pnf_info;
+
+typedef struct mac mac_t;
+
+typedef struct mac
+{
+	void* user_data;
+
+	void (*dl_config_req)(mac_t* mac, nfapi_dl_config_request_t* req);
+	void (*ul_config_req)(mac_t* mac, nfapi_ul_config_request_t* req);
+	void (*hi_dci0_req)(mac_t* mac, nfapi_hi_dci0_request_t* req);
+	void (*tx_req)(mac_t* mac, nfapi_tx_request_t* req);
+} mac_t;
+
+//class vnf_p7_info
+typedef struct 
+{
+	//public:
+
+#if 0
+		vnf_p7_info()
+			: thread_started(false), 
+			  config(nfapi_vnf_p7_config_create(), 
+				     [] (nfapi_vnf_p7_config_t* f) { nfapi_vnf_p7_config_destory(f); }),
+			  mac(0)
+		{
+			local_port = 0;
+			
+			timing_window = 0;
+			periodic_timing_enabled = 0;
+			aperiodic_timing_enabled = 0;
+			periodic_timing_period = 0;
+			
+			//config = nfapi_vnf_p7_config_create();
+		}
+		
+		vnf_p7_info(const vnf_p7_info& other)  = default;
+		
+		vnf_p7_info(vnf_p7_info&& other) = default;
+		
+		vnf_p7_info& operator=(const vnf_p7_info&) = default;
+		
+		vnf_p7_info& operator=(vnf_p7_info&&) = default;
+		
+		
+		
+		virtual	~vnf_p7_info()
+		{
+			//NFAPI_TRACE(NFAPI_TRACE_INFO, "*** vnf_p7_info delete ***\n");
+			
+			//nfapi_vnf_p7_config_destory(config);
+			
+			// should we delete the mac?
+		}
+#endif
+		
+
+		int local_port;
+		//DJP std::string local_addr;
+		char local_addr[80];
+
+		unsigned timing_window;
+		unsigned periodic_timing_enabled;
+		unsigned aperiodic_timing_enabled;
+		unsigned periodic_timing_period;
+
+		// This is not really the right place if we have multiple PHY, 
+		// should be part of the phy struct
+		udp_data udp;
+
+		uint8_t thread_started;
+
+		nfapi_vnf_p7_config_t* config;
+		//std::shared_ptr<nfapi_vnf_p7_config_t> config;
+
+		mac_t* mac;
+
+} vnf_p7_info;
+
+//class vnf_info
+typedef struct
+{
+	//public:
+	
+		uint8_t wireshark_test_mode;
+
+		//std::map<uint16_t, pnf_info> pnfs;
+		pnf_info pnfs[2];
+
+		//std::vector<vnf_p7_info> p7_vnfs;
+		vnf_p7_info p7_vnfs[2];
+} vnf_info;
+
+int vnf_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec)
+{
+  //NFAPI_TRACE(NFAPI_TRACE_INFO, "vnf_pack_vendor_extension_tlv\n");
+  nfapi_tl_t* tlv = (nfapi_tl_t*)ve;
+  switch(tlv->tag)
+  {
+    case VENDOR_EXT_TLV_2_TAG:
+      {
+        //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_2\n");
+        vendor_ext_tlv_2* ve = (vendor_ext_tlv_2*)tlv;
+        if(!push32(ve->dummy, ppWritePackedMsg, end))
+          return 0;
+        return 1;
+      }
+      break;
+  }
+  return -1;
+}
+int vnf_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* codec)
+{
+  return -1;
+}
+
+void install_schedule_handlers(IF_Module_t *if_inst);
+extern int single_thread_flag;
+extern void init_eNB_afterRU();
+
+void oai_create_enb(void)
+{
+  static int bodge_counter = 0;
+  PHY_VARS_eNB *eNB;
+
+  if (RC.eNB && RC.eNB[0] && RC.eNB[0][0])
+  {
+    eNB = RC.eNB[0][0];
+    printf("[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d\n", eNB->Mod_id, eNB->CC_id);
+  }
+  else
+  {
+    printf("[VNF] DJP ***** RC.eNB[] and RC.eNB[%d][%d] RC.nb_CC[%d]=1 MALLOCING structure and zeroing *******\n", bodge_counter, bodge_counter, bodge_counter);
+
+    RC.eNB[bodge_counter] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**));
+    RC.eNB[bodge_counter][bodge_counter] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB));
+    memset((void*)RC.eNB[bodge_counter][bodge_counter],0,sizeof(PHY_VARS_eNB));
+
+    eNB = RC.eNB[bodge_counter][bodge_counter];
+
+    eNB->Mod_id  = bodge_counter;
+    eNB->CC_id   = bodge_counter;
+    eNB->if_inst = IF_Module_init(bodge_counter);
+    eNB->abstraction_flag   = 0;
+    eNB->single_thread_flag = 0;//single_thread_flag;
+    eNB->td                   = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data;
+    eNB->te                   = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding;
+
+    RC.nb_CC[bodge_counter] = 1;
+  }
+
+  //init_eNB_proc(bodge_counter);
+
+  // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY
+  // that will result in eNB->configured being set to TRUE.
+  // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values
+  if (RC.eNB[0][0]->if_inst->PHY_config_req==0 || RC.eNB[0][0]->if_inst->schedule_response==0)
+  {
+    install_schedule_handlers(RC.eNB[0][0]->if_inst);
+  }
+
+  do {
+    printf("%s() Waiting for eNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__);
+    usleep(50000);
+  } while(eNB->configured != 1);
+}
+
+
+void oai_enb_init(void)
+{
+  PHY_VARS_eNB *eNB = RC.eNB[0][0];
+
+  init_eNB_afterRU();
+
+  //phy_init_lte_eNB(eNB,0,0);
+  
+  printf("%s() take this out - done properly now - eNB->frame_parms.nb_antennas_rx = 1;\n", __FUNCTION__);
+  eNB->frame_parms.nb_antennas_rx = 1; // DJP
+
+  //printf("%s() Mark eNB as configured\n", __FUNCTION__);
+  //eNB->configured = 1;
+}
+
+int pnf_connection_indication_cb(nfapi_vnf_config_t* config, int p5_idx)
+{
+  printf("[VNF] pnf connection indication idx:%d\n", p5_idx);
+
+  //pnf_info pnf;
+  //vnf_info* vnf = (vnf_info*)(config->user_data);
+  //vnf->pnfs.insert(std::pair<uint16_t, pnf_info>(p5_idx, pnf));
+
+  oai_create_enb();
+
+  nfapi_pnf_param_request_t req;
+  memset(&req, 0, sizeof(req));
+  req.header.message_id = NFAPI_PNF_PARAM_REQUEST;
+  nfapi_vnf_pnf_param_req(config, p5_idx, &req);
+  return 0;
+}
+
+int pnf_disconnection_indication_cb(nfapi_vnf_config_t* config, int p5_idx)
+{
+  printf("[VNF] pnf disconnection indication idx:%d\n", p5_idx);
+
+  vnf_info* vnf = (vnf_info*)(config->user_data);
+#if 0
+  auto find_result = vnf->pnfs.find(p5_idx);
+
+  if(find_result != vnf->pnfs.end())
+  {
+    pnf_info& pnf = find_result->second;
+
+    for(phy_info& phy : pnf.phys)
+    {
+      vnf_p7_info& p7_vnf = vnf->p7_vnfs[0];
+      nfapi_vnf_p7_del_pnf((p7_vnf.config.get()), phy.id);
+    }
+  }
+#else
+  pnf_info *pnf = vnf->pnfs;
+  phy_info *phy = pnf->phys;
+
+  vnf_p7_info* p7_vnf = vnf->p7_vnfs;
+  // DJP nfapi_vnf_p7_del_pnf((p7_vnf->config.get()), phy->id);
+  nfapi_vnf_p7_del_pnf((p7_vnf->config), phy->id);
+#endif
+
+  return 0;
+}
+
+int pnf_param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_response_t* resp)
+{
+  printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code);
+
+  vnf_info* vnf = (vnf_info*)(config->user_data);
+
+#if 0
+  auto find_result = vnf->pnfs.find(p5_idx);
+  if(find_result != vnf->pnfs.end())
+  {
+    pnf_info& pnf = find_result->second;
+#else
+    {
+      pnf_info *pnf = vnf->pnfs;
+#endif
+
+      for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i)
+      {
+        phy_info phy;
+        phy.index = resp->pnf_phy.phy[i].phy_config_index;
+
+        printf("[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index);
+
+        nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id));
+
+        for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j)
+        {
+          printf("[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index);
+          phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index;
+        }
+
+        pnf->phys[0] = phy;
+      }
+
+      for(int i = 0; i < resp->pnf_rf.number_of_rfs; ++i)
+      {
+        rf_info rf;
+        rf.index = resp->pnf_rf.rf[i].rf_config_index;
+
+        printf("[VNF] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index);
+
+        pnf->rfs[0] = rf;
+    }
+
+    nfapi_pnf_config_request_t req;
+    memset(&req, 0, sizeof(req));
+    req.header.message_id = NFAPI_PNF_CONFIG_REQUEST;
+
+    req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG;
+    req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size();
+    printf("DJP:Hard coded num phy rf to 2\n");
+
+    // DJP for(unsigned i = 0; i < pnf.phys.size(); ++i)
+    for(unsigned i = 0; i < 2; ++i)
+    {
+      req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id;
+      req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index;
+      req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0];
+    }
+
+    nfapi_vnf_pnf_config_req(config, p5_idx, &req);
+  }
+  return 0;
+}
+
+int pnf_config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* resp)
+{
+  printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%u message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length);
+
+  if(1)
+  {
+    //vnf_info* vnf = (vnf_info*)(config->user_data);
+#if 0
+    auto find_result = vnf->pnfs.find(p5_idx);
+    if(find_result != vnf->pnfs.end())
+    {
+      //pnf_info& pnf = find_result->second;
+    }
+#else
+      nfapi_pnf_start_request_t req;
+      memset(&req, 0, sizeof(req));
+      req.header.phy_id = resp->header.phy_id;
+      req.header.message_id = NFAPI_PNF_START_REQUEST;
+      nfapi_vnf_pnf_start_req(config, p5_idx, &req);
+#endif
+  }
+  else
+  {
+    // Rather than send the pnf_start_request we will demonstrate
+    // sending a vendor extention message. The start request will be
+    // send when the vendor extension response is received 
+
+    //vnf_info* vnf = (vnf_info*)(config->user_data);
+    vendor_ext_p5_req req;
+    memset(&req, 0, sizeof(req));
+    req.header.message_id = P5_VENDOR_EXT_REQ;
+    req.dummy1 = 45;
+    req.dummy2 = 1977;
+    nfapi_vnf_vendor_extension(config, p5_idx, &req.header);
+  }
+  return 0;
+}
+
+int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf)
+{
+  eNB_proc_t *proc=&eNB->proc;
+
+  eNB_rxtx_proc_t *proc_rxtx=&proc->proc_rxtx[sf&1];
+
+  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
+
+  //int i;
+  struct timespec wait;
+
+  wait.tv_sec=0;
+  wait.tv_nsec=5000000L;
+
+#if 0
+  /* accept some delay in processing - up to 5ms */
+  for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) {
+    LOG_W( PHY,"[eNB] sfn/sf:%d:%d proc_rxtx[%d]:TXsfn:%d/%d eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", sfn, sf, sf&1, proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx);
+    usleep(500);
+  }
+  if (proc_rxtx->instance_cnt_rxtx == 0) {
+    exit_fun( "TX thread busy" );
+    return(-1);
+  }
+#endif
+
+  // wake up TX for subframe n+4
+  // lock the TX mutex and make sure the thread is ready
+  if (pthread_mutex_timedlock(&proc_rxtx->mutex_rxtx,&wait) != 0) {
+    LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", proc_rxtx->subframe_rx&1,proc_rxtx->instance_cnt_rxtx );
+    exit_fun( "error locking mutex_rxtx" );
+    return(-1);
+  }
+
+  {
+    static uint16_t old_sf = 0;
+    static uint16_t old_sfn = 0;
+
+    proc->subframe_rx = old_sf;
+    proc->frame_rx = old_sfn;
+
+    // Try to be 1 frame back
+    old_sf = sf;
+    old_sfn = sfn;
+
+    if (old_sf == 0 && old_sfn % 100==0) LOG_W( PHY,"[eNB] sfn/sf:%d:%d old_sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d]\n", sfn, sf, old_sfn, old_sf, proc->frame_rx, proc->subframe_rx);
+  }
+
+  ++proc_rxtx->instance_cnt_rxtx;
+
+  //LOG_E( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] proc_rxtx->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, proc_rxtx->instance_cnt_rxtx);
+
+  // We have just received and processed the common part of a subframe, say n.
+  // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
+  // transmitted timestamp of the next TX slot (first).
+  // The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
+  // we want to generate subframe (n+4), so TS_tx = TX_rx+4*samples_per_tti,
+  // and proc->subframe_tx = proc->subframe_rx+4
+  proc_rxtx->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti);
+  proc_rxtx->frame_rx     = proc->frame_rx;
+  proc_rxtx->subframe_rx  = proc->subframe_rx;
+  proc_rxtx->frame_tx     = (proc_rxtx->subframe_rx > 5) ? (proc_rxtx->frame_rx+1)&1023 : proc_rxtx->frame_rx;
+  proc_rxtx->subframe_tx  = (proc_rxtx->subframe_rx + 4)%10;
+
+  // the thread can now be woken up
+  if (pthread_cond_signal(&proc_rxtx->cond_rxtx) != 0) {
+    LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB RXn-TXnp4 thread\n");
+    exit_fun( "ERROR pthread_cond_signal" );
+    return(-1);
+  }
+
+  pthread_mutex_unlock( &proc_rxtx->mutex_rxtx );
+
+  return(0);
+}
+
+extern pthread_cond_t nfapi_sync_cond;
+extern pthread_mutex_t nfapi_sync_mutex;
+extern int nfapi_sync_var;
+
+int phy_sync_indication(struct nfapi_vnf_p7_config* config, uint8_t sync)
+{
+  //vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+
+  printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST");
+  
+  if (1)
+  {
+    if (sync==1 && nfapi_sync_var!=0)
+    {
+
+      printf("[VNF] Signal to OAI main code that it can go\n");
+      pthread_mutex_lock(&nfapi_sync_mutex);
+      nfapi_sync_var=0;
+      pthread_cond_broadcast(&nfapi_sync_cond);
+      pthread_mutex_unlock(&nfapi_sync_mutex);
+    }
+  }
+
+  //if (RC.eNB && RC.eNB[0][0]->configured)
+  //wake_eNB_rxtx(RC.eNB[0][0], 0, 0);
+
+  return(0);
+}
+
+int phy_subframe_indication(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn_sf)
+{
+  static uint8_t first_time = 1;
+  if (first_time)
+  {
+    printf("[VNF] subframe indication %d\n", sfn_sf);
+    first_time = 0;
+  }
+
+  // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+  //mac_subframe_ind(p7_vnf->mac, phy_id, sfn_sf);
+
+#if 1
+  if (RC.eNB && RC.eNB[0][0]->configured)
+  {
+    uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf);
+    uint16_t sf = NFAPI_SFNSF2SF(sfn_sf);
+
+    //LOG_E(PHY,"[VNF] subframe indication sfn_sf:%d sfn:%d sf:%d\n", sfn_sf, sfn, sf);
+
+    wake_eNB_rxtx(RC.eNB[0][0], sfn, sf);
+  }
+  else
+  {
+    printf("[VNF] %s() RC.eNB:%p\n", __FUNCTION__, RC.eNB);
+    if (RC.eNB) printf("RC.eNB[0][0]->configured:%d\n", RC.eNB[0][0]->configured);
+  }
+#endif
+
+  return 0;
+}
+
+int phy_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_harq_indication_t* ind)
+{
+	// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+	//mac_harq_ind(p7_vnf->mac, ind);
+	return 1;
+}
+
+int phy_crc_indication(struct nfapi_vnf_p7_config* config, nfapi_crc_indication_t* ind)
+{
+	// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+	//mac_crc_ind(p7_vnf->mac, ind);
+	return 1;
+}
+int phy_rx_indication(struct nfapi_vnf_p7_config* config, nfapi_rx_indication_t* ind)
+{
+	// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+	//mac_rx_ind(p7_vnf->mac, ind);
+	return 1;
+}
+int phy_rach_indication(struct nfapi_vnf_p7_config* config, nfapi_rach_indication_t* ind)
+{
+	// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+	//mac_rach_ind(p7_vnf->mac, ind);
+	return 1;
+}
+int phy_srs_indication(struct nfapi_vnf_p7_config* config, nfapi_srs_indication_t* ind)
+{
+	// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+	//mac_srs_ind(p7_vnf->mac, ind);
+	return 1;
+}
+int phy_sr_indication(struct nfapi_vnf_p7_config* config, nfapi_sr_indication_t* ind)
+{
+	// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+	//mac_sr_ind(p7_vnf->mac, ind);
+	return 1;
+}
+int phy_cqi_indication(struct nfapi_vnf_p7_config* config, nfapi_cqi_indication_t* ind)
+{
+	// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+	//mac_cqi_ind(p7_vnf->mac, ind);
+	return 1;
+}
+int phy_lbt_dl_indication(struct nfapi_vnf_p7_config* config, nfapi_lbt_dl_indication_t* ind)
+{
+	// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+	//mac_lbt_dl_ind(p7_vnf->mac, ind);
+	return 1;
+}
+int phy_nb_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_nb_harq_indication_t* ind)
+{
+	// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+	//mac_nb_harq_ind(p7_vnf->mac, ind);
+	return 1;
+}
+int phy_nrach_indication(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind)
+{
+	// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
+	//mac_nrach_ind(p7_vnf->mac, ind);
+	return 1;
+}
+
+void* vnf_allocate(size_t size)
+{
+	//return (void*)memory_pool::allocate(size);
+	return (void*)malloc(size);
+}
+
+void vnf_deallocate(void* ptr)
+{
+	//memory_pool::deallocate((uint8_t*)ptr);
+	free(ptr);
+}
+
+void vnf_trace(nfapi_trace_level_t level, const char* message, ...)
+{
+	va_list args;
+	va_start(args, message);
+	vprintf(message, args);
+	va_end(args);
+}
+
+int phy_vendor_ext(struct nfapi_vnf_p7_config* config, nfapi_p7_message_header_t* msg)
+{
+	if(msg->message_id == P7_VENDOR_EXT_IND)
+	{
+		//vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg;
+		//printf("[VNF] vendor_ext (error_code:%d)\n", ind->error_code);
+	}
+	else
+	{
+		printf("[VNF] unknown %d\n", msg->message_id);
+	}
+	return 0;
+}
+
+nfapi_p7_message_header_t* phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t* msg_size)
+{
+	if(message_id == P7_VENDOR_EXT_IND)
+	{
+		*msg_size = sizeof(vendor_ext_p7_ind);
+		return (nfapi_p7_message_header_t*)malloc(sizeof(vendor_ext_p7_ind));
+	}
+	return 0;
+}
+
+void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t* header)
+{
+	free(header);
+}
+
+/// maybe these should be in the mac file...
+int phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p7_codec_config_t* codec)
+{
+	(void)tl;
+	(void)ppReadPackedMessage;
+	(void)ve;
+	return -1;
+}
+
+int phy_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* codec)
+{
+	//NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_pack_vendor_extension_tlv\n");
+
+	nfapi_tl_t* tlv = (nfapi_tl_t*)ve;
+	switch(tlv->tag)
+	{
+		case VENDOR_EXT_TLV_1_TAG:
+			{
+				//NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_1\n");
+				vendor_ext_tlv_1* ve = (vendor_ext_tlv_1*)tlv;
+				if(!push32(ve->dummy, ppWritePackedMsg, end))
+					return 0;
+				return 1;
+			}
+			break;
+		default:
+			return -1;
+			break;
+	}
+}
+
+int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+	//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+	if(header->message_id == P7_VENDOR_EXT_IND)
+	{
+		vendor_ext_p7_ind* req = (vendor_ext_p7_ind*)(header);
+		if(!pull16(ppReadPackedMessage, &req->error_code, end))
+			return 0;
+	}
+	return 1;
+}
+
+int phy_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+	//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+	if(header->message_id == P7_VENDOR_EXT_REQ)
+	{
+		//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+		vendor_ext_p7_req* req = (vendor_ext_p7_req*)(header);
+		if(!(push16(req->dummy1, ppWritePackedMsg, end) &&
+			 push16(req->dummy2, ppWritePackedMsg, end)))
+			return 0;
+	}
+	return 1;
+}
+
+int vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec)
+{
+	//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+	if(header->message_id == P5_VENDOR_EXT_REQ)
+	{
+		vendor_ext_p5_req* req = (vendor_ext_p5_req*)(header);
+		//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s %d %d\n", __FUNCTION__, req->dummy1, req->dummy2);
+		return (!(push16(req->dummy1, ppWritePackedMsg, end) &&
+				  push16(req->dummy2, ppWritePackedMsg, end)));
+	}
+	return 0;
+}
+
+static pthread_t vnf_start_pthread;
+static pthread_t vnf_p7_start_pthread;
+void* vnf_p7_start_thread(void *ptr)
+{
+  printf("%s()\n", __FUNCTION__);
+
+  nfapi_vnf_p7_config_t* config = (nfapi_vnf_p7_config_t*)ptr;
+
+  nfapi_vnf_p7_start(config);
+
+  return config;
+}
+
+void set_thread_priority(int priority);
+
+void* vnf_p7_thread_start(void* ptr)
+{
+	set_thread_priority(79);
+
+	vnf_p7_info* p7_vnf = (vnf_p7_info*)ptr;
+
+	p7_vnf->config->port = p7_vnf->local_port;
+	p7_vnf->config->sync_indication = &phy_sync_indication;
+	p7_vnf->config->subframe_indication = &phy_subframe_indication;
+	p7_vnf->config->harq_indication = &phy_harq_indication;
+	p7_vnf->config->crc_indication = &phy_crc_indication;
+	p7_vnf->config->rx_indication = &phy_rx_indication;
+	p7_vnf->config->rach_indication = &phy_rach_indication;
+	p7_vnf->config->srs_indication = &phy_srs_indication;
+	p7_vnf->config->sr_indication = &phy_sr_indication;
+	p7_vnf->config->cqi_indication = &phy_cqi_indication;
+	p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication;
+	p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication;
+	p7_vnf->config->nrach_indication = &phy_nrach_indication;
+	p7_vnf->config->malloc = &vnf_allocate;
+	p7_vnf->config->free = &vnf_deallocate;
+
+	p7_vnf->config->trace = &vnf_trace;
+
+	p7_vnf->config->vendor_ext = &phy_vendor_ext;
+	p7_vnf->config->user_data = p7_vnf;
+
+	p7_vnf->mac->user_data = p7_vnf;
+
+	p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension;
+	p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension;
+	p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv;
+	p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv;
+	p7_vnf->config->codec_config.allocate = &vnf_allocate;
+	p7_vnf->config->codec_config.deallocate = &vnf_deallocate;
+
+	p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext;
+	p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext;
+
+        {
+          NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
+          pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config);
+        }
+	return 0;
+}
+
+int pnf_start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* resp)
+{
+  vnf_info* vnf = (vnf_info*)(config->user_data);
+  vnf_p7_info *p7_vnf = vnf->p7_vnfs;
+
+  printf("[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started);
+
+  if(p7_vnf->thread_started == 0)
+  {
+    pthread_t vnf_p7_thread;
+    pthread_create(&vnf_p7_thread, NULL, &vnf_p7_thread_start, p7_vnf);
+    p7_vnf->thread_started = 1;
+  }
+  else
+  {
+    // P7 thread already running. 
+  }
+
+  // start all the phys in the pnf.
+
+#if 0
+  auto find_result = vnf->pnfs.find(p5_idx);
+  if(find_result != vnf->pnfs.end())
+  {
+    pnf_info& pnf = find_result->second;
+
+    for(unsigned i = 0; i < pnf.phys.size(); ++i)
+    {
+      pnf_info& pnf = find_result->second;
+    }
+  }
+#else
+  {
+    pnf_info *pnf = vnf->pnfs;
+    nfapi_param_request_t req;
+
+    printf("[VNF] Sending NFAPI_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id);
+
+    memset(&req, 0, sizeof(req));
+    req.header.message_id = NFAPI_PARAM_REQUEST;
+    req.header.phy_id = pnf->phys[0].id;
+
+    nfapi_vnf_param_req(config, p5_idx, &req);
+  }
+#endif
+
+  return 0;
+}
+
+extern uint32_t to_earfcn(int eutra_bandP,uint32_t dl_CarrierFreq,uint32_t bw);
+
+int param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t* resp)
+{
+  printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
+
+  vnf_info* vnf = (vnf_info*)(config->user_data);
+
+#if 0
+  auto find_result = vnf->pnfs.find(p5_idx);
+  if(find_result != vnf->pnfs.end())
+  {
+    pnf_info& pnf = find_result->second;
+
+    auto found = std::find_if(pnf.phys.begin(), pnf.phys.end(), [&](phy_info& item)
+        { return item.id == resp->header.phy_id; });
+
+    if(found != pnf.phys.end())
+    {
+      phy_info& phy = (*found);
+#else
+  pnf_info *pnf = vnf->pnfs;
+  phy_info *phy = pnf->phys;
+  {
+    {
+#endif
+
+      phy->remote_port = resp->nfapi_config.p7_pnf_port.value;
+
+      struct sockaddr_in pnf_p7_sockaddr;
+      memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4);
+
+      phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr);
+
+      // for now just 1
+      vnf_p7_info *p7_vnf = vnf->p7_vnfs;
+
+      printf("[VNF] %d.%d pnf p7 %s:%d timing %d %d %d %d\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, p7_vnf->periodic_timing_period);
+
+      nfapi_config_request_t *req = &RC.mac[0]->config[0];
+
+      //memset(&req, 0, sizeof(req));
+      req->header.message_id = NFAPI_CONFIG_REQUEST;
+      req->header.phy_id = phy->id;
+
+      printf("[VNF] Send NFAPI_CONFIG_REQUEST\n");
+
+      req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NFAPI_P7_VNF_PORT_TAG;
+      req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port;
+      req->num_tlv++;
+
+printf("[VNF] DJP local_port:%d\n", p7_vnf->local_port);
+
+      req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG;
+      struct sockaddr_in vnf_p7_sockaddr;
+      vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr);
+      memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4);
+      req->num_tlv++;
+printf("[VNF] DJP local_addr:%s\n", p7_vnf->local_addr);
+
+      req->nfapi_config.timing_window.tl.tag = NFAPI_NFAPI_TIMING_WINDOW_TAG;
+      req->nfapi_config.timing_window.value = p7_vnf->timing_window;
+      req->num_tlv++;
+
+      if(p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled)
+      {
+        req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NFAPI_TIMING_INFO_MODE_TAG;
+        req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled);
+        req->num_tlv++;
+
+        if(p7_vnf->periodic_timing_enabled)
+        {
+          req->nfapi_config.timing_info_period.tl.tag = NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG;
+          req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period;
+          req->num_tlv++;
+        }
+      }
+
+#if 0
+      req->nfapi_config.earfcn.tl.tag = NFAPI_NFAPI_EARFCN_TAG;
+      req->nfapi_config.earfcn.value = phy->earfcn;
+      req->num_tlv++;
+#endif
+
+      //req->rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG;
+      //req->rf_config.dl_channel_bandwidth.value = RC.eNB[0][0]->frame_parms.N_RB_DL;
+      //req->num_tlv++;
+
+      //req->rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG;
+      //req->rf_config.ul_channel_bandwidth.value = RC.eNB[0][0]->frame_parms.N_RB_UL;
+      //req->num_tlv++;
+
+      //req->nfapi_config.rf_bands.tl.tag = NFAPI_NFAPI_RF_BANDS_TAG;
+      //req->nfapi_config.rf_bands.number_rf_bands = 1;
+      //req->nfapi_config.rf_bands.rf_band[0] = RC.eNB[0][0]->frame_parms.eutra_band;
+      //req->num_tlv++;
+
+      //req->nfapi_config.earfcn.tl.tag = NFAPI_NFAPI_EARFCN_TAG;
+      //req->nfapi_config.earfcn.value = to_earfcn(RC.eNB[0][0]->frame_parms.eutra_band, RC.eNB[0][0]->frame_parms.dl_CarrierFreq, RC.eNB[0][0]->frame_parms.N_RB_DL);
+      //req->num_tlv++;
+
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() EARFCN:%u BAND:%u dlCarrierFreq:%u N_RB_DL:%u (NFAPI:%d)\n", 
+          __FUNCTION__, req->nfapi_config.earfcn.value, RC.eNB[0][0]->frame_parms.eutra_band, RC.eNB[0][0]->frame_parms.dl_CarrierFreq, RC.eNB[0][0]->frame_parms.N_RB_DL, req->rf_config.ul_channel_bandwidth.value);
+
+
+
+    //RC.eNB[0][0]->frame_parms.ul_CarrierFreq = req->nfapi_config.earfcn.value;
+
+      //req->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG;
+      //req->subframe_config.duplex_mode.value = RC.eNB[0][0]->frame_parms.frame_type;
+      //req->num_tlv++;
+
+      //req->subframe_config.dl_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG;
+      //req->subframe_config.dl_cyclic_prefix_type.value = RC.eNB[0][0]->frame_parms.Ncp;
+      //req->num_tlv++;
+
+      //req->subframe_config.ul_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG;
+      //req->subframe_config.ul_cyclic_prefix_type.value = RC.eNB[0][0]->frame_parms.Ncp_UL;
+      //req->num_tlv++;
+
+      //RC.eNB[0][0]->frame_parms.num_MBSFN_config = 0; // DJP - hard code alert
+
+      //req->sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG;
+      //req->sch_config.physical_cell_id.value = RC.eNB[0][0]->frame_parms.Nid_cell;
+      //req->num_tlv++;
+
+      //req->rf_config.tx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG;
+      //req->rf_config.tx_antenna_ports.value = RC.eNB[0][0]->frame_parms.nb_antennas_tx;
+      //req->num_tlv++;
+      //RC.eNB[0][0]->frame_parms.nb_antenna_ports_eNB = 1;
+
+      //req->rf_config.rx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG;
+      //req->rf_config.rx_antenna_ports.value = RC.eNB[0][0]->frame_parms.nb_antennas_rx;
+
+      //RC.eNB[0][0]->frame_parms.nushift = 0;
+
+      //req->phich_config.phich_resource.tl.tag = NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG;
+      //req->phich_config.phich_resource.value = RC.eNB[0][0]->frame_parms.phich_config_common.phich_resource;
+      //req->num_tlv++;
+
+      //req->phich_config.phich_duration.tl.tag = NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG;
+      //req->phich_config.phich_duration.value = RC.eNB[0][0]->frame_parms.phich_config_common.phich_duration;
+      //req->num_tlv++;
+
+      // DJP - not supported in OAI
+      //req->phich_config.phich_power_offset.tl.tag = NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG;
+      //req->phich_config.phich_power_offset.value = RC.eNB[0][0]->frame_parms.phich_config_common.
+      //req->num_tlv++;
+
+      // UL RS Config
+      //req->uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG;
+      //req->uplink_reference_signal_config.cyclic_shift_1_for_drms.value = RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift;
+      //req->num_tlv++;
+
+      //req->uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG;
+      //req->uplink_reference_signal_config.uplink_rs_hopping.value = RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled;
+      //req->num_tlv++;
+
+      //req->uplink_reference_signal_config.group_assignment.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG;
+      //req->uplink_reference_signal_config.group_assignment.value = RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH;
+      //req->num_tlv++;
+
+      //if (req->pusch_config.hopping_mode.tl.tag == NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG) { }  // DJP - not being handled?
+
+      //RC.eNB[0][0]->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; // DJP - not being handled
+
+      //req->prach_config.configuration_index.tl.tag = NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG;
+      //req->prach_config.configuration_index.value = RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
+      //req->num_tlv++;
+
+      //req->prach_config.root_sequence_index.tl.tag = NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG;
+      //req->prach_config.root_sequence_index.value = RC.eNB[0][0]->frame_parms.prach_config_common.rootSequenceIndex;
+      //req->num_tlv++;
+
+      //req->prach_config.zero_correlation_zone_configuration.tl.tag = NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG;
+      //req->prach_config.zero_correlation_zone_configuration.value = RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
+      //req->num_tlv++;
+
+      //req->prach_config.high_speed_flag.tl.tag = NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG;
+      //req->prach_config.high_speed_flag.value = RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag;
+      //req->num_tlv++;
+
+      //req->prach_config.frequency_offset.tl.tag = NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG;
+      //req->prach_config.frequency_offset.value = RC.eNB[0][0]->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
+      //req->num_tlv++;
+
+      vendor_ext_tlv_2 ve2;
+      memset(&ve2, 0, sizeof(ve2));
+      ve2.tl.tag = VENDOR_EXT_TLV_2_TAG;
+      ve2.dummy = 2016;
+      req->vendor_extension = &ve2.tl;
+
+      nfapi_vnf_config_req(config, p5_idx, req);
+      printf("[VNF] Sent NFAPI_CONFIG_REQ num_tlv:%u\n",req->num_tlv);
+    }
+#if 0
+    else
+    {
+      printf("[VNF] param response failed to find pnf %d phy %d\n", p5_idx, resp->header.phy_id);
+    }
+#endif
+  }
+#if 0
+  else
+  {
+    printf("[VNF] param response failed to find pnf %d\n", p5_idx);
+  }
+#endif
+
+  return 0;
+}
+
+int config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* resp)
+{
+  nfapi_start_request_t req;
+
+  printf("[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
+
+  printf("[VNF] Calling oai_enb_init()\n");
+  oai_enb_init();
+
+  memset(&req, 0, sizeof(req));
+  req.header.message_id = NFAPI_START_REQUEST;
+  req.header.phy_id = resp->header.phy_id;
+  nfapi_vnf_start_req(config, p5_idx, &req);
+
+  printf("[VNF] Send NFAPI_START_REQUEST idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
+
+  return 0;
+}
+
+void test_p4_requests(nfapi_vnf_config_t* config, int p5_idx, int phy_id)
+{
+#if 0
+	{
+		nfapi_measurement_request_t req;
+		memset(&req, 0, sizeof(req));
+		req.header.message_id = NFAPI_MEASUREMENT_REQUEST;
+		req.header.phy_id = phy_id;
+		
+		req.dl_rs_tx_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG;
+		req.dl_rs_tx_power.value = 42;
+		req.received_interference_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG;
+		req.received_interference_power.value = 42;
+		req.thermal_noise_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG;
+		req.thermal_noise_power.value = 42;
+		
+		nfapi_vnf_measurement_req(config, p5_idx, &req);
+	}
+	{
+		nfapi_rssi_request_t lte_req;
+		memset(&lte_req, 0, sizeof(lte_req));
+		lte_req.header.message_id = NFAPI_RSSI_REQUEST;
+		lte_req.header.phy_id = phy_id;
+		
+		lte_req.rat_type = NFAPI_RAT_TYPE_LTE;
+		lte_req.lte_rssi_request.tl.tag = NFAPI_LTE_RSSI_REQUEST_TAG;
+		lte_req.lte_rssi_request.frequency_band_indicator = 2;
+		lte_req.lte_rssi_request.measurement_period = 1000;
+		lte_req.lte_rssi_request.bandwidth = 50;
+		lte_req.lte_rssi_request.timeout = 0;
+		lte_req.lte_rssi_request.number_of_earfcns = 2;
+		lte_req.lte_rssi_request.earfcn[0] = 389;
+		lte_req.lte_rssi_request.earfcn[1] = 123;
+		
+		nfapi_vnf_rssi_request(config, p5_idx, &lte_req);
+		
+		nfapi_rssi_request_t utran_req;
+		memset(&utran_req, 0, sizeof(utran_req));
+		utran_req.header.message_id = NFAPI_RSSI_REQUEST;
+		utran_req.header.phy_id = phy_id;
+		
+		utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN;
+		utran_req.utran_rssi_request.tl.tag = NFAPI_UTRAN_RSSI_REQUEST_TAG;
+		utran_req.utran_rssi_request.frequency_band_indicator = 2;
+		utran_req.utran_rssi_request.measurement_period = 1000;
+		utran_req.utran_rssi_request.timeout = 0;
+		utran_req.utran_rssi_request.number_of_uarfcns = 2;
+		utran_req.utran_rssi_request.uarfcn[0] = 2348;
+		utran_req.utran_rssi_request.uarfcn[1] = 52;
+		
+		nfapi_vnf_rssi_request(config, p5_idx, &utran_req);		
+		
+		
+		nfapi_rssi_request_t geran_req;
+		memset(&geran_req, 0, sizeof(geran_req));
+		geran_req.header.message_id = NFAPI_RSSI_REQUEST;
+		geran_req.header.phy_id = phy_id;
+		
+		geran_req.rat_type = NFAPI_RAT_TYPE_GERAN;
+		geran_req.geran_rssi_request.tl.tag = NFAPI_GERAN_RSSI_REQUEST_TAG;
+		geran_req.geran_rssi_request.frequency_band_indicator = 2;
+		geran_req.geran_rssi_request.measurement_period = 1000;
+		geran_req.geran_rssi_request.timeout = 0;
+		geran_req.geran_rssi_request.number_of_arfcns = 1;
+		geran_req.geran_rssi_request.arfcn[0].arfcn = 34;
+		geran_req.geran_rssi_request.arfcn[0].direction = 0;
+		
+		nfapi_vnf_rssi_request(config, p5_idx, &geran_req);		
+	}
+	{
+		nfapi_cell_search_request_t lte_req;
+		memset(&lte_req, 0, sizeof(lte_req));
+		lte_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST;
+		lte_req.header.phy_id = phy_id;		
+		
+		lte_req.rat_type = NFAPI_RAT_TYPE_LTE;
+		lte_req.lte_cell_search_request.tl.tag = NFAPI_LTE_CELL_SEARCH_REQUEST_TAG;
+		lte_req.lte_cell_search_request.earfcn = 1234;
+		lte_req.lte_cell_search_request.measurement_bandwidth = 50;
+		lte_req.lte_cell_search_request.exhaustive_search = 1;
+		lte_req.lte_cell_search_request.timeout = 1000;
+		lte_req.lte_cell_search_request.number_of_pci = 1;
+		lte_req.lte_cell_search_request.pci[0] = 234;
+		
+		nfapi_vnf_cell_search_request(config, p5_idx, &lte_req);
+		
+		nfapi_cell_search_request_t utran_req;
+		memset(&utran_req, 0, sizeof(utran_req));
+		utran_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST;
+		utran_req.header.phy_id = phy_id;		
+		
+		utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN;
+		utran_req.utran_cell_search_request.tl.tag = NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG;
+		utran_req.utran_cell_search_request.uarfcn = 1234;
+		utran_req.utran_cell_search_request.exhaustive_search = 0;
+		utran_req.utran_cell_search_request.timeout = 1000;
+		utran_req.utran_cell_search_request.number_of_psc = 1;
+		utran_req.utran_cell_search_request.psc[0] = 234;
+		
+		nfapi_vnf_cell_search_request(config, p5_idx, &utran_req);		
+		
+		nfapi_cell_search_request_t geran_req;
+		memset(&geran_req, 0, sizeof(geran_req));
+		geran_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST;
+		geran_req.header.phy_id = phy_id;		
+		
+		geran_req.rat_type = NFAPI_RAT_TYPE_GERAN;
+		geran_req.geran_cell_search_request.tl.tag = NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG;
+		geran_req.geran_cell_search_request.timeout = 1000;
+		geran_req.geran_cell_search_request.number_of_arfcn = 1;
+		geran_req.geran_cell_search_request.arfcn[0] = 8765;
+		
+		nfapi_vnf_cell_search_request(config, p5_idx, &geran_req);				
+	}
+	{
+		nfapi_broadcast_detect_request_t lte_req;
+		memset(&lte_req, 0, sizeof(lte_req));
+		lte_req.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST;
+		lte_req.header.phy_id = phy_id;		
+		
+		lte_req.rat_type = NFAPI_RAT_TYPE_LTE;
+		lte_req.lte_broadcast_detect_request.tl.tag = NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG;
+		lte_req.lte_broadcast_detect_request.earfcn = 1234;
+		lte_req.lte_broadcast_detect_request.pci = 50;
+		lte_req.lte_broadcast_detect_request.timeout = 1000;
+		
+		lte_req.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG;
+		lte_req.pnf_cell_search_state.length = 3;
+		
+		nfapi_vnf_broadcast_detect_request(config, p5_idx, &lte_req);
+		
+		nfapi_broadcast_detect_request_t utran_req;
+		memset(&utran_req, 0, sizeof(utran_req));
+		utran_req.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST;
+		utran_req.header.phy_id = phy_id;		
+		
+		utran_req.rat_type = NFAPI_RAT_TYPE_LTE;
+		utran_req.utran_broadcast_detect_request.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG;
+		utran_req.utran_broadcast_detect_request.uarfcn = 1234;
+		utran_req.utran_broadcast_detect_request.psc = 50;
+		utran_req.utran_broadcast_detect_request.timeout = 1000;
+		
+		utran_req.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG;
+		utran_req.pnf_cell_search_state.length = 3;
+		
+		nfapi_vnf_broadcast_detect_request(config, p5_idx, &utran_req);		
+	}
+	{
+		nfapi_system_information_schedule_request_t lte_req;
+		memset(&lte_req, 0, sizeof(lte_req));
+		lte_req.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST;
+		lte_req.header.phy_id = phy_id;		
+		
+		lte_req.rat_type = NFAPI_RAT_TYPE_LTE;
+		lte_req.lte_system_information_schedule_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG;
+		lte_req.lte_system_information_schedule_request.earfcn = 1234;
+		lte_req.lte_system_information_schedule_request.pci = 50;
+		lte_req.lte_system_information_schedule_request.downlink_channel_bandwidth = 100;
+		lte_req.lte_system_information_schedule_request.phich_configuration = 3;
+		lte_req.lte_system_information_schedule_request.number_of_tx_antenna = 2;
+		lte_req.lte_system_information_schedule_request.retry_count = 4;
+		lte_req.lte_system_information_schedule_request.timeout = 1000;
+		
+		lte_req.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG;
+		lte_req.pnf_cell_broadcast_state.length = 3;
+		
+		nfapi_vnf_system_information_schedule_request(config, p5_idx, &lte_req);
+	}
+	{
+		nfapi_system_information_request_t lte_req;
+		memset(&lte_req, 0, sizeof(lte_req));
+		lte_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST;
+		lte_req.header.phy_id = phy_id;		
+		
+		lte_req.rat_type = NFAPI_RAT_TYPE_LTE;		
+		lte_req.lte_system_information_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG;
+		lte_req.lte_system_information_request.earfcn = 1234;
+		lte_req.lte_system_information_request.pci= 456;
+		lte_req.lte_system_information_request.downlink_channel_bandwidth = 5;
+		lte_req.lte_system_information_request.phich_configuration = 2;
+		lte_req.lte_system_information_request.number_of_tx_antenna = 2;
+		lte_req.lte_system_information_request.number_of_si_periodicity = 1;
+		lte_req.lte_system_information_request.si_periodicity[0].si_periodicity = 3;
+		lte_req.lte_system_information_request.si_periodicity[0].si_index = 3;
+		lte_req.lte_system_information_request.si_window_length = 15;
+		lte_req.lte_system_information_request.timeout = 1000;
+		
+		nfapi_vnf_system_information_request(config, p5_idx, &lte_req);
+		
+		nfapi_system_information_request_t utran_req;
+		memset(&utran_req, 0, sizeof(utran_req));
+		utran_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST;
+		utran_req.header.phy_id = phy_id;		
+		
+		utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN;
+		utran_req.utran_system_information_request.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG;
+		utran_req.utran_system_information_request.uarfcn = 1234;
+		utran_req.utran_system_information_request.psc = 456;
+		utran_req.utran_system_information_request.timeout = 1000;
+		
+		nfapi_vnf_system_information_request(config, p5_idx, &utran_req);		
+		
+		nfapi_system_information_request_t geran_req;
+		memset(&geran_req, 0, sizeof(geran_req));
+		geran_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST;
+		geran_req.header.phy_id = phy_id;		
+		
+		geran_req.rat_type = NFAPI_RAT_TYPE_GERAN;
+		geran_req.geran_system_information_request.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG;
+		geran_req.geran_system_information_request.arfcn = 1234;
+		geran_req.geran_system_information_request.bsic = 21;
+		geran_req.geran_system_information_request.timeout = 1000;
+		
+		nfapi_vnf_system_information_request(config, p5_idx, &geran_req);	
+	}
+	{
+		nfapi_nmm_stop_request_t req;
+		memset(&req, 0, sizeof(req));
+		req.header.message_id = NFAPI_NMM_STOP_REQUEST;
+		req.header.phy_id = phy_id;		
+		nfapi_vnf_nmm_stop_request(config, p5_idx, &req);	
+	}
+#endif
+}
+
+int start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp)
+{
+  printf("[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id);
+
+  vnf_info* vnf = (vnf_info*)(config->user_data);
+
+  if(vnf->wireshark_test_mode)
+    test_p4_requests(config, p5_idx,  resp->header.phy_id);
+
+#if 0
+  auto find_result = vnf->pnfs.find(p5_idx);
+  if(find_result != vnf->pnfs.end())
+  {
+    pnf_info& pnf = find_result->second;
+
+
+    auto found = std::find_if(pnf.phys.begin(), pnf.phys.end(), [&](phy_info& item)
+        { return item.id == resp->header.phy_id; });
+
+    if(found != pnf.phys.end())
+    {
+      phy_info& phy = (*found);
+
+      vnf_p7_info& p7_vnf = vnf->p7_vnfs[0];
+
+      nfapi_vnf_p7_add_pnf((p7_vnf.config.get()), phy.remote_addr.c_str(), phy.remote_port, phy.id);
+
+    }
+  }
+#else
+  pnf_info *pnf = vnf->pnfs;
+  phy_info *phy = pnf->phys;
+  vnf_p7_info *p7_vnf = vnf->p7_vnfs;
+  nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id);
+
+
+#if 0
+  {
+    extern pthread_cond_t nfapi_sync_cond;
+    extern pthread_mutex_t nfapi_sync_mutex;
+    extern int nfapi_sync_var;
+
+    printf("[VNF] Signal to OAI main code that it can go\n");
+    pthread_mutex_lock(&nfapi_sync_mutex);
+    nfapi_sync_var=0;
+    pthread_cond_broadcast(&nfapi_sync_cond);
+    pthread_mutex_unlock(&nfapi_sync_mutex);
+  }
+#endif
+
+#endif
+
+  return 0;
+}
+
+int vendor_ext_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_p4_p5_message_header_t* msg)
+{
+  printf("[VNF] %s\n", __FUNCTION__);
+
+  switch(msg->message_id)
+  {
+    case P5_VENDOR_EXT_RSP:
+      {
+        vendor_ext_p5_rsp* rsp = (vendor_ext_p5_rsp*)msg;
+        printf("[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code);
+
+        // send the start request
+
+        nfapi_pnf_start_request_t req;
+        memset(&req, 0, sizeof(req));
+        req.header.message_id = NFAPI_PNF_START_REQUEST;
+        nfapi_vnf_pnf_start_req(config, p5_idx, &req);
+      }
+      break;
+  }
+
+  return 0;
+}
+
+int vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t* codec)
+{
+  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if(header->message_id == P5_VENDOR_EXT_RSP)
+  {
+    vendor_ext_p5_rsp* req = (vendor_ext_p5_rsp*)(header);
+    return(!pull16(ppReadPackedMessage, &req->error_code, end));
+  }
+  return 0;
+}
+
+nfapi_p4_p5_message_header_t* vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t* msg_size)
+{
+  if(message_id == P5_VENDOR_EXT_RSP)
+  {
+    *msg_size = sizeof(vendor_ext_p5_rsp);
+    return (nfapi_p4_p5_message_header_t*)malloc(sizeof(vendor_ext_p5_rsp));
+  }
+  return 0;
+}
+
+void vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t* header)
+{
+  free(header);
+}
+
+nfapi_vnf_config_t *config = 0;
+
+void vnf_start_thread(void* ptr)
+{
+  NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] VNF NFAPI thread - nfapi_vnf_start()%s\n", __FUNCTION__);
+
+  config = (nfapi_vnf_config_t*)ptr;
+
+  nfapi_vnf_start(config);
+}
+
+static vnf_info vnf;
+/*------------------------------------------------------------------------------*/
+void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port)
+{
+  memset(&vnf, 0, sizeof(vnf));
+
+  memset(vnf.p7_vnfs, 0, sizeof(vnf.p7_vnfs));
+
+  vnf.p7_vnfs[0].timing_window = 32;
+  vnf.p7_vnfs[0].periodic_timing_enabled = 1;
+  vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
+  vnf.p7_vnfs[0].periodic_timing_period = 10;
+
+  vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
+  NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n", __FUNCTION__, vnf.p7_vnfs[0].config, vnf_addr, vnf_p5_port);
+
+  strcpy(vnf.p7_vnfs[0].local_addr, vnf_addr);
+  vnf.p7_vnfs[0].local_port = 50001;
+  vnf.p7_vnfs[0].mac = (mac_t*)malloc(sizeof(mac_t));
+
+  nfapi_vnf_config_t* config = nfapi_vnf_config_create();
+
+  config->malloc = malloc;
+  config->free = free;
+  config->trace = &vnf_trace;
+
+  config->vnf_p5_port = vnf_p5_port;
+  config->vnf_ipv4 = 1;
+  config->vnf_ipv6 = 0;
+
+  config->pnf_list = 0;
+  config->phy_list = 0;
+
+  config->pnf_connection_indication = &pnf_connection_indication_cb;
+  config->pnf_disconnect_indication = &pnf_disconnection_indication_cb;
+  config->pnf_param_resp = &pnf_param_resp_cb;
+  config->pnf_config_resp = &pnf_config_resp_cb;
+  config->pnf_start_resp = &pnf_start_resp_cb;
+  config->param_resp = &param_resp_cb;
+  config->config_resp = &config_resp_cb;
+  config->start_resp = &start_resp_cb;
+  config->vendor_ext = &vendor_ext_cb;
+
+  config->user_data = &vnf;
+
+  // To allow custom vendor extentions to be added to nfapi
+  config->codec_config.unpack_vendor_extension_tlv = &vnf_unpack_vendor_extension_tlv;
+  config->codec_config.pack_vendor_extension_tlv = &vnf_pack_vendor_extension_tlv;
+
+  config->codec_config.unpack_p4_p5_vendor_extension = &vnf_unpack_p4_p5_vendor_extension;
+  config->codec_config.pack_p4_p5_vendor_extension = &vnf_pack_p4_p5_vendor_extension;
+  config->allocate_p4_p5_vendor_ext = &vnf_allocate_p4_p5_vendor_ext;
+  config->deallocate_p4_p5_vendor_ext = &vnf_deallocate_p4_p5_vendor_ext;
+  config->codec_config.allocate = &vnf_allocate;
+  config->codec_config.deallocate = &vnf_deallocate;
+
+  {
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
+    pthread_create(&vnf_start_pthread, NULL, (void*)&vnf_start_thread, config);
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__);
+  }
+}
+
+int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req)
+{
+  nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
+
+  dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
+  //dl_config_req->header.message_id = NFAPI_DL_CONFIG_BCH_PDU_TYPE;
+
+  //NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() header message_id:%d\n", __FUNCTION__, dl_config_req->header.message_id);
+
+  //NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() p7_config:%p phy_id:%d message_id:%d sfn_sf:%d pdcch:%d dci:%d pdu:%d pdsch_rnti:%d pcfich:%d\n", __FUNCTION__, p7_config, dl_config_req->header.phy_id, dl_config_req->header.message_id, dl_config_req->sfn_sf, dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols, dl_config_req->dl_config_request_body.number_dci, dl_config_req->dl_config_request_body.number_pdu, dl_config_req->dl_config_request_body.number_pdsch_rnti, dl_config_req->dl_config_request_body.transmission_power_pcfich);
+
+  return nfapi_vnf_p7_dl_config_req(p7_config, dl_config_req);
+}
+
+int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req)
+{
+  nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
+
+  tx_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
+  //dl_config_req->header.message_id = NFAPI_DL_CONFIG_BCH_PDU_TYPE;
+
+  //NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() p7_config:%p phy_id:%d message_id:%d sfn_sf:%d pdcch:%d dci:%d pdu:%d pdsch_rnti:%d pcfich:%d\n", __FUNCTION__, p7_config, dl_config_req->header.phy_id, dl_config_req->header.message_id, dl_config_req->sfn_sf, dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols, dl_config_req->dl_config_request_body.number_dci, dl_config_req->dl_config_request_body.number_pdu, dl_config_req->dl_config_request_body.number_pdsch_rnti, dl_config_req->dl_config_request_body.transmission_power_pcfich);
+
+  return nfapi_vnf_p7_tx_req(p7_config, tx_req);
+}
diff --git a/nfapi/nfapi_vnf.h b/nfapi/nfapi_vnf.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a608d49555c22a5d2fed4436cfa4465545dc09b
--- /dev/null
+++ b/nfapi/nfapi_vnf.h
@@ -0,0 +1,6 @@
+#if !defined(NFAPI_VNF_H__)
+#define NFAPI_VNF_H__
+
+void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port);
+
+#endif
diff --git a/nfapi/vendor_ext.h b/nfapi/vendor_ext.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0fd57837d2eef4650700eb58399c0249eb68918
--- /dev/null
+++ b/nfapi/vendor_ext.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+#ifndef _VENDOR_EXT_H_
+#define _VENDOR_EXT_H_
+
+#include "nfapi_interface.h"
+
+typedef enum 
+{
+	P5_VENDOR_EXT_REQ = NFAPI_VENDOR_EXT_MSG_MIN,
+	P5_VENDOR_EXT_RSP,
+
+	P7_VENDOR_EXT_REQ,
+	P7_VENDOR_EXT_IND
+
+} vendor_ext_message_id_e;
+
+typedef struct {
+	nfapi_p4_p5_message_header_t header;
+	uint16_t dummy1;
+	uint16_t dummy2;
+} vendor_ext_p5_req;
+
+typedef struct {
+	nfapi_p4_p5_message_header_t header;
+	uint16_t error_code;
+} vendor_ext_p5_rsp;
+
+typedef struct {
+	nfapi_p7_message_header_t header;
+	uint16_t dummy1;
+	uint16_t dummy2;
+} vendor_ext_p7_req;
+
+typedef struct {
+	nfapi_p7_message_header_t header;
+	uint16_t error_code;
+} vendor_ext_p7_ind;
+
+typedef struct {
+	nfapi_tl_t tl;
+	uint32_t dummy;
+} vendor_ext_tlv_1;
+
+#define VENDOR_EXT_TLV_1_TAG 0xF001
+
+typedef struct {
+	nfapi_tl_t tl;
+	uint32_t dummy;
+} vendor_ext_tlv_2;
+
+#define VENDOR_EXT_TLV_2_TAG 0xF002
+
+
+
+
+#endif // _VENDOR_EXT_
diff --git a/oaienv b/oaienv
index f6b298debf69e2e24c2c65cce458291b9ff0a513..aa4bce9e78a513b7114f088b9062ebda10186af0 100644
--- a/oaienv
+++ b/oaienv
@@ -17,3 +17,12 @@ alias oait='cd $OPENAIR_TARGETS'
 alias oailte='cd $OPENAIR_TARGETS/RT/USER'
 alias oais='cd $OPENAIR_TARGETS/SIMU/USER'
 alias oaiex='cd $OPENAIR_TARGETS/SIMU/EXAMPLES'
+
+#export NFAPI_DIR=/home/nfapi-001/open-nFAPI/nfapi/public_inc
+export NFAPI_DIR=/home/nfapi-001/open-nFAPI
+
+alias bld='cd $OPENAIR_HOME/cmake_targets ; ./build_oai --eNB -x -w USRP'
+alias b='cd $OPENAIR_HOME/cmake_targets ; ./build_oai --eNB -x -w USRP'
+alias run='cd $OPENAIR_HOME/cmake_targets/lte_build_oai/build'
+alias nf='cd $OPENAIR_HOME/nfapi'
+alias conf='cd $OPENAIR_HOME/targets/PROJECTS/GENERIC-LTE-EPC/CONF'
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index 3a7eab5a5d7fe4874e17c00368cdaff93fdc5e98..832ba0ce5de236f74300366810423b92f9a9cf69 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -42,24 +42,37 @@ int N_RB_DL_array[6] = {6,15,25,50,75,100};
 int l1_north_init_eNB() {
 
   int i,j;
-  AssertFatal(RC.nb_L1_inst>0,"nb_L1_inst=%d\n",RC.nb_L1_inst);
-  AssertFatal(RC.nb_L1_CC!=NULL,"nb_L1_CC is null\n");
-  AssertFatal(RC.eNB!=NULL,"RC.eNB is null\n");
-  for (i=0;i<RC.nb_L1_inst;i++) {
-    AssertFatal(RC.eNB[i]!=NULL,"RC.eNB[%d] is null\n",i);
-    AssertFatal(RC.nb_L1_CC[i]>0,"RC.nb_L1_CC[%d]=%d\n",i,RC.nb_L1_CC[i]);
-    for (j=0;j<RC.nb_L1_CC[i];j++) {
-      AssertFatal(RC.eNB[i][j]!=NULL,"RC.eNB[%d][%d] is null\n",i,j);
-      if ((RC.eNB[i][j]->if_inst =  IF_Module_init(i))<0) return(-1); 
-      RC.eNB[i][j]->if_inst->PHY_config_req = phy_config_request;
-      RC.eNB[i][j]->if_inst->schedule_response = schedule_response;
+
+  if (RC.nb_L1_inst > 0 && RC.nb_L1_CC != NULL && RC.eNB != NULL)
+  {
+    AssertFatal(RC.nb_L1_inst>0,"nb_L1_inst=%d\n",RC.nb_L1_inst);
+    AssertFatal(RC.nb_L1_CC!=NULL,"nb_L1_CC is null\n");
+    AssertFatal(RC.eNB!=NULL,"RC.eNB is null\n");
+
+    LOG_I(PHY,"%s() RC.nb_L1_inst:%d\n", __FUNCTION__, RC.nb_L1_inst);
+
+    for (i=0;i<RC.nb_L1_inst;i++) {
+      AssertFatal(RC.eNB[i]!=NULL,"RC.eNB[%d] is null\n",i);
+      AssertFatal(RC.nb_L1_CC[i]>0,"RC.nb_L1_CC[%d]=%d\n",i,RC.nb_L1_CC[i]);
+
+      LOG_I(PHY,"%s() RC.nb_L1_CC[%d]:%d\n", __FUNCTION__, i,  RC.nb_L1_CC[i]);
+
+      for (j=0;j<RC.nb_L1_CC[i];j++) {
+        AssertFatal(RC.eNB[i][j]!=NULL,"RC.eNB[%d][%d] is null\n",i,j);
+
+        if ((RC.eNB[i][j]->if_inst =  IF_Module_init(i))<0) return(-1); 
+
+        LOG_I(PHY,"%s() RC.eNB[%d][%d] installing callbacks\n", __FUNCTION__, i,  j);
+
+        RC.eNB[i][j]->if_inst->PHY_config_req = phy_config_request;
+        RC.eNB[i][j]->if_inst->schedule_response = schedule_response;
+      }
     }
   }
   return(0);
 }
 
 
-
 void phy_config_request(PHY_Config_t *phy_config) {
 
   uint8_t Mod_id              = phy_config->Mod_id;
@@ -71,13 +84,14 @@ void phy_config_request(PHY_Config_t *phy_config) {
   PHICH_RESOURCE_t phich_resource_table[4]={oneSixth,half,one,two};
   int                 eutra_band     = cfg->nfapi_config.rf_bands.rf_band[0];  
   int                 dl_Bandwidth   = cfg->rf_config.dl_channel_bandwidth.value;
+  int                 ul_Bandwidth   = cfg->rf_config.ul_channel_bandwidth.value;
   int                 Nid_cell       = cfg->sch_config.physical_cell_id.value;
   int                 Ncp            = cfg->subframe_config.dl_cyclic_prefix_type.value;
   int                 p_eNB          = cfg->rf_config.tx_antenna_ports.value;
   uint32_t            dl_CarrierFreq = cfg->nfapi_config.earfcn.value;
 
-  LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,Ncp %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n",
-	Mod_id, CC_id, eutra_band, N_RB_DL_array[dl_Bandwidth], Nid_cell, p_eNB,Ncp,dl_CarrierFreq,
+  LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,eNB_tx_antenna_ports %d,Ncp %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n",
+	Mod_id, CC_id, eutra_band, dl_Bandwidth, ul_Bandwidth, Nid_cell, p_eNB,Ncp,dl_CarrierFreq,
 	cfg->phich_config.phich_resource.value,
 	cfg->phich_config.phich_duration.value);
 
@@ -91,8 +105,8 @@ void phy_config_request(PHY_Config_t *phy_config) {
 
   fp = &RC.eNB[Mod_id][CC_id]->frame_parms;
 
-  fp->N_RB_DL                            = N_RB_DL_array[dl_Bandwidth];
-  fp->N_RB_UL                            = N_RB_DL_array[dl_Bandwidth];
+  fp->N_RB_DL                            = dl_Bandwidth;
+  fp->N_RB_UL                            = ul_Bandwidth;
   fp->Nid_cell                           = Nid_cell;
   fp->nushift                            = fp->Nid_cell%6;
   fp->eutra_band                         = eutra_band;
@@ -153,93 +167,95 @@ void phy_config_request(PHY_Config_t *phy_config) {
                     RC.eNB[Mod_id][CC_id]->X_u);
 
 #ifdef Rel14
-  if (cfg->emtc_config.prach_ce_level_0_enable.value == 1) {
-    fp->prach_emtc_config_common.prach_Config_enabled=1;
-
-    fp->prach_emtc_config_common.rootSequenceIndex                                         = cfg->emtc_config.prach_catm_root_sequence_index.value;
-
-    fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag                            = cfg->emtc_config.prach_catm_high_speed_flag.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig                = cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value;
-
-    // CE Level 3 parameters
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3]                  = cfg->emtc_config.prach_ce_level_3_enable.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]   = cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3] = cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value;
-    AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3],
-		"prach_starting_subframe_periodicity[3] < prach_numPetitionPerPreambleAttempt[3]\n");
-
-
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3]                     = cfg->emtc_config.prach_ce_level_3_configuration_index.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[3]                      = cfg->emtc_config.prach_ce_level_3_frequency_offset.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[3]                  = cfg->emtc_config.prach_ce_level_3_hopping_enable.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[3]                  = cfg->emtc_config.prach_ce_level_3_hopping_offset.value;
-    if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] == 1)
-      compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
-			fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
-			fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
-			fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
-			fp->frame_type,
-			RC.eNB[Mod_id][CC_id]->X_u_br[3]);
-
-    // CE Level 2 parameters
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2]                  = cfg->emtc_config.prach_ce_level_2_enable.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]   = cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2] = cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value;
-    AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2],
-		"prach_starting_subframe_periodicity[2] < prach_numPetitionPerPreambleAttempt[2]\n");
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[2]                     = cfg->emtc_config.prach_ce_level_2_configuration_index.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[2]                      = cfg->emtc_config.prach_ce_level_2_frequency_offset.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[2]                  = cfg->emtc_config.prach_ce_level_2_hopping_enable.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[2]                  = cfg->emtc_config.prach_ce_level_2_hopping_offset.value;
-    if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] == 1)
-      compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
-			fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
-			fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
-			fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
-			fp->frame_type,
-			RC.eNB[Mod_id][CC_id]->X_u_br[2]);
-
-    // CE Level 1 parameters
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1]                  = cfg->emtc_config.prach_ce_level_1_enable.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]   = cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1] = cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value;
-    AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1],
-		"prach_starting_subframe_periodicity[1] < prach_numPetitionPerPreambleAttempt[1]\n");
-
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[1]                     = cfg->emtc_config.prach_ce_level_1_configuration_index.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[1]                      = cfg->emtc_config.prach_ce_level_1_frequency_offset.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[1]                  = cfg->emtc_config.prach_ce_level_1_hopping_enable.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[1]                  = cfg->emtc_config.prach_ce_level_1_hopping_offset.value;
-    if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] == 1)
-      compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
-			fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
-			fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
-			fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
-			fp->frame_type,
-			RC.eNB[Mod_id][CC_id]->X_u_br[1]);
+  fp->prach_emtc_config_common.prach_Config_enabled=1;
+
+  fp->prach_emtc_config_common.rootSequenceIndex                                         = cfg->emtc_config.prach_catm_root_sequence_index.value;
+
+  fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag                            = cfg->emtc_config.prach_catm_high_speed_flag.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig                = cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value;
+
+  // CE Level 3 parameters
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3]                  = cfg->emtc_config.prach_ce_level_3_enable.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]   = cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3] = cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value;
+  AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[3]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[3],
+	      "prach_starting_subframe_periodicity[3] < prach_numPetitionPerPreambleAttempt[3]\n");
+
+
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3]                     = cfg->emtc_config.prach_ce_level_3_configuration_index.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[3]                      = cfg->emtc_config.prach_ce_level_3_frequency_offset.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[3]                  = cfg->emtc_config.prach_ce_level_3_hopping_enable.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[3]                  = cfg->emtc_config.prach_ce_level_3_hopping_offset.value;
+  if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[3] == 1)
+    compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
+		      fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
+		      fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+		      fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
+		      fp->frame_type,
+		      RC.eNB[Mod_id][CC_id]->X_u_br[3]);
+
+  // CE Level 2 parameters
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2]                  = cfg->emtc_config.prach_ce_level_2_enable.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]   = cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2] = cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value;
+  AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[2]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[2],
+	      "prach_starting_subframe_periodicity[2] < prach_numPetitionPerPreambleAttempt[2]\n");
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[2]                     = cfg->emtc_config.prach_ce_level_2_configuration_index.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[2]                      = cfg->emtc_config.prach_ce_level_2_frequency_offset.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[2]                  = cfg->emtc_config.prach_ce_level_2_hopping_enable.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[2]                  = cfg->emtc_config.prach_ce_level_2_hopping_offset.value;
+  if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[2] == 1)
+    compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
+		      fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
+		      fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+		      fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
+		      fp->frame_type,
+		      RC.eNB[Mod_id][CC_id]->X_u_br[2]);
+
+  // CE Level 1 parameters
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1]                  = cfg->emtc_config.prach_ce_level_1_enable.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]   = cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1] = cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value;
+  AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[1]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[1],
+	      "prach_starting_subframe_periodicity[1] < prach_numPetitionPerPreambleAttempt[1]\n");
+
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[1]                     = cfg->emtc_config.prach_ce_level_1_configuration_index.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[1]                      = cfg->emtc_config.prach_ce_level_1_frequency_offset.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[1]                  = cfg->emtc_config.prach_ce_level_1_hopping_enable.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[1]                  = cfg->emtc_config.prach_ce_level_1_hopping_offset.value;
+  if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[1] == 1)
+    compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
+		      fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
+		      fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+		      fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
+		      fp->frame_type,
+		      RC.eNB[Mod_id][CC_id]->X_u_br[1]);
   
-    // CE Level 0 parameters
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0]                  = cfg->emtc_config.prach_ce_level_0_enable.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]   = cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] = cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value;
-    AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0],
-		"prach_starting_subframe_periodicity[0] %d < prach_numPetitionPerPreambleAttempt[0] %d\n",
-		fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0],
-		fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]);
-    AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] > 0,
-		"prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]==0\n");
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[0]                     = cfg->emtc_config.prach_ce_level_0_configuration_index.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[0]                      = cfg->emtc_config.prach_ce_level_0_frequency_offset.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[0]                = cfg->emtc_config.prach_ce_level_0_hopping_enable.value;
-    fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[0]                = cfg->emtc_config.prach_ce_level_0_hopping_offset.value;
-    if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1)
-      compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
-			fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
-			fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
-			fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
-			fp->frame_type,
-			RC.eNB[Mod_id][CC_id]->X_u_br[0]);
-  }
+  // CE Level 0 parameters
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0]                  = cfg->emtc_config.prach_ce_level_0_enable.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]   = cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] = cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value;
+  AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0]>=fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0],
+	      "prach_starting_subframe_periodicity[0] %d < prach_numPetitionPerPreambleAttempt[0] %d\n",
+	      fp->prach_emtc_config_common.prach_ConfigInfo.prach_starting_subframe_periodicity[0],
+	      fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]);
+#if 0
+  AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] > 0,
+	      "prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]==0\n");
+#else
+  LOG_E(PHY,"***DJP*** removed assert on preamble fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]:%d expecting >0 %s:%d\n\n\n", fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0], __FILE__, __LINE__);
+#endif
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[0]                     = cfg->emtc_config.prach_ce_level_0_configuration_index.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[0]                      = cfg->emtc_config.prach_ce_level_0_frequency_offset.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_enable[0]                = cfg->emtc_config.prach_ce_level_0_hopping_enable.value;
+  fp->prach_emtc_config_common.prach_ConfigInfo.prach_hopping_offset[0]                = cfg->emtc_config.prach_ce_level_0_hopping_offset.value;
+  if (fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1)
+    compute_prach_seq(fp->prach_emtc_config_common.rootSequenceIndex,
+		      fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[3],
+		      fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+		      fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag,
+		      fp->frame_type,
+		      RC.eNB[Mod_id][CC_id]->X_u_br[0]);
 #endif
 
 
@@ -266,9 +282,9 @@ void phy_config_request(PHY_Config_t *phy_config) {
   fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled     = 0;
   fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled  = 0;
   if (cfg->uplink_reference_signal_config.uplink_rs_hopping.value == 1) 
-    fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
+      fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1;
   if (cfg->uplink_reference_signal_config.uplink_rs_hopping.value == 2) 
-    fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 1;
+      fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 1;
   LOG_I(PHY,"pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = %d\n",fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled);
   fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH   =  cfg->uplink_reference_signal_config.group_assignment.value;
   LOG_I(PHY,"pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = %d\n",fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH);
@@ -315,14 +331,14 @@ void phy_config_sib1_ue(uint8_t Mod_id,int CC_id,
 }
 
 /*
-  void phy_config_sib2_eNB(uint8_t Mod_id,
-  int CC_id,
-  RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
-  ARFCN_ValueEUTRA_t *ul_CArrierFreq,
-  long *ul_Bandwidth,
-  AdditionalSpectrumEmission_t *additionalSpectrumEmission,
-  struct MBSFN_SubframeConfigList  *mbsfn_SubframeConfigList)
-  {
+void phy_config_sib2_eNB(uint8_t Mod_id,
+                         int CC_id,
+                         RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
+                         ARFCN_ValueEUTRA_t *ul_CArrierFreq,
+                         long *ul_Bandwidth,
+                         AdditionalSpectrumEmission_t *additionalSpectrumEmission,
+                         struct MBSFN_SubframeConfigList  *mbsfn_SubframeConfigList)
+{
 
   LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms;
   //LTE_eNB_UE_stats *eNB_UE_stats      = RC.eNB[Mod_id][CC_id].eNB_UE_stats;
@@ -349,7 +365,7 @@ void phy_config_sib1_ue(uint8_t Mod_id,int CC_id,
 
   init_prach_tables(839);
   compute_prach_seq(&fp->prach_config_common,fp->frame_type,
-  RC.eNB[Mod_id][CC_id]->X_u);
+                    RC.eNB[Mod_id][CC_id]->X_u);
 
   fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon.deltaPUCCH_Shift;
   fp->pucch_config_common.nRB_CQI          = radioResourceConfigCommon->pucch_ConfigCommon.nRB_CQI;
@@ -391,15 +407,15 @@ void phy_config_sib1_ue(uint8_t Mod_id,int CC_id,
   fp->soundingrs_ul_config_common.enabled_flag                        = 0;
 
   if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) {
-  fp->soundingrs_ul_config_common.enabled_flag                        = 1;
-  fp->soundingrs_ul_config_common.srs_BandwidthConfig                 = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig;
-  fp->soundingrs_ul_config_common.srs_SubframeConfig                  = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig;
-  fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission;
+    fp->soundingrs_ul_config_common.enabled_flag                        = 1;
+    fp->soundingrs_ul_config_common.srs_BandwidthConfig                 = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig;
+    fp->soundingrs_ul_config_common.srs_SubframeConfig                  = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig;
+    fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission;
 
-  if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts)
-  fp->soundingrs_ul_config_common.srs_MaxUpPts                      = 1;
-  else
-  fp->soundingrs_ul_config_common.srs_MaxUpPts                      = 0;
+    if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts)
+      fp->soundingrs_ul_config_common.srs_MaxUpPts                      = 1;
+    else
+      fp->soundingrs_ul_config_common.srs_MaxUpPts                      = 0;
   }
 
 
@@ -427,34 +443,34 @@ void phy_config_sib1_ue(uint8_t Mod_id,int CC_id,
 
   // MBSFN
   if (mbsfn_SubframeConfigList != NULL) {
-  fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count;
-
-  for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) {
-  fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod;
-  fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset;
-
-  if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {
-  fp->MBSFN_config[i].fourFrames_flag = 0;
-  fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration
-  LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %d\n", i,
-  fp->MBSFN_config[i].mbsfn_SubframeConfig);
-  } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
-  fp->MBSFN_config[i].fourFrames_flag = 1;
-  fp->MBSFN_config[i].mbsfn_SubframeConfig =
-  mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]|
-  (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
-  (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16);
-
-  LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %d\n", i,
-  fp->MBSFN_config[i].mbsfn_SubframeConfig);
-  }
-  }
+    fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count;
+
+    for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) {
+      fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod;
+      fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset;
+
+      if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {
+        fp->MBSFN_config[i].fourFrames_flag = 0;
+        fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration
+        LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %d\n", i,
+              fp->MBSFN_config[i].mbsfn_SubframeConfig);
+      } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
+        fp->MBSFN_config[i].fourFrames_flag = 1;
+        fp->MBSFN_config[i].mbsfn_SubframeConfig =
+          mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]|
+          (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
+          (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16);
+
+        LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is  %d\n", i,
+              fp->MBSFN_config[i].mbsfn_SubframeConfig);
+      }
+    }
 
   } else
-  fp->num_MBSFN_config = 0;
+    fp->num_MBSFN_config = 0;
 
   //
-  }
+}
 */
 
 void phy_config_sib2_ue(uint8_t Mod_id,int CC_id,
@@ -854,7 +870,7 @@ void phy_config_afterHO_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_id, Mobility
     PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8);
 
     LOG_I(PHY,"SET C-RNTI %x %x\n",PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti,
-	  PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti);
+                                   PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti);
   }
 
   if(ho_failed) {
@@ -883,67 +899,67 @@ void phy_config_meas_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n
 }
 
 /*
-  void phy_config_dedicated_eNB(uint8_t Mod_id,
-  int CC_id,
-  uint16_t rnti,
-  struct PhysicalConfigDedicated *physicalConfigDedicated)
-  {
+void phy_config_dedicated_eNB(uint8_t Mod_id,
+                              int CC_id,
+                              uint16_t rnti,
+                              struct PhysicalConfigDedicated *physicalConfigDedicated)
+{
 
   PHY_VARS_eNB *eNB = RC.eNB[Mod_id][CC_id];
   int8_t UE_id = find_ue(rnti,eNB);
   int i;
 
   if (UE_id == -1) {
-  LOG_E( PHY, "[eNB %"PRIu8"] find_ue() returns -1\n", Mod_id);
-  return;
+    LOG_E( PHY, "[eNB %"PRIu8"] find_ue() returns -1\n", Mod_id);
+    return;
   }
 
 
   if (physicalConfigDedicated) {
-  eNB->physicalConfigDedicated[UE_id] = physicalConfigDedicated;
-  LOG_I(PHY,"phy_config_dedicated_eNB: physicalConfigDedicated=%p\n",physicalConfigDedicated);
-
-  if (physicalConfigDedicated->antennaInfo) {
-  switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) {
-  case AntennaInfoDedicated__transmissionMode_tm1:
-  eNB->transmission_mode[UE_id] = 1;
-  break;
-  case AntennaInfoDedicated__transmissionMode_tm2:
-  eNB->transmission_mode[UE_id] = 2;
-  break;
-  case AntennaInfoDedicated__transmissionMode_tm3:
-  eNB->transmission_mode[UE_id] = 3;
-  break;
-  case AntennaInfoDedicated__transmissionMode_tm4:
-  eNB->transmission_mode[UE_id] = 4;
-  break;
-  case AntennaInfoDedicated__transmissionMode_tm5:
-  eNB->transmission_mode[UE_id] = 5;
-  break;
-  case AntennaInfoDedicated__transmissionMode_tm6:
-  eNB->transmission_mode[UE_id] = 6;
-  break;
-  case AntennaInfoDedicated__transmissionMode_tm7:
-  lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti);
-
-  for (i=0;i<eNB->num_RU;i++) eNB->RU_list[i]->do_precoding=1;
-  eNB->transmission_mode[UE_id] = 7;
-  break;
-  default:
-  LOG_E(PHY,"Unknown transmission mode!\n");
-  break;
-  }
-  LOG_I(PHY,"Transmission Mode (phy_config_dedicated_eNB) %d\n",eNB->transmission_mode[UE_id]);
+    eNB->physicalConfigDedicated[UE_id] = physicalConfigDedicated;
+    LOG_I(PHY,"phy_config_dedicated_eNB: physicalConfigDedicated=%p\n",physicalConfigDedicated);
 
+    if (physicalConfigDedicated->antennaInfo) {
+      switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) {
+      case AntennaInfoDedicated__transmissionMode_tm1:
+        eNB->transmission_mode[UE_id] = 1;
+        break;
+      case AntennaInfoDedicated__transmissionMode_tm2:
+        eNB->transmission_mode[UE_id] = 2;
+        break;
+      case AntennaInfoDedicated__transmissionMode_tm3:
+        eNB->transmission_mode[UE_id] = 3;
+        break;
+      case AntennaInfoDedicated__transmissionMode_tm4:
+        eNB->transmission_mode[UE_id] = 4;
+        break;
+      case AntennaInfoDedicated__transmissionMode_tm5:
+        eNB->transmission_mode[UE_id] = 5;
+        break;
+      case AntennaInfoDedicated__transmissionMode_tm6:
+        eNB->transmission_mode[UE_id] = 6;
+        break;
+      case AntennaInfoDedicated__transmissionMode_tm7:
+        lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],eNB->frame_parms.Nid_cell,rnti);
+
+	for (i=0;i<eNB->num_RU;i++) eNB->RU_list[i]->do_precoding=1;
+	eNB->transmission_mode[UE_id] = 7;
+	break;
+      default:
+        LOG_E(PHY,"Unknown transmission mode!\n");
+        break;
+      }
+      LOG_I(PHY,"Transmission Mode (phy_config_dedicated_eNB) %d\n",eNB->transmission_mode[UE_id]);
+
+    } else {
+      LOG_D(PHY,"[eNB %d] : Received NULL radioResourceConfigDedicated->antennaInfo from eNB %d\n",Mod_id,UE_id);
+    }
   } else {
-  LOG_D(PHY,"[eNB %d] : Received NULL radioResourceConfigDedicated->antennaInfo from eNB %d\n",Mod_id,UE_id);
-  }
-  } else {
-  LOG_E(PHY,"[eNB %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, UE_id);
-  return;
+    LOG_E(PHY,"[eNB %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, UE_id);
+    return;
   }
 
-  }
+}
 */
 
 #if defined(Rel10) || defined(Rel14)
@@ -955,11 +971,11 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id,
 
 }
 /*
-  void phy_config_dedicated_scell_eNB(uint8_t Mod_id,
-  uint16_t rnti,
-  SCellToAddMod_r10_t *sCellToAddMod_r10,
-  int CC_id)
-  {
+void phy_config_dedicated_scell_eNB(uint8_t Mod_id,
+                                    uint16_t rnti,
+                                    SCellToAddMod_r10_t *sCellToAddMod_r10,
+                                    int CC_id)
+{
 
 
   uint8_t UE_id = find_ue(rnti,RC.eNB[Mod_id][0]);
@@ -970,37 +986,37 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id,
   uint32_t carrier_freq_local;
 
   if ((dl_CarrierFreq_r10>=36000) && (dl_CarrierFreq_r10<=36199)) {
-  carrier_freq_local = 1900000000 + (dl_CarrierFreq_r10-36000)*100000; //band 33 from 3GPP 36.101 v 10.9 Table 5.7.3-1
-  LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id,
-  //eNB->frame
-  0,
-  CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id);
+    carrier_freq_local = 1900000000 + (dl_CarrierFreq_r10-36000)*100000; //band 33 from 3GPP 36.101 v 10.9 Table 5.7.3-1
+    LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id,
+	  //eNB->frame
+	  0,
+	  CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id);
   } else if ((dl_CarrierFreq_r10>=6150) && (dl_CarrierFreq_r10<=6449)) {
-  carrier_freq_local = 832000000 + (dl_CarrierFreq_r10-6150)*100000; //band 20 from 3GPP 36.101 v 10.9 Table 5.7.3-1
-  // this is actually for the UL only, but we use it for DL too, since there is no TDD mode for this band
-  LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id,
-  //eNB->frame
-  0,CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id);
+    carrier_freq_local = 832000000 + (dl_CarrierFreq_r10-6150)*100000; //band 20 from 3GPP 36.101 v 10.9 Table 5.7.3-1
+    // this is actually for the UL only, but we use it for DL too, since there is no TDD mode for this band
+    LOG_I(PHY,"[eNB %d] Frame %d: Configured SCell %d to frequency %d (ARFCN %ld) for UE %d\n",Mod_id,
+          //eNB->frame
+          0,CC_id,carrier_freq_local,dl_CarrierFreq_r10,UE_id);
   } else {
-  LOG_E(PHY,"[eNB %d] Frame %d: ARFCN %ld of SCell %d for UE %d not supported\n",Mod_id,
-  //eNB->frame
-  0,dl_CarrierFreq_r10,CC_id,UE_id);
+    LOG_E(PHY,"[eNB %d] Frame %d: ARFCN %ld of SCell %d for UE %d not supported\n",Mod_id,
+	  //eNB->frame
+	  0,dl_CarrierFreq_r10,CC_id,UE_id);
   }
 
   if (physicalConfigDedicatedSCell_r10) {
-  //#warning " eNB->physicalConfigDedicatedSCell_r10 does not exist in eNB"
-  //  eNB->physicalConfigDedicatedSCell_r10[UE_id] = physicalConfigDedicatedSCell_r10;
-  LOG_I(PHY,"[eNB %d] Frame %d: Configured phyConfigDedicatedSCell with CC_id %d for UE %d\n",Mod_id,
-  //eNB->frame
-  0,CC_id,UE_id);
+//#warning " eNB->physicalConfigDedicatedSCell_r10 does not exist in eNB"
+    //  eNB->physicalConfigDedicatedSCell_r10[UE_id] = physicalConfigDedicatedSCell_r10;
+    LOG_I(PHY,"[eNB %d] Frame %d: Configured phyConfigDedicatedSCell with CC_id %d for UE %d\n",Mod_id,
+	  //eNB->frame
+          0,CC_id,UE_id);
   } else {
-  LOG_E(PHY,"[eNB %d] Frame %d: Received NULL radioResourceConfigDedicated (CC_id %d, UE %d)\n",Mod_id, 
-  //eNB->frame
-  0,CC_id,UE_id);
-  return;
+    LOG_E(PHY,"[eNB %d] Frame %d: Received NULL radioResourceConfigDedicated (CC_id %d, UE %d)\n",Mod_id, 
+	  //eNB->frame
+	  0,CC_id,UE_id);
+    return;
   }
 
-  }
+}
 */
 
 #endif
@@ -1174,7 +1190,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
       }
       if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) {
         if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) {
-	  // configure PUCCH CQI reporting
+        // configure PUCCH CQI reporting
           phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex;
           phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex     = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex;
           if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex)
@@ -1213,12 +1229,12 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
   phy_vars_ue->decode_MIB = 0;
   //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti;
   if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234)
-    phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti;
+      phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti;
   else
-    phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti;
+      phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti;
 
   LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti,
-	phy_vars_ue->pdcch_vars[1][eNB_id]->crnti);
+                               phy_vars_ue->pdcch_vars[1][eNB_id]->crnti);
 
 }
 
@@ -1655,7 +1671,7 @@ int phy_init_RU(RU_t *ru) {
       ru->common.txdata[i]  = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
 
       LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes)\n",i,ru->common.txdata[i],
-	    fp->samples_per_tti*10*sizeof(int32_t));
+	     fp->samples_per_tti*10*sizeof(int32_t));
 
     }
     for (i=0;i<ru->nb_rx;i++) {
@@ -1720,11 +1736,18 @@ int phy_init_RU(RU_t *ru) {
 	    // antenna ports 5-14 are mapped on all antennas 
 	    if (((i<4) && (i==j)) || ((i==4) && (j==0))) {
 	      for (re=0; re<fp->ofdm_symbol_size; re++) 
+              {
 		ru->beam_weights[i][p][j][re] = 0x00007fff; 
+
+                LOG_E(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]);
+              }
 	    }
 	    else if (i>4) {
 	      for (re=0; re<fp->ofdm_symbol_size; re++) 
+              {
 		ru->beam_weights[i][p][j][re] = 0x00007fff/ru->nb_tx; 
+                LOG_E(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]);
+              }
 	    }  
 	    LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n",
 		  i,j,ru->beam_weights[i][p][j],
@@ -1755,6 +1778,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
 #endif
   int i,  eNB_id, UE_id; 
 
+  LOG_I(PHY,"[eNB %d] %s() About to wait for eNB to be configured", eNB->Mod_id, __FUNCTION__);
 
   eNB->total_dlsch_bitrate = 0;
   eNB->total_transmitted_bits = 0;
@@ -1763,10 +1787,18 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
  
   while(eNB->configured == 0) usleep(10000);
 
-  LOG_I(PHY,"[eNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d\n",
+  LOG_I(PHY,"[eNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u nb_antenna_ports_eNB:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n",
         eNB->Mod_id,
         fp->N_RB_DL,fp->phich_config_common.phich_resource,
-        fp->phich_config_common.phich_duration);
+        fp->phich_config_common.phich_duration,
+        fp->nb_antennas_tx, fp->nb_antennas_rx, fp->nb_antenna_ports_eNB,
+        fp->prach_config_common.rootSequenceIndex,
+        fp->prach_config_common.prach_Config_enabled,
+        fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
+        fp->prach_config_common.prach_ConfigInfo.highSpeedFlag,
+        fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,
+        fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset
+        );
   LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_eNB][MOD %02"PRIu8"][]\n", eNB->Mod_id);
 
 
@@ -1793,11 +1825,13 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
   common_vars->txdataF = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t*));
   common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*));
   
+  LOG_D(PHY,"[INIT] NB_ANTENNA_PORTS_ENB:%d fp->nb_antenna_ports_eNB:%d\n", NB_ANTENNA_PORTS_ENB, fp->nb_antenna_ports_eNB);
+
   for (i=0; i<NB_ANTENNA_PORTS_ENB; i++) {
     if (i<fp->nb_antenna_ports_eNB || i==5) {
       common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) );
       
-      LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
+      LOG_E(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
 	    i,common_vars->txdataF[i],
 	    fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t));
     }
@@ -1845,12 +1879,12 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
 #endif
   
   /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) 
-     AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]),
-     "nb_antennas_rx too large");
-     for (i=0; i<fp->nb_antennas_rx; i++) {
-     prach_vars->rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
-     LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]);
-     }*/
+  AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]),
+              "nb_antennas_rx too large");
+  for (i=0; i<fp->nb_antennas_rx; i++) {
+    prach_vars->rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
+    LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]);
+    }*/
   
   for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
     
@@ -1878,7 +1912,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
       pusch_vars[UE_id]->rxdataF_comp[i]     = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
       pusch_vars[UE_id]->ul_ch_mag[i]  = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
       pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
-    }
+      }
     
     pusch_vars[UE_id]->llr = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
   } //UE_id
@@ -1893,3 +1927,9 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
   return (0);
 
 }
+
+void install_schedule_handlers(IF_Module_t *if_inst)
+{
+  if_inst->PHY_config_req = phy_config_request;
+  if_inst->schedule_response = schedule_response;
+}
diff --git a/openair1/PHY/LTE_TRANSPORT/pbch.c b/openair1/PHY/LTE_TRANSPORT/pbch.c
index 603c92d69f121b8384d6eda2c8d7bd5e1121200c..d25cd7cc9369b649a708b39750b9fa1f85506ead 100644
--- a/openair1/PHY/LTE_TRANSPORT/pbch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pbch.c
@@ -174,6 +174,8 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch,
   pbch_E  = (frame_parms->Ncp==NORMAL) ? 1920 : 1728; //RE/RB * #RB * bits/RB (QPSK)
   //  pbch_E_bytes = pbch_coded_bits>>3;
 
+  LOG_D(PHY,"%s(eNB_pbch:%p txdataF:%p amp:%d frame_parms:%p pbch_pdu:%p frame_mod4:%d)\n", __FUNCTION__, eNB_pbch, txdataF, amp, frame_parms, pbch_pdu, frame_mod4==0);
+
   if (frame_mod4==0) {
     bzero(pbch_a,PBCH_A>>3);
     bzero(eNB_pbch->pbch_e,pbch_E);
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 2ca502d1f686d68bc203da6e772dfd22d2b7d39e..9c2fc6a16776e606c063a5f3a18871124af1f9aa 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -1531,6 +1531,8 @@ static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char *
     return(-1);
   }
 
+  LOG_D(PHY, "%s() name:%s instance_cnt:%u - about to decrement\n", __FUNCTION__, name, *instance_cnt);
+
   *instance_cnt=*instance_cnt-1;
 
   if (pthread_mutex_unlock(mutex) != 0) {
diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c
index 4e0c38174deecfc3e0f84fb7fc796876c4ca9af3..58f1ccd69db28bb9a8ca4f6368e9ee400e3e963b 100644
--- a/openair1/SCHED/fapi_l1.c
+++ b/openair1/SCHED/fapi_l1.c
@@ -37,6 +37,8 @@
 #include "nfapi_interface.h"
 #include "fapi_l1.h"
 
+int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req);
+int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req);
 
 
 void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,  
@@ -576,8 +578,9 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
   ul_subframe = pdcch_alloc2ul_subframe(fp,subframe);
   ul_frame    = pdcch_alloc2ul_frame(fp,frame,subframe);
 
-  AssertFatal(proc->subframe_tx == subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe);
-  AssertFatal(proc->subframe_tx == subframe, "Current frame %d != NFAPI frame %d\n",proc->frame_tx,frame);
+// DJP - subframe assert will fail - not sure why yet
+  // DJP - AssertFatal(proc->subframe_tx == subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe);
+  // DJP - AssertFatal(proc->subframe_tx == subframe, "Current frame %d != NFAPI frame %d\n",proc->frame_tx,frame);
 
   uint8_t number_dl_pdu             = DL_req->dl_config_request_body.number_pdu;
   uint8_t number_hi_dci0_pdu        = HI_DCI0_req->hi_dci0_request_body.number_of_dci+HI_DCI0_req->hi_dci0_request_body.number_of_hi;
@@ -591,12 +594,13 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
   int i;
 
   eNB->pdcch_vars[subframe&1].num_pdcch_symbols = DL_req->dl_config_request_body.number_pdcch_ofdm_symbols;
-  eNB->pdcch_vars[subframe&1].num_dci           = 0;
+  eNB->pdcch_vars[subframe&1].num_dci           = DL_req->dl_config_request_body.number_dci;
   eNB->phich_vars[subframe&1].num_hi            = 0;
 
   LOG_D(PHY,"NFAPI: Frame %d, Subframe %d: received %d dl_pdu, %d tx_req, %d hi_dci0_config_req, %d UL_config \n",
 	frame,subframe,number_dl_pdu,TX_req->tx_request_body.number_of_pdus,number_hi_dci0_pdu,number_ul_pdu);
 
+  int do_oai =0;
   
   if ((subframe_select(fp,ul_subframe)==SF_UL) ||
       (fp->frame_type == FDD)) {
@@ -619,6 +623,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
     case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE:
       handle_nfapi_dci_dl_pdu(eNB,proc,dl_config_pdu);
       eNB->pdcch_vars[subframe&1].num_dci++;
+      do_oai=1;
       break;
     case NFAPI_DL_CONFIG_BCH_PDU_TYPE:
       AssertFatal(dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index<TX_req->tx_request_body.number_of_pdus,
@@ -626,6 +631,11 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
 		  dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index,
 		  TX_req->tx_request_body.number_of_pdus);
       eNB->pbch_configured=1;
+      do_oai=1;
+      //LOG_D(PHY,"%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE TX:%d/%d RX:%d/%d TXREQ:%d/%d\n", 
+          //__FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2SFN(TX_req->sfn_sf), NFAPI_SFNSF2SF(TX_req->sfn_sf));
+
+
       handle_nfapi_bch_pdu(eNB,proc,dl_config_pdu,
 			   TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index].segments[0].segment_data);
       break;
@@ -633,6 +643,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
       //      handle_nfapi_mch_dl_pdu(eNB,dl_config_pdu);
       break;
     case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE:
+      //LOG_D(PHY,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE TX:%d/%d RX:%d/%d\n", __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx);
+
       AssertFatal(dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index<TX_req->tx_request_body.number_of_pdus,
 		  "dlsch_pdu_rel8.pdu_index>=TX_req->number_of_pdus (%d>%d)\n",
 		  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,
@@ -653,6 +665,10 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
 					   subframe);
 					   
 					   }	*/				   
+      // Send the data first so that the DL_CONFIG can just pluck it out of the buffer
+      // DJP - OAI was here - moved to bottom
+      do_oai=1;
+
       break;
     case NFAPI_DL_CONFIG_PCH_PDU_TYPE:
       //      handle_nfapi_pch_pdu(eNB,dl_config_pdu);
@@ -673,6 +689,15 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
     }
   }
   
+#if 1
+  if (do_oai)
+  {
+    oai_nfapi_tx_req(Sched_INFO->TX_req);
+
+    oai_nfapi_dl_config_req(Sched_INFO->DL_req); // DJP - .dl_config_request_body.dl_config_pdu_list[0]); // DJP - FIXME TODO - yuk - only copes with 1 pdu
+  }
+#endif
+
   for (i=0;i<number_hi_dci0_pdu;i++) {
 
     hi_dci0_req_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i];
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index e4be105a5fe994e878de49cf9f9dc38fcd9d2883..63ac501ecccf11fa0ff16563fd00980fb56b7e48 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -135,13 +135,11 @@ void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn,rel
 #endif
 }
 
-void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
+void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
 
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
   int **txdataF = eNB->common_vars.txdataF;
   uint8_t *pbch_pdu=&eNB->pbch_pdu[0];
-  int subframe = proc->subframe_tx;
-  int frame = proc->frame_tx;
 
   LOG_D(PHY,"common_signal_procedures: frame %d, subframe %d\n",frame,subframe); 
 
@@ -420,7 +418,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   }
   else {
     // this is not a pmch subframe, so generate PSS/SSS/PBCH
-    common_signal_procedures(eNB,proc);
+    common_signal_procedures(eNB,proc->frame_tx, proc->subframe_tx);
   }
 
   // clear existing ulsch dci allocations before applying info from MAC  (this is table
@@ -1914,10 +1912,20 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
   // Call SRS first since all others depend on presence of SRS or lack thereof
   srs_procedures(eNB,proc);
 
+  {
+    static int first_time=1;
+    if (first_time)
+    {
+      LOG_E(PHY,"%s() DJP - removed lte_eNB_I0_measurements because it core dumps - no idea why!!!\n\n\n\n\n", __FUNCTION__);
+      first_time=0;
+    }
+  }
+#if 0
   lte_eNB_I0_measurements(eNB,
 			  subframe,
 			  0,
 			  eNB->first_run_I0_measurements);
+#endif
   eNB->first_run_I0_measurements = 0;
 
   uci_procedures(eNB,proc);
diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c
index 19adae31b880116b8a1dfdc8c03bccddf935d201..ca480adb28c8bf15d00b67f737aba3d4dcba5af2 100644
--- a/openair1/SCHED/ru_procedures.c
+++ b/openair1/SCHED/ru_procedures.c
@@ -146,7 +146,7 @@ void feptx_ofdm(RU_t *ru) {
 	}
 	txdata = (int16_t*)&ru->common.txdata[aa][0];
 	for (j=0; i<(len<<1); i++,j++) {
-	  txdata[j++] = ((int16_t*)dummy_tx_b)[i];
+          txdata[j++] = ((int16_t*)dummy_tx_b)[i];
 	}
       }
       else {
@@ -205,6 +205,14 @@ void feptx_prec(RU_t *ru) {
     eNB = eNB_list[0];
     fp  = &eNB->frame_parms;
     
+    if (0) LOG_E(PHY,"%s() run->nb_tx:%u subframe:%u fp->symbols_per_tti:%u fp->ofdm_symbol_size:%u symbols:(%d, %d), (%d,%d)\n", 
+    __FUNCTION__, ru->nb_tx, subframe, fp->symbols_per_tti, fp->ofdm_symbol_size,
+    ((short*)&eNB->common_vars.txdataF[0][1])[0],
+    ((short*)&eNB->common_vars.txdataF[0][1])[1],
+    ((short*)&eNB->common_vars.txdataF[0][2])[0],
+    ((short*)&eNB->common_vars.txdataF[0][2])[1]
+    );
+
     for (aa=0;aa<ru->nb_tx;aa++)
       memcpy((void*)ru->common.txdataF_BF[aa],
 	     (void*)&eNB->common_vars.txdataF[aa][subframe*fp->symbols_per_tti*fp->ofdm_symbol_size],
@@ -409,4 +417,3 @@ void do_prach_ru(RU_t *ru) {
   }
 
 }
-
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index e26cf54a1ccced682d2d074fd9d994c7e8d9b85d..3c3f10a510b45186db14f0b3f975bd818413612e 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -53,7 +53,9 @@
 #include "LAYER2/MAC/extern.h"
 #include "PHY/extern.h"
 #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
-#include "enb_paramdef.h"
+#include "nfapi_vnf.h"
+#include "nfapi_pnf.h"
+
 /* those macros are here to help diagnose problems in configuration files
  * if the lookup fails, a warning is printed
  * (yes we can use the function name for the macro itself, the C preprocessor
@@ -75,6 +77,276 @@
   (config_setting_lookup_string(setting, name, value) ||		\
    (printf("WARNING: setting '%s' not found in configuration file\n", name), 0))
 
+#define ENB_CONFIG_STRING_ACTIVE_ENBS                   "Active_eNBs"
+
+#define ENB_CONFIG_STRING_ENB_LIST                      "eNBs"
+#define ENB_CONFIG_STRING_ENB_ID                        "eNB_ID"
+#define ENB_CONFIG_STRING_CELL_TYPE                     "cell_type"
+#define ENB_CONFIG_STRING_ENB_NAME                      "eNB_name"
+
+#define ENB_CONFIG_STRING_TRACKING_AREA_CODE            "tracking_area_code"
+#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE           "mobile_country_code"
+#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE           "mobile_network_code"
+
+#define ENB_CONFIG_STRING_LOCAL_S_IF_NAME               "local_s_if_name"
+#define ENB_CONFIG_STRING_LOCAL_S_ADDRESS               "local_s_address"
+#define ENB_CONFIG_STRING_REMOTE_S_ADDRESS              "remote_s_address"
+#define ENB_CONFIG_STRING_LOCAL_S_PORTC                 "local_s_portc"
+#define ENB_CONFIG_STRING_REMOTE_S_PORTC                "remote_s_portc"
+#define ENB_CONFIG_STRING_LOCAL_S_PORTD                 "local_s_portd"
+#define ENB_CONFIG_STRING_REMOTE_S_PORTD                "remote_s_portd"
+#define ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE        "tr_s_preference"
+
+
+#define ENB_CONFIG_STRING_COMPONENT_CARRIERS                            "component_carriers"
+
+#define ENB_CONFIG_STRING_CC_NODE_FUNCTION                              "node_function"
+#define ENB_CONFIG_STRING_CC_NODE_TIMING                                "node_timing"   
+#define ENB_CONFIG_STRING_CC_NODE_SYNCH_REF                             "node_synch_ref"   
+
+#define ENB_CONFIG_STRING_FRAME_TYPE                                    "frame_type"
+#define ENB_CONFIG_STRING_TDD_CONFIG                                    "tdd_config"
+#define ENB_CONFIG_STRING_TDD_CONFIG_S                                  "tdd_config_s"
+#define ENB_CONFIG_STRING_PREFIX_TYPE                                   "prefix_type"
+#define ENB_CONFIG_STRING_PBCH_REPETITION                               "pbch_repetition"
+#define ENB_CONFIG_STRING_EUTRA_BAND                                    "eutra_band"
+#define ENB_CONFIG_STRING_DOWNLINK_FREQUENCY                            "downlink_frequency"
+#define ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET                       "uplink_frequency_offset"
+
+#define ENB_CONFIG_STRING_NID_CELL                                      "Nid_cell"
+#define ENB_CONFIG_STRING_N_RB_DL                                       "N_RB_DL"
+#define ENB_CONFIG_STRING_CELL_MBSFN                                  "Nid_cell_mbsfn"
+#define ENB_CONFIG_STRING_NB_ANT_PORTS                              "nb_antenna_ports"
+#define ENB_CONFIG_STRING_NB_ANT_TX                                 "nb_antennas_tx"
+#define ENB_CONFIG_STRING_NB_ANT_RX                                 "nb_antennas_rx"
+#define ENB_CONFIG_STRING_TX_GAIN                                       "tx_gain"
+#define ENB_CONFIG_STRING_RX_GAIN                                       "rx_gain"
+#define ENB_CONFIG_STRING_PRACH_ROOT                                  "prach_root"
+#define ENB_CONFIG_STRING_PRACH_CONFIG_INDEX                          "prach_config_index"
+#define ENB_CONFIG_STRING_PRACH_HIGH_SPEED                          "prach_high_speed"
+#define ENB_CONFIG_STRING_PRACH_ZERO_CORRELATION                  "prach_zero_correlation"
+#define ENB_CONFIG_STRING_PRACH_FREQ_OFFSET                         "prach_freq_offset"
+#define ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT                         "pucch_delta_shift"
+#define ENB_CONFIG_STRING_PUCCH_NRB_CQI                                 "pucch_nRB_CQI"
+#define ENB_CONFIG_STRING_PUCCH_NCS_AN                                  "pucch_nCS_AN"
+#if !defined(Rel10) && !defined(Rel14)
+#define ENB_CONFIG_STRING_PUCCH_N1_AN                                 "pucch_n1_AN"
+#endif
+#define ENB_CONFIG_STRING_PDSCH_RS_EPRE                                 "pdsch_referenceSignalPower"
+#define ENB_CONFIG_STRING_PDSCH_PB                                  "pdsch_p_b"
+#define ENB_CONFIG_STRING_PUSCH_N_SB                                  "pusch_n_SB"
+#define ENB_CONFIG_STRING_PUSCH_HOPPINGMODE                             "pusch_hoppingMode"
+#define ENB_CONFIG_STRING_PUSCH_HOPPINGOFFSET                           "pusch_hoppingOffset"
+#define ENB_CONFIG_STRING_PUSCH_ENABLE64QAM                         "pusch_enable64QAM"
+#define ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN                  "pusch_groupHoppingEnabled"
+#define ENB_CONFIG_STRING_PUSCH_GROUP_ASSIGNMENT                  "pusch_groupAssignment"
+#define ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN                 "pusch_sequenceHoppingEnabled"
+#define ENB_CONFIG_STRING_PUSCH_NDMRS1                                  "pusch_nDMRS1"
+#define ENB_CONFIG_STRING_PHICH_DURATION                          "phich_duration"
+#define ENB_CONFIG_STRING_PHICH_RESOURCE                          "phich_resource"
+#define ENB_CONFIG_STRING_SRS_ENABLE                                  "srs_enable"
+#define ENB_CONFIG_STRING_SRS_BANDWIDTH_CONFIG                          "srs_BandwidthConfig"
+#define ENB_CONFIG_STRING_SRS_SUBFRAME_CONFIG                         "srs_SubframeConfig"
+#define ENB_CONFIG_STRING_SRS_ACKNACKST_CONFIG                          "srs_ackNackST"
+#define ENB_CONFIG_STRING_SRS_MAXUPPTS                                  "srs_MaxUpPts"
+#define ENB_CONFIG_STRING_PUSCH_PO_NOMINAL                          "pusch_p0_Nominal"
+#define ENB_CONFIG_STRING_PUSCH_ALPHA                                 "pusch_alpha"
+#define ENB_CONFIG_STRING_PUCCH_PO_NOMINAL                          "pucch_p0_Nominal"
+#define ENB_CONFIG_STRING_MSG3_DELTA_PREAMBLE                         "msg3_delta_Preamble"
+#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1                          "pucch_deltaF_Format1"
+#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1b                         "pucch_deltaF_Format1b"
+#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2                          "pucch_deltaF_Format2"
+#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2A                         "pucch_deltaF_Format2a"
+#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2B                         "pucch_deltaF_Format2b"
+#define ENB_CONFIG_STRING_RACH_NUM_RA_PREAMBLES                         "rach_numberOfRA_Preambles"
+#define ENB_CONFIG_STRING_RACH_PREAMBLESGROUPACONFIG                  "rach_preamblesGroupAConfig"
+#define ENB_CONFIG_STRING_RACH_SIZEOFRA_PREAMBLESGROUPA                 "rach_sizeOfRA_PreamblesGroupA"
+#define ENB_CONFIG_STRING_RACH_MESSAGESIZEGROUPA                        "rach_messageSizeGroupA"
+#define ENB_CONFIG_STRING_RACH_MESSAGEPOWEROFFSETGROUPB                 "rach_messagePowerOffsetGroupB"
+#define ENB_CONFIG_STRING_RACH_POWERRAMPINGSTEP                         "rach_powerRampingStep"
+#define ENB_CONFIG_STRING_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER "rach_preambleInitialReceivedTargetPower"
+#define ENB_CONFIG_STRING_RACH_PREAMBLETRANSMAX                         "rach_preambleTransMax"
+#define ENB_CONFIG_STRING_RACH_RARESPONSEWINDOWSIZE                 "rach_raResponseWindowSize"
+#define ENB_CONFIG_STRING_RACH_MACCONTENTIONRESOLUTIONTIMER         "rach_macContentionResolutionTimer"
+#define ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX                          "rach_maxHARQ_Msg3Tx"
+#define ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE                     "pcch_default_PagingCycle"
+#define ENB_CONFIG_STRING_PCCH_NB                                       "pcch_nB"
+#define ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF                  "bcch_modificationPeriodCoeff"
+#define ENB_CONFIG_STRING_UETIMERS_T300                                 "ue_TimersAndConstants_t300"
+#define ENB_CONFIG_STRING_UETIMERS_T301                                 "ue_TimersAndConstants_t301"
+#define ENB_CONFIG_STRING_UETIMERS_T310                                 "ue_TimersAndConstants_t310"
+#define ENB_CONFIG_STRING_UETIMERS_T311                                 "ue_TimersAndConstants_t311"
+#define ENB_CONFIG_STRING_UETIMERS_N310                                 "ue_TimersAndConstants_n310"
+#define ENB_CONFIG_STRING_UETIMERS_N311                                 "ue_TimersAndConstants_n311"
+#define ENB_CONFIG_STRING_UE_TRANSMISSION_MODE                          "ue_TransmissionMode"
+
+#define ENB_CONFIG_STRING_SRB1                                          "srb1_parameters"
+#define ENB_CONFIG_STRING_SRB1_TIMER_POLL_RETRANSMIT                    "timer_poll_retransmit"
+#define ENB_CONFIG_STRING_SRB1_TIMER_REORDERING                         "timer_reordering"
+#define ENB_CONFIG_STRING_SRB1_TIMER_STATUS_PROHIBIT                    "timer_status_prohibit"
+#define ENB_CONFIG_STRING_SRB1_POLL_PDU                                 "poll_pdu"
+#define ENB_CONFIG_STRING_SRB1_POLL_BYTE                                "poll_byte"
+#define ENB_CONFIG_STRING_SRB1_MAX_RETX_THRESHOLD                       "max_retx_threshold"
+#define ENB_CONFIG_STRING_MME_IP_ADDRESS                "mme_ip_address"
+#define ENB_CONFIG_STRING_MME_IPV4_ADDRESS              "ipv4"
+#define ENB_CONFIG_STRING_MME_IPV6_ADDRESS              "ipv6"
+#define ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE         "active"
+#define ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE     "preference"
+
+#define ENB_CONFIG_STRING_SCTP_CONFIG                    "SCTP"
+#define ENB_CONFIG_STRING_SCTP_INSTREAMS                 "SCTP_INSTREAMS"
+#define ENB_CONFIG_STRING_SCTP_OUTSTREAMS                "SCTP_OUTSTREAMS"
+
+#define ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG     "NETWORK_INTERFACES"
+#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME "ENB_INTERFACE_NAME_FOR_S1_MME"
+#define ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME   "ENB_IPV4_ADDRESS_FOR_S1_MME"
+#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U    "ENB_INTERFACE_NAME_FOR_S1U"
+#define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U         "ENB_IPV4_ADDRESS_FOR_S1U"
+#define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U              "ENB_PORT_FOR_S1U"
+
+#define ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG     "NETWORK_CONTROLLER"
+#define ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME      "FLEXRAN_AGENT_INTERFACE_NAME"
+#define ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS        "FLEXRAN_AGENT_IPV4_ADDRESS"
+#define ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT                "FLEXRAN_AGENT_PORT"
+#define ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE               "FLEXRAN_AGENT_CACHE"
+
+
+
+
+#define ENB_CONFIG_STRING_ASN1_VERBOSITY                   "Asn1_verbosity"
+#define ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE              "none"
+#define ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING          "annoying"
+#define ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO              "info"
+
+// OTG config per ENB-UE DL
+#define ENB_CONF_STRING_OTG_CONFIG                         "otg_config"
+#define ENB_CONF_STRING_OTG_UE_ID                          "ue_id"
+#define ENB_CONF_STRING_OTG_APP_TYPE                       "app_type"
+#define ENB_CONF_STRING_OTG_BG_TRAFFIC                     "bg_traffic"
+
+// per eNB configuration
+#define ENB_CONFIG_STRING_LOG_CONFIG                       "log_config"
+#define ENB_CONFIG_STRING_GLOBAL_LOG_LEVEL                 "global_log_level"
+#define ENB_CONFIG_STRING_GLOBAL_LOG_VERBOSITY             "global_log_verbosity"
+#define ENB_CONFIG_STRING_HW_LOG_LEVEL                     "hw_log_level"
+#define ENB_CONFIG_STRING_HW_LOG_VERBOSITY                 "hw_log_verbosity"
+#define ENB_CONFIG_STRING_PHY_LOG_LEVEL                    "phy_log_level"
+#define ENB_CONFIG_STRING_PHY_LOG_VERBOSITY                "phy_log_verbosity"
+#define ENB_CONFIG_STRING_MAC_LOG_LEVEL                    "mac_log_level"
+#define ENB_CONFIG_STRING_MAC_LOG_VERBOSITY                "mac_log_verbosity"
+#define ENB_CONFIG_STRING_RLC_LOG_LEVEL                    "rlc_log_level"
+#define ENB_CONFIG_STRING_RLC_LOG_VERBOSITY                "rlc_log_verbosity"
+#define ENB_CONFIG_STRING_PDCP_LOG_LEVEL                   "pdcp_log_level"
+#define ENB_CONFIG_STRING_PDCP_LOG_VERBOSITY               "pdcp_log_verbosity"
+#define ENB_CONFIG_STRING_RRC_LOG_LEVEL                    "rrc_log_level"
+#define ENB_CONFIG_STRING_RRC_LOG_VERBOSITY                "rrc_log_verbosity"
+#define ENB_CONFIG_STRING_GTPU_LOG_LEVEL                   "gtpu_log_level"
+#define ENB_CONFIG_STRING_GTPU_LOG_VERBOSITY               "gtpu_log_verbosity"
+#define ENB_CONFIG_STRING_UDP_LOG_LEVEL                    "udp_log_level"
+#define ENB_CONFIG_STRING_UDP_LOG_VERBOSITY                "udp_log_verbosity"
+#define ENB_CONFIG_STRING_OSA_LOG_LEVEL                    "osa_log_level"
+#define ENB_CONFIG_STRING_OSA_LOG_VERBOSITY                "osa_log_verbosity"
+
+#define CONFIG_STRING_MACRLC_LIST                          "MACRLCs"
+#define CONFIG_STRING_MACRLC_CONFIG                        "macrlc_config"
+#define CONFIG_STRING_MACRLC_CC                            "num_cc"
+#define CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME               "local_n_if_name"
+#define CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS               "local_n_address"
+#define CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS              "remote_n_address"
+#define CONFIG_STRING_MACRLC_LOCAL_N_PORTC                 "local_n_portc"
+#define CONFIG_STRING_MACRLC_REMOTE_N_PORTC                "remote_n_portc"
+#define CONFIG_STRING_MACRLC_LOCAL_N_PORTD                 "local_n_portd"
+#define CONFIG_STRING_MACRLC_REMOTE_N_PORTD                "remote_n_portd"
+#define CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME               "local_s_if_name"
+#define CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS               "local_s_address"
+#define CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS              "remote_s_address"
+#define CONFIG_STRING_MACRLC_LOCAL_S_PORTC                 "local_s_portc"
+#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC                "remote_s_portc"
+#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD                 "local_s_portd"
+#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD                "remote_s_portd"
+#define CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE        "tr_s_preference"
+#define CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE        "tr_n_preference"
+
+#define CONFIG_STRING_L1_LIST                              "L1s"
+#define CONFIG_STRING_L1_CONFIG                            "l1_config"
+#define CONFIG_STRING_L1_CC                                "num_cc"
+#define CONFIG_STRING_L1_LOCAL_N_IF_NAME                   "local_n_if_name"
+#define CONFIG_STRING_L1_LOCAL_N_ADDRESS                   "local_n_address"
+#define CONFIG_STRING_L1_REMOTE_N_ADDRESS                  "remote_n_address"
+#define CONFIG_STRING_L1_LOCAL_N_PORTC                     "local_n_portc"
+#define CONFIG_STRING_L1_REMOTE_N_PORTC                    "remote_n_portc"
+#define CONFIG_STRING_L1_LOCAL_N_PORTD                     "local_n_portd"
+#define CONFIG_STRING_L1_REMOTE_N_PORTD                    "remote_n_portd"
+#define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE            "tr_n_preference"
+
+#define CONFIG_STRING_ACTIVE_RUS                  "Active_RUs"
+#define CONFIG_STRING_RU_LIST                     "RUs"
+#define CONFIG_STRING_RU_CONFIG                   "ru_config"
+#define CONFIG_STRING_RU_LOCAL_IF_NAME            "local_if_name"
+#define CONFIG_STRING_RU_LOCAL_ADDRESS            "local_address"
+#define CONFIG_STRING_RU_REMOTE_ADDRESS           "remote_address"
+#define CONFIG_STRING_RU_LOCAL_PORTC              "local_portc"
+#define CONFIG_STRING_RU_REMOTE_PORTC             "remote_portc"
+#define CONFIG_STRING_RU_LOCAL_PORTD              "local_portd"
+#define CONFIG_STRING_RU_REMOTE_PORTD             "remote_portd"
+#define CONFIG_STRING_RU_LOCAL_RF                 "local_rf"
+#define CONFIG_STRING_RU_TRANSPORT_PREFERENCE     "tr_preference"
+#define CONFIG_STRING_RU_BAND_LIST                "bands"
+#define CONFIG_STRING_RU_ENB_LIST                 "eNB_instances"
+#define CONFIG_STRING_RU_NB_TX                    "nb_tx"
+#define CONFIG_STRING_RU_NB_RX                    "nb_rx"
+#define CONFIG_STRING_RU_ATT_TX                   "att_tx"
+#define CONFIG_STRING_RU_ATT_RX                   "att_rx"
+#define CONFIG_STRING_RU_MAX_RS_EPRE              "max_pdschReferenceSignalPower"
+#define CONFIG_STRING_RU_MAX_RXGAIN               "max_rxgain"
+#define CONFIG_STRING_RU_IF_COMPRESSION           "if_compression"
+
+#define KHz (1000UL)
+#define MHz (1000 * KHz)
+
+typedef struct eutra_band_s {
+  int16_t             band;
+  uint32_t            ul_min;
+  uint32_t            ul_max;
+  uint32_t            dl_min;
+  uint32_t            dl_max;
+  lte_frame_type_t    frame_type;
+} eutra_band_t;
+
+static const eutra_band_t eutra_bands[] = {
+  { 1, 1920    * MHz, 1980    * MHz, 2110    * MHz, 2170    * MHz, FDD},
+  { 2, 1850    * MHz, 1910    * MHz, 1930    * MHz, 1990    * MHz, FDD},
+  { 3, 1710    * MHz, 1785    * MHz, 1805    * MHz, 1880    * MHz, FDD},
+  { 4, 1710    * MHz, 1755    * MHz, 2110    * MHz, 2155    * MHz, FDD},
+  { 5,  824    * MHz,  849    * MHz,  869    * MHz,  894    * MHz, FDD},
+  { 6,  830    * MHz,  840    * MHz,  875    * MHz,  885    * MHz, FDD},
+  { 7, 2500    * MHz, 2570    * MHz, 2620    * MHz, 2690    * MHz, FDD},
+  { 8,  880    * MHz,  915    * MHz,  925    * MHz,  960    * MHz, FDD},
+  { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD},
+  {10, 1710    * MHz, 1770    * MHz, 2110    * MHz, 2170    * MHz, FDD},
+  {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD},
+  {12,  698    * MHz,  716    * MHz,  728    * MHz,  746    * MHz, FDD},
+  {13,  777    * MHz,  787    * MHz,  746    * MHz,  756    * MHz, FDD},
+  {14,  788    * MHz,  798    * MHz,  758    * MHz,  768    * MHz, FDD},
+
+  {17,  704    * MHz,  716    * MHz,  734    * MHz,  746    * MHz, FDD},
+  {20,  832    * MHz,  862    * MHz,  791    * MHz,  821    * MHz, FDD},
+  {33, 1900    * MHz, 1920    * MHz, 1900    * MHz, 1920    * MHz, TDD},
+  {33, 1900    * MHz, 1920    * MHz, 1900    * MHz, 1920    * MHz, TDD},
+  {34, 2010    * MHz, 2025    * MHz, 2010    * MHz, 2025    * MHz, TDD},
+  {35, 1850    * MHz, 1910    * MHz, 1850    * MHz, 1910    * MHz, TDD},
+  {36, 1930    * MHz, 1990    * MHz, 1930    * MHz, 1990    * MHz, TDD},
+  {37, 1910    * MHz, 1930    * MHz, 1910    * MHz, 1930    * MHz, TDD},
+  {38, 2570    * MHz, 2620    * MHz, 2570    * MHz, 2630    * MHz, TDD},
+  {39, 1880    * MHz, 1920    * MHz, 1880    * MHz, 1920    * MHz, TDD},
+  {40, 2300    * MHz, 2400    * MHz, 2300    * MHz, 2400    * MHz, TDD},
+  {41, 2496    * MHz, 2690    * MHz, 2496    * MHz, 2690    * MHz, TDD},
+  {42, 3400    * MHz, 3600    * MHz, 3400    * MHz, 3600    * MHz, TDD},
+  {43, 3600    * MHz, 3800    * MHz, 3600    * MHz, 3800    * MHz, TDD},
+  {44, 703    * MHz, 803    * MHz, 703    * MHz, 803    * MHz, TDD},
+};
+
+
 
 
 static int enb_check_band_frequencies(char* lib_config_file_name_pP,
@@ -117,6 +389,26 @@ static int enb_check_band_frequencies(char* lib_config_file_name_pP,
   return errors;
 }
 
+#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
+extern int asn_debug;
+extern int asn1_xer_print;
+#endif
+
+#ifdef LIBCONFIG_LONG
+#define libconfig_int long
+#else
+#define libconfig_int int
+#endif
+
+typedef enum {
+  RU     = 0,
+  L1     = 1,
+  L2     = 2,
+  L3     = 3,
+  S1     = 4,
+  lastel = 5
+} RC_config_functions_t;
+
 void RCconfig_RU(void);
 void RCconfig_L1(void);
 void RCconfig_macrlc(void);
@@ -140,6 +432,8 @@ int load_config_file(config_t *cfg) {
   }
 
 }
+extern uint8_t  nfapi_pnf;
+
 void RCconfig_RU() {
 
   config_t          cfg;
@@ -206,12 +500,9 @@ void RCconfig_RU() {
               config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_LOCAL_RF,(const char **)&local_rf)
               )
             ) {
-	local_rf_flag = CONFIG_FALSE;
+        local_rf_flag = CONFIG_FALSE;
       }			  
-      else {
-        if (strcmp(local_rf, "no") == 0) 
-	  local_rf_flag = CONFIG_FALSE;
-      }
+      
       if (local_rf_flag == CONFIG_TRUE) { // eNB or RRU
 	
 
@@ -258,27 +549,37 @@ void RCconfig_RU() {
 
       }
 
-      if (RC.nb_L1_inst>0) {
-	AssertFatal((setting_eNB_list = config_setting_get_member(setting_ru, CONFIG_STRING_RU_ENB_LIST))!=NULL,"No RU<->eNB mappings\n");
-      
-	if (setting_eNB_list != NULL) num_eNB4RU    = config_setting_length(setting_eNB_list);
-	else num_eNB4RU=0;
-	AssertFatal(num_eNB4RU>0,"Number of eNBs is zero\n");
-	
-	for (i=0;i<num_eNB4RU;i++) {
-	  setting_eNB_list_elem = config_setting_get_elem(setting_eNB_list,i);
-	  eNB_list[i] = config_setting_get_int(setting_eNB_list_elem);
-	  printf("RU %d: eNB %d\n",j,eNB_list[i]);
-	}
+      if (nfapi_pnf == 1 || nfapi_pnf == 2)
+      {
+        printf("DJP - COMMENTED OUT nb_L1_inst %s:%d\n\n\n\n", __FILE__, __LINE__);
+      }
+      else
+      {
+        printf("Before eNB_list\n");
+        printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst);
+        if (RC.nb_L1_inst>0) {
+          AssertFatal((setting_eNB_list = config_setting_get_member(setting_ru, CONFIG_STRING_RU_ENB_LIST))!=NULL,"No RU<->eNB mappings\n");
+
+          if (setting_eNB_list != NULL) num_eNB4RU    = config_setting_length(setting_eNB_list);
+          else num_eNB4RU=0;
+          AssertFatal(num_eNB4RU>0,"Number of eNBs is zero\n");
+
+          printf("num_eNB4RU:%u\n", num_eNB4RU);
+          for (i=0;i<num_eNB4RU;i++) {
+            setting_eNB_list_elem = config_setting_get_elem(setting_eNB_list,i);
+            eNB_list[i] = config_setting_get_int(setting_eNB_list_elem);
+            printf("RU %d: eNB %d\n",j,eNB_list[i]);
+          }
+        }
       }
 
       config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_ATT_TX, &att_tx);
       config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_ATT_RX, &att_rx);
 
       if ( !(
-	               config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_TX,  &nb_tx)
-		    && config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_RX,  &nb_rx)
-		    )) {
+            config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_TX,  &nb_tx)
+            && config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_RX,  &nb_rx)
+            )) {
 	AssertFatal (0,
 	  "Failed to parse configuration file %s, RU %d config !\n",
 	  RC.config_file_name, j);
@@ -293,7 +594,14 @@ void RCconfig_RU() {
       RC.ru[j]->if_timing                           = synch_to_ext_device;
       RC.ru[j]->num_eNB                             = num_eNB4RU;
 
-      for (i=0;i<num_eNB4RU;i++) RC.ru[j]->eNB_list[i] = RC.eNB[eNB_list[i]][0];
+      printf("RC.ru[%d]->num_eNB:%u\n", j, RC.ru[j]->num_eNB);
+
+      //for (i=0;i<num_eNB4RU;i++) RC.ru[j]->eNB_list[i] = RC.eNB[eNB_list[i]][0];
+      for (i=0;i<num_eNB4RU;i++)
+      {
+        printf("Copying RC.ru[%d]->eNB_list[%d] = RC.eNB[eNB_list[%d][0]\n", j, i, i);
+        RC.ru[j]->eNB_list[i] = RC.eNB[eNB_list[i]][0];
+      }
       
       if (strcmp(local_rf, "yes") == 0) {
 	if (fronthaul_flag == CONFIG_FALSE) {
@@ -336,6 +644,8 @@ void RCconfig_RU() {
 	RC.ru[j]->max_pdschReferenceSignalPower     = max_pdschReferenceSignalPower;
 	RC.ru[j]->max_rxgain                        = max_rxgain;
 	RC.ru[j]->num_bands                         = num_bands;
+	RC.ru[j]->att_tx                         = att_tx; 
+	RC.ru[j]->att_rx                         = att_rx; 
 	for (i=0;i<num_bands;i++) RC.ru[j]->band[i] = band[i]; 
       }
       else {
@@ -398,98 +708,127 @@ void RCconfig_L1() {
   char*             if_name_n                       = NULL;
   char*             ipv4_n                          = NULL;
   char*             ipv4_n_remote                   = NULL;
- 
+
   char*             tr_n_preference                 = NULL;
   libconfig_int     local_n_portc                   = 0;
   libconfig_int     remote_n_portc                  = 0;
   libconfig_int     local_n_portd                   = 0;
   libconfig_int     remote_n_portd                  = 0;
 
+  printf("%s()\n", __FUNCTION__);
+
   load_config_file(&cfg);
 
+  printf("%s() RC.eNB:%p - NEED? malloc it\n", __FUNCTION__, RC.eNB);
+
+  if (RC.eNB == NULL) {
+    RC.eNB                               = (PHY_VARS_eNB ***)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***));
+    LOG_I(PHY,"DJP - have malloced RC.eNB - RC.eNB = %p\n",RC.eNB);
+    memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***));
+    RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int));
+    printf("%s() RC.eNB:%p - RC.nb_L1_CC:%p\n", __FUNCTION__, RC.eNB, RC.nb_L1_CC);
+  }
+
+#if 0
+  if (RC.nb_L1_inst==0)
+  {
+    RC.nb_L1_inst = 1;
+    printf("********\n\n\n*********** DJP - hard coding RC.nb_L1_inst = 1 \n\n\n\n");
+  }
+#endif
+
   setting = config_lookup(&cfg, CONFIG_STRING_L1_LIST);
-  
-  if (setting != NULL) {
 
-    if (RC.eNB == NULL) {
-      RC.eNB                               = (PHY_VARS_eNB ***)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***));
-      LOG_I(PHY,"RC.eNB = %p\n",RC.eNB);
-      memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***));
-      RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int));
+  printf("%s() CONFIG_STRING_L1_LIST setting:%p\n", __FUNCTION__, setting);
+
+  for (j = 0; j < RC.nb_L1_inst; j++) {
+
+    if (RC.eNB[j] == NULL) {
+      RC.eNB[j]                       = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**));
+      LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]);
+      memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***));
     }
 
-    for (j = 0; j < RC.nb_L1_inst; j++) {
+    if (setting != NULL) {
 
       setting_l1 = config_setting_get_elem(setting, j);
       if (!config_setting_lookup_int   (setting_l1,CONFIG_STRING_L1_CC,&RC.nb_L1_CC[j]))
-	AssertFatal (0,
-		     "Failed to parse configuration file %s, L1 %d config !\n",
-		     RC.config_file_name, j);	
-
-      if (RC.eNB[j] == NULL) {
-	RC.eNB[j]                       = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**));
-	LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]);
-	memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***));
-      }
+        AssertFatal (0,
+            "Failed to parse configuration file %s, L1 %d config !\n",
+            RC.config_file_name, j);	
+    }
+    else
+    {
+#if 0
+      RC.nb_L1_CC[j] = 1;
 
+      printf("****DJP - hard coding  nb_L1_CC[%d] = 1 *************\n", j, RC.nb_L1_CC[j]);
+#endif
+    }
 
-      for (i=0;i<RC.nb_L1_CC[j];i++) {
-	if (RC.eNB[j][i] == NULL) {
-	  RC.eNB[j][i] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB));
-	  memset((void*)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB));
-	  LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]);
-	  RC.eNB[j][i]->Mod_id  = j;
-	  RC.eNB[j][i]->CC_id   = i;
-	}
+    for (i=0;i<RC.nb_L1_CC[j];i++) {
+      if (RC.eNB[j][i] == NULL) {
+        RC.eNB[j][i] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB));
+        memset((void*)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB));
+        LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]);
+        RC.eNB[j][i]->Mod_id  = j;
+        RC.eNB[j][i]->CC_id   = i;
       }
+    }
 
+    printf("l1 %d/%d (nb CC %d)\n",j,RC.nb_inst,RC.nb_L1_CC[j]);
 
-      
-      printf("l1 %d/%d (nb CC %d)\n",j,RC.nb_inst,RC.nb_L1_CC[j]);
-      
-
+    if (setting)
+    {
       printf("RU %d: Transport %s\n",j,tr_n_preference);
       if (!(config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE, (const char **)&tr_n_preference))) {
-	  AssertFatal (0,
-		       "Failed to parse configuration file %s, L1 %d config !\n",
-		       RC.config_file_name, j);
+        AssertFatal (0,
+            "Failed to parse configuration file %s, L1 %d config !\n",
+            RC.config_file_name, j);
       }
 
       if (strcmp(tr_n_preference, "local_mac") == 0) {
 
       }
       else if (strcmp(tr_n_preference, "nfapi") == 0) {
-	if (  !(
-		config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_LOCAL_N_IF_NAME,        (const char **)&if_name_n)
-		&& config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_LOCAL_N_ADDRESS,        (const char **)&ipv4_n)
-		&& config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_REMOTE_N_ADDRESS,       (const char **)&ipv4_n_remote)
-		&& config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_LOCAL_N_PORTC,          &local_n_portc)
-		&& config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_REMOTE_N_PORTC,         &remote_n_portc)
-		&& config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_LOCAL_N_PORTD,          &local_n_portd)
-		&& config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_REMOTE_N_PORTD,         &remote_n_portd)
-		)
-	      ) {
-	  AssertFatal (0,
-		       "Failed to parse configuration file %s, L1 %d config !\n",
-		       RC.config_file_name, j);
-	  continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
-	}
-	RC.eNB[j][0]->eth_params_n.local_if_name            = strdup(if_name_n);
-	RC.eNB[j][0]->eth_params_n.my_addr                  = strdup(ipv4_n);
-	RC.eNB[j][0]->eth_params_n.remote_addr              = strdup(ipv4_n_remote);
-	RC.eNB[j][0]->eth_params_n.my_portc                 = local_n_portc;
-	RC.eNB[j][0]->eth_params_n.remote_portc             = remote_n_portc;
-	RC.eNB[j][0]->eth_params_n.my_portd                 = local_n_portd;
-	RC.eNB[j][0]->eth_params_n.remote_portd             = remote_n_portd;
-	RC.eNB[j][0]->eth_params_n.transp_preference          = ETH_UDP_MODE;
+        if (  !(
+              config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_LOCAL_N_IF_NAME,        (const char **)&if_name_n)
+              && config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_LOCAL_N_ADDRESS,        (const char **)&ipv4_n)
+              && config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_REMOTE_N_ADDRESS,       (const char **)&ipv4_n_remote)
+              && config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_LOCAL_N_PORTC,          &local_n_portc)
+              && config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_REMOTE_N_PORTC,         &remote_n_portc)
+              && config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_LOCAL_N_PORTD,          &local_n_portd)
+              && config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_REMOTE_N_PORTD,         &remote_n_portd)
+              )
+           ) {
+          AssertFatal (0,
+              "Failed to parse configuration file %s, L1 %d config !\n",
+              RC.config_file_name, j);
+          continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
+        }
+        RC.eNB[j][0]->eth_params_n.local_if_name            = strdup(if_name_n);
+        RC.eNB[j][0]->eth_params_n.my_addr                  = strdup(ipv4_n);
+        RC.eNB[j][0]->eth_params_n.remote_addr              = strdup(ipv4_n_remote);
+        RC.eNB[j][0]->eth_params_n.my_portc                 = local_n_portc;
+        RC.eNB[j][0]->eth_params_n.remote_portc             = remote_n_portc;
+        RC.eNB[j][0]->eth_params_n.my_portd                 = local_n_portd;
+        RC.eNB[j][0]->eth_params_n.remote_portd             = remote_n_portd;
+        RC.eNB[j][0]->eth_params_n.transp_preference          = ETH_UDP_MODE;
+
+        configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_portd, RC.eNB[j][0]->eth_params_n.remote_portd);
+
+        {
+          extern uint8_t  nfapi_pnf;
+          nfapi_pnf = 1;
+        }
       }
-      
       else { // other midhaul
       }	
-    }// j=0..num_inst
-    printf("Initializing northbound interface for L1\n");
-    l1_north_init_eNB();
-  }
+    } // setting
+  }// j=0..num_inst
+  printf("Initializing northbound interface for L1\n");
+  l1_north_init_eNB();
+
   return;
 }
 
@@ -614,6 +953,18 @@ void RCconfig_macrlc() {
 	RC.mac[j]->eth_params_s.my_portd                 = local_s_portd;
 	RC.mac[j]->eth_params_s.remote_portd             = remote_s_portd;
 	RC.mac[j]->eth_params_s.transp_preference        = ETH_UDP_MODE;
+
+        {
+          extern uint8_t  nfapi_pnf;
+          nfapi_pnf = 2;
+        }
+
+        {
+          printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc);
+          configure_nfapi_vnf(RC.mac[j]->eth_params_s.my_addr, RC.mac[j]->eth_params_s.my_portc);
+          printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc);
+
+        }
       }
       
       else { // other midhaul
@@ -2807,6 +3158,7 @@ void RCConfig(const char *config_file_name) {
     // Get num RU instances
     setting = config_lookup(&cfg, CONFIG_STRING_RU_LIST);
     if (setting != NULL) RC.nb_RU     = config_setting_length(setting); 
+    printf("RC.nb_RU may have been set to:%d setting:%p\n", RC.nb_RU, setting);
   }
   else {
     config_destroy(&cfg);
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 7913f1a60285396225fa82f80f4de3d6b62fab57..4137fe5f4c7c0a54718a0dd399eb1039ca7d677e 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -57,6 +57,9 @@
 #endif
 
 extern RAN_CONTEXT_t RC;
+extern int l2_init_eNB(void);
+extern int mac_top_init_eNB(void);
+extern void mac_init_cell_params(int Mod_idP,int CC_idP);
 
 /* sec 5.9, 36.321: MAC Reset Procedure */
 void ue_mac_reset(module_id_t module_idP,uint8_t eNB_index)
@@ -217,32 +220,100 @@ void config_mib(int                 Mod_idP,
 		uint32_t            pbch_repetitionP) {
 
   nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP];
+
+  cfg->num_tlv=0;
 		
   cfg->subframe_config.pcfich_power_offset.value   = 6000;  // 0dB
+  cfg->subframe_config.pcfich_power_offset.tl.tag = NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG;
+  cfg->num_tlv++;
+
   cfg->subframe_config.dl_cyclic_prefix_type.value = NcpP;
+  cfg->subframe_config.dl_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG;
+  cfg->num_tlv++;
+
   cfg->subframe_config.ul_cyclic_prefix_type.value = NcpP;
+  cfg->subframe_config.ul_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG;
+  cfg->num_tlv++;
  
-  LOG_I(MAC,"Ncp %d,p_eNB %d\n",NcpP,p_eNBP);
+  cfg->rf_config.dl_channel_bandwidth.value        = to_prb(dl_BandwidthP);
+  cfg->rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG;
+  cfg->num_tlv++;
+LOG_E(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP);
+
+  cfg->rf_config.ul_channel_bandwidth.value        = to_prb(dl_BandwidthP);
+  cfg->rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG;
+  cfg->num_tlv++;
 
-  cfg->rf_config.dl_channel_bandwidth.value        = dl_BandwidthP;
-  cfg->rf_config.ul_channel_bandwidth.value        = dl_BandwidthP;
   cfg->rf_config.tx_antenna_ports.value            = p_eNBP;
+  cfg->rf_config.tx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG;
+  cfg->num_tlv++;
+
   cfg->rf_config.rx_antenna_ports.value            = 2;
+  cfg->rf_config.rx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG;
+  cfg->num_tlv++;
 
   cfg->nfapi_config.earfcn.value                   = to_earfcn(eutra_bandP,dl_CarrierFreqP,bw_table[dl_BandwidthP]/100);
+  cfg->nfapi_config.earfcn.tl.tag = NFAPI_NFAPI_EARFCN_TAG;
+  cfg->num_tlv++;
+
   cfg->nfapi_config.rf_bands.number_rf_bands       = 1;
   cfg->nfapi_config.rf_bands.rf_band[0]            = eutra_bandP;  
+  cfg->nfapi_config.rf_bands.tl.tag = NFAPI_PHY_RF_BANDS_TAG;
+  cfg->num_tlv++;
+
   cfg->phich_config.phich_resource.value           = phich_configP->phich_Resource;
+  cfg->phich_config.phich_resource.tl.tag = NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG;
+  cfg->num_tlv++;
+
   cfg->phich_config.phich_duration.value           = phich_configP->phich_Duration;
+  cfg->phich_config.phich_duration.tl.tag = NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG;
+  cfg->num_tlv++;
+
   cfg->phich_config.phich_power_offset.value       = 6000;  // 0dB
+  cfg->phich_config.phich_power_offset.tl.tag = NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG;
+  cfg->num_tlv++;
 
   cfg->sch_config.primary_synchronization_signal_epre_eprers.value   = 6000; // 0dB
+  cfg->sch_config.primary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG;
+  cfg->num_tlv++;
+
   cfg->sch_config.secondary_synchronization_signal_epre_eprers.value = 6000; // 0dB
+  cfg->sch_config.secondary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG;
+  cfg->num_tlv++;
+
   cfg->sch_config.physical_cell_id.value                             = Nid_cellP;
+  cfg->sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG;
+  cfg->num_tlv++;
 
 #ifdef Rel14
   cfg->emtc_config.pbch_repetitions_enable_r13.value                 = pbch_repetitionP;
+  cfg->emtc_config.pbch_repetitions_enable_r13.tl.tag = NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG;
+  cfg->num_tlv++;
 #endif  
+
+  LOG_I(MAC,
+      "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d"
+#ifdef Rel14
+      " PBCH repetition %d"
+#endif  
+      "\n"
+      ,__FUNCTION__
+      ,cfg->num_tlv
+      ,cfg->rf_config.dl_channel_bandwidth.value
+      ,cfg->rf_config.ul_channel_bandwidth.value
+      ,NcpP,p_eNBP
+      ,cfg->nfapi_config.earfcn.value
+      ,cfg->nfapi_config.rf_bands.rf_band[0]
+      ,cfg->phich_config.phich_resource.value
+      ,cfg->phich_config.phich_duration.value
+      ,cfg->phich_config.phich_power_offset.value
+      ,cfg->sch_config.primary_synchronization_signal_epre_eprers.value
+      ,cfg->sch_config.secondary_synchronization_signal_epre_eprers.value
+      ,cfg->sch_config.physical_cell_id.value
+#ifdef Rel14
+      ,cfg->emtc_config.pbch_repetitions_enable_r13.value
+#endif  
+      );
 }
 
 void config_sib1(int Mod_idP,
@@ -253,11 +324,21 @@ void config_sib1(int Mod_idP,
 
   if (tdd_ConfigP)   { //TDD
     cfg->subframe_config.duplex_mode.value                          = 0;
+    cfg->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG;
+    cfg->num_tlv++;
+
     cfg->tdd_frame_structure_config.subframe_assignment.value       = tdd_ConfigP->subframeAssignment;
+    cfg->tdd_frame_structure_config.subframe_assignment.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG;
+    cfg->num_tlv++;
+
     cfg->tdd_frame_structure_config.special_subframe_patterns.value = tdd_ConfigP->specialSubframePatterns;
+    cfg->tdd_frame_structure_config.special_subframe_patterns.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG;
+    cfg->num_tlv++;
   }
   else { // FDD
     cfg->subframe_config.duplex_mode.value                          = 1;
+    cfg->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG;
+    cfg->num_tlv++;
     // Note no half-duplex here
   }
 
@@ -280,46 +361,117 @@ void config_sib2(int Mod_idP,
   nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP];
 
   cfg->subframe_config.pb.value               = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b;
+  cfg->subframe_config.pb.tl.tag = NFAPI_SUBFRAME_CONFIG_PB_TAG;
+  cfg->num_tlv++;
+
   cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower;
+  cfg->rf_config.reference_signal_power.tl.tag = NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG;
+  cfg->num_tlv++;
+
   cfg->nfapi_config.max_transmit_power.value  = cfg->rf_config.reference_signal_power.value + power_off_dB[cfg->rf_config.dl_channel_bandwidth.value];
+  cfg->nfapi_config.max_transmit_power.tl.tag = NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG;
+  cfg->num_tlv++;
 
   cfg->prach_config.configuration_index.value                 = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
+  cfg->prach_config.configuration_index.tl.tag = NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG;
+  cfg->num_tlv++;
+
   cfg->prach_config.root_sequence_index.value                 = radioResourceConfigCommonP->prach_Config.rootSequenceIndex;
+  cfg->prach_config.root_sequence_index.tl.tag = NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG;
+  cfg->num_tlv++;
+
   cfg->prach_config.zero_correlation_zone_configuration.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig;
+  cfg->prach_config.zero_correlation_zone_configuration.tl.tag = NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG;
+  cfg->num_tlv++;
+
   cfg->prach_config.high_speed_flag.value                     = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.highSpeedFlag;
+  cfg->prach_config.high_speed_flag.tl.tag = NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG;
+  cfg->num_tlv++;
+
   cfg->prach_config.frequency_offset.value                    = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_FreqOffset;
+  cfg->prach_config.frequency_offset.tl.tag = NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG;
+  cfg->num_tlv++;
+
 
   cfg->pusch_config.hopping_mode.value                        = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode;
+  cfg->pusch_config.hopping_mode.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG;
+  cfg->num_tlv++;
+
   cfg->pusch_config.number_of_subbands.value                  = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.n_SB;
+  cfg->pusch_config.number_of_subbands.tl.tag = NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG;
+  cfg->num_tlv++;
+
   cfg->pusch_config.hopping_offset.value                      = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset;
+  cfg->pusch_config.hopping_offset.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG;
+  cfg->num_tlv++;
+
 
 
 		
   cfg->pucch_config.delta_pucch_shift.value                         = radioResourceConfigCommonP->pucch_ConfigCommon.deltaPUCCH_Shift;
+  cfg->pucch_config.delta_pucch_shift.tl.tag = NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG;
+  cfg->num_tlv++;
+
   cfg->pucch_config.n_cqi_rb.value                                  = radioResourceConfigCommonP->pucch_ConfigCommon.nRB_CQI;
+  cfg->pucch_config.n_cqi_rb.tl.tag = NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG;
+  cfg->num_tlv++;
+
   cfg->pucch_config.n_an_cs.value                                   = radioResourceConfigCommonP->pucch_ConfigCommon.nCS_AN;
+  cfg->pucch_config.n_an_cs.tl.tag = NFAPI_PUCCH_CONFIG_N_AN_CS_TAG;
+  cfg->num_tlv++;
+
   cfg->pucch_config.n1_pucch_an.value                               = radioResourceConfigCommonP->pucch_ConfigCommon.n1PUCCH_AN;
+  cfg->pucch_config.n1_pucch_an.tl.tag = NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG;
+  cfg->num_tlv++;
+
 
   if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true)
+  {
     cfg->uplink_reference_signal_config.uplink_rs_hopping.value     = 1;
+  }
   else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true)
+  {
     cfg->uplink_reference_signal_config.uplink_rs_hopping.value     = 2;
+  }
   else // No hopping
+  {
     cfg->uplink_reference_signal_config.uplink_rs_hopping.value     = 0;
+  }
+  cfg->uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG;
+  cfg->num_tlv++;
 
   cfg->uplink_reference_signal_config.group_assignment.value        = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH;
+  cfg->uplink_reference_signal_config.group_assignment.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG;
+  cfg->num_tlv++;
+
   cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift;
+  cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG;
+  cfg->num_tlv++;
+
 
   // how to enable/disable SRS?
   if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) {
     cfg->srs_config.bandwidth_configuration.value                       = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig;
+    cfg->srs_config.bandwidth_configuration.tl.tag = NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG;
+    cfg->num_tlv++;
+
     cfg->srs_config.srs_subframe_configuration.value                    = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig;
+    cfg->srs_config.srs_subframe_configuration.tl.tag = NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG;
+    cfg->num_tlv++;
+
     cfg->srs_config.srs_acknack_srs_simultaneous_transmission.value     = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission;
+    cfg->srs_config.srs_acknack_srs_simultaneous_transmission.tl.tag = NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG;
+    cfg->num_tlv++;
+
 
-    if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts)
+    if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) {
        cfg->srs_config.max_up_pts.value                                 = 1;
-    else
+    }
+    else {
        cfg->srs_config.max_up_pts.value                                 = 0;
+    }
+    cfg->srs_config.max_up_pts.tl.tag = NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG;
+    cfg->num_tlv++;
   }
 
 #ifdef Rel14
@@ -327,59 +479,165 @@ void config_sib2(int Mod_idP,
     AssertFatal(radioResourceConfigCommon_BRP!=NULL,"radioResource rou is missing\n");
     AssertFatal(radioResourceConfigCommon_BRP->ext4!=NULL,"ext4 is missing\n");
     cfg->emtc_config.prach_catm_root_sequence_index.value                 = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex;
+    cfg->emtc_config.prach_catm_root_sequence_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG;
+    cfg->num_tlv++;
+
     cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig;
+    cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG;
+    cfg->num_tlv++;
+
     cfg->emtc_config.prach_catm_high_speed_flag.value                     = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.highSpeedFlag;
+    cfg->emtc_config.prach_catm_high_speed_flag.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG;
+    cfg->num_tlv++;
  
     struct PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; 
 
     PRACH_ParametersListCE_r13_t	 *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
-    int i;
     PRACH_ParametersCE_r13_t *p;
     cfg->emtc_config.prach_ce_level_0_enable.value=0;
+    cfg->emtc_config.prach_ce_level_0_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG;
+    cfg->num_tlv++;
+ 
     cfg->emtc_config.prach_ce_level_1_enable.value=0;
+    cfg->emtc_config.prach_ce_level_1_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG;
+    cfg->num_tlv++;
+ 
     cfg->emtc_config.prach_ce_level_2_enable.value=0;
+    cfg->emtc_config.prach_ce_level_2_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG;
+    cfg->num_tlv++;
+ 
     cfg->emtc_config.prach_ce_level_3_enable.value=0;
+    cfg->emtc_config.prach_ce_level_3_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG;
+    cfg->num_tlv++;
+ 
     switch (prach_ParametersListCE_r13->list.count) {
     case 4:
       p=prach_ParametersListCE_r13->list.array[3];
       cfg->emtc_config.prach_ce_level_3_enable.value                            = 1;
+      cfg->emtc_config.prach_ce_level_3_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG;
+      cfg->num_tlv++;
+
       cfg->emtc_config.prach_ce_level_3_configuration_index.value               = p->prach_ConfigIndex_r13;
+      cfg->emtc_config.prach_ce_level_3_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG;
+      cfg->num_tlv++;
+
       cfg->emtc_config.prach_ce_level_3_frequency_offset.value                  = p->prach_FreqOffset_r13;
+      cfg->emtc_config.prach_ce_level_3_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG;
+      cfg->num_tlv++;
+
       cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13;
-      if (p->prach_StartingSubframe_r13) 
+      cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG;
+      cfg->num_tlv++;
+
+      if (p->prach_StartingSubframe_r13) {
 	cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value   = *p->prach_StartingSubframe_r13;
+	cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag  = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG;
+        cfg->num_tlv++;
+      }
+
       cfg->emtc_config.prach_ce_level_3_hopping_enable.value                    = p->prach_HoppingConfig_r13;
+      cfg->emtc_config.prach_ce_level_3_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG;
+      cfg->num_tlv++;
+
       cfg->emtc_config.prach_ce_level_3_hopping_offset.value                    = cfg->rf_config.ul_channel_bandwidth.value-6;
+      cfg->emtc_config.prach_ce_level_3_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG;
+      cfg->num_tlv++;
+
     case 3:
       p=prach_ParametersListCE_r13->list.array[2];
       cfg->emtc_config.prach_ce_level_2_enable.value                            = 1;
+      cfg->emtc_config.prach_ce_level_2_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG;
+      cfg->num_tlv++;
+
       cfg->emtc_config.prach_ce_level_2_configuration_index.value               = p->prach_ConfigIndex_r13;
+      cfg->emtc_config.prach_ce_level_2_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG;
+      cfg->num_tlv++;
+
       cfg->emtc_config.prach_ce_level_2_frequency_offset.value                  = p->prach_FreqOffset_r13;
+      cfg->emtc_config.prach_ce_level_2_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG;
+      cfg->num_tlv++;
+
       cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13;
-      if (p->prach_StartingSubframe_r13) 
+      cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG;
+      cfg->num_tlv++;
+
+      if (p->prach_StartingSubframe_r13) {
 	cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value   = *p->prach_StartingSubframe_r13;
+	cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag  = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG;
+        cfg->num_tlv++;
+      }
+
       cfg->emtc_config.prach_ce_level_2_hopping_enable.value                    = p->prach_HoppingConfig_r13;
+      cfg->emtc_config.prach_ce_level_2_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG;
+      cfg->num_tlv++;
+
       cfg->emtc_config.prach_ce_level_2_hopping_offset.value                    = cfg->rf_config.ul_channel_bandwidth.value-6;
+      cfg->emtc_config.prach_ce_level_2_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG;
+      cfg->num_tlv++;
+
     case 2:
       p=prach_ParametersListCE_r13->list.array[1];
       cfg->emtc_config.prach_ce_level_1_enable.value                            = 1;
+      cfg->emtc_config.prach_ce_level_1_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG;
+      cfg->num_tlv++;
+
       cfg->emtc_config.prach_ce_level_1_configuration_index.value               = p->prach_ConfigIndex_r13;
+      cfg->emtc_config.prach_ce_level_1_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG;
+      cfg->num_tlv++;
+
       cfg->emtc_config.prach_ce_level_1_frequency_offset.value                  = p->prach_FreqOffset_r13;
+      cfg->emtc_config.prach_ce_level_1_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG;
+      cfg->num_tlv++;
+
       cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13;
-      if (p->prach_StartingSubframe_r13) 
+      cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG;
+      cfg->num_tlv++;
+
+      if (p->prach_StartingSubframe_r13) {
 	cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value   = *p->prach_StartingSubframe_r13;
+	cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag  = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG;
+        cfg->num_tlv++;
+      }
+ 
       cfg->emtc_config.prach_ce_level_1_hopping_enable.value                    = p->prach_HoppingConfig_r13;
+      cfg->emtc_config.prach_ce_level_1_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG;
+      cfg->num_tlv++;
+ 
       cfg->emtc_config.prach_ce_level_1_hopping_offset.value                    = cfg->rf_config.ul_channel_bandwidth.value-6;
+      cfg->emtc_config.prach_ce_level_1_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG;
+      cfg->num_tlv++;
+ 
     case 1:
       p=prach_ParametersListCE_r13->list.array[0];
       cfg->emtc_config.prach_ce_level_0_enable.value                            = 1;
+      cfg->emtc_config.prach_ce_level_0_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG;
+      cfg->num_tlv++;
+ 
       cfg->emtc_config.prach_ce_level_0_configuration_index.value               = p->prach_ConfigIndex_r13;
+      cfg->emtc_config.prach_ce_level_0_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG;
+      cfg->num_tlv++;
+ 
       cfg->emtc_config.prach_ce_level_0_frequency_offset.value                  = p->prach_FreqOffset_r13;
+      cfg->emtc_config.prach_ce_level_0_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG;
+      cfg->num_tlv++;
+ 
       cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value = p->numRepetitionPerPreambleAttempt_r13;
-      if (p->prach_StartingSubframe_r13) 
+      cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG;
+      cfg->num_tlv++;
+ 
+      if (p->prach_StartingSubframe_r13) {
 	cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value   = *p->prach_StartingSubframe_r13;
+	cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag  = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG;
+        cfg->num_tlv++;
+      }
+ 
       cfg->emtc_config.prach_ce_level_0_hopping_enable.value                    = p->prach_HoppingConfig_r13;
+      cfg->emtc_config.prach_ce_level_0_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG;
+      cfg->num_tlv++;
+ 
       cfg->emtc_config.prach_ce_level_0_hopping_offset.value                    = cfg->rf_config.ul_channel_bandwidth.value-6;
+      cfg->emtc_config.prach_ce_level_0_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG;
+      cfg->num_tlv++;
     }
 
     struct FreqHoppingParameters_r13 *ext4_freqHoppingParameters = radioResourceConfigCommonP->ext4->freqHoppingParameters_r13;
@@ -390,9 +648,13 @@ void config_sib2(int Mod_idP,
 	break;
       case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13:
 	cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13;
+	cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG;
+        cfg->num_tlv++;
 	break;
       case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13:
 	cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13;
+	cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG;
+        cfg->num_tlv++;
 	break;
       }
     }
@@ -403,9 +665,13 @@ void config_sib2(int Mod_idP,
 	break;
       case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13:
 	cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13;
+	cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG;
+        cfg->num_tlv++;
 	break;
       case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13:
 	cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13;
+	cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG;
+        cfg->num_tlv++;
 	break;
       }
     }
@@ -582,7 +848,7 @@ int rrc_mac_config_req_eNB(module_id_t                      Mod_idP,
     if (UE_id == -1)
       LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__);
     else
-      UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated=physicalConfigDedicated;
+      config_dedicated(Mod_idP, CC_idP, UE_RNTI(Mod_idP, UE_id), physicalConfigDedicated);
   } 
 
 
@@ -658,20 +924,23 @@ int rrc_mac_config_req_eNB(module_id_t                      Mod_idP,
 
 #endif
 
-  if (radioResourceConfigCommon!=NULL) {
-    AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
-    PHY_Config_t phycfg;
-    phycfg.Mod_id = Mod_idP;
-    phycfg.CC_id  = CC_idP;
-    phycfg.cfg    = &RC.mac[Mod_idP]->config[CC_idP];
-    
-    if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); 
+  while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) {
+    // DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n");
+    usleep(100 * 1000);
+    printf("Waiting for PHY_config_req\n");
   }
+  PHY_Config_t phycfg;
+  phycfg.Mod_id = Mod_idP;
+  phycfg.CC_id  = CC_idP;
+  phycfg.cfg    = &RC.mac[Mod_idP]->config[CC_idP];
+
+  if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); 
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
-  
-  return(0);			     
-}
 
+  return(0);			   
+
+}
 int
 rrc_mac_config_req_ue(
   module_id_t                      Mod_idP,
@@ -710,8 +979,6 @@ rrc_mac_config_req_ue(
 
   int i;
 
-  int UE_id = -1;
- 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN);
 
   LOG_I(MAC,"[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n",Mod_idP,eNB_index);
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
index aec302c36a032d58c04189460a3101789d1ed029..c67a07d09a8407af057ed645289c9e3d1a01a6c5 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
@@ -100,6 +100,7 @@ schedule_SIB1_BR(
   int                            n_NB = 0;
   int                            TBS;
   int                            k=0,rvidx;
+  uint16_t sfn_sf = frameP << 4 | subframeP;
 
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 
@@ -240,10 +241,11 @@ schedule_SIB1_BR(
     // Rel13 fields
     dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type                               = 1; // CEModeA UE
     dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type                    = 0; // SIB1-BR
-    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = 0xFFFF; // absolute SFx
+    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = 0xFFFF; // absolute SF
     
     //	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
     dl_req->number_pdu++;
+    dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
     
     // Program TX Request
     TX_req                                                                = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; 
@@ -252,8 +254,14 @@ schedule_SIB1_BR(
     TX_req->num_segments                                                  = 1;
     TX_req->segments[0].segment_length                                    = bcch_sdu_length;
     TX_req->segments[0].segment_data                                      = cc->BCCH_BR_pdu[0].payload;
+    eNB->TX_req[CC_id].sfn_sf = sfn_sf;
+    eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
     eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
+    eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
     
+    if (frameP%100==0) LOG_E(MAC,"%s() TX_REQ: sfn_sf:%u pdus:%u pdu_length:%u pdu_index:%u segments:%u segment_length:%u\n", 
+        __FUNCTION__, eNB->TX_req[CC_id].sfn_sf, eNB->TX_req[CC_id].tx_request_body.number_of_pdus,
+        TX_req->pdu_length, TX_req->pdu_index, TX_req->num_segments, TX_req->segments[0].segment_length);
     
     
     if (opt_enabled == 1) {
@@ -314,6 +322,7 @@ schedule_SI_BR(
   int                                     i;
   int                                     rvidx;
   int                                     absSF = (frameP*10)+subframeP;
+  uint16_t sfn_sf = frameP << 4 | subframeP;
 
 
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
@@ -400,10 +409,10 @@ schedule_SI_BR(
 	    vrb_map[first_rb+4] = 1;
 	    vrb_map[first_rb+5] = 1;
 
-	    if ((frameP&1023) < 200) LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %d rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %d : si_RepetitionPattern_r13 %d) bcch_sdu_length %d\n",
-					   module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx,
-					   sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13,
-					   bcch_sdu_length);	    
+	    if ((frameP&1023) < 200) LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %ld rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %ld : si_RepetitionPattern_r13 %ld) bcch_sdu_length %d\n",
+					   module_idP,frameP,subframeP,CC_id,si_Narrowband_r13-1,rvidx,
+					   sf_mod_period,si_WindowLength_BR_r13,si_RepetitionPattern_r13,
+					   bcch_sdu_length);
 
 
 
@@ -412,6 +421,7 @@ schedule_SI_BR(
 	    memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
 	    dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; 
 	    dl_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
+	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
 	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length                                 = si_TBS_r13>>3;
 	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index                              = eNB->pdu_index[CC_id];
 	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = 0xFFFF;
@@ -443,6 +453,7 @@ schedule_SI_BR(
 	    
 	    //	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
 	    dl_req->number_pdu++;
+            dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
 	    
 	    // Program TX Request
 	    TX_req                                                                = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; 
@@ -452,7 +463,14 @@ schedule_SI_BR(
 	    TX_req->segments[0].segment_length                                    = bcch_sdu_length;
 	    TX_req->segments[0].segment_data                                      = cc->BCCH_BR_pdu[i+1].payload;
 	    eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
-	    
+            eNB->TX_req[CC_id].sfn_sf = sfn_sf;
+            eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
+            eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
+
+            if (frameP%100==0) LOG_E(MAC,"%s() TX_REQ: sfn_sf:%u pdus:%u pdu_length:%u pdu_index:%u segments:%u segment_length:%u\n", 
+                __FUNCTION__, eNB->TX_req[CC_id].sfn_sf, eNB->TX_req[CC_id].tx_request_body.number_of_pdus,
+                TX_req->pdu_length, TX_req->pdu_index, TX_req->num_segments, TX_req->segments[0].segment_length);
+
 	    if (opt_enabled == 1) {
 	      trace_pdu(1,
 			&cc->BCCH_BR_pdu[i+1].payload[0],
@@ -493,18 +511,22 @@ void schedule_mib(module_id_t   module_idP,
 
   eNB_MAC_INST                   *eNB = RC.mac[module_idP];
   COMMON_channels_t              *cc;
+  nfapi_dl_config_request_t      *dl_config_request;
   nfapi_dl_config_request_pdu_t  *dl_config_pdu;
   nfapi_tx_request_pdu_t         *TX_req;
   int mib_sdu_length;
   int CC_id;
   nfapi_dl_config_request_body_t *dl_req;
+  uint16_t sfn_sf = frameP << 4 | subframeP;
 
-  AssertFatal(subframeP==0,"Subframe must be 0\n");
-  AssertFatal((frameP&3)==0,"Frame must be a multiple of 4\n");
+// DJP - commented out because I am going to try and send MIB every frame
+  //AssertFatal(subframeP==0,"Subframe must be 0\n");
+  //AssertFatal((frameP&3)==0,"Frame must be a multiple of 4\n");
 
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 
-    dl_req          = &eNB->DL_req[CC_id].dl_config_request_body;
+    dl_config_request = &eNB->DL_req[CC_id];
+    dl_req          = &dl_config_request->dl_config_request_body;
     cc              = &eNB->common_channels[CC_id];
 
     mib_sdu_length = mac_rrc_data_req(module_idP,
@@ -516,36 +538,46 @@ void schedule_mib(module_id_t   module_idP,
 				      module_idP,
 				      0); // not used in this case
 
-    LOG_D(MAC,"Frame %d, subframe %d: BCH PDU length %d\n",
+    LOG_E(MAC,"Frame %d, subframe %d: BCH PDU length %d\n",
 	  frameP,subframeP,mib_sdu_length);
 
     if (mib_sdu_length > 0) {
 
-      LOG_D(MAC,"Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n",
-	    frameP,subframeP,dl_req->number_pdu,mib_sdu_length);
+      LOG_D(MAC,"Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", frameP,subframeP,dl_req->number_pdu,mib_sdu_length);
 
-      if ((frameP&1023) < 40) LOG_D(MAC,"[eNB %d] Frame %d : MIB->BCH  CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n",module_idP,frameP,CC_id,mib_sdu_length,(int)cc->mib->message.schedulingInfoSIB1_BR_r13);
+      if ((frameP&1023) < 40) LOG_D(MAC,"[eNB %d] Frame %d : MIB->BCH  CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %ld)\n",module_idP,frameP,CC_id,mib_sdu_length,cc->mib->message.schedulingInfoSIB1_BR_r13);
 
       dl_config_pdu                                                         = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
       memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
-      dl_config_pdu->pdu_type                                               = NFAPI_DL_CONFIG_BCH_PDU_TYPE,
+      dl_config_pdu->pdu_type                                               = NFAPI_DL_CONFIG_BCH_PDU_TYPE;
       dl_config_pdu->pdu_size                                               = 2+sizeof(nfapi_dl_config_bch_pdu);
+      dl_config_pdu->bch_pdu.bch_pdu_rel8.tl.tag                            = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG;
       dl_config_pdu->bch_pdu.bch_pdu_rel8.length                            = mib_sdu_length;
       dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index                         = eNB->pdu_index[CC_id];
       dl_config_pdu->bch_pdu.bch_pdu_rel8.transmission_power                = 6000;
+      dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
       dl_req->number_pdu++;
 
-      LOG_D(MAC,"eNB->DL_req[0].number_pdu %d (%p)\n",
-	    dl_req->number_pdu,&dl_req->number_pdu);
+      dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST;
+      dl_config_request->sfn_sf = sfn_sf;
+
+      //LOG_E(MAC,"eNB->DL_req[0].number_pdu %d (%p) sfn_sf:%d\n", dl_req->number_pdu,&dl_req->number_pdu, NFAPI_SFNSF2DEC(dl_config_request->sfn_sf));
       // DL request
 
       TX_req                                                                = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; 
       TX_req->pdu_length                                                    = 3;
       TX_req->pdu_index                                                     = eNB->pdu_index[CC_id]++;
       TX_req->num_segments                                                  = 1;
-      TX_req->segments[0].segment_length                                    = 0;
+      TX_req->segments[0].segment_length                                    = mib_sdu_length;
       TX_req->segments[0].segment_data                                      = cc[CC_id].MIB_pdu.payload;
       eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
+      eNB->TX_req[CC_id].sfn_sf = sfn_sf;
+      eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
+      eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
+
+      if (frameP%100==0) LOG_E(MAC,"%s() TX_REQ: sfn_sf:%u pdus:%u pdu_length:%u pdu_index:%u segments:%u segment_length:%u\n", 
+          __FUNCTION__, eNB->TX_req[CC_id].sfn_sf, eNB->TX_req[CC_id].tx_request_body.number_of_pdus,
+          TX_req->pdu_length, TX_req->pdu_index, TX_req->num_segments, TX_req->segments[0].segment_length);
     }
   }
 }
@@ -569,9 +601,11 @@ schedule_SI(
   uint8_t                        *vrb_map;
   int                            first_rb = -1;
   int                            N_RB_DL;
+  nfapi_dl_config_request_t      *dl_config_request;
   nfapi_dl_config_request_pdu_t  *dl_config_pdu;
   nfapi_tx_request_pdu_t         *TX_req;
   nfapi_dl_config_request_body_t *dl_req;
+  uint16_t sfn_sf = frameP << 4 | subframeP;
 
   start_meas(&eNB->schedule_si);
   
@@ -583,9 +617,9 @@ schedule_SI(
       cc              = &eNB->common_channels[CC_id];
       vrb_map         = (void*)&cc->vrb_map;
       N_RB_DL         = to_prb(cc->mib->message.dl_Bandwidth); 
+      dl_config_request = &eNB->DL_req[CC_id];
       dl_req          = &eNB->DL_req[CC_id].dl_config_request_body;
       
-      
       bcch_sdu_length = mac_rrc_data_req(module_idP,
 					 CC_id,
 					 frameP,
@@ -596,7 +630,7 @@ schedule_SI(
 					 0); // not used in this case
       
       if (bcch_sdu_length > 0) {
-	LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",module_idP,frameP,CC_id,bcch_sdu_length);
+	LOG_D(MAC,"[eNB %d] Frame %d subframe %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",module_idP,frameP,subframeP,CC_id,bcch_sdu_length);
 	
 	// Allocate 4 PRBs in a random location
 	/*
@@ -654,10 +688,20 @@ schedule_SI(
 	}
 	
 	
+        //dl_req->number_pdcch_ofdm_symbols = &RC.mac[module_idP]->DL_req[CC_id].dl_config_request_body;
+
+
+
+
+
+
+
 	dl_config_pdu                                                         = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
 	memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
 	dl_config_pdu->pdu_type                                               = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; 
-	dl_config_pdu->pdu_size                                               = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
+	dl_config_pdu->pdu_size                                               = (uint8_t)(sizeof(nfapi_dl_config_dci_dl_pdu));
+        dl_req->number_dci++;
+	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag                      = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format                  = NFAPI_DL_DCI_FORMAT_1A;
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level           = 4;
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                        = 0xFFFF;
@@ -671,23 +715,22 @@ schedule_SI(
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1        = 0;
 	
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding       = getRIV(N_RB_DL,first_rb,4);      
-
-	// Rel10 fields
-	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = 3;
-	// Rel13 fields
-	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type                               = 0; // regular UE
-	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type                    = 2; // not BR
-	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = 0xFFFF; // absolute SF	
-
+        dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST;
+        dl_config_request->sfn_sf = sfn_sf;
+	
 	if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,SI_RNTI)) {
-	  LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for S_RNTI\n",
-		frameP,subframeP);
-	  dl_req->number_dci++;
+	  // DJP - dl_req->number_dci++;
 	  dl_req->number_pdu++;
+	  dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+
+	  LOG_E(MAC,"Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", frameP,subframeP);
+
 	  dl_config_pdu                                                                  = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
 	  memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
 	  dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; 
-	  dl_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
+	  dl_config_pdu->pdu_size                                                        = (uint8_t)(sizeof(nfapi_dl_config_dlsch_pdu));
+	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG;
+
 	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index                              = eNB->pdu_index[CC_id];
 	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = 0xFFFF;
 	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2;   // format 1A/1B/1D
@@ -705,13 +748,24 @@ schedule_SI(
 	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa                                     = 4; // 0 dB
 	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index               = 0;
 	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap                                   = 0;
-	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb                                   = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
+	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb                                   = 1; // DJP - wireshark whinges - get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
 	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode                      = (cc->p_eNB==1 ) ? 1 : 2;
-	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband                 = 1;
-	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector                          = 1;
+	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband                 = 0; // DJP 
+	  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector                          = 0; // DJP 
 	  //	dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
-	  dl_req->number_pdu++;
+          dl_req->number_pdu++;
+          dl_config_request->header.message_id = NFAPI_DL_CONFIG_REQUEST;
+          dl_config_request->sfn_sf = sfn_sf;
 	  
+	  //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel9.tl.tag                                 = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG;
+	  //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel9.nscid = 0;
+
+	  //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG;
+
+	  //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel11.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG;
+	  //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel12.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG;
+	  //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag                                = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG;
+
 	  // Program TX Request
 	  TX_req                                                                = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; 
 	  TX_req->pdu_length                                                    = bcch_sdu_length;
@@ -720,7 +774,13 @@ schedule_SI(
 	  TX_req->segments[0].segment_length                                    = bcch_sdu_length;
 	  TX_req->segments[0].segment_data                                      = cc->BCCH_pdu.payload;
 	  eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
+          eNB->TX_req[CC_id].sfn_sf = sfn_sf;
+          eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
+          eNB->TX_req[CC_id].header.message_id = NFAPI_TX_REQUEST;
 	  
+	  if (frameP%100==0) LOG_E(MAC,"%s() TX_REQ: sfn_sf:%u pdus:%u pdu_length:%u pdu_index:%u segments:%u segment_length:%u\n", 
+              __FUNCTION__, eNB->TX_req[CC_id].sfn_sf, eNB->TX_req[CC_id].tx_request_body.number_of_pdus,
+              TX_req->pdu_length, TX_req->pdu_index, TX_req->num_segments, TX_req->segments[0].segment_length);
 	}
 	else {
 	  LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A for SI\n",module_idP, CC_id,frameP,subframeP);
@@ -772,6 +832,4 @@ schedule_SI(
 #endif
 
   stop_meas(&eNB->schedule_si);
-  return;
 }
- 
diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c
index ae4b52222d59daa436b61eedd5795a2ac13527e7..5d668ff3041f42e1132809b4aebd40a21a4648db 100644
--- a/openair2/LAYER2/MAC/main.c
+++ b/openair2/LAYER2/MAC/main.c
@@ -61,7 +61,7 @@ void dl_phy_sync_success(module_id_t   module_idP,
 #endif
 
   if (first_sync==1 && !(mme_enabled==1)) {
-    layer2_init_UE(module_idP);
+    //DJP layer2_init_UE(module_idP);
     openair_rrc_ue_init(module_idP,eNB_index);
   } else
   {
@@ -148,7 +148,7 @@ int mac_top_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
 }
 
 
-int mac_top_init_eNB()
+int mac_top_init_eNB(void)
 {
 
   module_id_t    Mod_id,i,j;
@@ -379,7 +379,7 @@ int l2_init_ue(int eMBMS_active, char *uecap_xer,uint8_t cba_group_active, uint8
   return(1);
 }
 
-int l2_init_eNB()
+int l2_init_eNB(void)
 {
 
 
diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c
index b05e983c30f99dfb2d76d1a2ddcdc63fe8053605..a7e4439e458106536df1822847fac89c15ff9b50 100644
--- a/openair2/PHY_INTERFACE/IF_Module.c
+++ b/openair2/PHY_INTERFACE/IF_Module.c
@@ -207,7 +207,7 @@ void UL_indication(UL_IND_t *UL_info)
 
     sched_info->TX_req      = &mac->TX_req[CC_id];
     AssertFatal(ifi->schedule_response!=NULL,
-		"UL_indication is null (mod %d, cc %d)\n",
+		"schedule_response is null (mod %d, cc %d)\n",
 		module_id,
 		CC_id);
     ifi->schedule_response(sched_info);
diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c
index 5c9d06f98630effb5175fd414decdd1c5953d20f..45b3822cd936687a7a02520cab1dc13d9c29e8ea 100644
--- a/openair2/RRC/LITE/rrc_common.c
+++ b/openair2/RRC/LITE/rrc_common.c
@@ -65,7 +65,7 @@ openair_rrc_on(
   int            CC_id;
 
   if (ctxt_pP->enb_flag == ENB_FLAG_YES) {
-    LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" OPENAIR RRC IN....\n",
+    LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" ENB:OPENAIR RRC IN....\n",
           PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
     for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
       rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI, BCCH, 1);
@@ -74,7 +74,7 @@ openair_rrc_on(
       RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Active = 1;
     }
   } else {
-    LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" OPENAIR RRC IN....\n",
+    LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" UE?:OPENAIR RRC IN....\n",
           PROTOCOL_RRC_CTXT_ARGS(ctxt_pP));
 
     for (i = 0; i < NB_eNB_INST; i++) {
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index a8769c2690cd1c5e8a76c751bc927fe6b3f14538..85b12c431e94987240586f9f830534b191f274d7 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -147,7 +147,7 @@ init_SI(
 #ifdef Rel14
   RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition = configuration->pbch_repetition[CC_id];
 #endif
-  LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", 
+  LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %ld,phich_Duration %ld)\n", 
 	configuration->N_RB_DL[CC_id],
 	configuration->phich_resource[CC_id],
 	configuration->phich_duration[CC_id]);
@@ -282,6 +282,8 @@ init_SI(
   }
 #endif
 
+  LOG_I(RRC, "About to call rrc_mac_config_req_eNB");
+
   rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id,
 			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId,
 			 RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB,
diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c
index b63eef9c7e6bd8764e1df05abfe38e2618175cf8..94b9d02016ebd1ab2ce42d79d168413f78ccc36d 100644
--- a/openair3/UDP/udp_eNB_task.c
+++ b/openair3/UDP/udp_eNB_task.c
@@ -99,7 +99,7 @@ void udp_eNB_receiver(struct udp_socket_desc_s *udp_sock_pP);
 
 void *udp_eNB_task(void *args_p);
 
-int udp_enb_init();
+int udp_enb_init(void);
 /* @brief Retrieve the descriptor associated with the task_id
  */
 static
@@ -427,7 +427,7 @@ on_error:
   return NULL;
 }
 
-int udp_enb_init()
+int udp_enb_init(void)
 {
   LOG_I(UDP_, "Initializing UDP task interface\n");
   STAILQ_INIT(&udp_socket_list);
diff --git a/openair3/UDP/udp_eNB_task.h b/openair3/UDP/udp_eNB_task.h
index 0f6461dda7f03c58e997c5a7f3ecac979a46c54d..2265a7a8b83bca6a71c549d8970ae7765c3aefa1 100644
--- a/openair3/UDP/udp_eNB_task.h
+++ b/openair3/UDP/udp_eNB_task.h
@@ -93,6 +93,6 @@ void *udp_eNB_task(void *args_p);
  *  \param enb_config_p configuration of eNB
  *  @returns always 0
  */
-int udp_enb_init();
+int udp_enb_init(void);
 
 #endif /* UDP_ENB_TASK_H_ */
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index 177a6455d3d9fea73ae3cd1324a2e76f54a428a2..de2ad05fae07d603ecc8bee0ed2370f58ce54f4c 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -138,10 +138,10 @@ static void trx_usrp_end(openair0_device *device) {
 
 /*! \brief Called to send samples to the USRP RF target
       @param device pointer to the device structure specific to the RF hardware target
-      @param timestamp The timestamp at whicch the first sample MUST be sent
+      @param timestamp The timestamp at which the first sample MUST be sent
       @param buff Buffer which holds the samples
       @param nsamps number of samples to be sent
-      @param antenna_id index of the antenna if the device has multiple anteannas
+      @param antenna_id index of the antenna if the device has multiple antennas
       @param flags flags must be set to TRUE if timestamp parameter needs to be applied
 */
 static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
@@ -515,6 +515,8 @@ extern "C" {
 
             openair0_cfg[0].rx_gain_calib_table = calib_table_x310;
 
+            LOG_I(PHY,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate);
+
             switch ((int)openair0_cfg[0].sample_rate) {
             case 30720000:
                 // from usrp_time_offset
@@ -648,6 +650,8 @@ extern "C" {
                 s->usrp->set_tx_rate(openair0_cfg[0].sample_rate,i);
                 s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i);
                 s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[i],i);
+
+                LOG_I(PHY,"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf\n", gain_range_tx.stop()-openair0_cfg[0].tx_gain[i], gain_range_tx.stop(), openair0_cfg[0].tx_gain[i]);
             }
         }
 
diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c
index ef3124ff248b3878886b2111179691cf2268fd2f..b3533d94bae63249c4db2998b88bfe7af9ab32d6 100644
--- a/targets/COMMON/create_tasks.c
+++ b/targets/COMMON/create_tasks.c
@@ -42,6 +42,8 @@
 
 int create_tasks(uint32_t enb_nb, uint32_t ue_nb)
 {
+  LOG_E(ENB_APP, "%s(enb_nb:%d ue_nb:%d)\n", __FUNCTION__, enb_nb, ue_nb);
+
   itti_wait_ready(1);
   if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
     LOG_E(PDCP, "Create task for L2L1 failed\n");
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
index 1e4933f859425856a5eb37e893241ed54899a529..842f32a70ea3dea8d747cc77290c1887b0a320fc 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
@@ -17,7 +17,8 @@ eNBs =
 
     mobile_country_code =  "208";
 
-    mobile_network_code =  "93";
+    #mobile_network_code =  "93";
+    mobile_network_code =  "92";
 
     tr_s_preference     = "local_mac"
 
@@ -140,7 +141,7 @@ eNBs =
 
 
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "127.0.0.3";
+    mme_ip_address      = ( { ipv4       = "192.168.1.78";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -150,10 +151,10 @@ eNBs =
     NETWORK_INTERFACES :
     {
 
-        ENB_INTERFACE_NAME_FOR_S1_MME            = "lo";
-        ENB_IPV4_ADDRESS_FOR_S1_MME              = "127.0.0.2/24";
-        ENB_INTERFACE_NAME_FOR_S1U               = "lo";
-        ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.5/24";
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eno1";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.1.74/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "eno1";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.1.74/24";
         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
@@ -200,6 +201,8 @@ RUs = (
 	att_tx         = 0
 	att_rx         = 0;
 	bands          = [7];
+       max_pdschReferenceSignalPower = -27;
+       max_rxgain                    = 125;
 	eNB_instances  = [0];
     }
 );  
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf
index f97cd0ad8ba0c0e4a82d1c11520dfea2a71634cc..1710121d78534b8539a2a1f0fa805b1334c0bdc6 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf
@@ -2,13 +2,14 @@ L1s = (
     	{
 	num_cc = 1;
 	tr_n_preference = "nfapi";
-      	local_n_if_name  = "lo";			  
-      	remote_n_address = "127.0.0.2";
-    	local_n_address  = "127.0.0.1"; 
-    	local_n_portc    = 50000;	
-    	remote_n_portc   = 50000;
-    	local_n_portd    = 50001;	
-    	remote_n_portd   = 50001;
+      	local_n_if_name  = "eno1";
+      	#remote_n_address = "192.168.1.78";
+      	remote_n_address = "192.168.1.28";
+    	local_n_address  = "192.168.1.74";
+    	local_n_portc    = 50000;
+    	remote_n_portc   = 50001;
+    	local_n_portd    = 50010;
+    	remote_n_portd   = 50011;
         }  
 );
 
@@ -17,11 +18,10 @@ RUs = (
        local_rf       = "yes"
        nb_tx          = 1
        nb_rx          = 1
-       att_tx         = 0
+       att_tx         = 90
        att_rx         = 0;
        bands          = [7,38,42,43];
        max_pdschReferenceSignalPower = -27;
        max_rxgain                    = 125;
-       eNB_instances  = [0];
     }		      
-);  
+);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
index 1e2cd126168553bad3d65b67b331a063a90da2d7..ca76f42ee0aadb82b0017668b953b97fd46b5888 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
@@ -17,7 +17,8 @@ eNBs =
 
     mobile_country_code =  "208";
 
-    mobile_network_code =  "93";
+    #mobile_network_code =  "93";
+    mobile_network_code =  "92";
 
     tr_s_preference     = "local_mac"
 
@@ -36,7 +37,8 @@ eNBs =
       downlink_frequency      			      = 2685000000L;
       uplink_frequency_offset 			      = -120000000;
       Nid_cell					      = 0;
-      N_RB_DL                 			      = 50;
+      #N_RB_DL                 			      = 50;
+      N_RB_DL                 			      = 25;
       Nid_cell_mbsfn          			      = 0;
       nb_antenna_ports                                = 1;
       nb_antennas_tx          			      = 1;
@@ -53,7 +55,8 @@ eNBs =
       pucch_nRB_CQI           			      = 1;
       pucch_nCS_AN            			      = 0;
       pucch_n1_AN             			      = 32;
-      pdsch_referenceSignalPower 			      = -27;
+      #pdsch_referenceSignalPower 			      = -27;
+      pdsch_referenceSignalPower 			      = -30;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
       pusch_enable64QAM          			      = "DISABLE";
@@ -89,7 +92,8 @@ eNBs =
       rach_messagePowerOffsetGroupB                      = ;
       */
       rach_powerRampingStep                              = 4;
-      rach_preambleInitialReceivedTargetPower            = -108;
+      #rach_preambleInitialReceivedTargetPower            = -108;
+      rach_preambleInitialReceivedTargetPower            = -104;
       rach_preambleTransMax                              = 10;
       rach_raResponseWindowSize                          = 10;
       rach_macContentionResolutionTimer                  = 48;
@@ -140,7 +144,7 @@ eNBs =
 
 
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "127.0.0.3";
+    mme_ip_address      = ( { ipv4       = "192.168.1.78";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -150,22 +154,22 @@ eNBs =
     NETWORK_INTERFACES :
     {
 
-        ENB_INTERFACE_NAME_FOR_S1_MME            = "lo";
-        ENB_IPV4_ADDRESS_FOR_S1_MME              = "127.0.0.2/24";
-        ENB_INTERFACE_NAME_FOR_S1U               = "lo";
-        ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.5/24";
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eno1";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.1.28/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "eno1";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.1.28/24";
         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
     log_config :
     {
-      global_log_level                      ="info";
-      global_log_verbosity                  ="medium";
+      global_log_level                      ="debug";
+      global_log_verbosity                  ="high";
       hw_log_level                          ="info";
       hw_log_verbosity                      ="medium";
-      phy_log_level                         ="info";
-      phy_log_verbosity                     ="medium";
-      mac_log_level                         ="info";
+      phy_log_level                         ="trace";
+      phy_log_verbosity                     ="high";
+      mac_log_level                         ="debug";
       mac_log_verbosity                     ="high";
       rlc_log_level                         ="info";
       rlc_log_verbosity                     ="medium";
@@ -180,15 +184,15 @@ eNBs =
 MACRLCs = (
 	{
 	num_cc = 1;
-      	local_s_if_name  = "lo";			  
-      	remote_s_address = "127.0.0.1";
-    	local_s_address  = "127.0.0.2"; 
-    	local_s_portc    = 50000;	
+      	local_s_if_name  = "eno1";			  
+      	remote_s_address = "192.168.1.74";
+    	#local_s_address  = "192.168.1.78"; 
+    	local_s_address  = "192.168.1.28"; 
+    	local_s_portc    = 50001;	
     	remote_s_portc   = 50000;
-    	local_s_portd    = 50001;	
-    	remote_s_portd   = 50001;
+    	local_s_portd    = 50011;	
+    	remote_s_portd   = 50010;
 	tr_s_preference = "nfapi";
 	tr_n_preference = "local_RRC";
         }  
 );
-
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index ec818ae0f4e6eeb1c312fe4255532146adffc0a1..bccd5b57e7538db03991b254d42575b45bf73cbd 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -148,30 +148,54 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
 void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
 #endif
 
+void oai_subframe_ind(uint16_t frame, uint16_t subframe);
+extern uint8_t nfapi_pnf;
+
 static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) {
 
   start_meas(&softmodem_stats_rxtx_sf);
 
+  if (nfapi_pnf)
+  {
+    oai_subframe_ind(proc->frame_tx, proc->subframe_tx); // PNF ---> P7:subframe_ind --> VNF 
+  }
+  else
+  {
+  }
+  // *******************************************************************
+
+  //if (proc->subframe_tx==0) LOG_W(PHY, "sfn/sf:%d:%d eNB:%p eNB[0]:%p eNB[0][0]:%p dlsch:%p:%p:%p rnti:%d\n", proc->frame_tx, proc->subframe_tx, RC.eNB, RC.eNB[0], RC.eNB[0][0], RC.eNB[0][0]->dlsch, RC.eNB[0][0]->dlsch[0], RC.eNB[0][0]->dlsch[0][0], RC.eNB[0][0]->dlsch[0][0]->rnti);
+  if ( proc->frame_tx == 22 && proc->subframe_tx==5) { LOG_D(PHY,"22/5\n"); }
+
   // ****************************************
   // Common RX procedures subframe n
 
   // if this is IF5 or 3GPP_eNB
-  if (eNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
+  if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
+  LOG_D(PHY,"%s:%s() %u/%u Before wakeup_prach_eNB() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
     wakeup_prach_eNB(eNB,NULL,proc->frame_rx,proc->subframe_rx);
+  LOG_D(PHY,"%s:%s() %u/%u Before wakeup_prach_eNB_br() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
 #ifdef Rel14
     wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx);
+  LOG_D(PHY,"%s:%s() %u/%u proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
 #endif
   }
   // UE-specific RX processing for subframe n
+  LOG_D(PHY,"%s:%s() %u/%u Before phy_procedures_eNB_uespec_RX() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
   phy_procedures_eNB_uespec_RX(eNB, proc, no_relay );
 
+  LOG_D(PHY,"%s:%s() %u/%u Before UL_INFO_mutex proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
   pthread_mutex_lock(&eNB->UL_INFO_mutex);
+  LOG_D(PHY,"%s:%s() %u/%u After UL_INFO_mutex proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
   eNB->UL_INFO.frame     = proc->frame_rx;
   eNB->UL_INFO.subframe  = proc->subframe_rx;
   eNB->UL_INFO.module_id = eNB->Mod_id;
   eNB->UL_INFO.CC_id     = eNB->CC_id;
+  LOG_D(PHY,"%s:%s() %u/%u Before UL_ind proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
   eNB->if_inst->UL_indication(&eNB->UL_INFO);
+  LOG_D(PHY,"%s:%s() %u/%u After UL_ind proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
+  LOG_D(PHY,"%s:%s() %u/%u After UL_INFO_mutex unlock proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
   // *****************************************
   // TX processing for subframe n+4
   // run PHY TX procedures the one after the other for all CCs to avoid race conditions
@@ -183,10 +207,16 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
   
   if (oai_exit) return(-1);
   
+  LOG_D(PHY,"%s:%s() %u/%u Before phy_procedures_eNB_TX() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
   phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
+  LOG_D(PHY,"%s:%s() %u/%u After phy_procedures_eNB_TX() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
   
+  LOG_D(PHY,"%s:%s() %u/%u Before release_thread() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx,  proc->instance_cnt_rxtx);
+
   if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1);
 
+  LOG_D(PHY,"%s:%s() %u/%u AFTER release_thread() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx,  proc->instance_cnt_rxtx);
+
   stop_meas( &softmodem_stats_rxtx_sf );
   
   return(0);
@@ -208,28 +238,35 @@ static void* eNB_thread_rxtx( void* param ) {
 
   char thread_name[100];
 
+  //LOG_D(PHY,"%s()\n", __FUNCTION__);
 
   // set default return value
   eNB_thread_rxtx_status = 0;
 
 
-  sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
+  sprintf(thread_name,"RXn_TXnp4_%d",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1);
   thread_top_init(thread_name,1,850000L,1000000L,2000000L);
 
+  //LOG_D(PHY,"%s() thread_name:%s\n", __FUNCTION__, thread_name);
+
   while (!oai_exit) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
 
+    LOG_D(PHY,"%s:%s() %u/%u About to wait on proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
     if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break;
 
+    LOG_D(PHY,"%s:%s() %u/%u - WOKEN on proc->instance_cnt_rxtx proc->instance_cnt_rxtx:%d \n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
+
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 );
 
-    
-  
     if (oai_exit) break;
 
+    LOG_D(PHY,"%s:%s() %u/%u About to rxtx()\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx);
     if (eNB->CC_id==0)
       if (rxtx(eNB,proc,thread_name) < 0) break;
 
+    LOG_D(PHY,"%s:%s() %u/%u DONE rxtx()\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx);
+
   } // while !oai_exit
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
@@ -355,6 +392,7 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
   }
   
   ++proc_rxtx->instance_cnt_rxtx;
+  LOG_E(PHY,"%s() %u/%u Just incremented proc->instance_cnt_rxtx:%d\n", __FUNCTION__, proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx);
   
   // We have just received and processed the common part of a subframe, say n. 
   // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired 
@@ -596,10 +634,12 @@ void init_eNB_proc(int inst) {
   pthread_attr_t *attr_prach_br=NULL;
 #endif
 
+  LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]);
+
   for (CC_id=0; CC_id<RC.nb_CC[inst]; CC_id++) {
     eNB = RC.eNB[inst][CC_id];
 #ifndef OCP_FRAMEWORK
-    LOG_I(PHY,"Initializing eNB processes %d CC_id %d \n",inst,CC_id);
+    LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id);
 #endif
     proc = &eNB->proc;
 
@@ -658,6 +698,8 @@ void init_eNB_proc(int inst) {
     attr_te     = &proc->attr_te; 
 #endif
 
+    LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag);
+
     if (eNB->single_thread_flag==0) {
       pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] );
       pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] );
@@ -801,8 +843,8 @@ void init_transport(PHY_VARS_eNB *eNB) {
 	LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i);
 	exit(-1);
       } else {
-	LOG_D(PHY,"dlsch[%d][%d] => %p\n",i,j,eNB->dlsch[i][j]);
 	eNB->dlsch[i][j]->rnti=0;
+	LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti);
       }
     }
     
@@ -854,13 +896,18 @@ void init_eNB_afterRU() {
   int inst,CC_id,ru_id,i,aa;
   PHY_VARS_eNB *eNB;
 
+  LOG_I(PHY,"%s() RC.nb_inst:%d\n", __FUNCTION__, RC.nb_inst);
 
   for (inst=0;inst<RC.nb_inst;inst++) {
+    LOG_I(PHY,"RC.nb_CC[inst]:%d\n", RC.nb_CC[inst]);
     for (CC_id=0;CC_id<RC.nb_CC[inst];CC_id++) {
+
+      LOG_I(PHY,"RC.nb_CC[inst:%d][CC_id:%d]:%d\n", inst, CC_id, RC.eNB[inst][CC_id]);
+
       eNB                                  =  RC.eNB[inst][CC_id];
       phy_init_lte_eNB(eNB,0,0);
       // map antennas and PRACH signals to eNB RX
-      AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id);
+      if (0) AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id);
       LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id);
       eNB->frame_parms.nb_antennas_rx       = 0;
       eNB->prach_vars.rxsigF[0] = (int16_t*)malloc16(64*sizeof(int16_t*));
@@ -868,6 +915,9 @@ void init_eNB_afterRU() {
       for (int ce_level=0;ce_level<4;ce_level++)
 	eNB->prach_vars_br.rxsigF[ce_level] = (int16_t*)malloc16(64*sizeof(int16_t*));
 #endif
+
+      LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU);
+
       for (ru_id=0,aa=0;ru_id<eNB->num_RU;ru_id++) {
 	eNB->frame_parms.nb_antennas_rx    += eNB->RU_list[ru_id]->nb_rx;
 
@@ -885,6 +935,25 @@ void init_eNB_afterRU() {
 	  eNB->common_vars.rxdataF[aa]     =  eNB->RU_list[ru_id]->common.rxdataF[i];
 	}
       }
+
+
+
+
+      if (eNB->frame_parms.nb_antennas_rx < 1)
+      {
+        LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_rx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_rx);
+        eNB->frame_parms.nb_antennas_rx = 1;
+      }
+
+      if (eNB->frame_parms.nb_antennas_tx < 1)
+      {
+        LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_tx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_tx);
+        eNB->frame_parms.nb_antennas_tx = 1;
+      }
+
+
+
+
       AssertFatal(eNB->frame_parms.nb_antennas_rx >0,
 		  "inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx);
       LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx);
@@ -892,9 +961,12 @@ void init_eNB_afterRU() {
       init_transport(eNB);
       init_precoding_weights(RC.eNB[inst][CC_id]);
     }
+    printf("RC.nb_CC[inst:%d]:%d CC_id:%d AFTER LOOP - About to init_eNB_proc\n", inst, RC.nb_CC[inst], CC_id);
     init_eNB_proc(inst);
   }
+  printf("%s() RC.nb_inst:%d AFTER LOOP\n", __FUNCTION__, RC.nb_inst);
 
+  printf("%s:%d RC.nb_RU:%d\n", __FILE__, __LINE__, RC.nb_RU);
   for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
 
     AssertFatal(RC.ru[ru_id]!=NULL,"ru_id %d is null\n",ru_id);
@@ -904,6 +976,8 @@ void init_eNB_afterRU() {
     RC.ru[ru_id]->wakeup_prach_eNB_br = wakeup_prach_eNB_br;
     RC.ru[ru_id]->eNB_top             = eNB_top;
   }
+
+  LOG_I(PHY,"%s() Exitting\n", __FUNCTION__);
 }
 
 void init_eNB(int single_thread_flag,int wait_for_sync) {
@@ -912,7 +986,10 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
   int inst;
   PHY_VARS_eNB *eNB;
 
+  LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated\n");
+
   if (RC.eNB == NULL) RC.eNB = (PHY_VARS_eNB***) malloc(RC.nb_L1_inst*sizeof(PHY_VARS_eNB **));
+  LOG_I(PHY,"[lte-softmodem.c] eNB structure RC.eNB allocated\n");
   for (inst=0;inst<RC.nb_L1_inst;inst++) {
     if (RC.eNB[inst] == NULL) RC.eNB[inst] = (PHY_VARS_eNB**) malloc(RC.nb_CC[inst]*sizeof(PHY_VARS_eNB *));
     for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) {
@@ -948,11 +1025,7 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
 
   }
 
-
   LOG_I(PHY,"[lte-softmodem.c] eNB structure allocated\n");
-  
-
-
 }
 
 
diff --git a/targets/RT/USER/lte-ran.c b/targets/RT/USER/lte-ran.c
index 597ceb0654c6a621df341e84637990efb1aa1b74..4f9f45df8672fd33548297dcf5c3adaa67460dce 100644
--- a/targets/RT/USER/lte-ran.c
+++ b/targets/RT/USER/lte-ran.c
@@ -1278,6 +1278,8 @@ void init_eNB_proc(int inst) {
   eNB_rxtx_proc_t *proc_rxtx;
   pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL,*attr_te;
 
+  printf("%s()\n", __FUNCTION__);
+
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     eNB = PHY_vars_eNB_g[inst][CC_id];
     LOG_I(PHY,"Initializing eNB %d CC_id %d (%s,%s),\n",inst,CC_id,eNB_functions[eNB->node_function],eNB_timing[eNB->node_timing]);
@@ -1673,10 +1675,15 @@ void init_RAN(RAN_CONTEXT *rc,eNB_func_t node_function[], eNB_timing_t node_timi
   PHY_VARS_eNB *eNB;
   int ret;
 
+  printf("%s() rc->nb_inst:%d\n", __FUNCTION__, rc->nb_inst);
+
   for (inst=0;inst<rc->nb_inst;inst++) {
+    printf("%s() rc->nb_inst:%d rc->nb_CC:%d\n", __FUNCTION__, rc->nb_inst, rc->nb_CC);
     for (CC_id=0;CC_id<rc->nb_CC;CC_id++) {
       eNB = rc->eNB[inst][CC_id]; 
+      printf("%s() rc->nb_inst:%d rc->nb_CC:%d eNB:%p rc->eNB[%d][%d]:%p\n", __FUNCTION__, rc->nb_inst, rc->nb_CC, eNB, inst, CC_id, rc->eNB[inst][CC_id]);
       if (eNB) {
+
 	eNB->node_function      = node_function[CC_id];
 	eNB->node_timing        = node_timing[CC_id];
 	eNB->abstraction_flag   = 0;
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index ee7d73263a9c5ce72c0aa50497e686b844b7d6c5..4a3078be9f4bfe6d8bebe6b6d76e3c6dfc2e01a1 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -592,12 +592,14 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) {
   uint32_t symbol_number,symbol_mask,symbol_mask_full;
   int subframe_tx,frame_tx;
 
+LOG_E(PHY, "%s(ru:%p frame, subframe)\n", __FUNCTION__, ru);
   symbol_number = 0;
   symbol_mask = 0;
   symbol_mask_full = (1<<fp->symbols_per_tti)-1;
 
   do {   
     recv_IF4p5(ru, &frame_tx, &subframe_tx, &packet_type, &symbol_number);
+    LOG_E(PHY, "%s(ru:%p frame, subframe) frame_tx:%d/%d packet_type:%u symbol_number:%u proc->first_tx:%d\n", __FUNCTION__, ru, frame_tx, subframe_tx, packet_type, symbol_number, proc->first_tx);
     if (proc->first_tx != 0) {
       *frame    = frame_tx;
       *subframe = subframe_tx;
@@ -777,14 +779,80 @@ void tx_rf(RU_t *ru) {
   lte_subframe_t SF_type     = subframe_select(fp,proc->subframe_tx%10);
   lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_tx+9)%10);
   lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_tx+1)%10);
+
+  //LOG_E(PHY,"%s() nb_tx:%d sf:%d tti:%d\n", __FUNCTION__, ru->nb_tx, proc->subframe_tx, fp->samples_per_tti);
+
   if ((SF_type == SF_DL) ||
       (SF_type == SF_S)) {
     
     for (i=0; i<ru->nb_tx; i++)
+    {
       txp[i] = (void*)&ru->common.txdata[i][proc->subframe_tx*fp->samples_per_tti]; 
+      if (0)
+      {
+        if (
+            (proc->frame_tx % 10 ==0 && proc->subframe_tx==0)  ||
+            (proc->frame_tx % 10 ==0 && proc->subframe_tx==5)
+           )
+        {
+          LOG_E(PHY,"%s() nb_tx:%d i:%d samples_per_tti:%u subframe_tx:%u txp[i]\n", __FUNCTION__, ru->nb_tx, i, fp->samples_per_tti, proc->subframe_tx, txp[i]);
+        }
+      }
+    }
     
     int siglen=fp->samples_per_tti,flags=1;
     
+    if (0 &&
+    (
+        (proc->frame_tx % 300 ==0 && proc->subframe_tx==0)  ||
+        (proc->frame_tx % 300 ==0 && proc->subframe_tx==5)
+        )
+       )
+    {
+       uint32_t *tx0p = &txp[0];
+
+      LOG_E(PHY,"%s() nb_tx:%d first_carrier_offset:%u samples_per_tti:%u subframe_tx:%u sf:%u(%u) txp:%2x %2x %2x %2x %2x %2x %2x %2x\n", 
+          __FUNCTION__, ru->nb_tx, fp->first_carrier_offset, fp->samples_per_tti, proc->subframe_tx,
+          SF_type, SF_type==SF_S,
+          tx0p[fp->first_carrier_offset],
+          tx0p[fp->first_carrier_offset+1],
+          tx0p[fp->first_carrier_offset+2],
+          tx0p[fp->first_carrier_offset+3],
+          tx0p[fp->first_carrier_offset+4],
+          tx0p[fp->first_carrier_offset+5],
+          tx0p[fp->first_carrier_offset+6],
+          tx0p[fp->first_carrier_offset+7]
+          );
+    }
+    if ( 0 &&
+        (
+         (proc->frame_tx % 300 ==0 && proc->subframe_tx==0)  ||
+         (proc->frame_tx % 300 ==0 && proc->subframe_tx==5)
+        )
+       )
+    {
+      int32_t *txpbuf = RC.ru[0]->common.txdata[0];
+
+      char *buf = malloc(fp->symbols_per_tti * 3 + 100);
+      char *pbuf = buf;
+
+      for (int i=0;i<10;i++)
+      {
+        buf[0]='\0';
+        pbuf = buf;
+
+        pbuf += sprintf(pbuf, "SF%d:", proc->subframe_tx);
+
+        for (int k=0;k<fp->symbols_per_tti;k++)
+        {
+          pbuf += sprintf(pbuf, "%2x ", txpbuf[k]);
+        }
+        LOG_E(PHY, "%s\n", buf);
+
+      }
+      free(buf);
+    }
+
     if (SF_type == SF_S) {
       siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0);
       flags=3; // end of burst
@@ -813,12 +881,14 @@ void tx_rf(RU_t *ru) {
 				      ru->nb_tx,
 				      flags);
     
-    LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx,
-	  proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx,proc);
+    if (0 && proc->frame_tx % 10 ==0 && proc->subframe_tx==0) 
+      LOG_E(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d flags:%d siglen:%d\n",
+          ru->idx,
+          proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx, flags, siglen);
+
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
     
     
-    
     if (txs !=  fp->samples_per_tti) {
       LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti);
       exit_fun( "problem transmitting samples" );
@@ -1109,7 +1179,7 @@ void wakeup_eNBs(RU_t *ru) {
 
   LOG_D(PHY,"wakeup_eNBs (num %d) for RU %d\n",ru->num_eNB,ru->idx);
 
-  if (ru->num_eNB==1) {
+  if (ru->num_eNB==1 && ru->eNB_top!=0) {
     // call eNB function directly
 
     char string[20];
@@ -1120,7 +1190,7 @@ void wakeup_eNBs(RU_t *ru) {
   else {
 
     for (i=0;i<ru->num_eNB;i++)
-      if (ru->wakeup_rxtx(eNB_list[i],ru->proc.frame_rx,ru->proc.subframe_rx) < 0)
+      if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru->proc.frame_rx,ru->proc.subframe_rx) < 0)
 	LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx);
   }
 }
@@ -1181,6 +1251,8 @@ static inline int wakeup_prach_ru_br(RU_t *ru) {
 }
 #endif
 
+void oai_subframe_ind(uint16_t frame, uint16_t subframe);
+
 static void* ru_thread( void* param ) {
 
   static int ru_thread_status;
@@ -1216,6 +1288,11 @@ static void* ru_thread( void* param ) {
         phy_init_RU(ru);
  //     }
 
+ru->openair0_cfg.tx_gain[0]=0.0;
+ru->openair0_cfg.tx_gain[1]=0.0;
+ru->openair0_cfg.tx_gain[2]=0.0;
+ru->openair0_cfg.tx_gain[3]=0.0;
+
       ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
       if (setup_RU_buffers(ru)!=0) {
         printf("Exiting, cannot initialize RU Buffers\n");
@@ -1278,6 +1355,7 @@ static void* ru_thread( void* param ) {
     if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe);
     else AssertFatal(1==0, "No fronthaul interface at south port");
 
+    oai_subframe_ind(frame, subframe);
 
     LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n",
 	  ru->do_prach,
@@ -1304,13 +1382,15 @@ static void* ru_thread( void* param ) {
     // If this proc is to provide synchronization, do so
     wakeup_slaves(proc);
 
-    LOG_D(PHY,"RU %d/%d frame_tx %d, subframe_tx %d\n",0,ru->idx,proc->frame_tx,proc->subframe_tx);
+    //LOG_E(PHY,"RU %d/%d frame_tx %d, subframe_tx %d\n",0,ru->idx,proc->frame_tx,proc->subframe_tx);
     // wakeup all eNB processes waiting for this RU
     if (ru->num_eNB>0) wakeup_eNBs(ru);
 
+    //LOG_E(PHY,"%s() Before wait_on_condition()\n", __FUNCTION__);
     // wait until eNBs are finished subframe RX n and TX n+4
     wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread");
-
+    //LOG_E(PHY,"%s() AFTER wait_on_condition() ru->feptx_prec:%p ru->fh_north_asynch_in:%p ru->feptx_ofdm:%p ru->fh_south_out:%p ru->fh_north_out:%p\n", 
+    //__FUNCTION__, ru->feptx_prec, ru->fh_north_asynch_in, ru->feptx_ofdm, ru->fh_south_out, ru->fh_north_out);
 
     // do TX front-end processing if needed (precoding and/or IDFTs)
     if (ru->feptx_prec) ru->feptx_prec(ru);
@@ -1544,6 +1624,8 @@ int setup_RU_buffers(RU_t *ru) {
   */
   
   
+  printf("%s() nb_rx:%d dma:%d\n", __FUNCTION__, ru->nb_rx, ru->openair0_cfg.mmapped_dma);
+
   if (ru->openair0_cfg.mmapped_dma == 1) {
     // replace RX signal buffers with mmaped HW versions
     
@@ -1578,6 +1660,7 @@ int setup_RU_buffers(RU_t *ru) {
   }
   else {  // not memory-mapped DMA 
     //nothing to do, everything already allocated in lte_init
+    printf("%s() Not memory-mapped DMA - nothing to do\n", __FUNCTION__);
   }
   return(0);
 }
@@ -1637,15 +1720,20 @@ void fill_rf_config(RU_t *ru,const char *rf_config_file) {
     cfg->tx_freq[i] = (double)fp->dl_CarrierFreq;
     cfg->rx_freq[i] = (double)fp->ul_CarrierFreq;
 
+//fp->att_tx = 0;
+//printf("%s() DJP - HARD CODE ALERT - fp->att_tx:%d\n", __FUNCTION__);
+
     cfg->tx_gain[i] = (double)fp->att_tx;
     cfg->rx_gain[i] = ru->max_rxgain-(double)fp->att_rx;
 
     cfg->configFilename = rf_config_file;
-    printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n",
+    printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f configFilename:%s fp->att_tx:%d\n",
 	   i, cfg->tx_gain[i],
 	   cfg->rx_gain[i],
 	   cfg->tx_freq[i],
-	   cfg->rx_freq[i]);
+	   cfg->rx_freq[i],
+           cfg->configFilename,
+           fp->att_tx);
   }
 }
 
@@ -1835,8 +1923,9 @@ void init_RU(const char *rf_config_file) {
   RCconfig_RU();
   printf("number of L1 instances %d, number of RU %d\n",RC.nb_L1_inst,RC.nb_RU);
 
-  for (i=0;i<RC.nb_L1_inst;i++) 
-    for (CC_id=0;CC_id<RC.nb_CC[i];CC_id++) RC.eNB[i][CC_id]->num_RU=0;
+  if (RC.nb_CC != 0)
+    for (i=0;i<RC.nb_L1_inst;i++) 
+      for (CC_id=0;CC_id<RC.nb_CC[i];CC_id++) RC.eNB[i][CC_id]->num_RU=0;
 
   for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
     ru               = RC.ru[ru_id];
@@ -1846,24 +1935,47 @@ void init_RU(const char *rf_config_file) {
     // use eNB_list[0] as a reference for RU frame parameters
     // NOTE: multiple CC_id are not handled here yet!
 
-    
-    eNB0             = ru->eNB_list[0];
-    if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5))
-      AssertFatal(eNB0!=NULL,"eNB0 is null!\n");
+    printf("%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file);
 
-    if (eNB0) {
-      LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx);
-      memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS));
+    if (ru->eNB_list[0] == 0)
+    {
+      LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__);
+      ru->eNB_list[0] = RC.eNB[0][0];
+      ru->num_eNB=1;
+      //
+      // DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU
+      //
+    }
 
-      // attach all RU to all eNBs in its list/
-      for (i=0;i<ru->num_eNB;i++) {
-	eNB0 = ru->eNB_list[i];
-	eNB0->RU_list[eNB0->num_RU++] = ru;
+    eNB0             = ru->eNB_list[0];
+    printf("RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south);
+    printf("eNB0:%p\n", eNB0);
+    if (eNB0)
+    {
+      if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5))
+        AssertFatal(eNB0!=NULL,"eNB0 is null!\n");
+
+      if (eNB0) {
+        LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx);
+        memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS));
+
+        // attach all RU to all eNBs in its list/
+        for (i=0;i<ru->num_eNB;i++) {
+          eNB0 = ru->eNB_list[i];
+          eNB0->RU_list[eNB0->num_RU++] = ru;
+        }
       }
     }
+    else
+    {
+      printf("eNB0 was NULL - DJP - missing out of copying of frame_params - NOT A GOOD THING TO MISS\n\n\n\n\n");
+      //extern uint8_t n_rb_dl;
+      //ru->frame_parms.N_RB_DL = n_rb_dl;
+      //printf("ru->frame_parms.N_RB_DL:%d\n", ru->frame_parms.N_RB_DL);
+    }
     //    LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function);
 
-    
+
     switch (ru->if_south) {
     case LOCAL_RF:   // this is an RU with integrated RF (RRU, eNB)
       if (ru->function ==  NGFI_RRU_IF5) {                 // IF5 RRU
@@ -1934,7 +2046,8 @@ void init_RU(const char *rf_config_file) {
       if (setup_RU_buffers(ru)!=0) {
 	printf("Exiting, cannot initialize RU Buffers\n");
 	exit(-1);
-      }*/
+      }
+      */
       break;
 
     case REMOTE_IF5: // the remote unit is IF5 RRU
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index aaaaf82647f826a5b1da774a6bc41633e250f7f4..005ae9bc87e23efe8aef105beed3c92deb86566c 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -109,6 +109,10 @@ unsigned char                   scope_enb_num_ue = 2;
 static pthread_t                forms_thread; //xforms
 #endif //XFORMS
 
+pthread_cond_t nfapi_sync_cond;
+pthread_mutex_t nfapi_sync_mutex;
+int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
+
 pthread_cond_t sync_cond;
 pthread_mutex_t sync_mutex;
 int sync_var=-1; //!< protected by mutex \ref sync_mutex.
@@ -204,8 +208,8 @@ int16_t           glog_level         = LOG_INFO;
 int16_t           glog_verbosity     = LOG_MED;
 int16_t           hw_log_level       = LOG_INFO;
 int16_t           hw_log_verbosity   = LOG_MED;
-int16_t           phy_log_level      = LOG_INFO;
-int16_t           phy_log_verbosity  = LOG_MED;
+int16_t           phy_log_level      = LOG_TRACE;
+int16_t           phy_log_verbosity  = LOG_FULL;
 int16_t           mac_log_level      = LOG_INFO;
 int16_t           mac_log_verbosity  = LOG_MED;
 int16_t           rlc_log_level      = LOG_INFO;
@@ -1257,18 +1261,38 @@ void wait_eNBs() {
 
   while (waiting==1) {
     printf("Waiting for eNB L1 instances to all get configured ... sleeping 500ms (nb_L1_inst %d)\n",RC.nb_L1_inst);
-    usleep(500000);
+    usleep(5000000);
     waiting=0;
-    for (i=0;i<RC.nb_L1_inst;i++)
-      for (j=0;j<RC.nb_L1_CC[i];j++)
+    for (i=0;i<RC.nb_L1_inst;i++) {
+
+      printf("RC.nb_L1_CC[%d]:%d\n", i, RC.nb_L1_CC[i]);
+
+      for (j=0;j<RC.nb_L1_CC[i];j++) {
 	if (RC.eNB[i][j]->configured==0) {
 	  waiting=1;
 	  break;
-	}
+        } 
+      }
+    }
   }
   printf("eNB L1 are configured\n");
 }
 
+static inline void wait_nfapi_init(char *thread_name) {
+
+  printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name);
+  pthread_mutex_lock( &nfapi_sync_mutex );
+  
+  while (nfapi_sync_var<0)
+    pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex );
+  
+  pthread_mutex_unlock(&nfapi_sync_mutex);
+  
+  printf( "NFAPI: got sync (%s)\n", thread_name);
+}
+
+uint8_t nfapi_pnf = 0;
+
 int main( int argc, char **argv )
 {
   int i,j,k,aa,re;
@@ -1397,6 +1421,7 @@ int main( int argc, char **argv )
     log_set_instance_type (LOG_INSTANCE_ENB);
   }
 
+  printf("ITTI init\n");
   itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
 
   // initialize mscgen log after ITTI
@@ -1416,6 +1441,7 @@ int main( int argc, char **argv )
   }
 
 #ifdef PDCP_USE_NETLINK
+  printf("PDCP netlink\n");
   netlink_init();
 #if defined(PDCP_USE_NETLINK_QUEUES)
   pdcp_netlink_init();
@@ -1449,6 +1475,7 @@ int main( int argc, char **argv )
 
 
 
+  printf("Before CC \n");
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 
     if (UE_flag==1) {     
@@ -1510,6 +1537,7 @@ int main( int argc, char **argv )
     }
   }
 
+  printf("Runtime table\n");
   fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
   cpuf=get_cpu_freq_GHz();
   
@@ -1517,6 +1545,7 @@ int main( int argc, char **argv )
   
 #ifndef DEADLINE_SCHEDULER
   
+  printf("NO deadline scheduler\n");
   /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */
   
   cpu_set_t cpuset;
@@ -1557,7 +1586,10 @@ int main( int argc, char **argv )
   
 #if defined(ENABLE_ITTI)
   
+  printf("ITTI enabled\n");
   
+  printf("UE_flag:%d\n", UE_flag);
+  printf("RC.nb_inst:%d\n", RC.nb_inst);
   if ((UE_flag == 1)||
       (RC.nb_inst > 0))  {
     
@@ -1586,6 +1618,7 @@ int main( int argc, char **argv )
   
   
   
+  printf("mlock\n");
   mlockall(MCL_CURRENT | MCL_FUTURE);
   
   pthread_cond_init(&sync_cond,NULL);
@@ -1594,6 +1627,8 @@ int main( int argc, char **argv )
 #ifdef XFORMS
   int UE_id;
   
+  printf("XFORMS\n");
+
   if (do_forms==1) {
     fl_initialize (&argc, argv, NULL, 0, 0);
     
@@ -1650,8 +1685,15 @@ int main( int argc, char **argv )
   
   rt_sleep_ns(10*100000000ULL);
   
+  printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
+  pthread_cond_init(&sync_cond,NULL);
+  pthread_mutex_init(&sync_mutex, NULL);
   
   
+  if (nfapi_pnf==2)
+    wait_nfapi_init("main?");
+  
+  printf("START MAIN THREADS\n");
   
   // start the main threads
   if (UE_flag == 1) {
@@ -1673,8 +1715,10 @@ int main( int argc, char **argv )
       //	for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0);
     }
 
+    printf("wait_eNBs()\n");
     wait_eNBs();
 
+    printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
     if (RC.nb_RU >0) {
       printf("Initializing RU threads\n");
       init_RU(rf_config_file);
@@ -1684,10 +1728,16 @@ int main( int argc, char **argv )
       }
     }
 
+    printf("wait RUs\n");
     wait_RUs();
+    printf("ALL RUs READY!\n");
+    printf("RC.nb_RU:%d\n", RC.nb_RU);
     // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration)
-    init_eNB_afterRU();
+    printf("ALL RUs ready - init eNBs\n");
+    printf("DJP - commented out call to init_eNB_afterRU() will be called by nFAPI\n\n\n\n");
+    //init_eNB_afterRU();
     
+    printf("ALL RUs ready - ALL eNBs ready\n");
   }
   
   
@@ -1721,30 +1771,21 @@ int main( int argc, char **argv )
     //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
   } else {
     
-    
-    
-    
+    printf("eNB mode\n");
     
   }
   
-  
-  
-  
   printf("Sending sync to all threads\n");
   
-  
-  
   pthread_mutex_lock(&sync_mutex);
   sync_var=0;
   pthread_cond_broadcast(&sync_cond);
   pthread_mutex_unlock(&sync_mutex);
   
-
   // wait for end of program
   printf("TYPE <CTRL-C> TO TERMINATE\n");
   //getchar();
 
-
 #if defined(ENABLE_ITTI)
   printf("Entering ITTI signals handler\n");
   itti_wait_tasks_end();
@@ -1795,6 +1836,9 @@ int main( int argc, char **argv )
   pthread_cond_destroy(&sync_cond);
   pthread_mutex_destroy(&sync_mutex);
 
+  pthread_cond_destroy(&nfapi_sync_cond);
+  pthread_mutex_destroy(&nfapi_sync_mutex);
+
 
 
   // *** Handle per CC_id openair0