diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index f52a3c465f6b7c75e2237e40c188425abcde4a33..a125219982ea6d6cc0c7b1b93d3500bbd515b06b 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -36,7 +36,7 @@ set (OPENAIR1_DIR    ${OPENAIR_DIR}/openair1)
 set (OPENAIR2_DIR    ${OPENAIR_DIR}/openair2)
 set (OPENAIR3_DIR    ${OPENAIR_DIR}/openair3)
 set (OPENAIR_TARGETS ${OPENAIR_DIR}/targets)
-set (OPENAIR3_DIR   ${OPENAIR_DIR}/openair3)
+set (OPENAIR3_DIR    ${OPENAIR_DIR}/openair3)
 set (OPENAIR_CMAKE   ${OPENAIR_DIR}/cmake_targets)
 set (OPENAIR_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY})
 
@@ -161,6 +161,11 @@ set(CMAKE_C_FLAGS
 set(CMAKE_CXX_FLAGS
   "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR}"
 )
+
+
+#########################
+set(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${OPENAIR_TARGETS}/bin")
+#########################
 # set a flag for changes in the source code
 # these changes are related to hardcoded path to include .h files
 add_definitions(-DCMAKER)
@@ -244,6 +249,9 @@ endif (${RTAI})
 set(asn1c_call "${OPENAIR_CMAKE}/tools/generate_asn1")
 set(asn1_generated_dir ${OPENAIR_BIN_DIR})
 
+set(protoc_call "${OPENAIR_CMAKE}/tools/generate_protobuf")
+set(protobuf_generated_dir ${OPENAIR_BIN_DIR})
+
 # RRC
 ######
 add_list2_option(RRC_ASN1_VERSION "Rel10" "ASN.1 version of RRC interface" "Rel8" "Rel10" "CBA")
@@ -404,8 +412,47 @@ add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4
 add_list1_option(NB_ANTENNAS_TX "2" "Number of antennas in transmission" "1" "2" "4")
 add_list1_option(NB_ANTENNAS_TXRX "2" "Number of antennas in ????" "1" "2" "4")
 
-add_list2_option(RF_BOARD "EXMIMO" "RF head type" "False" "EXMIMO" "OAI_USRP" "ETHERNET" "OAI_BLADERF" "CPRIGW")
+add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW")
+
+add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET")
+
+
+# include RF devices / transport protocols library modules
+######################################################################
+
+include_directories("${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/")
+include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/")
+#set (option_HWEXMIMOLIB_lib "-l ")
+set(HWLIB_EXMIMO_SOURCE 
+  ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
+  ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c
+  )
+add_library(oai_exmimodevif MODULE ${HWLIB_EXMIMO_SOURCE} )
+
+include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/")
+set (option_HWUSRPLIB_lib "-l uhd")
+set(HWLIB_USRP_SOURCE 
+  ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+  )
+add_library(oai_usrpdevif MODULE ${HWLIB_USRP_SOURCE} )
+
+include_directories("${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/")
+set (option_HWBLADERFLIB_lib "-l bladerf")
+set(HWLIB_BLADERF_SOURCE 
+  ${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
+  )
+add_library(oai_bladerfdevif MODULE ${HWLIB_BLADERF_SOURCE} )
+
+include_directories("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/")
+set(TPLIB_ETHERNET_SOURCE 
+  ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
+  ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
+  ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
+  )
+add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} )
 
+# RF devices / transport protocols settings
+######################################################################
 if (${RF_BOARD} STREQUAL "EXMIMO")
   set(DRIVER2013)
   include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/")
@@ -413,6 +460,7 @@ if (${RF_BOARD} STREQUAL "EXMIMO")
   set(HW_SOURCE ${HW_SOURCE}
     ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
     ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c)
+  set(option_HW_lib "-rdynamic -ldl")
 
 elseif (${RF_BOARD} STREQUAL "OAI_USRP")
   include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/")
@@ -420,8 +468,7 @@ elseif (${RF_BOARD} STREQUAL "OAI_USRP")
   set(HW_SOURCE ${HW_SOURCE}
     ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp)
   LINK_DIRECTORIES("/opt/lib")
-  set(option_HW_lib "uhd")
-  #set(LOWLATENCY False)
+  set(option_HW_lib "-luhd -rdynamic -ldl")
 
 elseif (${RF_BOARD} STREQUAL "OAI_BLADERF")
   include_directories("${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/")
@@ -431,24 +478,32 @@ elseif (${RF_BOARD} STREQUAL "OAI_BLADERF")
     ${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
     )
   LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu")
-  set(option_HW_lib "bladeRF")
- #set(LOWLATENCY False)
-
-elseif (${RF_BOARD} STREQUAL "ETHERNET")
-  include_directories ("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB")
-  set(HW_SOURCE ${HW_SOURCE}
-    ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
-    )
-  #set(LOWLATENCY True)
-  
-elseif (${RF_BOARD} STREQUAL "CPRIGW")
+  set(option_HW_lib "bladeRF -rdynamic -ldl")
+ 
+elseif (${RF_BOARD} STREQUAL "CPRIGW") #to ask
   set(HW_SOURCE ${HW_SOURCE}
     ${OPENAIR_TARGETS}/ARCH/CPRIGW/USERSPACE/LIB/cprigw_lib.c
     )
   include_directories("${OPENAIR_TARGETS}/ARCH/CPRIGW/USERSPACE/LIB/")
-   set(option_HW_lib "-rdynamic dl")
+  set(option_HW_lib "-rdynamic dl")
+  
 endif (${RF_BOARD} STREQUAL "EXMIMO")
 
+
+if (${TRANSP_PRO} STREQUAL "ETHERNET")
+  
+  include_directories ("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB")
+  set(TRANSPORT_SOURCE ${TRANSPORT_SOURCE}
+    ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
+    ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
+    ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
+    )
+  set(option_TP_lib "-rdynamic -ldl")
+
+  
+endif (${TRANSP_PRO} STREQUAL "ETHERNET")
+##########################################################
+
 include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
 
 Message("LOWLATENCY flag  is ${LOWLATENCY}")
@@ -474,6 +529,9 @@ add_list_string_option(PACKAGE_NAME "NotDefined" "As per attribute name")
 add_boolean_option(MESSAGE_CHART_GENERATOR False         "For generating sequence diagrams")
 add_boolean_option(MESSAGE_CHART_GENERATOR_RLC_MAC False "trace RLC-MAC exchanges in sequence diagrams")
 add_boolean_option(MESSAGE_CHART_GENERATOR_PHY     False "trace some PHY exchanges in sequence diagrams")
+
+add_boolean_option(ENB_AGENT                   True         "enable eNB agent to inteface with a SDN contrller")
+
 ########################
 # Include order
 ##########################
@@ -1403,10 +1461,11 @@ add_definitions(-DASN1_MINIMUM_VERSION=924)
 
 #################################
 # add executables for operation
-#################################""
+#################################
 
 # lte-softmodem is both eNB and UE implementation
 ###################################################
+
 add_executable(lte-softmodem
   ${rrc_h}
   ${s1ap_h}
@@ -1424,6 +1483,7 @@ add_executable(lte-softmodem
   ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
   ${GTPU_need_ITTI}
   ${HW_SOURCE}
+  ${TRANSPORT_SOURCE}  
   ${RTAI_SOURCE}
   ${XFORMS_SOURCE}
   ${XFORMS_SOURCE_SOFTMODEM}
@@ -1436,7 +1496,7 @@ target_link_libraries (lte-softmodem
 
 
 target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES})
-target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${option_HW_lib} ${XFORMS_LIBRARIES} )
+target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${option_HW_lib} ${option_TP_lib} ${XFORMS_LIBRARIES} ) 
 target_link_libraries (lte-softmodem ${LIBBOOST_LIBRARIES})
 
 # lte-softmodem-nos1 is both eNB and UE implementation
@@ -1458,6 +1518,7 @@ add_executable(lte-softmodem-nos1
   #${OPENAIR2_DIR}/RRC/NAS/rb_config.c
   ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
   ${HW_SOURCE}
+  ${TRANSPORT_SOURCE}  
   ${RTAI_SOURCE}
   ${XFORMS_SOURCE}
   ${XFORMS_SOURCE_SOFTMODEM}
@@ -1468,38 +1529,36 @@ target_link_libraries (lte-softmodem-nos1
   -Wl,--end-group )
 
 target_link_libraries (lte-softmodem-nos1 ${LIBXML2_LIBRARIES})
-target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES}  ${option_HW_lib} ${XFORMS_LIBRARIES} )
+target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES}  ${option_HW_lib}  ${option_TP_lib} ${XFORMS_LIBRARIES} )
 target_link_libraries (lte-softmodem-nos1 ${LIBBOOST_LIBRARIES})
 
 
 
 # rrh
 ################################
-set(DRIVER2013)
-
-#Note: only on RF type is currently supported for RRH
+#Note: only one RF type (USRP) is currently supported for RRH
 add_executable(rrh_gw
   ${OPENAIR_TARGETS}/RT/USER/rrh_gw.c
   ${OPENAIR_TARGETS}/RT/USER/eNB_transport_IQ.c
   ${OPENAIR_TARGETS}/RT/USER/UE_transport_IQ.c
   ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
   ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c		
-  ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c 
   ${HW_SOURCE}
+  ${TRANSPORT_SOURCE}  
   )
-# assert and common_lib.h
-target_include_directories(rrh_gw PRIVATE  ${OPENAIR_DIR}/common/utils/itti ${OPENAIR_TARGETS}/ARCH/COMMON ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ )
-
+# assert
+target_include_directories(rrh_gw PRIVATE  ${OPENAIR_DIR}/common/utils/itti)
 target_link_libraries(rrh_gw
   -Wl,--start-group
   UTIL LFDS  
   -Wl,--end-group )
 target_link_libraries (rrh_gw rt pthread m )
-target_link_libraries (rrh_gw ${option_HW_lib} ${LIBBOOST_LIBRARIES} )
+target_link_libraries (rrh_gw  ${option_HW_lib} ${option_TP_lib} ${LIBBOOST_LIBRARIES} )
 
-#Message("-- default_HW_lib=ETHERNET") # only in case of RRH
 Message("-- option_HW_lib=${option_HW_lib}")
 Message("-- HW_SOURCE=${HW_SOURCE}")
+Message("-- option_TP_lib=${option_TP_lib}")
+Message("-- TRANSPORT_SOURCE=${TRANSPORT_SOURCE}")
 
 # USIM process
 #################
@@ -1550,6 +1609,7 @@ add_executable(oaisim
   ${GTPU_need_ITTI}
   ${OPENAIR_TARGETS}/COMMON/create_tasks.c
   ${HW_SOURCE}
+  ${TRANSPORT_SOURCE}  
   ${XFORMS_SOURCE}
 )
 
@@ -1561,7 +1621,7 @@ target_link_libraries (oaisim
   -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 ${option_HW_lib}
+target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES}  ${NETTLE_LIBRARIES} sctp ${option_HW_lib} ${option_TP_lib}
   ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES})
 #Force link with forms, regardless XFORMS option
 target_link_libraries (oaisim forms)
@@ -1588,6 +1648,7 @@ add_executable(oaisim_nos1
   ${OPENAIR2_DIR}/UTIL/OMG/sumo.c
   ${OPENAIR_TARGETS}/COMMON/create_tasks.c
   ${HW_SOURCE}
+  ${TRANSPORT_SOURCE}  
   ${XFORMS_SOURCE}
 )
 target_include_directories(oaisim_nos1 PUBLIC  ${OPENAIR_TARGETS}/SIMU/USER)
@@ -1597,7 +1658,7 @@ target_link_libraries (oaisim_nos1
   -Wl,--end-group )
 
 target_link_libraries (oaisim_nos1 ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES})
-target_link_libraries (oaisim_nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES}  ${NETTLE_LIBRARIES}  ${option_HW_lib}
+target_link_libraries (oaisim_nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES}  ${NETTLE_LIBRARIES}  ${option_HW_lib}  ${option_TP_lib}
   ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES})
 #Force link with forms, regardless XFORMS option
 target_link_libraries (oaisim_nos1 forms)
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 03f10ce57880096d05724a702a4ba14afd43a9f8..037f5c8ee9bef643165ad7820dcc0d2f856a3a86 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -81,7 +81,8 @@
      <compile_prog_args>--eNB -w USRP -r Rel10 --noS1  -c </compile_prog_args>
      <compile_prog_out>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1
                        $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/rb_tool
-                       $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/CMakeFiles/nasmesh/nasmesh.ko</compile_prog_out>
+                       $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/CMakeFiles/nasmesh/nasmesh.ko
+                       $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/liboai_usrpdevif.so</compile_prog_out>
      <pre_exec></pre_exec>
      <pre_exec_args></pre_exec_args>
      <main_exec></main_exec>
@@ -122,7 +123,8 @@
      <compile_prog_args>--eNB -w BLADERF -r Rel10 --noS1  -c </compile_prog_args>
      <compile_prog_out>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1
                        $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/rb_tool
-                       $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/CMakeFiles/nasmesh/nasmesh.ko</compile_prog_out>
+                       $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/CMakeFiles/nasmesh/nasmesh.ko
+                       $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/liboai_bladerfdevif.so</compile_prog_out>
      <pre_exec></pre_exec>
      <pre_exec_args></pre_exec_args>
      <main_exec></main_exec>
@@ -138,10 +140,11 @@
      <desc>Build lte_softmodem_noS1.ETHERNET.Rel10</desc>
      <pre_compile_prog></pre_compile_prog>
      <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
-     <compile_prog_args>--eNB -w ETHERNET -r Rel10 --noS1  -c </compile_prog_args>
+     <compile_prog_args>--eNB -w None -t ETHERNET -r Rel10 --noS1  -c </compile_prog_args>
      <compile_prog_out>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1
                        $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/rb_tool
-                       $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/CMakeFiles/nasmesh/nasmesh.ko</compile_prog_out>
+                       $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/CMakeFiles/nasmesh/nasmesh.ko
+                       $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/liboai_eth_transpro.so</compile_prog_out>
      <pre_exec></pre_exec>
      <pre_exec_args></pre_exec_args>
      <main_exec></main_exec>
@@ -160,7 +163,8 @@
      <pre_compile_prog></pre_compile_prog>
      <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
      <compile_prog_args>--eNB -w USRP -r Rel10   -c </compile_prog_args>
-     <compile_prog_out>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</compile_prog_out>
+     <compile_prog_out>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem
+                       $OPENAIR_DIR/cmake_targets/lte_build_oai/build/liboai_usrpdevif.so</compile_prog_out>
      <pre_exec></pre_exec>
      <pre_exec_args></pre_exec_args>
      <main_exec></main_exec>
@@ -197,7 +201,8 @@
      <pre_compile_prog></pre_compile_prog>
      <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
      <compile_prog_args>--eNB -w BLADERF -r Rel10   -c </compile_prog_args>
-     <compile_prog_out>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</compile_prog_out>
+     <compile_prog_out>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem
+                       $OPENAIR_DIR/cmake_targets/lte_build_oai/build/liboai_bladerfdevif.so</compile_prog_out>
      <pre_exec></pre_exec>
      <pre_exec_args></pre_exec_args>
      <main_exec></main_exec>
@@ -213,8 +218,9 @@
      <desc>Build lte_softmodem.ETHERNET.Rel10</desc>
      <pre_compile_prog></pre_compile_prog>
      <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
-     <compile_prog_args>--eNB -w ETHERNET -r Rel10   -c </compile_prog_args>
-     <compile_prog_out>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</compile_prog_out>
+     <compile_prog_args>--eNB -w None -t ETHERNET -r Rel10   -c </compile_prog_args>
+     <compile_prog_out>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem
+                       $OPENAIR_DIR/cmake_targets/lte_build_oai/build/liboai_eth_transpro.so</compile_prog_out>
      <pre_exec></pre_exec>
      <pre_exec_args></pre_exec_args>
      <main_exec></main_exec>
@@ -261,11 +267,13 @@
 
      <testCase id="010140" >
      <class>compilation</class>
-     <desc>Build RRH Gateway</desc>
+     <desc>Build RRH Gateway for USRP(RF) + Ethernet (Transport)</desc>
      <pre_compile_prog></pre_compile_prog>
      <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
-     <compile_prog_args>--RRH -w USRP  -c </compile_prog_args>
-     <compile_prog_out>$OPENAIR_DIR/cmake_targets/rrh_gw/build/rrh_gw</compile_prog_out>
+     <compile_prog_args>--RRH -w USRP -t ETHERNET  -c </compile_prog_args>
+     <compile_prog_out>$OPENAIR_DIR/cmake_targets/rrh_gw/build/rrh_gw
+                       $OPENAIR_DIR/cmake_targets/rrh_gw/build/liboai_usrpdevif.so
+                       $OPENAIR_DIR/cmake_targets/rrh_gw/build/liboai_eth_transpro.so</compile_prog_out>
      <pre_exec></pre_exec>
      <pre_exec_args></pre_exec_args>
      <main_exec></main_exec>
@@ -278,14 +286,16 @@
 
      <testCase id="010141" >
      <class>compilation</class>
-     <desc>Build RRH Gateway</desc>
+     <desc>Build RRH Gateway for EXMIMO(RF) + Ethernet (Transport)</desc>
      <pre_compile_prog></pre_compile_prog>
      <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
-     <compile_prog_args>--RRH -w EXMIMO  -c </compile_prog_args>
+     <compile_prog_args>--RRH -w EXMIMO -t ETHNERNET  -c </compile_prog_args>
      <compile_prog_out>$OPENAIR_DIR/cmake_targets/rrh_gw/build/rrh_gw
                        $OPENAIR_DIR/cmake_targets/rrh_gw/build/CMakeFiles/openair_rf/openair_rf.ko
                        $OPENAIR_DIR/cmake_targets/rrh_gw/build/updatefw
-                       $OPENAIR_DIR/cmake_targets/rrh_gw/build/oarf_config_exmimo.oct</compile_prog_out>
+                       $OPENAIR_DIR/cmake_targets/rrh_gw/build/oarf_config_exmimo.oct
+                       $OPENAIR_DIR/cmake_targets/rrh_gw/build/liboai_exmimodevif.so
+                       $OPENAIR_DIR/cmake_targets/rrh_gw/build/liboai_eth_transpro.so</compile_prog_out>
      <pre_exec></pre_exec>
      <pre_exec_args></pre_exec_args>
      <main_exec></main_exec>
@@ -301,8 +311,10 @@
      <desc>Build RRH Gateway</desc>
      <pre_compile_prog></pre_compile_prog>
      <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
-     <compile_prog_args>--RRH -w BLADERF  -c </compile_prog_args>
-     <compile_prog_out>$OPENAIR_DIR/cmake_targets/rrh_gw/build/rrh_gw</compile_prog_out>
+     <compile_prog_args>--RRH -w BLADERF -t ETHERNET  -c </compile_prog_args>
+     <compile_prog_out>$OPENAIR_DIR/cmake_targets/rrh_gw/build/rrh_gw
+                       $OPENAIR_DIR/cmake_targets/rrh_gw/build/liboai_bladerfdevif.so
+                       $OPENAIR_DIR/cmake_targets/rrh_gw/build/liboai_eth_transpro.so</compile_prog_out>
      <pre_exec></pre_exec>
      <pre_exec_args></pre_exec_args>
      <main_exec></main_exec>
@@ -4622,7 +4634,7 @@
   <testCase id="016500" >
     <class>lte-softmodem</class>
     <desc></desc>
-    <eNB>calisson</eNB>
+    <eNB>mozart</eNB>
     <UE>stevens</UE>
     <EPC>amerique</EPC>
     <TimeOut_cmd>390</TimeOut_cmd>
@@ -4639,17 +4651,17 @@
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  frame_type \"FDD\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_rx  1
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_tx 1
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower -29
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.82/24\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.82/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower -26
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.111/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.111/24\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_PORT_FOR_S1U                     2152</eNB_config_file>
     <eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
     <eNB_compile_prog_args>--eNB -w BLADERF -x -c </eNB_compile_prog_args>
     <eNB_pre_exec>sudo -E $OPENAIR_DIR/cmake_targets/tools/start_bladerf.py</eNB_pre_exec>
     <eNB_pre_exec_args></eNB_pre_exec_args>
-    <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
+    <eNB_main_exec>sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
     <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  -W </eNB_main_exec_args>
     <eNB_traffic_exec></eNB_traffic_exec>
     <eNB_traffic_exec_args></eNB_traffic_exec_args>
@@ -4698,7 +4710,7 @@
   <testCase id="016501" >
     <class>lte-softmodem</class>
     <desc></desc>
-    <eNB>calisson</eNB>
+    <eNB>mozart</eNB>
     <UE>stevens</UE>
     <EPC>amerique</EPC>
     <TimeOut_cmd>390</TimeOut_cmd>
@@ -4715,23 +4727,23 @@
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  frame_type \"FDD\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_rx  1
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_tx 1
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower      -32
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.82/24\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.82/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower -29
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.111/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.111/24\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_PORT_FOR_S1U                     2152</eNB_config_file>
     <eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
     <eNB_compile_prog_args>--eNB -w BLADERF -x -c </eNB_compile_prog_args>
     <eNB_pre_exec>sudo -E $OPENAIR_DIR/cmake_targets/tools/start_bladerf.py</eNB_pre_exec>
     <eNB_pre_exec_args></eNB_pre_exec_args>
-    <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
+    <eNB_main_exec>sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
     <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  -W </eNB_main_exec_args>
     <eNB_traffic_exec></eNB_traffic_exec>
     <eNB_traffic_exec_args></eNB_traffic_exec_args>
     <eNB_search_expr_true></eNB_search_expr_true>
     <eNB_search_expr_false></eNB_search_expr_false>
-    <eNB_terminate_missing_procs>True</eNB_terminate_missing_procs>
+    <eNB_terminate_missing_procs>False</eNB_terminate_missing_procs>
 
     <UE_working_dir>/tmp</UE_working_dir>
     <UE_config_file></UE_config_file>
@@ -4773,7 +4785,7 @@
   <testCase id="016502" >
     <class>lte-softmodem</class>
     <desc></desc>
-    <eNB>calisson</eNB>
+    <eNB>mozart</eNB>
     <UE>stevens</UE>
     <EPC>amerique</EPC>
     <TimeOut_cmd>390</TimeOut_cmd>
@@ -4790,23 +4802,23 @@
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  frame_type \"FDD\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_rx  1
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_tx 1
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower       -35
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.82/24\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.82/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower -32
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.111/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.111/24\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_PORT_FOR_S1U                     2152</eNB_config_file>
     <eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
     <eNB_compile_prog_args>--eNB -w BLADERF -x -c </eNB_compile_prog_args>
     <eNB_pre_exec>sudo -E $OPENAIR_DIR/cmake_targets/tools/start_bladerf.py</eNB_pre_exec>
     <eNB_pre_exec_args></eNB_pre_exec_args>
-    <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
+    <eNB_main_exec>sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
     <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  -W </eNB_main_exec_args>
     <eNB_traffic_exec></eNB_traffic_exec>
     <eNB_traffic_exec_args></eNB_traffic_exec_args>
     <eNB_search_expr_true></eNB_search_expr_true>
     <eNB_search_expr_false></eNB_search_expr_false>
-    <eNB_terminate_missing_procs>True</eNB_terminate_missing_procs>
+    <eNB_terminate_missing_procs>False</eNB_terminate_missing_procs>
 
     <UE_working_dir>/tmp</UE_working_dir>
     <UE_config_file></UE_config_file>
@@ -4848,7 +4860,7 @@
   <testCase id="016503" >
     <class>lte-softmodem</class>
     <desc></desc>
-    <eNB>calisson</eNB>
+    <eNB>mozart</eNB>
     <UE>stevens</UE>
     <EPC>amerique</EPC>
     <TimeOut_cmd>390</TimeOut_cmd>
@@ -4865,23 +4877,23 @@
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  frame_type \"FDD\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_rx  1
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_tx 1
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower       -29
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.82/24\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.82/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower -26
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.111/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.111/24\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_PORT_FOR_S1U                     2152</eNB_config_file>
     <eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
     <eNB_compile_prog_args>--eNB -w BLADERF -x -c </eNB_compile_prog_args>
     <eNB_pre_exec>sudo -E $OPENAIR_DIR/cmake_targets/tools/start_bladerf.py</eNB_pre_exec>
     <eNB_pre_exec_args></eNB_pre_exec_args>
-    <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
+    <eNB_main_exec>sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
     <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  -W </eNB_main_exec_args>
     <eNB_traffic_exec></eNB_traffic_exec>
     <eNB_traffic_exec_args></eNB_traffic_exec_args>
     <eNB_search_expr_true></eNB_search_expr_true>
     <eNB_search_expr_false></eNB_search_expr_false>
-    <eNB_terminate_missing_procs>True</eNB_terminate_missing_procs>
+    <eNB_terminate_missing_procs>False</eNB_terminate_missing_procs>
 
     <UE_working_dir>/tmp</UE_working_dir>
     <UE_config_file></UE_config_file>
@@ -4922,7 +4934,7 @@
   <testCase id="016504" >
     <class>lte-softmodem</class>
     <desc></desc>
-    <eNB>calisson</eNB>
+    <eNB>mozart</eNB>
     <UE>stevens</UE>
     <EPC>amerique</EPC>
     <TimeOut_cmd>390</TimeOut_cmd>
@@ -4939,23 +4951,23 @@
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  frame_type \"FDD\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_rx  1
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_tx 1
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower       -32
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.82/24\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.82/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower -29
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.111/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.111/24\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_PORT_FOR_S1U                     2152</eNB_config_file>
     <eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
     <eNB_compile_prog_args>--eNB -w BLADERF -x -c </eNB_compile_prog_args>
     <eNB_pre_exec>sudo -E $OPENAIR_DIR/cmake_targets/tools/start_bladerf.py</eNB_pre_exec>
     <eNB_pre_exec_args></eNB_pre_exec_args>
-    <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
+    <eNB_main_exec>sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
     <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  -W </eNB_main_exec_args>
     <eNB_traffic_exec></eNB_traffic_exec>
     <eNB_traffic_exec_args></eNB_traffic_exec_args>
     <eNB_search_expr_true></eNB_search_expr_true>
     <eNB_search_expr_false></eNB_search_expr_false>
-    <eNB_terminate_missing_procs>True</eNB_terminate_missing_procs>
+    <eNB_terminate_missing_procs>False</eNB_terminate_missing_procs>
 
     <UE_working_dir>/tmp</UE_working_dir>
     <UE_config_file></UE_config_file>
@@ -4996,7 +5008,7 @@
   <testCase id="016505" >
     <class>lte-softmodem</class>
     <desc></desc>
-    <eNB>calisson</eNB>
+    <eNB>mozart</eNB>
     <UE>stevens</UE>
     <EPC>amerique</EPC>
     <TimeOut_cmd>390</TimeOut_cmd>
@@ -5013,23 +5025,23 @@
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  frame_type \"FDD\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_rx  1
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  nb_antennas_tx 1
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower       -35
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.82/24\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth1\"
-                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.82/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  pdsch_referenceSignalPower -32
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1_MME       \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1_MME          \"192.168.12.111/24\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_INTERFACE_NAME_FOR_S1U          \"eth0\"
+                     targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_IPV4_ADDRESS_FOR_S1U           \"192.168.12.111/24\"
                      targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  ENB_PORT_FOR_S1U                     2152</eNB_config_file>
     <eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
     <eNB_compile_prog_args>--eNB -w BLADERF -x -c </eNB_compile_prog_args>
     <eNB_pre_exec>sudo -E $OPENAIR_DIR/cmake_targets/tools/start_bladerf.py</eNB_pre_exec>
     <eNB_pre_exec_args></eNB_pre_exec_args>
-    <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
+    <eNB_main_exec>sudo -E chrt -f 99 $OPENAIR_DIR/cmake_targets/lte_build_oai/build/lte-softmodem</eNB_main_exec>
     <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.bladerfx40.conf  -W </eNB_main_exec_args>
     <eNB_traffic_exec></eNB_traffic_exec>
     <eNB_traffic_exec_args></eNB_traffic_exec_args>
     <eNB_search_expr_true></eNB_search_expr_true>
     <eNB_search_expr_false></eNB_search_expr_false>
-    <eNB_terminate_missing_procs>True</eNB_terminate_missing_procs>
+    <eNB_terminate_missing_procs>False</eNB_terminate_missing_procs>
 
     <UE_working_dir>/tmp</UE_working_dir>
     <UE_config_file></UE_config_file>
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index a25d02c630e438e8608e7d1e38caff008e71413e..0f7af3305ae6a79a9e1109688e6ee9103a40e515 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -49,6 +49,7 @@ LOWLATENCY_FLAG_USER="False"
 FORCE_LOWLATENCY_FLAG_USER=""
 REL="Rel10"
 HW="EXMIMO"
+TP="None"
 NOS1=0
 EPC=0
 VERBOSE_COMPILE=0
@@ -90,10 +91,13 @@ Options
    default is Rel10,
    Rel8 limits the implementation to 3GPP Release 8 version
 -w | --hardware
-   EXMIMO (Default), USRP, BLADERF, ETHERNET, None
+   EXMIMO (Default), USRP, BLADERF, None
    Adds this RF board support (in external packages installation and in compilation)
+-t | --transport protocol
+   ETHERNET , None
+   Adds this trasport protocol support in compilation
 --oaisim
-   Makes the oaisim simulator. Hardware will be defaulted to "NONE".
+   Makes the oaisim simulator. Hardware will be defaulted to "None".
 --phy_simulators
    Makes the unitary tests Layer 1 simulators
 --core_simulators
@@ -172,20 +176,32 @@ function main() {
             shift;;
        -r | --3gpp-release)
             REL=$2
-            echo_info "setting release to: $REL"
+            echo_info "Setting release to: $REL"
             shift 2;;
        -w | --hardware)
             HW="$2" #"${i#*=}"
-            # Use OAI_USRP  as the key word USRP is used inside UHD driver
-            if [ "$HW" == "USRP" ] ; then 
-		HW="OAI_USRP"
-	    fi 
-            if [ "$HW" == "BLADERF" ] ; then 
-		HW="OAI_BLADERF"
-	    fi 
-            echo_info "setting hardware to: $HW"
+            # Use OAI_USRP  as the key word USRP is used inside UHD driver           
+	    if [ "$HW" != "BLADERF" -a  "$HW" != "USRP" -a  "$HW" != "None" -a  "$HW" != "EXMIMO"  ] ; then 
+		echo_fatal "Unknown HW type $HW will exit..."		
+	    else
+		if [ "$HW" == "USRP" ] ; then 
+		    HW="OAI_USRP"
+		fi 
+		if [ "$HW" == "BLADERF" ] ; then 
+		    HW="OAI_BLADERF"
+		fi
+		echo_info "Setting hardware to: $HW"
+	    fi
             shift 2;;
-       --oaisim)
+	-t | --transport_protocol)
+            TP="$2" #"${i#*=}"
+	    if [ "$TP" != "ETHERNET" -a "$TP" != "None" ] ; then 
+		echo_fatal "Unknown TP type $TP will exit..."		
+	    else
+		echo_info "Setting transport protocol to: $TP"		
+	    fi
+            shift 2;;
+	--oaisim)
             oaisim=1
             echo_info "Will compile oaisim and drivers nasmesh, ..."
             shift;;
@@ -207,7 +223,7 @@ function main() {
             echo_info "executing test cases only in group: $TEST_CASE_GROUP"
             shift 2;;
        -V | --vcd)
-            echo_info "setting gtk-wave output"
+            echo_info "Setting gtk-wave output"
             VCD_TIMING=1
             EXE_ARGUMENTS="$EXE_ARGUMENTS -V"
             shift;;
@@ -230,7 +246,7 @@ function main() {
             shift;;
        --cflags_processor)
             CFLAGS_PROCESSOR_USER=$2
-            echo_info "setting CPU FLAGS from USER to: $CFLAGS_PROCESSOR_USER"
+            echo_info "Setting CPU FLAGS from USER to: $CFLAGS_PROCESSOR_USER"
             shift 2;;
        --build-doxygen)
 	    BUILD_DOXYGEN=1
@@ -253,6 +269,35 @@ function main() {
             break;;
    esac
   done
+  
+  #########################################################
+  # check validity of HW and TP parameters for RRH and eNB
+  #########################################################
+  # to be discussed
+  
+  if [ "$eNB" = "1" ] ; then
+      if [ "$HW" = "None" -a  "$TP" = "None" ] ; then
+	  echo_fatal "Define a local radio head (e.g. -w EXMIMO) or a transport protocol (e.g. -t ETHERNET) to communicate with a remote radio head!"
+      fi
+      if [ "$HW" != "None" -a  "$TP" != "None" ] ; then
+	  echo_fatal "Currently eNB  can not support simultaniously local and remote radio heads!!"
+      fi      
+      if [ "$HW" = "None" ] ; then 
+	  echo_info "No radio head has been selected (HW set to $HW)"	
+      fi
+      if [ "$TP" = "None" ] ; then
+	  echo_info "No transport protocol has been selected (TP set to $TP)"	
+      fi
+  fi
+  
+  if [ "$RRH" = "1" ] ; then
+      if [ "$TP" = "None" ] ; then
+	  echo_fatal "A transport protocol (e.g. -t ETHERNET) must be defined!"
+      fi
+      if [ "$HW" = "None" ] ; then
+	  echo_info "No radio head has been selected (HW set to $HW)"	
+      fi
+  fi
 
   #Now we set flags to enable deadline scheduler settings
   #By default: USRP: disable, 
@@ -279,6 +324,7 @@ function main() {
 
   echo_info "Flags for Deadline scheduler: $LOWLATENCY_FLAG_USER"
 
+
   ############################################
   # setting and printing OAI envs, we should check here
   ############################################
@@ -317,7 +363,7 @@ function main() {
       check_install_usrp_uhd_driver
     fi 
     if [ "$HW" == "OAI_BLADERF" ] ; then
-      echo_info "installing packages for BALDERF support"
+      echo_info "installing packages for BLADERF support"
       check_install_bladerf_driver
     fi
   fi
@@ -328,9 +374,11 @@ function main() {
   fi
 
   if [ "$oaisim" = "1" ] ; then
-      if [ "$HW" != "ETHERNET" ] ; then 
-	  HW="NONE"
-      fi 
+      #to be discussed
+      # there is no RF device and no transport protocol 
+      HW="None" 
+      TP="None"
+      
       if [ "$XFORMS" == "True" ] ; then 
 	  PRINT_STATS="True"
       fi 
@@ -364,7 +412,8 @@ function main() {
     echo "set ( RRC_ASN1_VERSION \"${REL}\")"      >>  $cmake_file
     echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )"     >>  $cmake_file
     echo "set ( RF_BOARD \"${HW}\")"               >>  $cmake_file
-    echo "set(PACKAGE_NAME \"${lte_exec}\")"     >>  $cmake_file
+    echo "set ( TRANSP_PRO \"${TP}\")"             >>  $cmake_file
+    echo "set(PACKAGE_NAME \"${lte_exec}\")"       >>  $cmake_file
     echo "set (LOWLATENCY \"${LOWLATENCY_FLAG_USER}\" )"    >>$cmake_file
     echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
     cd  $DIR/$lte_build_dir/build
@@ -570,31 +619,97 @@ function main() {
   fi
 
   # RRH compilation
-  ##################
+  #####################
   if [ "$RRH" = "1" ] ; then
-    echo_info "Compiling RRH"
-    if [  $HW == "ETHERNET" ] ; then 
-	echo_info "RF frontend for RRH is not defined. This mode is used for testing (loopback)."
-    elif [ $HW != "EXMIMO" -a $HW != "OAI_USRP" -a $HW != "OAI_BLADERF" ] ; then 
-	echo_fatal "Hardware not defined ($HW)"
-    fi
-    cmake_file=$DIR/rrh_gw/CMakeLists.txt
-    echo "cmake_minimum_required(VERSION 2.8)"   >   $cmake_file
-    echo "set(ENABLE_VCD_FIFO $VCD_TIMING )"     >>  $cmake_file
-    echo "set(ENABLE_ITTI False )"     					 >>  $cmake_file
-    echo "set(RF_BOARD \"${HW}\")"               >>  $cmake_file
-    echo 'set(PACKAGE_NAME "\"rrh_gw\"")' >>  $cmake_file
-    echo "set(LOWLATENCY \"${LOWLATENCY_FLAG_USER}\")"    >>$cmake_file
-    echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
 
-    [ "$CLEAN" = "1" ] && rm -rf $DIR/rrh_gw/build
-    mkdir -p $DIR/rrh_gw/build
-    cd $DIR/rrh_gw/build
-    cmake ..
-    compilations \
-      rrh_gw rrh_gw \
-      rrh_gw $dbin/rrh_gw
+     rrh_exec=rrh_gw
+     rrh_build_dir=rrh_gw
+     
+     echo_info "Compiling $rrh_exec ..."
+    
+     [ "$CLEAN" = "1" ] && rm -rf $DIR/rrh_gw/build 
+     mkdir -p $DIR/$rrh_build_dir/build
+     cmake_file=$DIR/$rrh_build_dir/CMakeLists.txt
+     echo "cmake_minimum_required(VERSION 2.8)"   >   $cmake_file
+     echo "set(ENABLE_VCD_FIFO $VCD_TIMING )"     >>  $cmake_file
+     echo "set(ENABLE_ITTI False )"     		 >>  $cmake_file
+     echo "set(RF_BOARD \"${HW}\")"               >>  $cmake_file
+     echo "set(TRANSP_PRO \"${TP}\")"             >>  $cmake_file
+     echo 'set(PACKAGE_NAME "\"rrh_gw\"")'        >>  $cmake_file
+     echo "set (LOWLATENCY \"${LOWLATENCY_FLAG_USER}\" )"    >>$cmake_file
+     echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file    
+     cd $DIR/$rrh_build_dir/build
+     cmake ..
+     compilations \
+	 rrh_gw rrh_gw \
+	 rrh_gw $dbin/rrh_gw
+
   fi
+  
+  # build RF device and transport protocol libraries
+  #####################################
+  if [ "$eNB" = "1" -o  "$RRH" = "1" ] ; then
+
+      if [ "$eNB" = "1" ] ; then
+	  build_dir=$lte_build_dir	  
+      else
+	  build_dir=$rrh_build_dir	 
+      fi
+
+      # build RF device libraries (currently EXMIMO is not complied with the rest of HW targets)
+      if [ "$HW" != "None" ] ; then
+	  rm -f liboai_device.so
+	  rm -f $dbin/liboai_device.so
+
+
+	  # link liboai_device.so with the selected RF device library
+	  if [ "$HW" == "EXMIMO" ] ; then
+	      
+	      #add exmimo compilation
+	      #TODO EXMIMO library support
+	     
+	      echo_info "liboai_device.so is linked to EXMIMO device library"       
+	  elif [ "$HW" == "OAI_USRP" ] ; then
+	      if [ -d "/usr/include/uhd" ] ; then
+		  compilations \
+		      $build_dir oai_usrpdevif \
+		      liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL
+	      fi
+
+	      ln -s liboai_usrpdevif.so liboai_device.so
+	      ln -s $dbin/liboai_usrpdevif.so.$REL $dbin/liboai_device.so
+	      echo_info "liboai_device.so is linked to USRP device library"        
+	  elif [ "$HW" == "OAI_BLADERF" ] ; then
+	      if [ -f "/usr/include/libbladeRF.h" ] ; then
+		  compilations \
+		      $build_dir oai_bladerfdevif \
+		      liboai_bladerfdevif.so $dbin/liboai_bladerfdevif.so.$REL
+	      fi
+
+	      ln -s liboai_bladerfdevif.so liboai_device.so
+	      ln -s $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so
+	      echo_info "liboai_device.so is linked to BLADERF device library"	 
+	  else 
+	      echo_info "liboai_device.so is not linked to any device library"	    
+	  fi
+      fi
+      
+      # build trasport protocol libraries (currently only ETHERNET is available)
+      if [ "$TP" != "None" ] ; then
+	  rm -f liboai_transpro.so
+	  rm -f $dbin/liboai_transpro.so
+
+	  if [ "$TP" == "ETHERNET" ] ; then
+	      compilations \
+		  $build_dir oai_eth_transpro \
+		  liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL
+	      ln -s liboai_eth_transpro.so liboai_transpro.so
+	      ln -s $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
+	      echo_info "liboai_transpro.so is linked with ETHERNET library"	 
+	  fi      
+      fi
+fi
+
 
   # Doxygen Support
   #####################
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 496096e9727218981330afbf5c89953996111325..d29dbffe13d8997255e7c0be42eeb2f37af5a0c6 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -180,7 +180,7 @@ check_install_bladerf_driver(){
 	$SUDO apt-get install -y bladerf libbladerf-dev
 	$SUDO apt-get install -y bladerf-firmware-fx3
 	$SUDO apt-get install -y bladerf-fpga-hostedx40	
-	bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img	
+	$SUDO bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img	
 }
 
 check_install_additional_tools (){
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index dc0b79e4714f65bb8a8b66e325e56e2cb287b684..f308c0500aca2bd6908625c9a63cee6947a21b1c 100755
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -76,6 +76,13 @@
 #define openair_free(y,x) free((y))
 #define PAGE_SIZE 4096
 
+//#ifdef SHRLIBDEV
+//extern int rxrescale;
+//#define RX_IQRESCALELEN rxrescale
+//#else
+//#define RX_IQRESCALELEN 15
+//#endif
+
 //! \brief Allocate \c size bytes of memory on the heap with alignment 16 and zero it afterwards.
 //! If no more memory is available, this function will terminate the program with an assertion error.
 static inline void* malloc16_clear( size_t size )
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 07e0ffa6406da3494da46822a28a470a78e2f179..b437c7e2640a318919ad2dfda0f1fa550e8035ae 100755
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -170,6 +170,14 @@
 #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_RRH_GW_CONFIG                   "rrh_gw_config"
+#define ENB_CONFIG_STRING_RRH_GW_LOCAL_IF_NAME            "local_if_name"
+#define ENB_CONFIG_STRING_RRH_GW_LOCAL_ADDRESS            "local_address"
+#define ENB_CONFIG_STRING_RRH_GW_REMOTE_ADDRESS           "remote_address"
+#define ENB_CONFIG_STRING_RRH_GW_LOCAL_PORT               "local_port"
+#define ENB_CONFIG_STRING_RRH_GW_REMOTE_PORT              "remote_port"
+#define ENB_CONFIG_STRING_RRH_GW_ACTIVE                   "active"
+#define ENB_CONFIG_STRING_RRH_GW_PREFERENCE               "preference"
 
 #define ENB_CONFIG_STRING_ASN1_VERBOSITY                   "Asn1_verbosity"
 #define ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE              "none"
@@ -274,6 +282,18 @@ static void enb_config_display(void)
     } else {
       printf( "\tMNC:                \t%02"PRIu16":\n",enb_properties.properties[i]->mnc);
     }
+    
+    for (j=0; j< enb_properties.properties[i]->nb_rrh_gw; j++) {
+      if (enb_properties.properties[i]->rrh_gw_config[j].active == 1 ){
+	printf( "\n\tRRH GW %d config for eNB %u:\n\n", j, i);
+	printf( "\tinterface name :       \t%s:\n",enb_properties.properties[i]->rrh_gw_if_name);
+	printf( "\tlocal address  :       \t%s:\n",enb_properties.properties[i]->rrh_gw_config[j].local_address);
+	printf( "\tlocal port     :       \t%d:\n",enb_properties.properties[i]->rrh_gw_config[j].local_port);
+	printf( "\tremote address :       \t%s:\n",enb_properties.properties[i]->rrh_gw_config[j].remote_address);
+	printf( "\tremote port    :       \t%d:\n",enb_properties.properties[i]->rrh_gw_config[j].remote_port);
+	printf( "\ttransport      :       \t%s Ethernet:\n\n",(enb_properties.properties[i]->rrh_gw_config[j].raw == 1)? "RAW" : "UDP");
+      }
+    }
 
     for (j=0; j< enb_properties.properties[i]->nb_cc; j++) {
       printf( "\teutra band for CC %d:         \t%"PRId16":\n",j,enb_properties.properties[i]->eutra_band[j]);
@@ -455,6 +475,8 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
   config_setting_t *setting_srb1                  = NULL;
   config_setting_t *setting_mme_addresses         = NULL;
   config_setting_t *setting_mme_address           = NULL;
+  config_setting_t *setting_rrh_gws               = NULL;
+  config_setting_t *setting_rrh_gw                = NULL;
   config_setting_t *setting_enb                   = NULL;
   config_setting_t *setting_otg                   = NULL;
   config_setting_t *subsetting_otg                   = NULL;
@@ -462,6 +484,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
   int               enb_properties_index          = 0;
   int               num_enbs                      = 0;
   int               num_mme_address               = 0;
+  int               num_rrh_gw                    = 0;
   int               num_otg_elements              =0;
   int               num_component_carriers        =0;
   int               i                             = 0;
@@ -558,10 +581,15 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
 
   libconfig_int     my_int;
 
+
+  char*             if_name                       = NULL;
   char*             ipv4                          = NULL;
+  char*             ipv4_remote                   = NULL;
   char*             ipv6                          = NULL;
   char*             active                        = NULL;
   char*             preference                    = NULL;
+  libconfig_int     local_port                    = 0;
+  libconfig_int     remote_port                   = 0;
   const char*       active_enb[MAX_ENB];
   char*             enb_interface_name_for_S1U    = NULL;
   char*             enb_ipv4_address_for_S1U      = NULL;
@@ -2136,6 +2164,63 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
               enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1;
             }
           }
+	  // RRH Config 
+	  setting_rrh_gws = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_RRH_GW_CONFIG);
+	  if ( setting_rrh_gws != NULL) {
+          num_rrh_gw     = config_setting_length(setting_rrh_gws);
+          enb_properties.properties[enb_properties_index]->nb_rrh_gw = 0;
+
+          for (j = 0; j < num_rrh_gw; j++) {
+            setting_rrh_gw = config_setting_get_elem(setting_rrh_gws, j);
+
+            if (  !(
+                   config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_IF_NAME, (const char **)&if_name)
+		   && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_ADDRESS, (const char **)&ipv4)
+                   && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_ADDRESS , (const char **)&ipv4_remote)
+                   && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_PORT, &local_port)
+                   && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_PORT, &remote_port)
+                   && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_ACTIVE, (const char **)&active)
+                   && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_PREFERENCE, (const char **)&preference)
+                 )
+              ) {
+              AssertError (0, parse_errors ++,
+                           "Failed to parse eNB configuration file %s, %u th enb %u the RRH GW address !\n",
+                           lib_config_file_name_pP, i, j);
+              continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
+            }
+
+            enb_properties.properties[enb_properties_index]->nb_rrh_gw += 1;
+
+	    enb_properties.properties[enb_properties_index]->rrh_gw_if_name = strdup(if_name);
+            enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_address  = strdup(ipv4);
+            enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_address = strdup(ipv4_remote);
+	    enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_port= local_port;
+	    enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_port= remote_port;
+
+            if (strcmp(active, "yes") == 0) {
+              enb_properties.properties[enb_properties_index]->rrh_gw_config[j].active = 1;
+            } 
+
+            if (strcmp(preference, "udp") == 0) {
+              enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1;
+            } else if (strcmp(preference, "raw") == 0) {
+              enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1;
+            } else {//if (strcmp(preference, "no") == 0) 
+              enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1;
+              enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1;
+            }
+          }
+	  } else {
+	    enb_properties.properties[enb_properties_index]->nb_rrh_gw = 0;	    
+	    enb_properties.properties[enb_properties_index]->rrh_gw_if_name = "none";
+            enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_address  = "0.0.0.0";
+            enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_address = "0.0.0.0";
+	    enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_port= 0;
+	    enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_port= 0;	    
+	    enb_properties.properties[enb_properties_index]->rrh_gw_config[j].active = 0;	    
+	    enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 0;
+	    enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 0;
+	  }
 
           // SCTP SETTING
           enb_properties.properties[enb_properties_index]->sctp_out_streams = SCTP_OUT_STREAMS;
diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h
index 113681dafe62cd476c14ace0c09dc1644a1b4b62..9c271ca4f4ae5c087da9d9ffceea8c0e2e5b72e0 100755
--- a/openair2/ENB_APP/enb_config.h
+++ b/openair2/ENB_APP/enb_config.h
@@ -78,6 +78,17 @@ typedef struct mme_ip_address_s {
   char     *ipv6_address;
 } mme_ip_address_t;
 
+typedef struct rrh_gw_config_s {
+  unsigned  udp:1;
+  unsigned  raw:1;
+  unsigned  active:1;
+  char     *local_address;
+  char     *remote_address;
+  uint16_t  local_port;
+  uint16_t  remote_port;
+
+} rrh_gw_config_t;
+
 typedef struct Enb_properties_s {
   /* Unique eNB_id to identify the eNB within EPC.
    * For macro eNB ids this field should be 20 bits long.
@@ -203,6 +214,13 @@ typedef struct Enb_properties_s {
   char               *enb_interface_name_for_S1_MME;
   in_addr_t           enb_ipv4_address_for_S1_MME;
 
+
+  /* Nb of RRH to connect to */
+  uint8_t             nb_rrh_gw;
+  char               *rrh_gw_if_name;
+  /* List of MME to connect to */
+  rrh_gw_config_t       rrh_gw_config[4];
+
   // otg config
   /* Nb of OTG elements */
   uint8_t            num_otg_elements;
diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.c b/openair2/UTIL/LOG/vcd_signal_dumper.c
index 8dfbfd6ef5cb9d9d666a9c4e09591fa164fbee3f..31ce2e0d71078bd4d12586db7a27ba861a61a6d9 100644
--- a/openair2/UTIL/LOG/vcd_signal_dumper.c
+++ b/openair2/UTIL/LOG/vcd_signal_dumper.c
@@ -106,6 +106,9 @@ const char* eurecomVariablesNames[] = {
   "lhw_cnt_tx",
   "pck_rx",
   "pck_tx",
+  "rx_seq_num",
+  "rx_seq_num_prv",
+  "tx_seq_num",
   "cnt",
   "dummy_dump",
   "itti_send_msg",
diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h
index 68257484f0a1c141d3f1a2392f157d729b09d3f9..9ca55846fd2aef75d3da598dbdd4f250a6591db6 100644
--- a/openair2/UTIL/LOG/vcd_signal_dumper.h
+++ b/openair2/UTIL/LOG/vcd_signal_dumper.h
@@ -78,6 +78,9 @@ typedef enum {
   VCD_SIGNAL_DUMPER_VARIABLES_TX_LHWCNT,
   VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK,
   VCD_SIGNAL_DUMPER_VARIABLES_TX_PCK,
+  VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM,
+  VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM_PRV,
+  VCD_SIGNAL_DUMPER_VARIABLES_TX_SEQ_NUM,
   VCD_SIGNAL_DUMPER_VARIABLES_CNT,
   VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP,
   VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG,
diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
index cfcc8f405992748522af971af85c1e9fe9231234..69677beaecf4c483a56c63c5defd643894d4d0ca 100644
--- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
+++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
@@ -887,14 +887,18 @@ void calibrate_rf(openair0_device *device) {
  * \param openair0_cfg RF frontend parameters set by application
  */
 int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg) {
-
   int status;
   int card=0;
   
   brf_state_t *brf = (brf_state_t*)malloc(sizeof(brf_state_t));
   memset(brf, 0, sizeof(brf_state_t));
+  /* device specific */
+  openair0_cfg->txlaunch_wait = 1;//manage when TX processing is triggered
+  openair0_cfg->txlaunch_wait_slotcount = 1; //manage when TX processing is triggered
+  openair0_cfg->iq_txshift = 0;// shift
+  openair0_cfg->iq_rxrescale = 15;//rescale iqs
+  
   // init required params
-
   switch ((int)openair0_cfg->sample_rate) {
   case 30720000:
     openair0_cfg->samples_per_packet    = 2048;
@@ -921,7 +925,8 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai
     exit(-1);
     break;
   }
-
+  openair0_cfg->iq_txshift= 0;
+  openair0_cfg->iq_rxrescale = 15; /*not sure*/
   openair0_cfg->rx_gain_calib_table = calib_table_fx4;
 
   //  The number of buffers to use in the underlying data stream
@@ -1065,6 +1070,7 @@ int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openai
   printf("BLADERF: Initializing openair0_device\n");
   device->priv           = brf; 
   device->Mod_id         = num_devices++;
+  device->type             = BLADERF_DEV; 
   device->trx_start_func = trx_brf_start;
   device->trx_end_func   = trx_brf_end;
   device->trx_read_func  = trx_brf_read;
diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c
index 7479a6aa0b475ebd7b53efd38b9e13b36f2b7e89..6ba59660b3301eec1ecad4c0f9f5a3d40db3cfc4 100644
--- a/targets/ARCH/COMMON/common_lib.c
+++ b/targets/ARCH/COMMON/common_lib.c
@@ -37,31 +37,136 @@
  * \warning
  */
 #include <stdio.h>
+#include <strings.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <string.h>
+
 #include "common_lib.h"
 
+int set_device(openair0_device *device) {
+
+  switch (device->type) {
+    
+  case EXMIMO_DEV:
+    printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
+    break;
+  case USRP_B200_DEV:
+    printf("[%s] has loaded USRP B200 device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); 
+    break;
+case USRP_X300_DEV:
+    printf("[%s] has loaded USRP X300 device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); 
+    break;
+  case BLADERF_DEV:
+    printf("[%s] has loaded BLADERF device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); 
+    break;
+  case NONE_DEV:
+    printf("[%s] has not loaded a HW device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
+    break;    
+  default:
+    printf("[%s] invalid HW device.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); 
+    return -1;
+  }
+  return 0;
+}
+
+int set_transport(openair0_device *device) {
+
+  switch (device->transp_type) {
+    
+  case ETHERNET_TP:
+    printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
+    return 0;     
+    break;
+  case NONE_TP:
+    printf("[%s] has not loaded a transport protocol.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"));
+    return 0; 
+    break;    
+  default:
+    printf("[%s] invalid transport protocol.\n",((device->host_type == BBU_HOST) ? "BBU": "RRH")); 
+    return -1;
+    break;
+  }
+  
+}
+
+/* look for the interface library and load it */
+int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * cfg, uint8_t flag) {
+  
+  void *lib_handle;
+  oai_device_initfunc_t dp ;
+  oai_transport_initfunc_t tp ;
+
+  if (flag == BBU_LOCAL_RADIO_HEAD) {
+      lib_handle = dlopen(OAI_RF_LIBNAME, RTLD_LAZY);
+      if (!lib_handle) {
+	printf( "Unable to locate %s: HW device set to NONE_DEV.\n", OAI_RF_LIBNAME);
+	return 0;
+      } 
+      
+      dp = dlsym(lib_handle,"device_init");
+      
+      if (dp != NULL ) {
+	dp(device,openair0_cfg);
+      } else {
+	fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror());
+	return -1;
+      }
+    } else {
+      lib_handle = dlopen(OAI_TP_LIBNAME, RTLD_LAZY);
+      if (!lib_handle) {
+	printf( "Unable to locate %s: transport protocol set to NONE_TP.\n", OAI_TP_LIBNAME);
+	return 0;
+      } 
+      
+      tp = dlsym(lib_handle,"transport_init");
+      
+      if (tp != NULL ) {
+	tp(device,openair0_cfg,cfg);
+      } else {
+	fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror());
+	return -1;
+      }
+    } 
+    
+  return 0; 	       
+}
+
+
 
-int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
+int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) {
   
-#ifdef ETHERNET 
-  device->type=ETH_IF; 
-  device->func_type = BBU_FUNC;
-  printf(" openair0_dev_init_eth ...\n");
-  return(openair0_dev_init_eth(device, openair0_cfg));
-
-#elif EXMIMO
-  device->type=EXMIMO_IF;
-  printf("openair0_dev_init_exmimo...\n");
-  return(openair0_dev_init_exmimo(device, openair0_cfg));
-#elif OAI_USRP
-  device->type=USRP_B200_IF;
-  printf("openair0_dev_init_usrp ...\n");
-  return(openair0_dev_init_usrp(device, openair0_cfg));
-
-#elif OAI_BLADERF  
-  device->type=BLADERF_IF;
-  printf(" openair0_dev_init_bladerf ...\n");   
-  return(openair0_dev_init_bladerf(device, openair0_cfg));	
-
-#endif 
-   
+  int rc;
+  //ToDo: EXMIMO harmonization is not complete. That is the reason for this ifdef
+  #ifdef EXMIMO
+  device_init(device, openair0_cfg);
+  #else
+  rc=load_lib(device, openair0_cfg, NULL,BBU_LOCAL_RADIO_HEAD );
+  if ( rc >= 0) {       
+    if ( set_device(device) < 0) {
+      fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__);
+      return -1;		   
+    }   
+  }
+  #endif
+  return 0;
+}
+
+int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params) {
+  int rc;
+  rc=load_lib(device, openair0_cfg, eth_params, BBU_REMOTE_RADIO_HEAD);
+  if ( rc >= 0) {       
+    if ( set_transport(device) < 0) {
+      fprintf(stderr, "%s %d:Unsupported transport protocol\n",__FILE__, __LINE__);
+      return -1;		   
+      }   
+  }
+  return 0;
 }
+
+
+
+
+
+
+
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index bc5845cbcb34e6237503e45a0ea5cc14aded02d2..0abe8fd22e47448c5768cebb5d3b4b9a03ad5ddf 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -42,6 +42,15 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+/* name of shared library implementing the radio front end */
+#define OAI_RF_LIBNAME        "liboai_device.so"
+/* name of shared library implementing the transport */
+#define OAI_TP_LIBNAME        "liboai_transpro.so"
+
+/* flags for BBU to determine whether the attached radio head is local or remote */
+#define BBU_LOCAL_RADIO_HEAD  0
+#define BBU_REMOTE_RADIO_HEAD 1
+
 typedef int64_t openair0_timestamp;
 typedef volatile int64_t openair0_vtimestamp;
 
@@ -65,9 +74,52 @@ typedef enum {
 } duplex_mode_t;
 
 
+
 /** @addtogroup _GENERIC_PHY_RF_INTERFACE_
  * @{
  */
+/*!\brief RF device types
+ */
+typedef enum {
+  MIN_RF_DEV_TYPE = 0,
+  /*!\brief device is ExpressMIMO */
+  EXMIMO_DEV,
+  /*!\brief device is USRP B200/B210*/
+  USRP_B200_DEV,
+  /*!\brief device is USRP X300/X310*/
+  USRP_X300_DEV,
+  /*!\brief device is BLADE RF*/
+  BLADERF_DEV,
+  /*!\brief device is NONE*/
+  NONE_DEV,
+  MAX_RF_DEV_TYPE
+
+} dev_type_t;
+
+/*!\brief transport protocol types
+ */
+typedef enum {
+  MIN_TRANSP_TYPE = 0,
+  /*!\brief transport protocol ETHERNET */
+  ETHERNET_TP,
+  /*!\brief no transport protocol*/
+  NONE_TP,
+  MAX_TRANSP_TYPE
+
+} transport_type_t;
+
+
+/*!\brief  openair0 device host type */
+typedef enum {
+  MIN_HOST_TYPE = 0,
+ /*!\brief device functions within a BBU */
+  BBU_HOST,
+ /*!\brief device functions within a RRH */
+  RRH_HOST,
+  MAX_HOST_TYPE
+
+}host_type_t;
+
 
 /*! \brief RF Gain clibration */ 
 typedef struct {
@@ -92,11 +144,15 @@ typedef struct {
   //! the sample rate for both transmit and receive.
   double sample_rate;
   //! number of samples per RX/TX packet (USRP + Ethernet)
-  int samples_per_packet;
+  unsigned int samples_per_packet; 
   //! delay in sending samples (write)  due to hardware access, softmodem processing and fronthaul delay if exist
   int tx_scheduling_advance;
   //! offset in samples between TX and RX paths
   int tx_sample_advance;
+  //! configurable tx thread lauch delay 
+  int txlaunch_wait;               /* 1 or 0 */
+  //! configurable tx thread lauch delay 
+  int txlaunch_wait_slotcount;
   //! number of RX channels (=RX antennas)
   int rx_num_channels;
   //! number of TX channels (=TX antennas)
@@ -127,14 +183,18 @@ typedef struct {
   double tx_bw;
   //! Auto calibration flag
   int autocal[4];
-  //! RRH IP addr for Ethernet interface
-  char *remote_ip;
-  //! RRH port number for Ethernet interface
-  int remote_port;
-  //! my IP addr for Ethernet interface (eNB/BBU, UE)
-  char *my_ip;
-  //! my port number for Ethernet interface (eNB/BBU, UE)
-  int my_port;
+  //! rf devices work with x bits iqs when oai have its own iq format
+  //! the two following parameters are used to convert iqs 
+  int iq_txshift;
+  int iq_rxrescale;
+  //! remote IP/MAC addr for Ethernet interface
+  char *remote_addr;
+  //! remote port number for Ethernet interface
+  unsigned int remote_port;
+  //! local IP/MAC addr for Ethernet interface (eNB/BBU, UE)
+  char *my_addr;
+  //! local port number for Ethernet interface (eNB/BBU, UE)
+  unsigned int my_port;
 
 } openair0_config_t;
 
@@ -146,60 +206,39 @@ typedef struct {
   int chain;
 } openair0_rf_map;
 
-
-
-/*!\brief interface types that apply to modules (RRH_BBU/RRH_UE) created in RRH (rrh_gw.c)
-          and are defined with respect to the RF device that is present in RRH
-          -RRH_BBU modules have two devices, one is by default ETHERNET (will have ETH_IF) and the other one is a
-	  RF device (EXMIMO,USRP,BLADERF) or no device (NONE_IF).
-          -RRH_UE modules have two devices one is by default ETHERNET (will have ETH_IF) 
-	  and the other one by default not present so it will have NONE_IF
- */
-typedef enum {
-  MIN_DEV_TYPE = 0,
-  /*!\brief device is ETH */
-  ETH_IF,
-  /*!\brief device is ExpressMIMO */
-  EXMIMO_IF,
-  /*!\brief device is USRP B200/B210*/
-  USRP_B200_IF,
-  /*!\brief device is USRP X300/X310*/
-  USRP_X300_IF,
-  /*!\brief device is BLADE RF*/
-  BLADERF_IF,
-  /*!\brief device is NONE*/
-  NONE_IF,
-  MAX_DEV_TYPE
-
-} dev_type_t;
-
-
-/*!\brief  openair0 device host type */
-typedef enum {
-  MIN_FUNC_TYPE = 0,
- /*!\brief device functions within a BBU */
-  BBU_FUNC,
- /*!\brief device functions within a RRH */
-  RRH_FUNC,
-  MAX_FUNC_TYPE
-
-}func_type_t;
-
-/*!\brief structrue holds the parameters to configure USRP devices */
+typedef struct {
+  char *remote_addr;
+  //! remote port number for Ethernet interface
+  unsigned int remote_port;
+  //! local IP/MAC addr for Ethernet interface (eNB/BBU, UE)
+  char *my_addr;
+  //! local port number for Ethernet interface (eNB/BBU, UE)
+  unsigned int my_port;
+  //! local port number for Ethernet interface (eNB/BBU, UE)
+  char *local_if_name;
+ //! local port number for Ethernet interface (eNB/BBU, UE)
+  uint8_t transp_preference;
+} eth_params_t;
+
+
+/*!\brief structure holds the parameters to configure USRP devices */
 struct openair0_device_t {
-  //! Module ID of this device 
+  /*!brief Module ID of this device */
   int Mod_id;
   
-  //! Type of this device 
+  /*!brief Type of this device */
   dev_type_t type;
 
-  //! Type of the device's host (BBU/RRH)
-  func_type_t func_type;
+  /*!brief Transport protocol type that the device suppports (in case I/Q samples need to be transported) */
+  transport_type_t transp_type;
+
+   /*!brief Type of the device's host (BBU/RRH) */
+  host_type_t host_type;
 
-  //! RF frontend parameters set by application 
+  /* !brief RF frontend parameters set by application */
   openair0_config_t *openair0_cfg;
 
-  //! Can be used by driver to hold internal structure
+  /*!brief Can be used by driver to hold internal structure*/
   void *priv;
 
   /* Functions API, which are called by the application*/
@@ -287,17 +326,22 @@ struct openair0_device_t {
 
 };
 
+/* type of device init function, implemented in shared lib */
+typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg);
+/* type of transport init function, implemented in shared lib */
+typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params);
 
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
- /*! \brief Initialize Openair RF target. It returns 0 if OK 
-   * \param device the hardware to use
-   * \param openair0_cfg RF frontend parameters set by application
- */
-  int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg);
+
+  /*! \brief Initialize openair RF target. It returns 0 if OK */
+  int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg);  
+  /*! \brief Initialize transport protocol . It returns 0 if OK */
+  int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params);
+
   
  /*! \brief Get current timestamp of USRP
   * \param device the hardware to use
@@ -310,31 +354,7 @@ extern "C"
   * \returns 0 in success 
   */
   int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
-  
-  //extern functions
-  /*! \brief Initialize Openair ETHERNET target. It returns 0 if OK 
-   * \param device the hardware to use
-   * \param openair0_cfg RF frontend parameters set by application
-  */
-  int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg);
-
-  /*! \brief Initialize Openair BLADERF target. It returns 0 if OK 
-   * \param device the hardware to use
-   * \param openair0_cfg RF frontend parameters set by application
-  */
-  int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg);
-
-  /*! \brief Initialize Openair USRP target. It returns 0 if OK
-   * \param device the hardware to use
-   * \param openair0_cfg RF frontend parameters set by application
-  */
-  int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg);
 
-  /*! \brief Initialize Openair EXMIMO target. It returns 0 if OK 
-   * \param device the hardware to use
-   * \param openair0_cfg RF frontend parameters set by application
-  */
-  int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg);
 /*@}*/
 
 #ifdef __cplusplus
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
new file mode 100644
index 0000000000000000000000000000000000000000..a360f2655656906a885fde7281847ade2ecc8192
--- /dev/null
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
@@ -0,0 +1,319 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenAirInterface.The full GNU General Public License is
+    included in this distribution in the file called "COPYING". If not,
+    see <http://www.gnu.org/licenses/>.
+
+   Contact Information
+   OpenAirInterface Admin: openair_admin@eurecom.fr
+   OpenAirInterface Tech : openair_tech@eurecom.fr
+   OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+   Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+
+ *******************************************************************************/
+/*! \file ethernet_lib.c 
+ * \brief API to stream I/Q samples over standard ethernet
+ * \author  add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp
+ * \date 2015
+ * \version 0.2
+ * \company Eurecom
+ * \maintainer:  navid.nikaein@eurecom.fr
+ * \note
+ * \warning 
+ */
+
+#include <arpa/inet.h>
+#include <linux/if_packet.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/ether.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "common_lib.h"
+#include "ethernet_lib.h"
+
+#define DEBUG 0
+
+struct sockaddr_ll dest_addr[MAX_INST];
+struct sockaddr_ll local_addr[MAX_INST];
+int addr_len[MAX_INST];
+struct ifreq if_index[MAX_INST];
+struct ether_header eh; 
+
+int eth_socket_init_raw(openair0_device *device) {
+ 
+  int i = 0;
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  int Mod_id = device->Mod_id;
+  const char *local_mac, *remote_mac;
+  int local_port=0, remote_port=0;
+  int sock_dom=0;
+  int sock_type=0;
+  int sock_proto=0;  
+ 
+  if (device->host_type == RRH_HOST ) {  /* RRH doesn't know remote MAC(will be retrieved from first packet send from BBU) and remote port(don't care) */
+    local_mac = device->openair0_cfg->my_addr; 
+    local_port = device->openair0_cfg->my_port;    
+    remote_mac = malloc(ETH_ALEN);
+    memset(remote_mac,0,ETH_ALEN);
+    remote_port = 0;    
+    printf("[%s] local MAC addr %s remote MAC addr %s\n","RRH", local_mac,remote_mac);    
+  } else {
+    local_mac = device->openair0_cfg->my_addr;
+    local_port = device->openair0_cfg->my_port;  
+    remote_mac = device->openair0_cfg->remote_addr;
+    remote_port = device->openair0_cfg->remote_port;  
+    printf("[%s] local MAC addr %s remote MAC addr %s\n","BBU", local_mac,remote_mac);    
+  }
+   
+  
+  /* Open a RAW socket to send on */
+  sock_dom=AF_PACKET;
+  sock_type=SOCK_RAW;
+  sock_proto=IPPROTO_RAW;
+  if ((eth->sockfd[Mod_id] = socket(sock_dom, sock_type, sock_proto)) == -1) {
+    perror("ETHERNET: Error opening RAW socket");
+    exit(0);
+  }
+  
+  /* initialize destination address */
+  for (i=0; i< MAX_INST; i++) {
+    bzero((void *)&(local_addr[i]), sizeof(struct sockaddr_ll));
+    bzero((void *)&(if_index[i]), sizeof(struct ifreq)); 
+  }
+  /* Get the index of the interface to send on */
+  strcpy(if_index[Mod_id].ifr_name,eth->if_name[Mod_id]);
+  if (ioctl(eth->sockfd[Mod_id], SIOCGIFINDEX, &(if_index[Mod_id])) < 0)
+    perror("SIOCGIFINDEX");
+   
+  local_addr[Mod_id].sll_family   = AF_PACKET;
+  local_addr[Mod_id].sll_ifindex  = if_index[Mod_id].ifr_ifindex;
+  /* hear traffic from specific protocol*/
+  local_addr[Mod_id].sll_protocol = htons((short)device->openair0_cfg->my_port);
+  local_addr[Mod_id].sll_halen    = ETH_ALEN;
+  local_addr[Mod_id].sll_pkttype  = PACKET_OTHERHOST;
+  addr_len[Mod_id] = sizeof(struct sockaddr_ll);
+  
+ if (bind(eth->sockfd[Mod_id],(struct sockaddr *)&local_addr[Mod_id],addr_len[Mod_id])<0) {
+   perror("ETHERNET: Cannot bind to socket");
+   exit(0);
+ }
+ 
+ /* Construct the Ethernet header */ 
+ ether_aton_r(local_mac, (struct ether_addr *)(&(eh.ether_shost)));
+ ether_aton_r(remote_mac, (struct ether_addr *)(&(eh.ether_dhost)));
+ eh.ether_type = htons((short)device->openair0_cfg->my_port);
+
+ printf("[%s] binding mod_%d to hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),Mod_id,eh.ether_shost[0],eh.ether_shost[1],eh.ether_shost[2],eh.ether_shost[3],eh.ether_shost[4],eh.ether_shost[5]);
+ 
+ return 0;
+}
+
+
+int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {
+  
+  int bytes_sent=0;
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  int Mod_id = device->Mod_id;
+  int sendto_flag =0;
+  int i=0;
+  //sendto_flag|=flags;
+
+  eth->tx_nsamps=nsamps;
+
+  for (i=0;i<cc;i++) {	
+    /* buff[i] points to the position in tx buffer where the payload to be sent is
+       buff2 points to the position in tx buffer where the packet header will be placed */
+    void *buff2 = (void*)(buff[i]-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES); 
+    
+    /* we don't want to ovewrite with the header info the previous tx buffer data so we store it*/
+    struct ether_header temp =  *(struct ether_header *)buff2;
+    int32_t temp0 = *(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES);
+    openair0_timestamp  temp1 = *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t));
+    
+    bytes_sent = 0;
+    memcpy(buff2,(void*)&eh,MAC_HEADER_SIZE_BYTES);
+    *(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t))=1+(i<<1);
+    *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = timestamp;
+    
+    /*printf("[RRH]write mod_%d %d , len %d, buff %p \n",
+      Mod_id,eth->sockfd[Mod_id],RAW_PACKET_SIZE_BYTES(nsamps), buff2);*/
+    
+    while(bytes_sent < RAW_PACKET_SIZE_BYTES(nsamps)) {
+#if DEBUG   
+      printf("------- TX ------: buff2 current position=%d remaining_bytes=%d  bytes_sent=%d \n",
+	     (void *)(buff2+bytes_sent), 
+	     RAW_PACKET_SIZE_BYTES(nsamps) - bytes_sent,
+	     bytes_sent);
+#endif
+      /* Send packet */
+      bytes_sent += send(eth->sockfd[Mod_id],
+			   buff2, 
+			   RAW_PACKET_SIZE_BYTES(nsamps),
+			   sendto_flag);
+      if ( bytes_sent == -1) {
+	eth->num_tx_errors++;
+	perror("ETHERNET WRITE: ");
+	exit(-1);
+      } else {
+#if DEBUG
+	printf("------- TX ------: nu=%x an_id=%d ts%d bytes_sent=%d\n",
+	       *(uint8_t *)(buff2+ETH_ALEN),
+	       *(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t)),
+	       *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)),
+	       bytes_sent);
+    dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, RAW_PACKET_SIZE_BYTES(nsamps), TX_FLAG);
+#endif
+    eth->tx_actual_nsamps=bytes_sent>>2;
+    eth->tx_count++;
+      }
+    }    			    
+    
+  /* tx buffer values restored */  
+    *(struct ether_header *)buff2 = temp;
+    *(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES) = temp0;
+    *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = temp1;
+  }
+  return (bytes_sent-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES)>>2;
+}
+
+
+int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
+      
+  int bytes_received=0;
+  int i=0;
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  int Mod_id = device->Mod_id;
+  int rcvfrom_flag =0;
+  
+  eth->rx_nsamps=nsamps;
+
+  for (i=0;i<cc;i++) {
+      /* buff[i] points to the position in rx buffer where the payload to be received will be placed
+	 buff2 points to the position in rx buffer where the packet header will be placed */
+      void *buff2 = (void*)(buff[i]-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES); 
+      
+      /* we don't want to ovewrite with the header info the previous rx buffer data so we store it*/
+      struct ether_header temp =  *(struct ether_header *)buff2;
+      int32_t temp0 = *(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES);
+      openair0_timestamp  temp1 = *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t));
+      
+      bytes_received=0;
+      
+      while(bytes_received < RAW_PACKET_SIZE_BYTES(nsamps)) {
+	bytes_received +=recv(eth->sockfd[Mod_id],
+			      buff2,
+			      RAW_PACKET_SIZE_BYTES(nsamps),
+			      rcvfrom_flag);
+	
+	if (bytes_received ==-1) {
+	  eth->num_rx_errors++;
+	  perror("ETHERNET READ: ");
+	  exit(-1);	
+	} else {
+	  /* store the timestamp value from packet's header */
+	  *timestamp =  *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t));  
+	  eth->rx_actual_nsamps=bytes_received>>2;   
+	  eth->rx_count++;
+	}
+      }
+      
+#if DEBUG   
+      printf("------- RX------: nu=%x an_id=%d ts%d bytes_recv=%d \n",
+	     *(uint8_t *)(buff2+ETH_ALEN),
+	     *(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t)),
+	     *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)),
+	     bytes_received);
+      dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, RAW_PACKET_SIZE_BYTES(nsamps),RX_FLAG);	  
+
+#endif  
+
+     /* tx buffer values restored */  
+      *(struct ether_header *)buff2 = temp;
+      *(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES) = temp0;
+      *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = temp1;
+    }
+  return (bytes_received-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES)>>2;
+}
+
+ 
+
+
+int eth_set_dev_conf_raw(openair0_device *device) {
+
+  int 	       Mod_id = device->Mod_id;
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  void 	      *msg;
+  ssize_t      msg_len;
+  
+  /* a BBU client sends to RRH a set of configuration parameters (openair0_config_t)
+     so that RF front end is configured appropriately and
+     frame/packet size etc. can be set */ 
+  
+  msg = malloc(MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t));
+  msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t);
+
+  
+  memcpy(msg,(void*)&eh,MAC_HEADER_SIZE_BYTES);	
+  memcpy((msg+MAC_HEADER_SIZE_BYTES),(void*)device->openair0_cfg,sizeof(openair0_config_t));
+ 	  
+  if (send(eth->sockfd[Mod_id],
+	     msg,
+	     msg_len,
+	     0)==-1) {
+    perror("ETHERNET: ");
+    exit(0);
+  }
+  
+  return 0;
+}
+
+
+int eth_get_dev_conf_raw(openair0_device *device) {
+
+  eth_state_t   *eth = (eth_state_t*)device->priv;
+  int 		Mod_id = device->Mod_id;
+  char 		str[INET_ADDRSTRLEN];
+  void 		*msg;
+  ssize_t	msg_len;
+  
+  msg = malloc(MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t));
+  msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t);
+  
+  /* RRH receives from BBU openair0_config_t */
+  if (recv(eth->sockfd[Mod_id],
+	   msg,
+	   msg_len,
+	   0)==-1) {
+    perror("ETHERNET: ");
+    exit(0);
+  }
+  
+  /* RRH stores the remote MAC address */
+  memcpy(eh.ether_dhost,(msg+ETH_ALEN),ETH_ALEN);	
+  //memcpy((void*)&device->openair0_cfg,(msg + MAC_HEADER_SIZE_BYTES), sizeof(openair0_config_t));
+  device->openair0_cfg=(openair0_config_t *)(msg + MAC_HEADER_SIZE_BYTES);
+  printf("[%s] binding mod_%d to hardware address %x:%x:%x:%x:%x:%x           hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),Mod_id,eh.ether_shost[0],eh.ether_shost[1],eh.ether_shost[2],eh.ether_shost[3],eh.ether_shost[4],eh.ether_shost[5],eh.ether_dhost[0],eh.ether_dhost[1],eh.ether_dhost[2],eh.ether_dhost[3],eh.ether_dhost[4],eh.ether_dhost[5]);
+ 	  
+  return 0;
+}
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
new file mode 100644
index 0000000000000000000000000000000000000000..a9706c73bdd16dad3cce786ead09bca8700b65f2
--- /dev/null
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
@@ -0,0 +1,383 @@
+/*******************************************************************************
+    OpenAirInterface
+    Copyright(c) 1999 - 2014 Eurecom
+
+    OpenAirInterface is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+
+    OpenAirInterface is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenAirInterface.The full GNU General Public License is
+    included in this distribution in the file called "COPYING". If not,
+    see <http://www.gnu.org/licenses/>.
+
+   Contact Information
+   OpenAirInterface Admin: openair_admin@eurecom.fr
+   OpenAirInterface Tech : openair_tech@eurecom.fr
+   OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
+
+   Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+
+ *******************************************************************************/
+/*! \file ethernet_lib.c 
+ * \brief API to stream I/Q samples over standard ethernet
+ * \author  add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp
+ * \date 2015
+ * \version 0.2
+ * \company Eurecom
+ * \maintainer:  navid.nikaein@eurecom.fr
+ * \note
+ * \warning 
+ */
+
+#include <arpa/inet.h>
+#include <linux/if_packet.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/ether.h>
+#include <unistd.h>
+#include <errno.h>
+#include "vcd_signal_dumper.h"
+
+#include "common_lib.h"
+#include "ethernet_lib.h"
+
+#define DEBUG 0
+struct sockaddr_in dest_addr[MAX_INST];
+struct sockaddr_in local_addr[MAX_INST];
+int addr_len[MAX_INST];
+
+
+uint16_t pck_seq_num = 1;
+uint16_t pck_seq_num_cur=0;
+uint16_t pck_seq_num_prev=0;
+
+ int eth_socket_init_udp(openair0_device *device) {
+
+  int i = 0;
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  int Mod_id = device->Mod_id;  
+  char str_local[INET_ADDRSTRLEN];
+  char str_remote[INET_ADDRSTRLEN];
+  const char *local_ip, *remote_ip;
+  int local_port=0, remote_port=0;
+  int sock_dom=0;
+  int sock_type=0;
+  int sock_proto=0;
+  int enable=1;
+
+  if (device->host_type == RRH_HOST ) {
+    local_ip   = device->openair0_cfg->my_addr;   
+    local_port = device->openair0_cfg->my_port;
+    remote_ip   = "0.0.0.0";   
+    remote_port =  0;   
+    printf("[%s] local ip addr %s port %d\n", "RRH", local_ip, local_port);    
+  } else {
+    local_ip   = device->openair0_cfg->my_addr;   
+    local_port = device->openair0_cfg->my_port;
+    remote_ip   = device->openair0_cfg->remote_addr;
+    remote_port = device->openair0_cfg->remote_port;  
+    printf("[%s] local ip addr %s port %d\n","BBU", local_ip, local_port);    
+  }
+  
+  /* Open socket to send on */
+  sock_dom=AF_INET;
+  sock_type=SOCK_DGRAM;
+  sock_proto=IPPROTO_UDP;
+  
+  if ((eth->sockfd[Mod_id] = socket(sock_dom, sock_type, sock_proto)) == -1) {
+    perror("ETHERNET: Error opening socket");
+    exit(0);
+  }
+  
+  /* initialize addresses */
+  for (i=0; i< MAX_INST; i++) {
+    bzero((void *)&(dest_addr[i]), sizeof(dest_addr[i]));
+    bzero((void *)&(local_addr[i]), sizeof(local_addr[i]));
+  }
+
+  addr_len[Mod_id] = sizeof(struct sockaddr_in);
+
+  dest_addr[Mod_id].sin_family = AF_INET;
+  inet_pton(AF_INET,remote_ip,&(dest_addr[Mod_id].sin_addr.s_addr));
+  dest_addr[Mod_id].sin_port=htons(remote_port);
+  inet_ntop(AF_INET, &(dest_addr[Mod_id].sin_addr), str_remote, INET_ADDRSTRLEN);
+
+
+  local_addr[Mod_id].sin_family = AF_INET;
+  inet_pton(AF_INET,local_ip,&(local_addr[Mod_id].sin_addr.s_addr));
+  local_addr[Mod_id].sin_port=htons(local_port);
+  inet_ntop(AF_INET, &(local_addr[Mod_id].sin_addr), str_local, INET_ADDRSTRLEN);
+
+  
+  /* set reuse address flag */
+  if (setsockopt(eth->sockfd[Mod_id], SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) {
+    perror("ETHERNET: Cannot set SO_REUSEADDR option on socket");
+    exit(0);
+  }
+  
+  /* want to receive -> so bind */   
+    if (bind(eth->sockfd[Mod_id],(struct sockaddr *)&local_addr[Mod_id],addr_len[Mod_id])<0) {
+      perror("ETHERNET: Cannot bind to socket");
+      exit(0);
+    } else {
+      printf("[%s] binding mod_%d to %s:%d\n","RRH",Mod_id,str_local,ntohs(local_addr[Mod_id].sin_port));
+    }
+ 
+  return 0;
+}
+
+int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {	
+  
+  int bytes_sent=0;
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  int Mod_id = device->Mod_id;
+  int sendto_flag =0;
+  int i=0;
+  //sendto_flag|=flags;
+  eth->tx_nsamps=nsamps;
+
+  for (i=0;i<cc;i++) {	
+    /* buff[i] points to the position in tx buffer where the payload to be sent is
+       buff2 points to the position in tx buffer where the packet header will be placed */
+    void *buff2 = (void*)(buff[i]- APP_HEADER_SIZE_BYTES); 
+    
+    /* we don't want to ovewrite with the header info the previous tx buffer data so we store it*/
+    int32_t temp0 = *(int32_t *)buff2;
+    openair0_timestamp  temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
+    
+    bytes_sent = 0;
+    
+    /* constract application header */
+    // eth->pck_header.seq_num = pck_seq_num;
+    //eth->pck_header.antenna_id = 1+(i<<1);
+    //eth->pck_header.timestamp = timestamp;
+    *(uint16_t *)buff2 = pck_seq_num;
+    *(uint16_t *)(buff2 + sizeof(uint16_t)) = 1+(i<<1);
+    *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = timestamp;
+    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_SEQ_NUM, pck_seq_num);
+
+    while(bytes_sent < UDP_PACKET_SIZE_BYTES(nsamps)) {
+#if DEBUG   
+      printf("------- TX ------: buff2 current position=%d remaining_bytes=%d  bytes_sent=%d \n",
+	     (void *)(buff2+bytes_sent), 
+	     UDP_PACKET_SIZE_BYTES(nsamps) - bytes_sent,
+	     bytes_sent);
+#endif
+      /* Send packet */
+      bytes_sent += sendto(eth->sockfd[Mod_id],
+			   buff2, 
+                           UDP_PACKET_SIZE_BYTES(nsamps),
+			   sendto_flag,
+			   (struct sockaddr*)&dest_addr[Mod_id],
+			   addr_len[Mod_id]);
+      
+      if ( bytes_sent == -1) {
+	eth->num_tx_errors++;
+	perror("ETHERNET WRITE: ");
+	exit(-1);
+      } else {
+#if DEBUG
+    printf("------- TX ------: nu=%d an_id=%d ts%d bytes_send=%d\n",
+	   *(int16_t *)buff2,
+	   *(int16_t *)(buff2 + sizeof(int16_t)),
+	   *(openair0_timestamp *)(buff2 + sizeof(int32_t)),
+	   bytes_sent);
+    dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, UDP_PACKET_SIZE_BYTES(nsamps), TX_FLAG);
+#endif
+    eth->tx_actual_nsamps=bytes_sent>>2;
+    eth->tx_count++;
+    pck_seq_num++;
+    if ( pck_seq_num > MAX_PACKET_SEQ_NUM(nsamps,76800) )  pck_seq_num = 1;
+      }
+    }              
+      /* tx buffer values restored */  
+      *(int32_t *)buff2 = temp0;
+      *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
+  }
+ 
+  return (bytes_sent-APP_HEADER_SIZE_BYTES)>>2;
+}
+      
+
+
+int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
+  
+  int bytes_received=0;
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  openair0_timestamp prev_timestamp = -1;
+  int Mod_id = device->Mod_id;
+  int rcvfrom_flag =0;
+  int block_cnt=0;
+  int again_cnt=0;
+  int i=0;
+
+  eth->rx_nsamps=nsamps;
+
+  for (i=0;i<cc;i++) {
+    /* buff[i] points to the position in rx buffer where the payload to be received will be placed
+       buff2 points to the position in rx buffer where the packet header will be placed */
+    void *buff2 = (void*)(buff[i]- APP_HEADER_SIZE_BYTES);
+    
+    /* we don't want to ovewrite with the header info the previous rx buffer data so we store it*/
+    int32_t temp0 = *(int32_t *)buff2;
+    openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
+    
+    bytes_received=0;
+    block_cnt=0;
+    
+    
+    while(bytes_received < UDP_PACKET_SIZE_BYTES(nsamps)) {
+    again:
+#if DEBUG   
+	   printf("------- RX------: buff2 current position=%d remaining_bytes=%d  bytes_recv=%d \n",
+		  (void *)(buff2+bytes_received),
+		  UDP_PACKET_SIZE_BYTES(nsamps) - bytes_received,
+		  bytes_received);
+#endif
+      bytes_received +=recvfrom(eth->sockfd[Mod_id],
+				buff2,
+	                        UDP_PACKET_SIZE_BYTES(nsamps),
+				rcvfrom_flag,
+				(struct sockaddr *)&dest_addr[Mod_id],
+				(socklen_t *)&addr_len[Mod_id]);
+      
+      if (bytes_received ==-1) {
+	eth->num_rx_errors++;
+	if (errno == EAGAIN) {
+	  again_cnt++;
+	  usleep(10);
+	  if (again_cnt == 1000) {
+	  perror("ETHERNET READ: ");
+	  exit(-1);
+	  } else {
+	    printf("AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN \n");
+	    goto again;
+	  }	  
+	} else if (errno == EWOULDBLOCK) {
+	     block_cnt++;
+	     usleep(10);	  
+	     if (block_cnt == 1000) {
+      perror("ETHERNET READ: ");
+      exit(-1);
+    } else {
+	    printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n");
+	    goto again;
+	  }
+	}
+      } else {
+#if DEBUG   
+	   printf("------- RX------: nu=%d an_id=%d ts%d bytes_recv=%d\n",
+		  *(int16_t *)buff2,
+		  *(int16_t *)(buff2 + sizeof(int16_t)),
+		  *(openair0_timestamp *)(buff2 + sizeof(int32_t)),
+		  bytes_received);
+	   dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, UDP_PACKET_SIZE_BYTES(nsamps),RX_FLAG);	  
+#endif  
+	   
+	   /* store the timestamp value from packet's header */
+	   *timestamp =  *(openair0_timestamp *)(buff2 + sizeof(int32_t));
+	   /* store the sequence number of the previous packet received */    
+	   if (pck_seq_num_cur == 0) {
+	     pck_seq_num_prev = *(uint16_t *)buff2;
+	   } else {
+	     pck_seq_num_prev = pck_seq_num_cur;
+	   }
+	   /* get the packet sequence number from packet's header */
+	   pck_seq_num_cur = *(uint16_t *)buff2;
+	   //printf("cur=%d prev=%d buff=%d\n",pck_seq_num_cur,pck_seq_num_prev,*(uint16_t *)(buff2));
+	   if ( ( pck_seq_num_cur != (pck_seq_num_prev + 1) ) && !((pck_seq_num_prev==75) && (pck_seq_num_cur==1 ))){
+	     printf("out of order packet received1! %d|%d|%d\n",pck_seq_num_cur,pck_seq_num_prev,	*timestamp);
+	   }
+	   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM,pck_seq_num_cur);
+	   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM_PRV,pck_seq_num_prev);
+						    eth->rx_actual_nsamps=bytes_received>>2;
+						    eth->rx_count++;
+						    }	 
+	     
+      }
+      /* tx buffer values restored */  
+      *(int32_t *)buff2 = temp0;
+      *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
+	  
+    }      
+  return (bytes_received-APP_HEADER_SIZE_BYTES)>>2;
+}
+      
+
+
+
+int eth_set_dev_conf_udp(openair0_device *device) {
+
+  int 	       Mod_id = device->Mod_id;
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  void 	      *msg;
+  ssize_t      msg_len;
+
+  
+  /* a BBU client sents to RRH a set of configuration parameters (openair0_config_t)
+     so that RF front end is configured appropriately and
+     frame/packet size etc. can be set */ 
+
+  msg=malloc(sizeof(openair0_config_t));
+  msg_len=sizeof(openair0_config_t);
+  memcpy(msg,(void*)device->openair0_cfg,msg_len);	
+  
+  if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&dest_addr[Mod_id],addr_len[Mod_id])==-1) {
+    perror("ETHERNET: ");
+    exit(0);
+  }
+
+  return 0;
+}
+
+int eth_get_dev_conf_udp(openair0_device *device) {
+
+  eth_state_t   *eth = (eth_state_t*)device->priv;
+  int 		Mod_id = device->Mod_id;
+  char 		str1[INET_ADDRSTRLEN],str[INET_ADDRSTRLEN];
+  void 		*msg;
+  ssize_t	msg_len;
+  
+  msg=malloc(sizeof(openair0_config_t));
+  msg_len=sizeof(openair0_config_t);
+
+  inet_ntop(AF_INET, &(local_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
+  inet_ntop(AF_INET, &(dest_addr[Mod_id].sin_addr), str1, INET_ADDRSTRLEN);
+
+  /* RRH receives from BBU openair0_config_t */
+  if (recvfrom(eth->sockfd[Mod_id],
+	       msg,
+	       msg_len,
+	       0,
+	       (struct sockaddr *)&dest_addr[Mod_id],
+	       (socklen_t *)&addr_len[Mod_id])==-1) {
+    perror("ETHERNET: ");
+    exit(0);
+  }
+  device->openair0_cfg=(openair0_config_t *)msg;
+
+   /* get remote ip address and port */
+   /* inet_ntop(AF_INET, &(dest_addr[Mod_id].sin_addr), str1, INET_ADDRSTRLEN); */
+   /* device->openair0_cfg->remote_port =ntohs(dest_addr[Mod_id].sin_port); */
+   /* device->openair0_cfg->remote_addr =str1; */
+
+   /* /\* restore local ip address and port *\/ */
+   /* inet_ntop(AF_INET, &(local_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN); */
+   /* device->openair0_cfg->my_port =ntohs(local_addr[Mod_id].sin_port); */
+   /* device->openair0_cfg->my_addr =str; */
+
+   /*  printf("[RRH] mod_%d socket %d connected to BBU %s:%d  %s:%d\n", Mod_id, eth->sockfd[Mod_id],str1, device->openair0_cfg->remote_port, str, device->openair0_cfg->my_port);  */
+   return 0;
+}
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
index ce90d2cff967e03d90d3c82bc401f3b93a156768..1582273d486aa36be3b437d7bdca57754799b26e 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
@@ -28,7 +28,7 @@
  *******************************************************************************/
 /*! \file ethernet_lib.c 
  * \brief API to stream I/Q samples over standard ethernet
- * \author Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp
+ * \author  add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp
  * \date 2015
  * \version 0.2
  * \company Eurecom
@@ -52,196 +52,56 @@
 #include "common_lib.h"
 #include "ethernet_lib.h"
 
-//#define DEBUG 1
 
 int num_devices_eth = 0;
+struct sockaddr_in dest_addr[MAX_INST];
 int dest_addr_len[MAX_INST];
-char sendbuf[MAX_INST][BUF_SIZ]; /*TODO*/
-
-
-/*! \fn static int eth_socket_init(openair0_device *device)
-* \brief initialization of UDP Socket to communicate with one destination
-* \param[in] *device openair device for which the socket will be created
-* \param[out]
-* \return 0 on success, otherwise -1
-* \note
-* @ingroup  _oai
-*/
-static int eth_socket_init(openair0_device *device);
-
-/*! \fn static int eth_set_dev_conf(openair0_device *device)
-* \brief 
-* \param[in] *device openair device 
-* \param[out]
-* \return 0 on success, otherwise -1
-* \note
-* @ingroup  _oai
-*/
-static int eth_set_dev_conf(openair0_device *device);
-
-/*! \fn static int eth_get_dev_conf(openair0_device *device)
-* \brief
-* \param[in] *device openair device
-* \param[out]
-* \return 0 on success, otherwise -1
-* \note
-* @ingroup  _oai
-*/
-static int eth_get_dev_conf(openair0_device *device);
-
 
 
 int trx_eth_start(openair0_device *device) {
-  
-  /* initialize socket */
-  if (eth_socket_init(device)!=0) {
-    return -1;
-  }
-  
-  /* RRH gets openair0 device configuration BBU sets openair0 device configuration*/
-  if (device->func_type == BBU_FUNC) {
-    return eth_set_dev_conf(device);
-  } else {
-    return eth_get_dev_conf(device);
-  }
-
-  return 0;
-}
 
-
-int trx_eth_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {	
-  
-  int n_written=0,i;
-  uint16_t header_size=sizeof(int32_t) + sizeof(openair0_timestamp);
   eth_state_t *eth = (eth_state_t*)device->priv;
-  int Mod_id = device->Mod_id;
-  int sendto_flag =0;
-  sendto_flag|=MSG_DONTWAIT;
   
-  for (i=0;i<cc;i++) {	
-    /* buff[i] points to the position in tx buffer where the payload to be sent is
-       buff2 points to the position in tx buffer where the packet header will be placed */
-    void *buff2 = (void*)(buff[i]-header_size); 
-    
-    /* we don't want to ovewrite with the header info the previous tx buffer data so we store it*/
-    int32_t temp0 = *(int32_t *)buff2;
-    openair0_timestamp  temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
-    
-    n_written = 0;
-    
-    *(int16_t *)(buff2 + sizeof(int16_t))=1+(i<<1);
-    *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = timestamp;
-    
-    /* printf("[RRH]write mod_%d %d , len %d, buff %p antenna %d\n",
-       Mod_id,eth->sockfd[Mod_id],(nsamps<<2)+header_size, buff2, antenna_id);*/
-    
-    while(n_written < nsamps) {
-      /* Send packet */
-      if ((n_written += sendto(eth->sockfd[Mod_id],
-			       buff2, 
-			       (nsamps<<2)+header_size,
-			       0,
-			       (struct sockaddr*)&eth->dest_addr[Mod_id],
-			       dest_addr_len[Mod_id])) < 0) {
-	perror("ETHERNET WRITE");
-	exit(-1);
-      }
+  /* initialize socket */
+  if ((eth->flags & ETH_RAW_MODE) != 0 ) {     
+    if (eth_socket_init_raw(device)!=0)   return -1;
+    /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
+    if (device->host_type == BBU_HOST) {
+      if(eth_set_dev_conf_raw(device)!=0)  return -1;
+    } else {
+      if(eth_get_dev_conf_raw(device)!=0)  return -1;
     }
-
-#if DEBUG
-    printf("Buffer head TX: nu=%d an_id=%d ts%d samples_send=%d i=%d data=%x\n",
-	   *(int16_t *)buff2,
-	   *(int16_t *)(buff2 + sizeof(int16_t)),
-	   *(openair0_timestamp *)(buff2 + sizeof(int32_t)),
-	   n_written>>2,i,*(int32_t *)(buff2 + 20*sizeof(int32_t)));
-#endif
-
-    /* tx buffer values restored */  
-    *(int32_t *)buff2 = temp0;
-    *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
-  }
-  return n_written;
-  
-}
-
-int trx_eth_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
-
-  int bytes_received=0;
-  int block_cnt=0;
-  int ret=0,i;
-  uint16_t  header_size=sizeof(int32_t) + sizeof(openair0_timestamp);
-
-  eth_state_t *eth = (eth_state_t*)device->priv;
-  int Mod_id = device->Mod_id;
-  
-  for (i=0;i<cc;i++) {
-    /* buff[i] points to the position in rx buffer where the payload to be received will be placed
-       buff2 points to the position in rx buffer where the packet header will be placed */
-    void *buff2 = (void*)(buff[i]-header_size);
-    
-    /* we don't want to ovewrite with the header info the previous rx buffer data so we store it*/
-    int32_t temp0 = *(int32_t *)buff2;
-    openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
-    
-    bytes_received=0;
-    block_cnt=0;
-    ret=0;
-    
-    /* printf("[RRH] read mod_%d %d,len %d, buff %p antenna %d\n",
-       Mod_id,eth->sockfd[Mod_id],(nsamps<<2)+header_size, buff2, antenna_id);*/
-    
-    while(bytes_received < (int)((nsamps<<2))) {
-      ret=recvfrom(eth->sockfd[Mod_id],
-		   buff2+bytes_received,
-		   (nsamps<<2)+header_size-bytes_received,
-		   0,//MSG_DONTWAIT,
-                 (struct sockaddr *)&eth->dest_addr[Mod_id],
-		   (socklen_t *)&dest_addr_len[Mod_id]);
-      
-      if (ret==-1) {
-	if (errno == EAGAIN) {
-	  perror("ETHERNET READ: ");
-	  return((nsamps<<2) + header_size);
-	} else if (errno == EWOULDBLOCK) {
-	  block_cnt++;
-	  usleep(10);
-	  
-	  if (block_cnt == 100) return(-1);
-	}
-      } else {
-	bytes_received+=ret;
-      }
+    /* adjust MTU wrt number of samples per packet */
+    if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0)  return -1;
+  } else {
+    if (eth_socket_init_udp(device)!=0)   return -1; 
+    /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
+    if (device->host_type == BBU_HOST) {
+      if(eth_set_dev_conf_udp(device)!=0)  return -1;
+    } else {
+      if(eth_get_dev_conf_udp(device)!=0)  return -1;
     }
-
-#if DEBUG   
-    printf("Buffer head RX: nu=%d an_id=%d ts%d samples_recv=%d i=%d data=%x\n",
-	   *(int16_t *)buff2,
-	   *(int16_t *)(buff2 + sizeof(int16_t)),
-	   *(openair0_timestamp *)(buff2 + sizeof(int32_t)),
-	   ret>>2,i,*(int32_t *)(buff2 + 20*sizeof(int32_t)));
-#endif  
-
-    /* store the timestamp value from packet's header */
-    *timestamp =  *(openair0_timestamp *)(buff2 + sizeof(int32_t));
-    
-    /* tx buffer values restored */  
-    *(int32_t *)buff2 = temp0;
-    *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
+    /* adjust MTU wrt number of samples per packet */
+    //if(ethernet_tune (device,MTU_SIZE,UDP_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0)  return -1;
   }
-  return nsamps;
+  /* apply additional configuration */
+  if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0)  return -1;
+  if(ethernet_tune (device, RCV_BUF_SIZE,2000000000)!=0)  return -1;
   
+  return 0;
 }
 
+
 void trx_eth_end(openair0_device *device) {
 
   eth_state_t *eth = (eth_state_t*)device->priv;
   int Mod_id = device->Mod_id;
-  /*destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */
+  /* destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */
   if ( close(eth->sockfd[Mod_id]) <0 ) {
     perror("ETHERNET: Failed to close socket");
     exit(0);
    } else {
-    printf("[RRH] socket for mod_id %d has been successfully closed.\n",Mod_id);
+    printf("[%s] socket for mod_id %d has been successfully closed.\n",(device->host_type == BBU_HOST)? "BBU":"RRH",Mod_id);
    }
  
 }
@@ -253,7 +113,7 @@ int trx_eth_request(openair0_device *device, void *msg, ssize_t msg_len) {
   eth_state_t *eth = (eth_state_t*)device->priv;
  
   /* BBU sends a message to RRH */
- if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&eth->dest_addr[Mod_id],dest_addr_len[Mod_id])==-1) {
+ if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&dest_addr[Mod_id],dest_addr_len[Mod_id])==-1) {
     perror("ETHERNET: ");
     exit(0);
   }
@@ -262,7 +122,6 @@ int trx_eth_request(openair0_device *device, void *msg, ssize_t msg_len) {
 }
 
 
-
 int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
 
   eth_state_t   *eth = (eth_state_t*)device->priv;
@@ -273,7 +132,7 @@ int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
 	       msg,
 	       msg_len,
 	       0,
-	       (struct sockaddr *)&eth->dest_addr[Mod_id],
+	       (struct sockaddr *)&dest_addr[Mod_id],
 	       (socklen_t *)&dest_addr_len[Mod_id])==-1) {
     perror("ETHERNET: ");
     exit(0);
@@ -283,65 +142,6 @@ int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
 }
 
 
-static int eth_set_dev_conf(openair0_device *device) {
-
-  int 	       Mod_id = device->Mod_id;
-  eth_state_t *eth = (eth_state_t*)device->priv;
-  void 	      *msg;
-  ssize_t      msg_len;
-
-  
-  /* a BBU client sents to RRH a set of configuration parameters (openair0_config_t)
-     so that RF front end is configured appropriately and
-     frame/packet size etc. can be set */ 
-  
-  msg=malloc(sizeof(openair0_config_t));
-  msg_len=sizeof(openair0_config_t);
-  memcpy(msg,(void*)&device->openair0_cfg,msg_len);	
-  
-  if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)&eth->dest_addr[Mod_id],dest_addr_len[Mod_id])==-1) {
-    perror("ETHERNET: ");
-    exit(0);
-  }
-     
-  return 0;
-}
-
-
-static int eth_get_dev_conf(openair0_device *device) {
-
-  eth_state_t   *eth = (eth_state_t*)device->priv;
-  int 		Mod_id = device->Mod_id;
-  char 		str[INET_ADDRSTRLEN];
-  void 		*msg;
-  ssize_t	msg_len;
-  
-  msg=malloc(sizeof(openair0_config_t));
-  msg_len=sizeof(openair0_config_t);
-
-  /* RRH receives from BBU openair0_config_t */
-  if (recvfrom(eth->sockfd[Mod_id],
-	       msg,
-	       msg_len,
-	       0,
-	       (struct sockaddr *)&eth->dest_addr[Mod_id],
-	       (socklen_t *)&dest_addr_len[Mod_id])==-1) {
-    perror("ETHERNET: ");
-    exit(0);
-  }
-		
-   memcpy((void*)&device->openair0_cfg,msg,msg_len);	
-   inet_ntop(AF_INET, &(eth->dest_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
-   device->openair0_cfg.remote_port =ntohs(eth->dest_addr[Mod_id].sin_port);
-   device->openair0_cfg.remote_ip=str;
-   /*apply additional configuration*/
-   //ethernet_tune (device, RING_PAR);
-   // printf("[RRH] write mod_%d %d to %s:%d\n",Mod_id,eth->sockfd[Mod_id],str,ntohs(eth->dest_addr[Mod_id].sin_port));
-
-   return 0;
-}
-
-
 
 int trx_eth_stop(int card) {
   return(0);
@@ -364,186 +164,315 @@ int trx_eth_reset_stats(openair0_device* device) {
 }
 
 
-static int eth_socket_init(openair0_device *device) {
-
-  int i = 0;
-  eth_state_t *eth = (eth_state_t*)device->priv;
-  int Mod_id = device->Mod_id;  
-  char str[INET_ADDRSTRLEN];
-  const char *dest_ip;
-  int dest_port=0;
-  
-  if (device->func_type == RRH_FUNC ) {
-    dest_ip   = device->openair0_cfg.my_ip;   
-    dest_port = device->openair0_cfg.my_port;
-    printf("[RRH] ip addr %s port %d\n",dest_ip, dest_port);
-  } else {
-    dest_ip   = device->openair0_cfg.remote_ip;
-    dest_port = device->openair0_cfg.remote_port;
-    printf("[BBU] ip addr %s port %d\n",dest_ip, dest_port);
-  }
-    
-  /* Open RAW socket to send on */
-  if ((eth->sockfd[Mod_id] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
-    perror("ETHERNET: Error opening socket");
-    exit(0);
-  }
-
-  /* initialize destination address */
-  for (i=0; i< MAX_INST; i++) {
-    bzero((void *)&(eth->dest_addr[i]), sizeof(eth->dest_addr[i]));
-  }
-
- // bzero((void *)dest,sizeof(struct sockaddr_in));
-  eth->dest_addr[Mod_id].sin_family = AF_INET;
-  inet_pton(AF_INET,dest_ip,&(eth->dest_addr[Mod_id].sin_addr.s_addr));
-  eth->dest_addr[Mod_id].sin_port=htons(dest_port);
-  dest_addr_len[Mod_id] = sizeof(struct sockaddr_in);
-  inet_ntop(AF_INET, &(eth->dest_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
-  
-  /* if RRH, then I am the server, so bind */
-  if (device->func_type == RRH_FUNC ) {    
-    if (bind(eth->sockfd[Mod_id],(struct sockaddr *)&eth->dest_addr[Mod_id], dest_addr_len[Mod_id])<0) {
-      perror("ETHERNET: Cannot bind to socket");
-      exit(0);
-    } else {
-      printf("[RRH] binding mod_%d to %s:%d\n",Mod_id,str,ntohs(eth->dest_addr[Mod_id].sin_port));
-    }
-    
-  } else {
-    printf("[BBU] Connecting to %s:%d\n",str,ntohs(eth->dest_addr[Mod_id].sin_port));
-  }
-  
-  return 0;
-}
-
-
-int ethernet_tune(openair0_device *device , eth_opt_t option) {
+int ethernet_tune(openair0_device *device, unsigned int option, int value) {
   
   eth_state_t *eth = (eth_state_t*)device->priv;
   int Mod_id=device->Mod_id;
-  
-  unsigned int sndbuf_size=0, rcvbuf_size=0;
-  struct timeval snd_timeout, rcv_timeout;
+  struct timeval timeout;
   struct ifreq ifr;   
   char system_cmd[256]; 
   char* if_name=DEFAULT_IF;
-
-  /****************** socket level options ************************/
-  if (option== SND_BUF_SIZE) {    /* transmit socket buffer size */   
+  struct in_addr ia;
+  struct if_nameindex *ids;
+  int ret=0;
+  int i=0;
+  
+  /****************** socket level options ************************/  
+  switch(option) {
+  case SND_BUF_SIZE:  /* transmit socket buffer size */   
     if (setsockopt(eth->sockfd[Mod_id],  
 		   SOL_SOCKET,  
 		   SO_SNDBUF,  
-		   &sndbuf_size,sizeof(sndbuf_size))) {
+		   &value,sizeof(value))) {
       perror("[ETHERNET] setsockopt()");
     } else {
-      printf( "sndbuf_size= %d bytes\n", sndbuf_size); 
-    }     
-  } else if (option== RCV_BUF_SIZE) {  /* receive socket buffer size */   
+      printf("send buffer size= %d bytes\n",value); 
+    }   
+    break;
+    
+  case RCV_BUF_SIZE:   /* receive socket buffer size */   
     if (setsockopt(eth->sockfd[Mod_id],  
 		   SOL_SOCKET,  
 		   SO_RCVBUF,  
-		   &rcvbuf_size,sizeof(rcvbuf_size))) {
+		   &value,sizeof(value))) {
       perror("[ETHERNET] setsockopt()");
     } else {     
-      printf( "rcvbuf_size= %d bytes\n", rcvbuf_size);    
+      printf("receive bufffer size= %d bytes\n",value);    
     }
-  } else if (option==RCV_TIMEOUT) {
-    rcv_timeout.tv_sec = 0;
-    rcv_timeout.tv_usec = 180;//less than rt_period
+    break;
+    
+  case RCV_TIMEOUT:
+    timeout.tv_sec = value/1000000000;
+    timeout.tv_usec = value%1000000000;//less than rt_period?
     if (setsockopt(eth->sockfd[Mod_id],  
 		   SOL_SOCKET,  
 		   SO_RCVTIMEO,  
-		   (char *)&rcv_timeout,sizeof(rcv_timeout))) {
+		   (char *)&timeout,sizeof(timeout))) {
       perror("[ETHERNET] setsockopt()");  
     } else {   
-      printf( "rcv_timeout= %d usecs\n", rcv_timeout.tv_usec);  
+      printf( "receive timeout= %d,%d sec\n",timeout.tv_sec,timeout.tv_usec);  
     }  
-  } else if (option==SND_TIMEOUT) {
-    snd_timeout.tv_sec = 0;
-    snd_timeout.tv_usec = 180;//less than rt_period
+    break;
+    
+  case SND_TIMEOUT:
+    timeout.tv_sec = value/1000000000;
+    timeout.tv_usec = value%1000000000;//less than rt_period?
     if (setsockopt(eth->sockfd[Mod_id],  
 		   SOL_SOCKET,  
 		   SO_SNDTIMEO,  
-		   (char *)&snd_timeout,sizeof(snd_timeout))) {
+		   (char *)&timeout,sizeof(timeout))) {
       perror("[ETHERNET] setsockopt()");     
     } else {
-      printf( "snd_timeout= %d usecs\n", snd_timeout.tv_usec);    
+      printf( "send timeout= %d,%d sec\n",timeout.tv_sec,timeout.tv_usec);    
     }
-  }
-  
-  /******************* interface level options  *************************/
-  else if (option==MTU_SIZE) {    /* change  MTU of the eth interface */ 
+    break;
+    
+    
+    /******************* interface level options  *************************/
+  case MTU_SIZE: /* change  MTU of the eth interface */ 
     ifr.ifr_addr.sa_family = AF_INET;
-    strncpy(ifr.ifr_name,if_name, sizeof(ifr.ifr_name));
-    ifr.ifr_mtu =8960;
+    strncpy(ifr.ifr_name,eth->if_name[Mod_id], sizeof(ifr.ifr_name));
+    ifr.ifr_mtu =value;
     if (ioctl(eth->sockfd[Mod_id],SIOCSIFMTU,(caddr_t)&ifr) < 0 )
       perror ("[ETHERNET] Can't set the MTU");
     else 
-      printf("[ETHERNET] %s MTU size has changed to %d\n",DEFAULT_IF,ifr.ifr_mtu);
-  } else if (option==TX_Q_LEN) {    /* change TX queue length of eth interface */ 
+      printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name[Mod_id],ifr.ifr_mtu);
+    break;
+    
+  case TX_Q_LEN:  /* change TX queue length of eth interface */ 
     ifr.ifr_addr.sa_family = AF_INET;
-    strncpy(ifr.ifr_name,if_name, sizeof(ifr.ifr_name));
-    ifr.ifr_qlen =3000 ;
+    strncpy(ifr.ifr_name,eth->if_name[Mod_id], sizeof(ifr.ifr_name));
+    ifr.ifr_qlen =value;
     if (ioctl(eth->sockfd[Mod_id],SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 )
       perror ("[ETHERNET] Can't set the txqueuelen");
     else 
-      printf("[ETHERNET] %s txqueuelen size has changed to %d\n",DEFAULT_IF,ifr.ifr_qlen);
-
-
+      printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name[Mod_id],ifr.ifr_qlen);
+    break;
+    
     /******************* device level options  *************************/
-  } else if (option==COALESCE_PAR) {  
-    if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs 3",DEFAULT_IF) > 0) {
-      system(system_cmd);
+  case COALESCE_PAR:
+    ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs %d",eth->if_name[Mod_id],value);
+    if (ret > 0) {
+      ret=system(system_cmd);
+      if (ret == -1) {
+	fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
+      } else {
+	printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret));
+      }
       printf("[ETHERNET] Coalesce parameters %s\n",system_cmd);
     } else {
       perror("[ETHERNET] Can't set coalesce parameters\n");
     }
+    break;
     
-  } else if (option==PAUSE_PAR ) {  
-    if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",DEFAULT_IF) > 0) {
-      system(system_cmd);
+  case PAUSE_PAR:
+    if (value==1) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",eth->if_name[Mod_id]);
+    else if (value==0) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg on rx on tx on",eth->if_name[Mod_id]);
+    else break;
+    if (ret > 0) {
+      ret=system(system_cmd);
+      if (ret == -1) {
+	fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
+      } else {
+	printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret));
+      }
       printf("[ETHERNET] Pause parameters %s\n",system_cmd);
     } else {
       perror("[ETHERNET] Can't set pause parameters\n");
     }
-  } else if (option==RING_PAR ) {  
-    if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s rx 4096 tx 4096",DEFAULT_IF) > 0) {
-      system(system_cmd);
+    break;
+    
+  case RING_PAR:
+    ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s rx %d tx %d",eth->if_name[Mod_id],value);
+    if (ret > 0) {
+      ret=system(system_cmd);
+      if (ret == -1) {
+	fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
+      } else {
+	printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret));
+      }            
       printf("[ETHERNET] Ring parameters %s\n",system_cmd);
     } else {
       perror("[ETHERNET] Can't set ring parameters\n");
     }
+    break;
     
+  default:
+    break;
   }
+  
   return 0;
 }
 
 
 
-int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg) {
+int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params ) {
 
   eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t));
-  int card = 0;
   memset(eth, 0, sizeof(eth_state_t));
-  eth->buffer_size =  (unsigned int)openair0_cfg[card].samples_per_packet*sizeof(int32_t); // buffer size = 4096 for sample_len of 1024
-  eth->sample_rate = (unsigned int)openair0_cfg[card].sample_rate;
-  device->priv = eth; 	
 
-  printf("ETHERNET: Initializing openair0_device for %s ...\n", ((device->func_type == BBU_FUNC) ? "BBU": "RRH"));
+  if (eth_params->transp_preference == 1) {
+    eth->flags = ETH_RAW_MODE;
+  } else {
+    eth->flags = ETH_UDP_MODE;
+  }
+  
+  printf("[ETHERNET]: Initializing openair0_device for %s ...\n", ((device->host_type == BBU_HOST) ? "BBU": "RRH"));
   device->Mod_id           = num_devices_eth++;
+  device->transp_type      = ETHERNET_TP;
   device->trx_start_func   = trx_eth_start;
   device->trx_request_func = trx_eth_request;
   device->trx_reply_func   = trx_eth_reply;
-  device->trx_write_func   = trx_eth_write;
-  device->trx_read_func    = trx_eth_read;  
   device->trx_get_stats_func   = trx_eth_get_stats;
   device->trx_reset_stats_func = trx_eth_reset_stats;
-  device->trx_end_func = trx_eth_end;
-  device->trx_stop_func = trx_eth_stop;
+  device->trx_end_func         = trx_eth_end;
+  device->trx_stop_func        = trx_eth_stop;
   device->trx_set_freq_func = trx_eth_set_freq;
   device->trx_set_gains_func = trx_eth_set_gains;
-  
-  memcpy((void*)&device->openair0_cfg,(void*)openair0_cfg,sizeof(openair0_config_t));
+
+  if ((eth->flags & ETH_RAW_MODE) != 0 ) {
+    device->trx_write_func   = trx_eth_write_raw;
+    device->trx_read_func    = trx_eth_read_raw;     
+  } else {
+    device->trx_write_func   = trx_eth_write_udp;
+    device->trx_read_func    = trx_eth_read_udp;     
+  }
+
+  eth->if_name[device->Mod_id] = eth_params->local_if_name;
+  device->priv = eth;
+ 	
+  /* device specific */
+  openair0_cfg[0].txlaunch_wait = 0;//manage when TX processing is triggered
+  openair0_cfg[0].txlaunch_wait_slotcount = 0; //manage when TX processing is triggered
+  openair0_cfg[0].iq_txshift = 5;// shift
+  openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
+
+  /* RRH does not have any information to make this configuration atm */
+  if (device->host_type == BBU_HOST) {
+    /*Note scheduling advance values valid only for case 7680000 */    
+    switch ((int)openair0_cfg[0].sample_rate) {
+    case 30720000:
+      openair0_cfg[0].samples_per_packet    = 4096;
+      openair0_cfg[0].tx_sample_advance     = 0;
+      openair0_cfg[0].tx_scheduling_advance = 22*openair0_cfg[0].samples_per_packet;
+      break;
+    case 23040000:     
+      openair0_cfg[0].samples_per_packet    = 2048;
+      openair0_cfg[0].tx_sample_advance     = 0;
+      openair0_cfg[0].tx_scheduling_advance = 16*openair0_cfg[0].samples_per_packet;
+      break;
+    case 15360000:
+      openair0_cfg[0].samples_per_packet    = 2048;
+      openair0_cfg[0].tx_sample_advance     = 0;
+      openair0_cfg[0].tx_scheduling_advance = 10*openair0_cfg[0].samples_per_packet;
+      break;
+    case 7680000:
+      openair0_cfg[0].samples_per_packet    = 1024;
+      openair0_cfg[0].tx_sample_advance     = 0;
+      openair0_cfg[0].tx_scheduling_advance = 10*openair0_cfg[0].samples_per_packet;
+      break;
+    case 1920000:
+      openair0_cfg[0].samples_per_packet    = 256;
+      openair0_cfg[0].tx_sample_advance     = 0;
+      openair0_cfg[0].tx_scheduling_advance = 16*openair0_cfg[0].samples_per_packet;
+      break;
+    default:
+      printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
+      exit(-1);
+      break;
+    }
+  }
+ 
+  device->openair0_cfg=&openair0_cfg[0];
   return 0;
 }
+
+
+/**************************************************************************************************************************
+ *                                         DEBUGING-RELATED FUNCTIONS                                                     *
+ **************************************************************************************************************************/
+void dump_packet(char *title, unsigned char* pkt, int bytes, unsigned int tx_rx_flag) {
+   
+  static int numSend = 1;
+  static int numRecv = 1;
+  int num, k;
+  char tmp[48];
+  unsigned short int cksum;
+  
+  num = (tx_rx_flag)? numSend++:numRecv++;
+  for (k = 0; k < 24; k++) sprintf(tmp+k, "%02X", pkt[k]);
+  cksum = calc_csum((unsigned short *)pkt, bytes>>2);
+  printf("%s-%s (%06d): %s 0x%04X\n", title,(tx_rx_flag)? "TX":"RX", num, tmp, cksum);
+}
+
+unsigned short calc_csum (unsigned short *buf, int nwords) {
+ 
+ unsigned long sum;
+  for (sum = 0; nwords > 0; nwords--)
+    sum += *buf++;
+  sum = (sum >> 16) + (sum & 0xffff);
+  sum += (sum >> 16);
+  return ~sum;
+}
+
+void dump_dev(openair0_device *device) {
+
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  
+  printf("Ethernet device interface %i configuration:\n" ,device->openair0_cfg->Mod_id);
+  printf("       Log level is %i :\n" ,device->openair0_cfg->log_level);	
+  printf("       RB number: %i, sample rate: %lf \n" ,
+        device->openair0_cfg->num_rb_dl, device->openair0_cfg->sample_rate);
+  printf("       Scheduling_advance: %i, Sample_advance: %u \n" ,
+        device->openair0_cfg->tx_scheduling_advance, device->openair0_cfg->tx_sample_advance);		
+  printf("       BBU configured for %i tx/%i rx channels)\n",
+	device->openair0_cfg->tx_num_channels,device->openair0_cfg->rx_num_channels);
+   printf("       Running flags: %s %s %s\n",      
+	((eth->flags & ETH_RAW_MODE)  ? "RAW socket mode - ":""),
+	((eth->flags & ETH_UDP_MODE)  ? "UDP socket mode - ":""));	  	
+  printf("       Number of iqs dumped when displaying packets: %i\n\n",eth->iqdumpcnt);   
+  
+}
+
+void inline dump_txcounters(openair0_device *device) {
+  eth_state_t *eth = (eth_state_t*)device->priv;  
+  printf("   Ethernet device interface %i, tx counters:\n" ,device->openair0_cfg->Mod_id);
+  printf("   Sent packets: %llu send errors: %i\n",   eth->tx_count, eth->num_tx_errors);	 
+}
+
+void inline dump_rxcounters(openair0_device *device) {
+
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  printf("   Ethernet device interface %i rx counters:\n" ,device->openair0_cfg->Mod_id);
+  printf("   Received packets: %llu missed packets errors: %i\n", eth->rx_count, eth->num_underflows);	 
+}  
+
+void inline dump_buff(openair0_device *device, char *buff,unsigned int tx_rx_flag, int nsamps) {
+  
+  char *strptr;
+  eth_state_t *eth = (eth_state_t*)device->priv;  
+  /*need to add ts number of iqs in printf need to fix dump iqs call */
+  strptr = (( tx_rx_flag == TX_FLAG) ? "TX" : "RX");
+  printf("\n %s, nsamps=%i \n" ,strptr,nsamps);     
+  
+  if (tx_rx_flag == 1) {
+    dump_txcounters(device);
+    printf("  First %i iqs of TX buffer\n",eth->iqdumpcnt);
+    dump_iqs(buff,eth->iqdumpcnt);
+  } else {
+    dump_rxcounters(device);
+    printf("  First %i iqs of RX buffer\n",eth->iqdumpcnt);
+    dump_iqs(buff,eth->iqdumpcnt);      
+  }
+  
+}
+
+void dump_iqs(char * buff, int iq_cnt) {
+  int i;
+  for (i=0;i<iq_cnt;i++) {
+    printf("s%02i: Q=%+ij I=%+i%s",i,
+	   ((iqoai_t *)(buff))[i].q,
+	   ((iqoai_t *)(buff))[i].i,
+	   ((i+1)%3 == 0) ? "\n" : "  ");
+  }   
+}
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h
index eabec94ebcba082f1c72929664e452919f7cd5bd..b4618bb8254d4abccaf8808ad7024e6cbb53a6b6 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h
@@ -36,6 +36,8 @@
  * \note
  * \warning 
  */
+#ifndef ETHERNET_LIB_H
+#define ETHERNET_LIB_H
 
 #include <arpa/inet.h>
 #include <linux/if_packet.h>
@@ -47,71 +49,90 @@
 #include <net/if.h>
 #include <netinet/ether.h>
 
-#define MAX_INST        4
-#define DEFAULT_IF  "lo"
-#define BUF_SIZ      8960 /*Jumbo frame size*/
+#define MAX_INST      4
+#define DEFAULT_IF   "lo"
 
-typedef struct {
+#define ETH_RAW_MODE        1
+#define ETH_UDP_MODE        0
 
-  // opaque eth data struct
-  //struct eth_if *dev;
-  // An empty ("") or NULL device identifier will result in the first encountered device being opened (using the first discovered backend)
+#define TX_FLAG	        1
+#define RX_FLAG 	0
 
-  int sockfd[MAX_INST];
-  struct sockaddr_in dest_addr[MAX_INST];
+#define MAX_PACKET_SEQ_NUM(spp,spf) (spf/spp)
+#define MAC_HEADER_SIZE_BYTES (sizeof(struct ether_header))
+#define APP_HEADER_SIZE_BYTES (sizeof(int32_t) + sizeof(openair0_timestamp))
+#define PAYLOAD_SIZE_BYTES(nsamps) (nsamps<<2)
+#define UDP_PACKET_SIZE_BYTES(nsamps) (APP_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES(nsamps))
+#define RAW_PACKET_SIZE_BYTES(nsamps) (APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES(nsamps))
 
-  unsigned int buffer_size;
-  unsigned int timeout_ns;
 
-  //struct eth_metadata meta_rx;
-  //struct eth_metadata meta_tx;
-
-  unsigned int sample_rate;
-  // time offset between transmiter timestamp and receiver timestamp;
+/*!\brief opaque ethernet data structure */
+typedef struct {
+  
+  /*!\brief socket file desc */ 
+  int sockfd[MAX_INST];
+  /*!\brief interface name */ 
+  char *if_name[MAX_INST];
+  /*!\brief buffer size */ 
+  unsigned int buffer_size;
+  /*!\brief timeout ms */ 
+  unsigned int rx_timeout_ms;
+  /*!\brief timeout ms */ 
+  unsigned int tx_timeout_ms;
+  /*!\brief runtime flags */ 
+  uint32_t flags;   
+  /*!\ time offset between transmiter timestamp and receiver timestamp */ 
   double tdiff;
-  // use brf_time_offset to get this value
-  int tx_forward_nsamps; //166 for 20Mhz
-
-
+  /*!\ calibration */
+  int tx_forward_nsamps;
+  
   // --------------------------------
   // Debug and output control
   // --------------------------------
+  
+  /*!\brief number of I/Q samples to be printed */ 
+  int iqdumpcnt;
+
+  /*!\brief number of underflows in interface */ 
   int num_underflows;
+  /*!\brief number of overflows in interface */ 
   int num_overflows;
+  /*!\brief number of concesutive errors in interface */ 
   int num_seq_errors;
+  /*!\brief number of errors in interface's receiver */ 
   int num_rx_errors;
+  /*!\brief umber of errors in interface's transmitter */ 
   int num_tx_errors;
-
-  uint64_t tx_actual_nsamps; // actual number of samples transmitted
+  
+  /*!\brief current TX timestamp */ 
+  openair0_timestamp tx_current_ts;
+  /*!\brief socket file desc */ 
+  openair0_timestamp rx_current_ts;
+  /*!\brief actual number of samples transmitted */ 
+  uint64_t tx_actual_nsamps; 
+  /*!\brief actual number of samples received */
   uint64_t rx_actual_nsamps;
-  uint64_t tx_nsamps; // number of planned samples
+  /*!\brief number of samples to be transmitted */
+  uint64_t tx_nsamps; 
+  /*!\brief number of samples to be received */
   uint64_t rx_nsamps;
-  uint64_t tx_count; // number pf packets
+  /*!\brief number of packets transmitted */
+  uint64_t tx_count; 
+  /*!\brief number of packets received */
   uint64_t rx_count;
-  //openair0_timestamp rx_timestamp;
 
 } eth_state_t;
 
-#define 	ETH_META_STATUS_OVERRUN   (1 << 0)
-#define 	ETH_META_STATUS_UNDERRUN  (1 << 1)
-
-struct eth_meta_data{
-	uint64_t 	timestamp;
-	uint32_t 	flags;	 
-	uint32_t 	status;
- 	unsigned int 	actual_count;
-};
-
 
 
 /*!\brief packet header */
 typedef struct {
+  /*!\brief packet sequence number max value=packets per frame*/
+  uint16_t seq_num ;
+  /*!\brief antenna port used to resynchronize */
+  uint16_t antenna_id;
   /*!\brief packet's timestamp */ 
   openair0_timestamp timestamp;
-  /*!\brief variable declared for alignment purposes (sample size=32 bit)  */
-  int16_t not_used;
-  /*!\brief antenna port used to resynchronize */
-  int16_t antenna_id;
 } header_t;
 
 /*!\brief different options for ethernet tuning in socket and driver level */
@@ -138,9 +159,37 @@ typedef enum {
   MAX_OPT
 } eth_opt_t;
 
+/*
+#define SND_BUF_SIZE	1
+#define RCV_BUF_SIZE	1<<1
+#define SND_TIMEOUT	1<<2
+#define RCV_TIMEOUT	1<<3
+#define MTU_SIZE        1<<4
+#define TX_Q_LEN	1<<5
+#define RING_PAR	1<<5
+#define COALESCE_PAR	1<<6
+#define PAUSE_PAR       1<<7
+*/
 
+/*!\brief I/Q samples */
+typedef struct {
+  /*!\brief phase  */
+  short i;
+  /*!\brief quadrature */
+  short q;
+} iqoai_t ;
 
-/*! \fn int ethernet_tune (openair0_device *device, eth_opt_t option)
+void dump_packet(char *title, unsigned char* pkt, int bytes, unsigned int tx_rx_flag);
+unsigned short calc_csum (unsigned short *buf, int nwords);
+void dump_dev(openair0_device *device);
+void inline dump_buff(openair0_device *device, char *buff,unsigned int tx_rx_flag,int nsamps);
+void inline dump_rxcounters(openair0_device *device);
+void inline dump_txcounters(openair0_device *device);
+void dump_iqs(char * buff, int iq_cnt);
+
+
+
+/*! \fn int ethernet_tune (openair0_device *device, unsigned int option, int value);
 * \brief this function allows you to configure certain ethernet parameters in socket or device level
 * \param[in] openair0 device which bears the socket
 * \param[in] name of parameter to configure
@@ -148,6 +197,37 @@ typedef enum {
 * \note
 * @ingroup  _oai
 */
-int ethernet_tune (openair0_device *device, eth_opt_t option);
-int ethernet_write_data(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc) ;
-int ethernet_read_data(openair0_device *device,openair0_timestamp *timestamp,void **buff, int nsamps,int cc);
+int ethernet_tune(openair0_device *device, unsigned int option, int value);
+
+
+
+/*! \fn int eth_socket_init_udp(openair0_device *device)
+* \brief initialization of UDP Socket to communicate with one destination
+* \param[in] *device openair device for which the socket will be created
+* \param[out]
+* \return 0 on success, otherwise -1
+* \note
+* @ingroup  _oai
+*/
+int eth_socket_init_udp(openair0_device *device);
+int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
+int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
+int eth_get_dev_conf_udp(openair0_device *device);
+
+/*! \fn static int eth_set_dev_conf_udp(openair0_device *device)
+* \brief
+* \param[in] *device openair device
+* \param[out]
+* \return 0 on success, otherwise -1
+* \note
+* @ingroup  _oai
+*/
+int eth_set_dev_conf_udp(openair0_device *device);
+int eth_socket_init_raw(openair0_device *device);
+int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags);
+int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
+int eth_get_dev_conf_raw(openair0_device *device);
+int eth_set_dev_conf_raw(openair0_device *device);
+
+
+#endif
diff --git a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
index 238c94bd7e97a6ce6d6330f260ca99c38e83e5b5..427cd47be831bd4f266789d1d1af1ebf34176f46 100644
--- a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
+++ b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c
@@ -247,7 +247,7 @@ int openair0_stop_without_reset(int card)
 #define MY_RF_MODE      (RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX)
 #define RF_MODE_BASE    (LNA1ON + RFBBNORM)
 
-int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg) {
+int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
 
   // Initialize card
   //  exmimo_config_t         *p_exmimo_config;
@@ -287,6 +287,8 @@ int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair
     return(-1);
   }
 
+  device->type             = EXMIMO_DEV; 
+
   return(0);
 }
 
@@ -323,6 +325,12 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
     else
       p_exmimo_config->framing.multicard_syncmode=SYNCMODE_SLAVE;
 
+    /* device specific */
+    openair0_cfg[card].txlaunch_wait = 1;//manage when TX processing is triggered
+    openair0_cfg[card].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered
+    openair0_cfg[card].iq_txshift = 4;//shift
+    openair0_cfg[card].iq_rxrescale = 15;//rescale iqs
+
     if (openair0_cfg[card].sample_rate==30.72e6) {
       resampling_factor = 0;
       rx_filter = RXLPF10;
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index 7fac005472775f6c2349fbfec58824bd7a475ff1..ece81dc7c3ba1c061983cb04daa797ff60e19f1a 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -217,7 +217,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
 #endif
 
 
-  if (device->type == USRP_B200_IF) {  
+  if (device->type == USRP_B200_DEV) {  
     if (cc>1) {
     // receive multiple channels (e.g. RF A and RF B)
       std::vector<void *> buff_ptrs;
@@ -243,7 +243,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
 #endif
       }
     }
-  } else if (device->type == USRP_X300_IF) {
+  } else if (device->type == USRP_X300_DEV) {
     if (cc>1) {
     // receive multiple channels (e.g. RF A and RF B)
       std::vector<void *> buff_ptrs;
@@ -383,6 +383,7 @@ rx_gain_calib_table_t calib_table_b210[] = {
   {816000000.0,58.0},
   {-1,0}};
 
+/*! \brief USRPB210 RX calibration table */
 rx_gain_calib_table_t calib_table_b210_38[] = {
   {3500000000.0,44.0},
   {2660000000.0,49.8},
@@ -470,17 +471,21 @@ int trx_usrp_reset_stats(openair0_device* device) {
 
 }
 
+
+
+extern "C" {
 /*! \brief Initialize Openair USRP target. It returns 0 if OK
 * \param device the hardware to use
 * \param openair0_cfg RF frontend parameters set by application
 */
-int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg)
-{
-  uhd::set_thread_priority_safe(1.0);
-  usrp_state_t *s = (usrp_state_t*)malloc(sizeof(usrp_state_t));
-  memset(s, 0, sizeof(usrp_state_t));
+  int device_init(openair0_device* device, openair0_config_t *openair0_cfg) {
+    
+    uhd::set_thread_priority_safe(1.0);
+    usrp_state_t *s = (usrp_state_t*)malloc(sizeof(usrp_state_t));
+    memset(s, 0, sizeof(usrp_state_t));
+    
+    // Initialize USRP device
 
-  // Initialize USRP device
 
   std::string args = "type=b200";
 
@@ -524,14 +529,14 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_
     s->usrp->set_clock_source("internal");
     
     //Setting device type to USRP X300/X310 
-    device->type=USRP_X300_IF;
+    device->type=USRP_X300_DEV;
 
     // this is not working yet, master clock has to be set via constructor
     // set master clock rate and sample rate for tx & rx for streaming
     //s->usrp->set_master_clock_rate(usrp_master_clock);
 
     openair0_cfg[0].rx_gain_calib_table = calib_table_x310;
-
+    
     switch ((int)openair0_cfg[0].sample_rate) {
     case 30720000:
             // from usrp_time_offset
@@ -575,13 +580,13 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_
 
     //  s->usrp->set_rx_subdev_spec(rx_subdev);
     //  s->usrp->set_tx_subdev_spec(tx_subdev);
-
-// do not explicitly set the clock to "internal", because this will disable the gpsdo
-//    // lock mboard clocks
-//    s->usrp->set_clock_source("internal");
+    
+    // do not explicitly set the clock to "internal", because this will disable the gpsdo
+    //    // lock mboard clocks
+    //    s->usrp->set_clock_source("internal");
     // set master clock rate and sample rate for tx & rx for streaming
 
-    device->type = USRP_B200_IF;
+    device->type = USRP_B200_DEV;
 
 
     if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) {
@@ -641,6 +646,12 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_
     }
   }
 
+  /* device specific */
+  openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered
+  openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered
+  openair0_cfg[0].iq_txshift = 4;//shift
+  openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
+  
   for(i=0;i<s->usrp->get_rx_num_channels();i++) {
     if (i<openair0_cfg[0].rx_num_channels) {
       s->usrp->set_rx_rate(openair0_cfg[0].sample_rate,i);
@@ -694,10 +705,7 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_
 
 
   s->usrp->set_time_now(uhd::time_spec_t(0.0));
-
-
-
-  
+ 
 
   for (i=0;i<openair0_cfg[0].rx_num_channels;i++) {
     if (i<openair0_cfg[0].rx_num_channels) {
@@ -745,5 +753,6 @@ int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_
   if(is_equal(s->sample_rate, (double)7.68e6))
     s->tx_forward_nsamps = 50;
   return 0;
+  }
 }
 /*@}*/
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf
new file mode 100644
index 0000000000000000000000000000000000000000..e8d49cca1869205bc1886e1a2145f36f2c89368e
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.usrpb210.conf
@@ -0,0 +1,189 @@
+Active_eNBs = ( "eNB_Eurecom_LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    ////////// Identification parameters:
+    eNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_ENB";
+
+    eNB_name  =  "eNB_Eurecom_LTEBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  "1";
+
+    mobile_country_code =  "208";
+
+    mobile_network_code =  "92";
+
+       ////////// Physical parameters:
+
+    component_carriers = (
+      {
+      frame_type					      = "FDD";
+      tdd_config 					      = 3;
+      tdd_config_s            			      = 0;
+      prefix_type             			      = "NORMAL";
+      eutra_band              			      = 7;
+      downlink_frequency      			      = 2660000000L;
+      uplink_frequency_offset 			      = -120000000;
+      Nid_cell					      = 0;
+      N_RB_DL                 			      = 25;
+      Nid_cell_mbsfn          			      = 0;
+      nb_antennas_tx          			      = 1;
+      nb_antennas_rx          			      = 1;
+      tx_gain                                            = 90;
+      rx_gain                                            = 125;
+      prach_root              			      = 0;
+      prach_config_index      			      = 0;
+      prach_high_speed        			      = "DISABLE";
+      prach_zero_correlation  			      = 1;
+      prach_freq_offset       			      = 2;
+      pucch_delta_shift       			      = 1;
+      pucch_nRB_CQI           			      = 1;
+      pucch_nCS_AN            			      = 0;
+      pucch_n1_AN             			      = 32;
+      pdsch_referenceSignalPower 			      = -29;
+      pdsch_p_b                  			      = 0;
+      pusch_n_SB                 			      = 1;
+      pusch_enable64QAM          			      = "DISABLE";
+      pusch_hoppingMode                                  = "interSubFrame";
+      pusch_hoppingOffset                                = 0;
+      pusch_groupHoppingEnabled  			      = "ENABLE";
+      pusch_groupAssignment      			      = 0;
+      pusch_sequenceHoppingEnabled		   	      = "DISABLE";
+      pusch_nDMRS1                                       = 1;
+      phich_duration                                     = "NORMAL";
+      phich_resource                                     = "ONESIXTH";
+      srs_enable                                         = "DISABLE";
+      /*  srs_BandwidthConfig                                =;
+      srs_SubframeConfig                                 =;
+      srs_ackNackST                                      =;
+      srs_MaxUpPts                                       =;*/
+
+      pusch_p0_Nominal                                   = -90;
+      pusch_alpha                                        = "AL1";
+      pucch_p0_Nominal                                   = -96;
+      msg3_delta_Preamble                                = 6;
+      pucch_deltaF_Format1                               = "deltaF2";
+      pucch_deltaF_Format1b                              = "deltaF3";
+      pucch_deltaF_Format2                               = "deltaF0";
+      pucch_deltaF_Format2a                              = "deltaF0";
+      pucch_deltaF_Format2b		    	      = "deltaF0";
+
+      rach_numberOfRA_Preambles                          = 64;
+      rach_preamblesGroupAConfig                         = "DISABLE";
+      /*
+      rach_sizeOfRA_PreamblesGroupA                      = ;
+      rach_messageSizeGroupA                             = ;
+      rach_messagePowerOffsetGroupB                      = ;
+      */
+      rach_powerRampingStep                              = 4;
+      rach_preambleInitialReceivedTargetPower            = -108;
+      rach_preambleTransMax                              = 10;
+      rach_raResponseWindowSize                          = 10;
+      rach_macContentionResolutionTimer                  = 48;
+      rach_maxHARQ_Msg3Tx                                = 4;
+
+      pcch_default_PagingCycle                           = 128;
+      pcch_nB                                            = "oneT";
+      bcch_modificationPeriodCoeff			      = 2;
+      ue_TimersAndConstants_t300			      = 1000;
+      ue_TimersAndConstants_t301			      = 1000;
+      ue_TimersAndConstants_t310			      = 1000;
+      ue_TimersAndConstants_t311			      = 10000;
+      ue_TimersAndConstants_n310			      = 20;
+      ue_TimersAndConstants_n311			      = 1;
+
+      }
+    );
+
+
+    srb1_parameters :
+    {
+        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+        timer_poll_retransmit    = 80;
+
+        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+        timer_reordering         = 35;
+
+        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+        timer_status_prohibit    = 0;
+
+        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+        poll_pdu                 =  4;
+
+        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+        poll_byte                =  99999;
+
+        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+        max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "192.168.12.170";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+rrh_gw_config = (
+ {			  
+    local_if_name = "eth0";			  
+    remote_address = "169.254.8.28";					  
+    #remote_address = "127.0.0.1";						  
+    #remote_address = "74:d4:35:cc:88:45";	 
+    local_address = "169.254.7.91";
+    #local_address = "127.0.0.1";
+    #local_address = "d4:be:d9:22:0a:ac";
+    #for raw option local port must be the same to remote
+    local_port = 50001;		       
+    remote_port = 50000; 
+    active = "yes";
+    preference = "udp";	                
+                             
+}
+);  
+
+    NETWORK_INTERFACES :
+    {
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.242/24";
+
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.242/24";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+
+    log_config :
+    {
+      global_log_level                      ="info";
+      global_log_verbosity                  ="medium";
+      hw_log_level                          ="info";
+      hw_log_verbosity                      ="medium";
+      phy_log_level                         ="info";
+      phy_log_verbosity                     ="medium";
+      mac_log_level                         ="info";
+      mac_log_verbosity                     ="high";
+      rlc_log_level                         ="info";
+      rlc_log_verbosity                     ="medium";
+      pdcp_log_level                        ="info";
+      pdcp_log_verbosity                    ="medium";
+      rrc_log_level                         ="info";
+      rrc_log_verbosity                     ="medium";
+   };
+  }
+);
diff --git a/targets/RT/USER/.#lte-softmodem.c b/targets/RT/USER/.#lte-softmodem.c
new file mode 120000
index 0000000000000000000000000000000000000000..dbbd6586599c14ca75f79061f52ecdff42891b13
--- /dev/null
+++ b/targets/RT/USER/.#lte-softmodem.c
@@ -0,0 +1 @@
+guepe@guepe.25164:1451994252
\ No newline at end of file
diff --git a/targets/RT/USER/UE_transport_IQ.c b/targets/RT/USER/UE_transport_IQ.c
index a52e3654aec845ab9666e7402fc0db65f2db81d1..a45b8ba43b40171e106689ea91ef32d90fdbb852 100644
--- a/targets/RT/USER/UE_transport_IQ.c
+++ b/targets/RT/USER/UE_transport_IQ.c
@@ -148,7 +148,7 @@ void *rrh_proc_UE_thread(void * arg) {
   unsigned int                  samples_per_frame=0;
   rrh_module_t 	*dev=(rrh_module_t *)arg;
   
-  samples_per_frame= dev->eth_dev.openair0_cfg.samples_per_frame;
+  samples_per_frame= dev->eth_dev.openair0_cfg->samples_per_frame;
   AssertFatal(samples_per_frame <=0, "invalide samples_per_frame !%u\n",samples_per_frame);
 
   time_req.tv_sec = 0;
@@ -260,7 +260,7 @@ void *rrh_UE_thread(void *arg) {
   void 			*tmp;
   unsigned int          samples_per_frame=0;
   
-  samples_per_frame= dev->eth_dev.openair0_cfg.samples_per_frame;
+  samples_per_frame= dev->eth_dev.openair0_cfg->samples_per_frame;
   time_req_1us.tv_sec = 0;
   time_req_1us.tv_nsec = 1000;
   
@@ -269,26 +269,26 @@ void *rrh_UE_thread(void *arg) {
     cmd=dev->eth_dev.trx_start_func(&dev->eth_dev);
     
     /* allocate memory for TX/RX buffers */
-    rx_buffer_UE = (int32_t**)malloc16(dev->eth_dev.openair0_cfg.rx_num_channels*sizeof(int32_t*));
-    tx_buffer_UE = (int32_t**)malloc16(dev->eth_dev.openair0_cfg.tx_num_channels*sizeof(int32_t*));
+    rx_buffer_UE = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->rx_num_channels*sizeof(int32_t*));
+    tx_buffer_UE = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->tx_num_channels*sizeof(int32_t*));
     
-    for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++) {
+    for (i=0; i<dev->eth_dev.openair0_cfg->rx_num_channels; i++) {
       tmp=(void *)malloc(sizeof(int32_t)*(samples_per_frame+4));
       memset(tmp,0,sizeof(int32_t)*(samples_per_frame+4));
       rx_buffer_UE[i]=(tmp+4*sizeof(int32_t));  
     }
     
-    for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) {
+    for (i=0; i<dev->eth_dev.openair0_cfg->tx_num_channels; i++) {
       tmp=(void *)malloc(sizeof(int32_t)*(samples_per_frame+4));
       memset(tmp,0,sizeof(int32_t)*(samples_per_frame+4));
       tx_buffer_UE[i]=(tmp+4*sizeof(int32_t));  
     }
     
-    printf("Client %s:%d is connected (DL_RB=%d) rt=%d|%d. \n" ,   dev->eth_dev.openair0_cfg.remote_ip,
-	   dev->eth_dev.openair0_cfg.remote_port,
-	   dev->eth_dev.openair0_cfg.num_rb_dl,
-	   dev->eth_dev.openair0_cfg.rx_num_channels,
-	   dev->eth_dev.openair0_cfg.tx_num_channels);
+    printf("Client %s:%d is connected (DL_RB=%d) rt=%d|%d. \n" ,   dev->eth_dev.openair0_cfg->remote_addr,
+	   dev->eth_dev.openair0_cfg->remote_port,
+	   dev->eth_dev.openair0_cfg->num_rb_dl,
+	   dev->eth_dev.openair0_cfg->rx_num_channels,
+	   dev->eth_dev.openair0_cfg->tx_num_channels);
     
     if (cmd==START_CMD) {
       
@@ -348,8 +348,8 @@ void *rrh_UE_rx_thread(void *arg) {
   openair0_timestamp  temp, last_hw_counter=0;
   
   antenna_index     = 0;
-  nsamps	    = dev->eth_dev.openair0_cfg.samples_per_packet;
-  samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame;
+  nsamps	    = dev->eth_dev.openair0_cfg->samples_per_packet;
+  samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame;
   
   while (rrh_exit == 0) {
     if (!UE_rx_started) {
@@ -492,8 +492,8 @@ void *rrh_UE_tx_thread(void *arg) {
   unsigned int          samples_per_frame=0;
   
   antenna_index    = 0;
-  nsamps 	   = dev->eth_dev.openair0_cfg.samples_per_packet;
-  samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame;
+  nsamps 	   = dev->eth_dev.openair0_cfg->samples_per_packet;
+  samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame;
   
   
   while (rrh_exit == 0) {
diff --git a/targets/RT/USER/eNB_transport_IQ.c b/targets/RT/USER/eNB_transport_IQ.c
index af3873ef76cfd4b940988333c93f4c9d586f5fb7..594b075941c59a9b666cecc95a3734d14193842d 100644
--- a/targets/RT/USER/eNB_transport_IQ.c
+++ b/targets/RT/USER/eNB_transport_IQ.c
@@ -127,7 +127,7 @@ static void check_dev_config( rrh_module_t *mod_enb);
  * \note
  * @ingroup  _oai
  */
-static void calc_rt_period_ns( openair0_config_t openair0_cfg);
+static void calc_rt_period_ns( openair0_config_t *openair0_cfg);
 
 
 
@@ -140,104 +140,33 @@ void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag) {
   
   RT_flag_eNB=RT_flag;
   NRT_flag_eNB=NRT_flag;
-    
-  /* handshake with client to exchange parameters */
+  
+  /* init socket and have handshake-like msg with client to exchange parameters */
   mod_enb->eth_dev.trx_start_func(&mod_enb->eth_dev);//change port  make it plus_id
- 
- /* if a RF iterface is added to RRH module get the  configuration parameters sent from eNB  */
-  if (mod_enb->devs->type != NONE_IF ) {  
 
-    memcpy((void*)&mod_enb->devs->openair0_cfg,(void *)&mod_enb->eth_dev.openair0_cfg,sizeof(openair0_config_t));
-    
-    /* certain parameters have to be updated (calibration related)*/
-    if ( mod_enb->devs->type == EXMIMO_IF ) {
-      if ( mod_enb->devs->openair0_cfg.num_rb_dl == 100 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
-	mod_enb->devs->openair0_cfg.tx_delay = 8;
-      }
-      else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 95;
-	mod_enb->devs->openair0_cfg.tx_delay = 5;
-      }
-      else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 1024;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 70;
-	mod_enb->devs->openair0_cfg.tx_delay = 6;
-      }
-      else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 256;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 40;
-	mod_enb->devs->openair0_cfg.tx_delay = 8;
-      }
-    }
-    else if ((mod_enb->devs->type == USRP_B200_IF )||(mod_enb->devs->type == USRP_X300_IF )) {
-      if ( mod_enb->devs->openair0_cfg.num_rb_dl == 100 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
-	mod_enb->devs->openair0_cfg.tx_delay = 8;
-      }
-      else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 95;
-	mod_enb->devs->openair0_cfg.tx_delay = 5;
-      }
-      else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 1024;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 70;
-	mod_enb->devs->openair0_cfg.tx_delay = 6;
-      }
-      else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 256;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 40;
-	mod_enb->devs->openair0_cfg.tx_delay = 8;
-      }
-    }
-    else if(mod_enb->devs->type == BLADERF_IF) {
-      if ( mod_enb->devs->openair0_cfg.num_rb_dl == 100 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
-	mod_enb->devs->openair0_cfg.tx_delay = 8;
-      }
-      else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 50 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 95;
-	mod_enb->devs->openair0_cfg.tx_delay = 5;
-      }
-      else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 25 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 1024;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 70;
-	mod_enb->devs->openair0_cfg.tx_delay = 6;
-      }
-      else if ( mod_enb->devs->openair0_cfg.num_rb_dl == 6 ) {
-	mod_enb->devs->openair0_cfg.samples_per_packet = 256;
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps = 40;
-	mod_enb->devs->openair0_cfg.tx_delay = 8;
-      }           
-    }  
-    
-    /* check sanity of configuration parameters and print */
-    check_dev_config(mod_enb);    
-    
-    /* initialize and configure the RF device */
-    if (openair0_device_init(mod_enb->devs, &mod_enb->devs->openair0_cfg)<0){
-      LOG_E(RRH,"Exiting, cannot initialize RF device.\n");
-      exit(-1);
-    }
-    else {
-      LOG_I(RRH,"RF device has been successfully initialized.\n");
-    }    
+  mod_enb->devs->openair0_cfg = mod_enb->eth_dev.openair0_cfg;
 
-    /* start RF device */
-    if (mod_enb->devs->type == EXMIMO_IF ) {
+  /* check sanity of configuration parameters and print */
+  check_dev_config(mod_enb);    
+  
+  /* initialize and configure the RF device */
+  if (openair0_device_load(mod_enb->devs, mod_enb->devs->openair0_cfg)<0) {
+    LOG_E(RRH,"Exiting, cannot initialize RF device.\n");
+    exit(-1);
+  } else {
+    if (mod_enb->devs->type != NONE_DEV) {
+      /* start RF device */
+      if (mod_enb->devs->type == EXMIMO_DEV) {
+	//call start function for exmino
+      } else {
+	if (mod_enb->devs->trx_start_func(mod_enb->devs)!=0)
+	  LOG_E(RRH,"Unable to initiate RF device.\n");
+	else
+	  LOG_I(RRH,"RF device has been initiated.\n");
+      }
       
-    } else {
-      if (mod_enb->devs->trx_start_func(mod_enb->devs)!=0)
-	LOG_E(RRH,"Unable to initiate RF device.\n");
     }
-    LOG_I(RRH,"RF device has been initiated.\n");
-  }
+  }  
   
   /* create main eNB module thread
      main_rrh_eNB_thread allocates memory 
@@ -266,7 +195,7 @@ void *rrh_eNB_thread(void *arg) {
   void 			*tmp;
   unsigned int          samples_per_frame=0;
   
-  samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame;    
+  samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame;    
 
   while (rrh_exit==0) {
     
@@ -278,42 +207,42 @@ void *rrh_eNB_thread(void *arg) {
     /* allocate memory for TX/RX buffers
        each antenna port has a TX and a RX buffer
        each TX and RX buffer is of (samples_per_frame + HEADER_SIZE) samples (size of samples is 4 bytes) */
-    rx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg.rx_num_channels*sizeof(int32_t*));
-    tx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg.tx_num_channels*sizeof(int32_t*));    
+    rx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->rx_num_channels*sizeof(int32_t*));
+    tx_buffer_eNB = (int32_t**)malloc16(dev->eth_dev.openair0_cfg->tx_num_channels*sizeof(int32_t*));    
     LOG_D(RRH,"rx_buffer_eNB address =%p tx_buffer_eNB address =%p  \n",rx_buffer_eNB,tx_buffer_eNB);
     
     /* rx_buffer_eNB points to the beginning of data */
-    for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++) {
+    for (i=0; i<dev->eth_dev.openair0_cfg->rx_num_channels; i++) {
       tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32));
       memset(tmp,0,sizeof(int32_t)*(samples_per_frame + 32));
       rx_buffer_eNB[i]=( tmp + (32*sizeof(int32_t)) );  
       LOG_D(RRH,"i=%d rx_buffer_eNB[i]=%p tmp= %p\n",i,rx_buffer_eNB[i],tmp);
     }
     /* tx_buffer_eNB points to the beginning of data */
-    for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) {
+    for (i=0; i<dev->eth_dev.openair0_cfg->tx_num_channels; i++) {
       tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32));
       memset(tmp,0,sizeof(int32_t)*(samples_per_frame + 32));
       tx_buffer_eNB[i]=( tmp + (32*sizeof(int32_t)) );  
       LOG_D(RRH,"i= %d tx_buffer_eNB[i]=%p tmp= %p \n",i,tx_buffer_eNB[i],tmp);
     }
     /* dummy initialization for TX/RX buffers */
-    for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++) {
+    for (i=0; i<dev->eth_dev.openair0_cfg->rx_num_channels; i++) {
       for (j=0; j<samples_per_frame; j++) {
 	rx_buffer_eNB[i][j]=32+i; 
       } 
     }
     /* dummy initialization for TX/RX buffers */
-    for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) {
+    for (i=0; i<dev->eth_dev.openair0_cfg->tx_num_channels; i++) {
       for (j=0; j<samples_per_frame; j++) {
 	tx_buffer_eNB[i][j]=12+i; 
       } 
     }    
     /* allocate TX/RX buffers pointers used in write/read operations */
-    rx_eNB = (void**)malloc16(dev->eth_dev.openair0_cfg.rx_num_channels*sizeof(int32_t*));
-    tx_eNB = (void**)malloc16(dev->eth_dev.openair0_cfg.tx_num_channels*sizeof(int32_t*));
+    rx_eNB = (void**)malloc16(dev->eth_dev.openair0_cfg->rx_num_channels*sizeof(int32_t*));
+    tx_eNB = (void**)malloc16(dev->eth_dev.openair0_cfg->tx_num_channels*sizeof(int32_t*));
 
     /* init mutexes */    
-    for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) {
+    for (i=0; i<dev->eth_dev.openair0_cfg->tx_num_channels; i++) {
       pthread_mutex_init(&sync_eNB_mutex[i],NULL);
       pthread_cond_init(&sync_eNB_cond[i],NULL);
     }
@@ -353,7 +282,7 @@ void *rrh_eNB_thread(void *arg) {
     }
    
     /* create timer thread; when no RF device is present a software clock is generated */    
-    if (dev->devs->type == NONE_IF) {
+    if (dev->devs->type == NONE_DEV) {
 
       int 			error_code_timer;
       pthread_t 		main_timer_proc_thread;
@@ -405,10 +334,11 @@ void *rrh_eNB_thread(void *arg) {
   return(0);
 }
 
+/* Receive from RF and transmit to RRH */
 
 void *rrh_eNB_rx_thread(void *arg) {
 
-  /* measuremnt related vars */
+  /* measurement related vars */
   struct timespec time0,time1,time2;
   unsigned long long max_rx_time=0, min_rx_time=rt_period, total_rx_time=0, average_rx_time=rt_period, s_period=0, trial=0;
   int trace_cnt=0;
@@ -425,10 +355,10 @@ void *rrh_eNB_rx_thread(void *arg) {
 
   time_req_1us.tv_sec = 0;
   time_req_1us.tv_nsec =1000;  //time_req_1us.tv_nsec = (int)rt_period/2;--->granularity issue
-  spp_eth =  dev->eth_dev.openair0_cfg.samples_per_packet;
-  spp_rf  =  dev->devs->openair0_cfg.samples_per_packet;
+  spp_eth =  dev->eth_dev.openair0_cfg->samples_per_packet;
+  spp_rf  =  dev->devs->openair0_cfg->samples_per_packet;
 
-  samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame;
+  samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame;
   samples_per_subframe = (unsigned int)samples_per_frame/10;
   loopback = dev->loopback;
   measurements = dev->measurements;
@@ -456,14 +386,14 @@ void *rrh_eNB_rx_thread(void *arg) {
 
   while (rrh_exit == 0) {    
     while (rx_pos <(1 + subframe)*samples_per_subframe) {
-      LOG_D(RRH,"starting a new send:%d  %d\n",sync_trx,frame);
+      //LOG_D(RRH,"starting a new send:%d  %d\n",sync_trx,frame);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 1 );
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME_RX, frame);
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME_RX, subframe );  
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK, pck_rx );
       LOG_D(RRH,"pack=%d    rx_pos=%d    subframe=%d frame=%d\n ",pck_rx, rx_pos, subframe,frame);
       
-      if (dev->devs->type == NONE_IF) {	
+      if (dev->devs->type == NONE_DEV) {	
 	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_HWCNT, hw_counter );
 	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_LHWCNT, last_hw_counter );
 	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_CNT, s_cnt );
@@ -501,19 +431,19 @@ void *rrh_eNB_rx_thread(void *arg) {
 	}
        }
        
-       for (i=0; i<dev->eth_dev.openair0_cfg.rx_num_channels; i++) {
+       for (i=0; i<dev->eth_dev.openair0_cfg->rx_num_channels; i++) {
 	 rx_eNB[i] = (void*)&rx_buffer_eNB[i][rx_pos];
 	 LOG_D(RRH," rx_eNB[i]=%p rx_buffer_eNB[i][rx_pos]=%p ,rx_pos=%d, i=%d ts=%d\n",rx_eNB[i],&rx_buffer_eNB[i][rx_pos],rx_pos,i,timestamp_rx);	 
        }  
        VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RXCNT, rx_pos );
-       if (dev->devs->type != NONE_IF) {
+       if (dev->devs->type != NONE_DEV) {
 	 VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_RF, 1 ); 
 	 /* Read operation to RF device (RX)*/
 	 if ( dev->devs->trx_read_func (dev->devs,
 					&timestamp_rx,
 					rx_eNB,
 					spp_rf,
-					dev->devs->openair0_cfg.rx_num_channels
+					dev->devs->openair0_cfg->rx_num_channels
 					)<0) {
 	   perror("RRH eNB : USRP read");
 	 }
@@ -526,14 +456,14 @@ void *rrh_eNB_rx_thread(void *arg) {
 						      timestamp_rx,
 						      rx_eNB,
 						      spp_eth,
-						      dev->eth_dev.openair0_cfg.rx_num_channels,
+						      dev->eth_dev.openair0_cfg->rx_num_channels,
 						      0))<0) {
 	 perror("RRH eNB : ETHERNET write");
        }    
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
 
        /* when there is no RF timestamp is updated by number of samples */
-       if (dev->devs->type == NONE_IF) {
+       if (dev->devs->type == NONE_DEV) {
 	 timestamp_rx+=spp_eth;
 	 last_hw_counter=hw_counter;
        }
@@ -559,7 +489,7 @@ void *rrh_eNB_rx_thread(void *arg) {
 	   }
 	   if (s_period++ == PRINTF_PERIOD) {
 	     s_period=0;
-	     LOG_I(RRH,"Average eNB RX time : %lu\tMax RX time : %lu\tMin RX time : %lu\n",average_rx_time,max_rx_time,min_rx_time);
+	     LOG_I(RRH,"Average eNB RX time : %lu ns\tMax RX time : %lu ns\tMin RXX time : %lu ns\n",average_rx_time,max_rx_time,min_rx_time);
 	   }
 	 }
 	 
@@ -577,7 +507,7 @@ void *rrh_eNB_rx_thread(void *arg) {
        next_rx_pos=(rx_pos+spp_eth);
        
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 0 );
-       /**/
+       /*
        if (frame>50) {
 	 pthread_mutex_lock(&sync_trx_mutex);
 	 while (sync_trx) {
@@ -587,7 +517,7 @@ void *rrh_eNB_rx_thread(void *arg) {
 	 LOG_D(RRH,"out of while send:%d  %d\n",sync_trx,frame);
 	 pthread_cond_signal(&sync_trx_cond);
 	 pthread_mutex_unlock(&sync_trx_mutex);
-       }
+	 }*/
     } // while 
     
     subframe++;
@@ -609,6 +539,7 @@ void *rrh_eNB_rx_thread(void *arg) {
   return 0;
 }
 
+/* Receive from eNB and transmit to RF */
 
 void *rrh_eNB_tx_thread(void *arg) {
 
@@ -647,60 +578,34 @@ void *rrh_eNB_tx_thread(void *arg) {
   
   time_req_1us.tv_sec = 1;
   time_req_1us.tv_nsec = 0;
-  spp_eth = dev->eth_dev.openair0_cfg.samples_per_packet;
-  spp_rf =  dev->devs->openair0_cfg.samples_per_packet;
-  samples_per_frame = dev->eth_dev.openair0_cfg.samples_per_frame;
+  spp_eth = dev->eth_dev.openair0_cfg->samples_per_packet;
+  spp_rf =  dev->devs->openair0_cfg->samples_per_packet;
+  samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame;
   samples_per_subframe = (unsigned int)samples_per_frame/10;
   tx_pos=0;
-  //tx_pos_rf=spp_rf*dev->devs->openair0_cfg.tx_delay;
-  
+
   loopback = dev->loopback;
   measurements = dev->measurements;
   
   while (rrh_exit == 0) {     
     while (tx_pos < (1 + subframe)*samples_per_subframe) {
       
-      LOG_D(RRH,"bef lock read:%d  %d\n",sync_trx,frame);
-      pthread_mutex_lock(&sync_trx_mutex);
+      //LOG_D(RRH,"bef lock read:%d  %d\n",sync_trx,frame);
+      //pthread_mutex_lock(&sync_trx_mutex);
       
-      while (!sync_trx) {
-	LOG_D(RRH,"in sync read:%d  %d\n",sync_trx,frame);
-	pthread_cond_wait(&sync_trx_cond,&sync_trx_mutex);
-      }
-      LOG_D(RRH,"out of while read:%d  %d\n",sync_trx,frame);
+      //while (!sync_trx) {
+      //LOG_D(RRH,"in sync read:%d  %d\n",sync_trx,frame);
+      //pthread_cond_wait(&sync_trx_cond,&sync_trx_mutex);
+      //}
+      //LOG_D(RRH,"out of while read:%d  %d\n",sync_trx,frame);
       
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 1 );
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame);
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, subframe );
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_PCK, pck_tx );
-      
-      /*	
-		if (dev->devs->type == NONE_IF) {  
-		VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_HWCNT, hw_counter );
-		VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_LHWCNT, last_hw_counter );    
-		
-		if (!eNB_tx_started) {
-		eNB_tx_started=1; // set this flag to 1 to indicate that eNB started
-		if (RT_flag_eNB==1) {
-		last_hw_counter=hw_counter;
-		}
-		} else {
-		if (RT_flag_eNB==1) {
-		if (hw_counter > last_hw_counter+1) {
-		printf("LT");
-		} else {
-		while ((hw_counter < last_hw_counter+1)) {
-		VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX_SLEEP, 1 );
-		nanosleep(&time_req_1us,&time_rem_1us);
-		VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX_SLEEP, 0 );
-		}
-		}
-		}
-		}
-		}    */
-      
+          
       if (measurements == 1 ) 	clock_gettime(CLOCK_MONOTONIC,&time1); 
-      for (i=0; i<dev->eth_dev.openair0_cfg.tx_num_channels; i++) tx_eNB[i] = (void*)&tx_buffer_eNB[i][tx_pos];	//RF!!!!!		
+      for (i=0; i<dev->eth_dev.openair0_cfg->tx_num_channels; i++) tx_eNB[i] = (void*)&tx_buffer_eNB[i][tx_pos];		
       
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TXCNT, tx_pos );
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
@@ -710,12 +615,12 @@ void *rrh_eNB_tx_thread(void *arg) {
 							&timestamp_tx,
 							tx_eNB,
 							spp_eth,
-							dev->eth_dev.openair0_cfg.tx_num_channels))<0) {
+							dev->eth_dev.openair0_cfg->tx_num_channels))<0) {
 	perror("RRH eNB : ETHERNET read");
       }		
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );	
       
-      if (dev->devs->type != NONE_IF) {  
+      if (dev->devs->type != NONE_DEV) {  
 	LOG_D(RRH," tx_buffer_eNB[i][tx_pos]=%x t_buffer_eNB[i][tx_pos+1]=%x t_buffer_eNB[i][tx_pos+2]=%x \n",tx_buffer_eNB[0][tx_pos],tx_buffer_eNB[0][tx_pos+1],tx_buffer_eNB[0][tx_pos+2]);	 
 	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF, 1 );    
 	/* Write operation to RF device (TX)*/
@@ -723,8 +628,8 @@ void *rrh_eNB_tx_thread(void *arg) {
 					timestamp_tx,
 					tx_eNB,
 					spp_rf,
-					dev->devs->openair0_cfg.tx_num_channels,
-					0)<0){
+					dev->devs->openair0_cfg->tx_num_channels,
+					1)<0){
 	  perror("RRH eNB : USRP write");
 	}
 	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF, 0 );
@@ -733,7 +638,7 @@ void *rrh_eNB_tx_thread(void *arg) {
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_TS, timestamp_tx&0xffffffff ); 
       
             
-      if (dev->devs->type == NONE_IF)	last_hw_counter=hw_counter;
+      if (dev->devs->type == NONE_DEV)	last_hw_counter=hw_counter;
     
     
       if (loopback ==1 ) { 
@@ -754,10 +659,10 @@ void *rrh_eNB_tx_thread(void *arg) {
       tx_pos += spp_eth;
       pck_tx++;   
       
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 0 );
-      sync_trx=0;
-      pthread_cond_signal(&sync_trx_cond);
-      pthread_mutex_unlock(&sync_trx_mutex);
+      //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 0 );
+      //sync_trx=0;
+      //pthread_cond_signal(&sync_trx_cond);
+      //pthread_mutex_unlock(&sync_trx_mutex);
     }
 
     /* wrap around tx buffer index */
@@ -775,72 +680,67 @@ void *rrh_eNB_tx_thread(void *arg) {
 }
 
 
-static void calc_rt_period_ns( openair0_config_t openair0_cfg) {
+static void calc_rt_period_ns( openair0_config_t *openair0_cfg) {
 
-  rt_period= (double)(openair0_cfg.samples_per_packet/(openair0_cfg.samples_per_frame/10.0)*1000000);
+  rt_period= (double)(openair0_cfg->samples_per_packet/(openair0_cfg->samples_per_frame/10.0)*1000000);
   AssertFatal(rt_period > 0, "Invalid rt period !%u\n", rt_period);
   LOG_I(RRH,"[eNB] Real time period is set to %u ns\n", rt_period);	
 }
 
 
 static void check_dev_config( rrh_module_t *mod_enb) {
-  
-  
-  AssertFatal( (mod_enb->devs->openair0_cfg.num_rb_dl==100 || mod_enb->devs->openair0_cfg.num_rb_dl==50 || mod_enb->devs->openair0_cfg.num_rb_dl==25 || mod_enb->devs->openair0_cfg.num_rb_dl==6) , "Invalid number of resource blocks! %d\n", mod_enb->devs->openair0_cfg.num_rb_dl);
- AssertFatal( mod_enb->devs->openair0_cfg.samples_per_frame  > 0 ,  "Invalid number of samples per frame! %d\n",mod_enb->devs->openair0_cfg.samples_per_frame); 
- AssertFatal( mod_enb->devs->openair0_cfg.sample_rate        > 0.0, "Invalid sample rate! %f\n", mod_enb->devs->openair0_cfg.sample_rate);
- AssertFatal( mod_enb->devs->openair0_cfg.samples_per_packet > 0 ,  "Invalid number of samples per packet! %d\n",mod_enb->devs->openair0_cfg.samples_per_packet);
- AssertFatal( mod_enb->devs->openair0_cfg.rx_num_channels    > 0 ,  "Invalid number of RX antennas! %d\n", mod_enb->devs->openair0_cfg.rx_num_channels); 
- AssertFatal( mod_enb->devs->openair0_cfg.tx_num_channels    > 0 ,  "Invalid number of TX antennas! %d\n", mod_enb->devs->openair0_cfg.tx_num_channels);
- AssertFatal( mod_enb->devs->openair0_cfg.rx_freq[0]         > 0.0 ,"Invalid RX frequency! %f\n", mod_enb->devs->openair0_cfg.rx_freq[0]); 
- AssertFatal( mod_enb->devs->openair0_cfg.tx_freq[0]         > 0.0 ,"Invalid TX frequency! %f\n", mod_enb->devs->openair0_cfg.tx_freq[0]);
- AssertFatal( mod_enb->devs->openair0_cfg.rx_gain[0]         > 0.0 ,"Invalid RX gain! %f\n", mod_enb->devs->openair0_cfg.rx_gain[0]); 
- AssertFatal( mod_enb->devs->openair0_cfg.tx_gain[0]         > 0.0 ,"Invalid TX gain! %f\n", mod_enb->devs->openair0_cfg.tx_gain[0]);
- AssertFatal( mod_enb->devs->openair0_cfg.rx_bw              > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg.rx_bw); 
- AssertFatal( mod_enb->devs->openair0_cfg.tx_bw              > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg.tx_bw);
- AssertFatal( mod_enb->devs->openair0_cfg.autocal[0]         > 0 ,  "Invalid auto calibration choice! %d\n", mod_enb->devs->openair0_cfg.autocal[0]);
+    
+ AssertFatal( (mod_enb->devs->openair0_cfg->num_rb_dl==100 || mod_enb->devs->openair0_cfg->num_rb_dl==50 || mod_enb->devs->openair0_cfg->num_rb_dl==25 || mod_enb->devs->openair0_cfg->num_rb_dl==6) , "Invalid number of resource blocks! %d\n", mod_enb->devs->openair0_cfg->num_rb_dl);
+ AssertFatal( mod_enb->devs->openair0_cfg->samples_per_frame  > 0 ,  "Invalid number of samples per frame! %d\n",mod_enb->devs->openair0_cfg->samples_per_frame); 
+ AssertFatal( mod_enb->devs->openair0_cfg->sample_rate        > 0.0, "Invalid sample rate! %f\n", mod_enb->devs->openair0_cfg->sample_rate);
+ AssertFatal( mod_enb->devs->openair0_cfg->samples_per_packet > 0 ,  "Invalid number of samples per packet! %d\n",mod_enb->devs->openair0_cfg->samples_per_packet);
+ AssertFatal( mod_enb->devs->openair0_cfg->rx_num_channels    > 0 ,  "Invalid number of RX antennas! %d\n", mod_enb->devs->openair0_cfg->rx_num_channels); 
+ AssertFatal( mod_enb->devs->openair0_cfg->tx_num_channels    > 0 ,  "Invalid number of TX antennas! %d\n", mod_enb->devs->openair0_cfg->tx_num_channels);
+ AssertFatal( mod_enb->devs->openair0_cfg->rx_freq[0]         > 0.0 ,"Invalid RX frequency! %f\n", mod_enb->devs->openair0_cfg->rx_freq[0]); 
+ AssertFatal( mod_enb->devs->openair0_cfg->tx_freq[0]         > 0.0 ,"Invalid TX frequency! %f\n", mod_enb->devs->openair0_cfg->tx_freq[0]);
+ AssertFatal( mod_enb->devs->openair0_cfg->rx_gain[0]         > 0.0 ,"Invalid RX gain! %f\n", mod_enb->devs->openair0_cfg->rx_gain[0]); 
+ AssertFatal( mod_enb->devs->openair0_cfg->tx_gain[0]         > 0.0 ,"Invalid TX gain! %f\n", mod_enb->devs->openair0_cfg->tx_gain[0]);
+ AssertFatal( mod_enb->devs->openair0_cfg->rx_bw              > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg->rx_bw); 
+ AssertFatal( mod_enb->devs->openair0_cfg->tx_bw              > 0.0 ,"Invalid RX bw! %f\n", mod_enb->devs->openair0_cfg->tx_bw);
+ AssertFatal( mod_enb->devs->openair0_cfg->autocal[0]         > 0 ,  "Invalid auto calibration choice! %d\n", mod_enb->devs->openair0_cfg->autocal[0]);
  
  printf("\n---------------------RF device configuration parameters---------------------\n");
  
- printf("\tMod_id=%d\n \tlog level=%d\n \tDL_RB=%d\n \tsamples_per_frame=%d\n \tsample_rate=%f\n \tsamples_per_packet=%d\n \ttx_delay=%d\n \ttx_forward_nsamps=%d\n \trx_num_channels=%d\n \ttx_num_channels=%d\n \trx_freq_0=%f\n \ttx_freq_0=%f\n \trx_freq_1=%f\n \ttx_freq_1=%f\n \trx_freq_2=%f\n \ttx_freq_2=%f\n \trx_freq_3=%f\n \ttx_freq_3=%f\n \trxg_mode=%d\n \trx_gain_0=%f\n \ttx_gain_0=%f\n  \trx_gain_1=%f\n \ttx_gain_1=%f\n  \trx_gain_2=%f\n \ttx_gain_2=%f\n  \trx_gain_3=%f\n \ttx_gain_3=%f\n \trx_gain_offset_2=%f\n \ttx_gain_offset_3=%f\n  \trx_bw=%f\n \ttx_bw=%f\n \tautocal=%d\n \trem_addr %s:%d\n \tmy_addr %s:%d\n",	
-	mod_enb->devs->openair0_cfg.Mod_id,
-	mod_enb->devs->openair0_cfg.log_level,
-	mod_enb->devs->openair0_cfg.num_rb_dl,
-	mod_enb->devs->openair0_cfg.samples_per_frame,
-	mod_enb->devs->openair0_cfg.sample_rate,
-	mod_enb->devs->openair0_cfg.samples_per_packet,
-	mod_enb->devs->openair0_cfg.tx_delay,
-	mod_enb->devs->openair0_cfg.tx_forward_nsamps,
-	mod_enb->devs->openair0_cfg.rx_num_channels,
-	mod_enb->devs->openair0_cfg.tx_num_channels,
-	mod_enb->devs->openair0_cfg.rx_freq[0],
-	mod_enb->devs->openair0_cfg.tx_freq[0],
-	mod_enb->devs->openair0_cfg.rx_freq[1],
-	mod_enb->devs->openair0_cfg.tx_freq[1],
-	mod_enb->devs->openair0_cfg.rx_freq[2],
-	mod_enb->devs->openair0_cfg.tx_freq[2],
-	mod_enb->devs->openair0_cfg.rx_freq[3],
-	mod_enb->devs->openair0_cfg.tx_freq[3],
-	mod_enb->devs->openair0_cfg.rxg_mode[0],
-	mod_enb->devs->openair0_cfg.rx_gain[0],
-	mod_enb->devs->openair0_cfg.tx_gain[0],
-	mod_enb->devs->openair0_cfg.rx_gain[1],
-	mod_enb->devs->openair0_cfg.tx_gain[1],
-	mod_enb->devs->openair0_cfg.rx_gain[2],
-	mod_enb->devs->openair0_cfg.tx_gain[2],
-	mod_enb->devs->openair0_cfg.rx_gain[3],
-	mod_enb->devs->openair0_cfg.tx_gain[3],
-	//mod_enb->devs->openair0_cfg.rx_gain_offset[0],
-	//mod_enb->devs->openair0_cfg.rx_gain_offset[1],
-	mod_enb->devs->openair0_cfg.rx_gain_offset[2],
-	mod_enb->devs->openair0_cfg.rx_gain_offset[3],
-	mod_enb->devs->openair0_cfg.rx_bw,
-	mod_enb->devs->openair0_cfg.tx_bw,
-	mod_enb->devs->openair0_cfg.autocal[0],
-	mod_enb->devs->openair0_cfg.remote_ip,
-	mod_enb->devs->openair0_cfg.remote_port,
-	mod_enb->devs->openair0_cfg.my_ip,
-	mod_enb->devs->openair0_cfg.my_port  
+ printf("\tMod_id=%d\n \tlog level=%d\n \tDL_RB=%d\n \tsamples_per_frame=%d\n \tsample_rate=%f\n \tsamples_per_packet=%d\n \ttx_scheduling_advance=%d\n \ttx_sample_advance=%d\n \trx_num_channels=%d\n \ttx_num_channels=%d\n \trx_freq_0=%f\n \ttx_freq_0=%f\n \trx_freq_1=%f\n \ttx_freq_1=%f\n \trx_freq_2=%f\n \ttx_freq_2=%f\n \trx_freq_3=%f\n \ttx_freq_3=%f\n \trxg_mode=%d\n \trx_gain_0=%f\n \ttx_gain_0=%f\n  \trx_gain_1=%f\n \ttx_gain_1=%f\n  \trx_gain_2=%f\n \ttx_gain_2=%f\n  \trx_gain_3=%f\n \ttx_gain_3=%f\n \trx_gain_offset_2=%f\n \ttx_gain_offset_3=%f\n  \trx_bw=%f\n \ttx_bw=%f\n \tautocal=%d\n",	
+	mod_enb->devs->openair0_cfg->Mod_id,
+	mod_enb->devs->openair0_cfg->log_level,
+	mod_enb->devs->openair0_cfg->num_rb_dl,
+	mod_enb->devs->openair0_cfg->samples_per_frame,
+	mod_enb->devs->openair0_cfg->sample_rate,
+	mod_enb->devs->openair0_cfg->samples_per_packet,
+	mod_enb->devs->openair0_cfg->tx_scheduling_advance,
+	mod_enb->devs->openair0_cfg->tx_sample_advance,
+	mod_enb->devs->openair0_cfg->rx_num_channels,
+	mod_enb->devs->openair0_cfg->tx_num_channels,
+	mod_enb->devs->openair0_cfg->rx_freq[0],
+	mod_enb->devs->openair0_cfg->tx_freq[0],
+	mod_enb->devs->openair0_cfg->rx_freq[1],
+	mod_enb->devs->openair0_cfg->tx_freq[1],
+	mod_enb->devs->openair0_cfg->rx_freq[2],
+	mod_enb->devs->openair0_cfg->tx_freq[2],
+	mod_enb->devs->openair0_cfg->rx_freq[3],
+	mod_enb->devs->openair0_cfg->tx_freq[3],
+	mod_enb->devs->openair0_cfg->rxg_mode[0],
+	mod_enb->devs->openair0_cfg->tx_gain[0],
+	mod_enb->devs->openair0_cfg->tx_gain[0],
+	mod_enb->devs->openair0_cfg->rx_gain[1],
+	mod_enb->devs->openair0_cfg->tx_gain[1],
+	mod_enb->devs->openair0_cfg->rx_gain[2],
+	mod_enb->devs->openair0_cfg->tx_gain[2],
+	mod_enb->devs->openair0_cfg->rx_gain[3],
+	mod_enb->devs->openair0_cfg->tx_gain[3],
+	//mod_enb->devs->openair0_cfg->rx_gain_offset[0],
+	//mod_enb->devs->openair0_cfg->rx_gain_offset[1],
+	mod_enb->devs->openair0_cfg->rx_gain_offset[2],
+	mod_enb->devs->openair0_cfg->rx_gain_offset[3],
+	mod_enb->devs->openair0_cfg->rx_bw,
+	mod_enb->devs->openair0_cfg->tx_bw,
+	mod_enb->devs->openair0_cfg->autocal[0]  
 	);
  
  printf("----------------------------------------------------------------------------\n");
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index e67bcb6b07fa0a73bc79d10ed14c18daff1fb020..baba632de12c192ba1661e145decc803b17f0ffd 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -330,7 +330,6 @@ void reset_opp_meas(void);
 void print_opp_meas(void);
 int transmission_mode=1;
 
-
 int16_t           glog_level         = LOG_INFO;
 int16_t           glog_verbosity     = LOG_MED;
 int16_t           hw_log_level       = LOG_INFO;
@@ -361,16 +360,60 @@ int16_t           osa_log_verbosity  = LOG_MED;
 
 
 #ifdef ETHERNET
-char rrh_eNB_ip[20] = "127.0.0.1";
-int rrh_eNB_port = 50000;
 char *rrh_UE_ip = "127.0.0.1";
 int rrh_UE_port = 51000;
 #endif
 
+/* flag set by eNB conf file to specify if the radio head is local or remote (default option is local) */
+uint8_t local_remote_radio = BBU_LOCAL_RADIO_HEAD;
+/* struct for ethernet specific parameters given in eNB conf file */
+eth_params_t *eth_params;
+
 char uecap_xer[1024],uecap_xer_in=0;
 extern void *UE_thread(void *arg);
 extern void init_UE_threads(void);
 
+/*---------------------BMC: timespec helpers -----------------------------*/
+
+struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
+struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
+
+struct timespec clock_difftime(struct timespec start, struct timespec end)
+{
+    struct timespec temp;
+    if ((end.tv_nsec-start.tv_nsec)<0) {
+        temp.tv_sec = end.tv_sec-start.tv_sec-1;
+	temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
+    } else {
+        temp.tv_sec = end.tv_sec-start.tv_sec;
+	temp.tv_nsec = end.tv_nsec-start.tv_nsec;
+    }
+    return temp;
+}
+
+void print_difftimes()
+{
+#ifdef DEBUG
+    printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
+#else
+    LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
+#endif
+}
+
+void update_difftimes(struct timespec start, struct timespec end)
+{
+    struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
+    int             changed = 0;
+    diff_time = clock_difftime(start, end);
+    if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { min_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
+    if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { max_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
+#if 1
+    if (changed) print_difftimes();
+#endif
+}
+
+/*------------------------------------------------------------------------*/
+
 unsigned int build_rflocal(int txi, int txq, int rxi, int rxq)
 {
   return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
@@ -430,7 +473,6 @@ void help (void) {
   printf("  -h provides this help message!\n");
   printf("  -K Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n");
   printf("  -m Set the maximum downlink MCS\n");
-  printf("  -M IP address of RRH\n");
   printf("  -O eNB configuration file (located in targets/PROJECTS/GENERIC-LTE-EPC/CONF\n");
   printf("  -q Enable processing timing measurement of lte softmodem on per subframe basis \n");
   printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
@@ -948,22 +990,10 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB)
         if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti))
           tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*phy_vars_eNB->lte_frame_parms.samples_per_tti;
 
-        ((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[0]=
-#ifdef EXMIMO
-          ((short*)dummy_tx_b)[2*i]<<4;
-#elif OAI_BLADERF
-	((short*)dummy_tx_b)[2*i];
-#else
-          ((short*)dummy_tx_b)[2*i]<<4;
-#endif
-	  ((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[1]=
-#ifdef EXMIMO
-	    ((short*)dummy_tx_b)[2*i+1]<<4;
-#elif OAI_BLADERF
-	  ((short*)dummy_tx_b)[2*i+1];
-#else
-	  ((short*)dummy_tx_b)[2*i+1]<<4;
-#endif
+	((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[0] = ((short*)dummy_tx_b)[2*i]<<openair0_cfg[0].iq_txshift;
+	
+	((short*)&phy_vars_eNB->lte_eNB_common_vars.txdata[0][aa][tx_offset])[1] = ((short*)dummy_tx_b)[2*i+1]<<openair0_cfg[0].iq_txshift;
+  
      }
      // if S-subframe switch to RX in second subframe
      if (subframe_select(&phy_vars_eNB->lte_frame_parms,subframe) == SF_S) {
@@ -1820,7 +1850,9 @@ static void* eNB_thread( void* arg )
 				     PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_rx);
       
       stop_meas( &softmodem_stats_hw );
-      clock_gettime( CLOCK_MONOTONIC, &trx_time1 );
+      if (frame > 50) { 
+	  clock_gettime( CLOCK_MONOTONIC, &trx_time1 );
+      }
 
       if (frame > 20){ 
 	if (rxs != spp)
@@ -1829,8 +1861,6 @@ static void* eNB_thread( void* arg )
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
 
       // Transmit TX buffer based on timestamp from RX
-
-
     
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
       // prepare tx buffer pointers
@@ -1850,17 +1880,28 @@ static void* eNB_thread( void* arg )
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp+(openair0_cfg[card].tx_scheduling_advance)-openair0_cfg[card].tx_sample_advance)&0xffffffff );
 
       stop_meas( &softmodem_stats_mt );
-      clock_gettime( CLOCK_MONOTONIC, &trx_time2 );
+      if (frame > 50) { 
+	  clock_gettime( CLOCK_MONOTONIC, &trx_time2 );
+	  //update_difftimes(trx_time1, trx_time2);
+      }
+
 
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,0);
 #else
       // USRP_DEBUG is active
       rt_sleep_ns(1000000);
 #endif
-
-      if ((frame>50) &&
-	  (tx_launched == 0) &&
-          (rx_pos >= (((2*hw_subframe)+1)*PHY_vars_eNB_g[0][0]->lte_frame_parms.samples_per_tti>>1))) {
+      /* FT configurable tx lauch delay (in slots): txlaunch_wait, txlaunch_wait_slotcount is device specific and 
+	 set in the corresponding library (with txlaunch_wait=1 and txlaunch_wait_slotcount=1 the check is as it previously was) */
+      /* old check:
+	 if ((frame>50) &&
+	 (tx_launched == 0) &&
+	 (rx_pos >= (((2*hw_subframe)+1)*PHY_vars_eNB_g[0][0]->lte_frame_parms.samples_per_tti>>1))) {*/
+      if ( (frame>50) && (tx_launched == 0) &&
+	   ((openair0_cfg[card].txlaunch_wait == 0) ||
+	    ((openair0_cfg[card].txlaunch_wait == 1) &&
+	     (rx_pos >= (((2*hw_subframe)+openair0_cfg[card].txlaunch_wait_slotcount)*PHY_vars_eNB_g[0][0]->lte_frame_parms.samples_per_tti>>1))))) { 
+	
         tx_launched = 1;
 
         for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
@@ -2022,6 +2063,9 @@ eNB_thread_cleanup:
 #endif
 
   eNB_thread_status = 0;
+
+  // print_difftimes();
+
   return &eNB_thread_status;
 }
 
@@ -2150,14 +2194,7 @@ static void get_options (int argc, char **argv)
 
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
-     break;
-
-    case 'M':
-#ifdef ETHERNET
-      strcpy(rrh_eNB_ip,optarg);
-#endif
-      break;
-
+     break;   
     case 'A':
       timing_advance = atoi (optarg);
       break;
@@ -2400,6 +2437,34 @@ static void get_options (int argc, char **argv)
                    "lte-softmodem compiled with MAX_NUM_CCs=%d, but only %d CCs configured for eNB %d!",
                    MAX_NUM_CCs, enb_properties->properties[i]->nb_cc, i);
 
+      for (j=0; j<enb_properties->properties[i]->nb_rrh_gw; j++) {
+	
+	if (enb_properties->properties[i]->rrh_gw_config[j].active == 1 ) {
+	  local_remote_radio = BBU_REMOTE_RADIO_HEAD;
+	  eth_params = (eth_params_t*)malloc(sizeof(eth_params_t));
+	  memset(eth_params, 0, sizeof(eth_params_t));
+	 
+	  printf( "\n\tRRH GW %d config for eNB %u:\n\n", j, i);
+	  printf( "\tinterface name :       \t%s:\n",enb_properties->properties[i]->rrh_gw_if_name);
+	  printf( "\tlocal address  :       \t%s:\n",enb_properties->properties[i]->rrh_gw_config[j].local_address);
+	  printf( "\tlocal port     :       \t%d:\n",enb_properties->properties[i]->rrh_gw_config[j].local_port);
+	  printf( "\tremote address :       \t%s:\n",enb_properties->properties[i]->rrh_gw_config[j].remote_address);
+	  printf( "\tremote port    :       \t%d:\n",enb_properties->properties[i]->rrh_gw_config[j].remote_port);
+	  printf( "\ttransport      :       \t%s Ethernet:\n\n",(enb_properties->properties[i]->rrh_gw_config[j].raw == 1)? "RAW" : "UDP");
+	  
+	  eth_params->local_if_name             = enb_properties->properties[i]->rrh_gw_if_name;
+	  eth_params->my_addr                   = enb_properties->properties[i]->rrh_gw_config[j].local_address;
+	  eth_params->my_port                   = enb_properties->properties[i]->rrh_gw_config[j].local_port;
+	  eth_params->remote_addr               = enb_properties->properties[i]->rrh_gw_config[j].remote_address;
+	  eth_params->remote_port               = enb_properties->properties[i]->rrh_gw_config[j].remote_port;
+	  eth_params->transp_preference         = enb_properties->properties[i]->rrh_gw_config[j].raw;
+ 
+	} else {
+	  local_remote_radio = BBU_LOCAL_RADIO_HEAD; 
+	}
+	
+      }
+
       for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
         frame_parms[CC_id]->frame_type =       enb_properties->properties[i]->frame_type[CC_id];
         frame_parms[CC_id]->tdd_config =       enb_properties->properties[i]->tdd_config[CC_id];
@@ -2938,20 +3003,13 @@ int main( int argc, char **argv )
     else //FDD
       openair0_cfg[card].duplex_mode = duplex_mode_FDD;
 
-#ifdef ETHERNET
-
-    //calib needed
-    openair0_cfg[card].tx_scheduling_advance = 0;
-    openair0_cfg[card].tx_sample_advance = 0;
-    
-    if (frame_parms[0]->N_RB_DL == 6) 
-      openair0_cfg[card].samples_per_packet = 256;
-    else 
-      openair0_cfg[card].samples_per_packet = 1024;
-
-    printf("HW: samples_per_packet %d\n",openair0_cfg[card].samples_per_packet);
-#endif
 
+    if (local_remote_radio == BBU_REMOTE_RADIO_HEAD) {      
+      openair0_cfg[card].remote_addr    = eth_params->remote_addr;
+      openair0_cfg[card].remote_port    = eth_params->remote_port;
+      openair0_cfg[card].my_addr        = eth_params->my_addr;
+      openair0_cfg[card].my_port        = eth_params->my_port;    
+    }
 
     printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
            ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->lte_frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->lte_frame_parms.nb_antennas_tx),
@@ -2961,13 +3019,10 @@ int main( int argc, char **argv )
 
     if (UE_flag) {
       printf("ETHERNET: Configuring UE ETH for %s:%d\n",rrh_UE_ip,rrh_UE_port);
-      openair0_cfg[card].remote_ip   = &rrh_UE_ip[0];
+      openair0_cfg[card].remote_addr   = &rrh_UE_ip[0];
       openair0_cfg[card].remote_port = rrh_UE_port;
-    } else {
-      printf("ETHERNET: Configuring eNB ETH for %s:%d\n",rrh_eNB_ip,rrh_eNB_port);
-      openair0_cfg[card].remote_ip   = &rrh_eNB_ip[0];
-      openair0_cfg[card].remote_port = rrh_eNB_port;
-    }
+    } 
+
     openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
 #endif
 
@@ -3024,22 +3079,40 @@ int main( int argc, char **argv )
 
 #endif
   }
-
-  openair0.func_type = BBU_FUNC;
+  /* device host type is set*/
+  openair0.host_type = BBU_HOST;
+  /* device type is initialized NONE_DEV (no RF device) when the RF device will be initiated device type will be set */
+  openair0.type = NONE_DEV;
+  /* transport type is initialized NONE_TP (no transport protocol) when the transport protocol will be initiated transport protocol type will be set */
+  openair0.transp_type = NONE_TP;
   openair0_cfg[0].log_level = glog_level;
 
-  if (mode!=loop_through_memory){
-    int ret;
-    ret= openair0_device_init(&openair0, &openair0_cfg[0]);
-    printf("openair0_device_init returns %d\n",ret);
-    if (ret<0) {
-      printf("Exiting, cannot initialize device\n");
-      exit(-1);
+  int returns=-1;
+  /* BBU can have either a local or a remote radio head */  
+  if (local_remote_radio == BBU_LOCAL_RADIO_HEAD) { //local radio head active  - load library of radio head and initiate it
+    if (mode!=loop_through_memory) {
+      returns=openair0_device_load(&openair0, &openair0_cfg[0]);
+      printf("openair0_device_init returns %d\n",returns);
+      if (returns<0) {
+	printf("Exiting, cannot initialize device\n");
+	exit(-1);
+      }
     }
-  }
-  else if (mode==loop_through_memory) {    
-  }
- 
+    else if (mode==loop_through_memory) {    
+    }
+  }  else { //remote radio head active - load library of transport protocol and initiate it 
+    if (mode!=loop_through_memory) {
+      returns=openair0_transport_load(&openair0, &openair0_cfg[0], eth_params);
+      printf("openair0_transport_init returns %d\n",returns);
+      if (returns<0) { 
+	printf("Exiting, cannot initialize transport protocol\n");
+	exit(-1);
+      }
+    }
+    else if (mode==loop_through_memory) {    
+    }
+  }   
+  
   printf("Done\n");
 
   mac_xface = malloc(sizeof(MAC_xface));
@@ -3462,7 +3535,6 @@ int main( int argc, char **argv )
     if (multi_thread>0) {
       printf("Killing eNB processing threads\n");
       kill_eNB_proc();
-
     }
   }
 
@@ -3554,10 +3626,6 @@ int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_c
 
 #endif
 
-
-
-
-
     // replace RX signal buffers with mmaped HW versions
 #ifdef EXMIMO
     openair0_cfg[CC_id].tx_num_channels = 0;
diff --git a/targets/RT/USER/rrh.gtkw b/targets/RT/USER/rrh.gtkw
index 22a5a9f575b252528a9bb701ba3940c826296adc..891f23ada52417ffd360f617eab2eeecd2ef16cd 100644
--- a/targets/RT/USER/rrh.gtkw
+++ b/targets/RT/USER/rrh.gtkw
@@ -1,19 +1,19 @@
 [*]
 [*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
-[*] Thu Sep 17 14:23:43 2015
+[*] Fri Jan 29 16:34:46 2016
 [*]
 [dumpfile] "/tmp/openair_dump_rrh.vcd"
-[dumpfile_mtime] "Thu Sep 17 14:21:43 2015"
-[dumpfile_size] 636509125
-[savefile] "/home/guepe/openair4G/targets/RT/USER/rrh.gtkw"
-[timestart] 17746655400
-[size] 1855 1056
-[pos] -1 -1
-*-15.826077 17746846200 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[dumpfile_mtime] "Fri Jan 29 16:20:55 2016"
+[dumpfile_size] 224259458
+[savefile] "/home/guepe/openairinterface5g_rrh/openairinterface5g/targets/RT/USER/rrh.gtkw"
+[timestart] 31315875900
+[size] 1004 1028
+[pos] 926 -1
+*-17.429794 31316090054 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
 [sst_width] 224
-[signals_width] 230
+[signals_width] 261
 [sst_expanded] 1
-[sst_vpaned_height] 287
+[sst_vpaned_height] 278
 @24
 [color] 1
 variables.hw_frame_rx[63:0]
@@ -23,7 +23,10 @@ variables.hw_subframe_rx[63:0]
 [color] 1
 functions.eNB_rx
 functions.eNB_rx_sleep
-functions.trx_write_rf
+[color] 3
+functions.trx_read_rf
+[color] 7
+functions.trx_write
 @c00024
 variables.rxcnt[63:0]
 @28
@@ -95,24 +98,97 @@ variables.rxcnt[63:0]
 -group_end
 @24
 variables.pck_rx[63:0]
+variables.rx_ts[63:0]
+@c00024
+variables.tx_seq_num[63:0]
+@28
+(0)variables.tx_seq_num[63:0]
+(1)variables.tx_seq_num[63:0]
+(2)variables.tx_seq_num[63:0]
+(3)variables.tx_seq_num[63:0]
+(4)variables.tx_seq_num[63:0]
+(5)variables.tx_seq_num[63:0]
+(6)variables.tx_seq_num[63:0]
+(7)variables.tx_seq_num[63:0]
+(8)variables.tx_seq_num[63:0]
+(9)variables.tx_seq_num[63:0]
+(10)variables.tx_seq_num[63:0]
+(11)variables.tx_seq_num[63:0]
+(12)variables.tx_seq_num[63:0]
+(13)variables.tx_seq_num[63:0]
+(14)variables.tx_seq_num[63:0]
+(15)variables.tx_seq_num[63:0]
+(16)variables.tx_seq_num[63:0]
+(17)variables.tx_seq_num[63:0]
+(18)variables.tx_seq_num[63:0]
+(19)variables.tx_seq_num[63:0]
+(20)variables.tx_seq_num[63:0]
+(21)variables.tx_seq_num[63:0]
+(22)variables.tx_seq_num[63:0]
+(23)variables.tx_seq_num[63:0]
+(24)variables.tx_seq_num[63:0]
+(25)variables.tx_seq_num[63:0]
+(26)variables.tx_seq_num[63:0]
+(27)variables.tx_seq_num[63:0]
+(28)variables.tx_seq_num[63:0]
+(29)variables.tx_seq_num[63:0]
+(30)variables.tx_seq_num[63:0]
+(31)variables.tx_seq_num[63:0]
+(32)variables.tx_seq_num[63:0]
+(33)variables.tx_seq_num[63:0]
+(34)variables.tx_seq_num[63:0]
+(35)variables.tx_seq_num[63:0]
+(36)variables.tx_seq_num[63:0]
+(37)variables.tx_seq_num[63:0]
+(38)variables.tx_seq_num[63:0]
+(39)variables.tx_seq_num[63:0]
+(40)variables.tx_seq_num[63:0]
+(41)variables.tx_seq_num[63:0]
+(42)variables.tx_seq_num[63:0]
+(43)variables.tx_seq_num[63:0]
+(44)variables.tx_seq_num[63:0]
+(45)variables.tx_seq_num[63:0]
+(46)variables.tx_seq_num[63:0]
+(47)variables.tx_seq_num[63:0]
+(48)variables.tx_seq_num[63:0]
+(49)variables.tx_seq_num[63:0]
+(50)variables.tx_seq_num[63:0]
+(51)variables.tx_seq_num[63:0]
+(52)variables.tx_seq_num[63:0]
+(53)variables.tx_seq_num[63:0]
+(54)variables.tx_seq_num[63:0]
+(55)variables.tx_seq_num[63:0]
+(56)variables.tx_seq_num[63:0]
+(57)variables.tx_seq_num[63:0]
+(58)variables.tx_seq_num[63:0]
+(59)variables.tx_seq_num[63:0]
+(60)variables.tx_seq_num[63:0]
+(61)variables.tx_seq_num[63:0]
+(62)variables.tx_seq_num[63:0]
+(63)variables.tx_seq_num[63:0]
+@1401200
+-group_end
+@24
 variables.hw_frame[63:0]
 variables.hw_subframe[63:0]
 @28
 [color] 1
 functions.eNB_tx
 functions.eNB_tx_sleep
-functions.trx_read_rf
-[color] 7
-functions.trx_write
 [color] 7
 functions.trx_read
+[color] 3
+functions.trx_write_rf
 @24
 variables.txcnt[63:0]
-variables.rx_ts[63:0]
+variables.pck_tx[63:0]
 variables.tx_ts[63:0]
+@25
+variables.rx_seq_num_prv[63:0]
+@24
+variables.rx_seq_num[63:0]
 variables.hw_cnt_rx[63:0]
 variables.lhw_cnt_rx[63:0]
-@25
 [color] 3
 variables.cnt[63:0]
 [pattern_trace] 1
diff --git a/targets/RT/USER/rrh_gw.c b/targets/RT/USER/rrh_gw.c
index 89c8679554ef7053b2853dc8b10d4ea01145ded9..87c4d4d77d136b99067a5e4353df7e8043ae4497 100644
--- a/targets/RT/USER/rrh_gw.c
+++ b/targets/RT/USER/rrh_gw.c
@@ -51,9 +51,9 @@
 #include <time.h>
 
 #include "common_lib.h"
-#include "rrh_gw.h" // change to rrh_new.h, put externs in rrh_extern.h
+#include "rrh_gw.h"
 #include "rt_wrapper.h"
-#include "rrh_gw_externs.h" // change to rrh_new.h, put externs in rrh_extern.h
+#include "rrh_gw_externs.h"
 
 
 #include "log_if.h"
@@ -71,8 +71,9 @@
  *****************************************************************************************/
 
 
-
-char rrh_ip[20] = "192.168.12.242"; // there is code to detect the my ip address
+/* local IP/MAC address is detected*/
+char rrh_ip[20] = "0.0.0.0"; 
+unsigned char rrh_mac[6] = "0:0:0:0:0:0"; 
 int  rrh_port = 50000; // has to be an option
 
 /* log */
@@ -86,7 +87,7 @@ int16_t           ue_log_level        = LOG_INFO;
 int16_t           ue_log_verbosity    = LOG_MED;
 
 
-/* flags definitions */
+/* flag definitions */
 uint8_t 	eNB_flag=0;
 uint8_t 	UE_flag=0;
 uint8_t 	EXMIMO_flag=0;
@@ -102,10 +103,8 @@ uint8_t         measurements_flag=0;
    - default ethernet interface is local */
 uint8_t 	    num_eNB_mod=0;
 uint8_t 	    num_UE_mod=0;
-uint8_t 	    num_EXMIMO_mod=0;
-uint8_t 	    num_USRP_mod=0;
-uint8_t             hardware_target=NONE_IF;
-char*               if_name="lo";
+char*           if_name="lo";
+uint8_t         eth_mode=ETH_UDP_MODE;
 
 rrh_module_t 	        *enb_array;
 rrh_module_t            *ue_array;
@@ -128,14 +127,14 @@ static void print_help(void);
 */
 static rrh_module_t new_module(unsigned int id);
 
-/*!\fn static int get_ip_address(char* if_name)
+/*!\fn static int get_address(char* if_name, uint8_t flag);
  * \brief retrieves IP address from the specified network interface
  * \param[in] name of network interface
  * \return 0 
  * \note
  * @ingroup  _oai
  */
-static int get_ip_address(char* if_name);
+static int get_address(char* if_name, uint8_t flag);
 
 
 
@@ -192,48 +191,53 @@ static rrh_module_t new_module (unsigned int id) {
   rrh_mod.measurements=measurements_flag;
 
   /* each module is associated with an ethernet device */
-  rrh_mod.eth_dev.type=ETH_IF;
+  rrh_mod.eth_dev.type=NONE_DEV;
+  rrh_mod.eth_dev.transp_type=NONE_TP;
   /* ethernet device is functioning within RRH */
-  rrh_mod.eth_dev.func_type=RRH_FUNC; 
-  /* specify IP address */
-  get_ip_address(if_name);
-  openair0_cfg.my_ip=&rrh_ip[0];
-  openair0_cfg.my_port=rrh_port;
+  rrh_mod.eth_dev.host_type=RRH_HOST;
+  /* */
+  rrh_mod.eth_dev.openair0_cfg = (openair0_config_t*)malloc(sizeof(openair0_config_t));
+  memset(rrh_mod.eth_dev.openair0_cfg,0,sizeof(openair0_config_t));
+  /* get IP and MAC address */
+  get_address(if_name,eth_mode);
+  
+  if(eth_mode==ETH_UDP_MODE) {
+    openair0_cfg.my_addr = &rrh_ip[0];
+    openair0_cfg.my_port = rrh_port;
+    LOG_I(RRH,"UDP mode selected for ethernet.\n");
+  } else if (eth_mode==ETH_RAW_MODE) {
+    openair0_cfg.my_addr = &rrh_mac[0];
+    openair0_cfg.my_port = rrh_port;
+    LOG_I(RRH,"RAW mode selected for ethernet.\n");
+  } 
+
+  /* */
+  eth_params_t *eth_params = (eth_params_t*)malloc(sizeof(eth_params_t));
+  memset(eth_params, 0, sizeof(eth_params_t));
+  eth_params->local_if_name     = if_name;
+  eth_params->transp_preference = eth_mode;
 
   /* ethernet device initialization */
-  if (openair0_dev_init_eth(&rrh_mod.eth_dev, &openair0_cfg)<0){
+  if (openair0_transport_load(&rrh_mod.eth_dev, &openair0_cfg,eth_params)<0) {
     LOG_E(RRH,"Exiting, cannot initialize ethernet interface.\n");
     exit(-1);
   }
 
   /* allocate space and specify associated RF device */
   openair0_device *oai_dv = (openair0_device *)malloc(sizeof(openair0_device));
-  memset(oai_dv,0, sizeof(openair0_device));
+  memset(oai_dv,0,sizeof(openair0_device));
 
-#ifdef EXMIMO
   rrh_mod.devs=oai_dv;   
-  rrh_mod.devs->type=EXMIMO_IF;
-  LOG_I(RRH,"Setting RF device to EXMIMO\n");	   
-#elif OAI_USRP
-  rrh_mod.devs=oai_dv;	
-  rrh_mod.devs->type=USRP_B200_IF;
-  LOG_I(RRH,"Setting RF device to USRP\n");    	 
-#elif OAI_BLADERF
-  rrh_mod.devs=oai_dv;	
-  rrh_mod.devs->type=BLADERF_IF;
-  LOG_I(RRH,"Setting RF device to BLADERF\n");
-#else
-  rrh_mod.devs=oai_dv;
-  rrh_mod.devs->type=NONE_IF;
-  LOG_I(RRH,"Setting RF interface to NONE_IF... \n");
-#endif  
-  
+  rrh_mod.devs->type=NONE_DEV;
+  rrh_mod.devs->transp_type=NONE_TP;
+  rrh_mod.devs->host_type=RRH_HOST; 
+
   return rrh_mod;
 }
 
 static void debug_init(void) {
   
-  // log initialization
+  /* log initialization */
   logInit();
   set_glog(glog_level,  glog_verbosity);
   
@@ -241,7 +245,7 @@ static void debug_init(void) {
   //set_comp_log(ENB_LOG, enb_log_level,   enb_log_verbosity, 1);
   //set_comp_log(UE_LOG,  ue_log_level,    ue_log_verbosity,  1);
   
-  // vcd initialization
+  /* vcd initialization */
   if (ouput_vcd) {
     vcd_signal_dumper_init("/tmp/openair_dump_rrh.vcd");
     
@@ -253,7 +257,7 @@ static void get_options(int argc, char *argv[]) {
 
   int 	opt;
 
-  while ((opt = getopt(argc, argv, "xvhlte:n:u:g:r:w:i:")) != -1) {
+  while ((opt = getopt(argc, argv, "xvhlte:n:u:g:r:m:i:")) != -1) {
     
     switch (opt) {
     case 'n':
@@ -273,6 +277,9 @@ static void get_options(int argc, char *argv[]) {
 	printf("RRH interface name is set to %s\n", if_name);	
       }
       break;
+    case 'm':  
+      eth_mode=atoi(optarg);      
+      break;
     case 'r':
       //rrh_log_level=atoi(optarg);
       break;
@@ -293,16 +300,12 @@ static void get_options(int argc, char *argv[]) {
       loopback_flag=1; 
       break;
     case 't':
-      /*When measurements are enabled statistics related to TX/RX time are printed*/
+      /* When measurements are enabled statistics related to TX/RX time are printed */
       measurements_flag=1; 
-      break;
-    case 'w':
-      /* force to use this target*/    
-      hardware_target=1;
-      break;
-  case 'h':
-    print_help();
-    exit(-1);
+      break;      
+    case 'h':
+      print_help();
+      exit(-1);
     default: /* '?' */
       //fprintf(stderr, "Usage: \n", argv[0]);
       exit(-1);
@@ -311,31 +314,34 @@ static void get_options(int argc, char *argv[]) {
 
 }
 
-static int get_ip_address(char* if_name) {
+static int get_address(char* if_name, uint8_t flag) {
   
   int fd;
   struct ifreq ifr;
-  
-  
-  fd = socket(AF_INET, SOCK_DGRAM, 0);
-  
+    
+  fd = socket(AF_INET, SOCK_DGRAM, 0);  
   /* I want to get an IPv4 IP address */
-  ifr.ifr_addr.sa_family = AF_INET;
-  
+  ifr.ifr_addr.sa_family = AF_INET;  
   /* I want IP address attached to "if_name" */
   strncpy(ifr.ifr_name, if_name, IFNAMSIZ-1);
-  
-  if ( ioctl(fd, SIOCGIFADDR, &ifr)<0 ) {
-    perror("IOCTL:");
-    exit(-1);
-  } 
+
+  if (flag==ETH_UDP_MODE) {
+    if ( ioctl(fd, SIOCGIFADDR, &ifr)<0 ) {
+      perror("IOCTL:");
+      exit(-1);
+    } 
+    snprintf(&rrh_ip[0],20,"%s", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
+    LOG_I(RRH,"%s: IP address: %s\n",if_name,rrh_ip);
+  } else if (flag==ETH_RAW_MODE) {
+    if ( ioctl(fd, SIOCGIFHWADDR, &ifr)<0 ) {
+      perror("IOCTL:");
+      exit(-1);
+    } 
+    ether_ntoa_r ((unsigned char *)ifr.ifr_hwaddr.sa_data, rrh_mac);
+    LOG_I(RRH,"%s: MAC address: %s\n",if_name,rrh_mac);    
+  }
   
   close(fd);
-  
-  /* display result */
-  snprintf(&rrh_ip[0],20,"%s", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
-  LOG_I(RRH,"Got IP address %s from interface %s\n", rrh_ip,if_name);
-
   return 0;
 }
 
@@ -343,19 +349,19 @@ static int get_ip_address(char* if_name) {
 static void print_help(void) {
 
   puts("Usage: \n");
-  puts("     sudo -E chrt 99 ./rrh -n1 -g6 -v -t");
+  puts("     sudo -E chrt 99 ./rrh -n1 -g6 -v -t -i lo -m1");
   puts("Options:\n");
   puts("\t -n create eNB module\n");
   puts("\t -u create UE module\n");
   puts("\t -g define global log level\n");
   puts("\t -i set the RRH interface (default lo)\n");
+  puts("\t -m set ethernet mode to be used by RRH, valid options: (1:raw, 0:udp) \n");
   puts("\t -r define rrh log level\n");
   puts("\t -e define eNB log level\n");
   puts("\t -x enable real time bahaviour\n");
   puts("\t -v enable vcd dump\n");
   puts("\t -l enable loopback mode\n");
   puts("\t -t enable measurements\n");
-  puts("\t -w force to use specified HW\n");
   puts("\t -h display info\n");
 
 }