From d4da46a249a5def267e4cf2bb33d393c0efe52cb Mon Sep 17 00:00:00 2001
From: Raymond Knopp <raymond.knopp@eurecom.fr>
Date: Thu, 5 Sep 2019 22:32:32 +0200
Subject: [PATCH] added third-party driver support for IF5 interface.

---
 targets/ARCH/COMMON/common_lib.c              |  5 +-
 targets/ARCH/COMMON/common_lib.h              |  8 ++-
 targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c | 72 ++-----------------
 .../ETHERNET/USERSPACE/LIB/ethernet_lib.c     | 33 +++------
 targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h |  6 +-
 targets/RT/USER/lte-ru.c                      |  8 ++-
 6 files changed, 37 insertions(+), 95 deletions(-)

diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c
index 010f54a3ba..7f0ff0ce18 100644
--- a/targets/ARCH/COMMON/common_lib.c
+++ b/targets/ARCH/COMMON/common_lib.c
@@ -111,9 +111,12 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param
   } else if (flag == RAU_LOCAL_RADIO_HEAD) {
     libname=OAI_RF_LIBNAME;
     shlib_fdesc[0].fname="device_init";
-  } else {
+  } else if (flag == RAU_REMOTE_RADIO_HEAD) {
     libname=OAI_TP_LIBNAME;
     shlib_fdesc[0].fname="transport_init";
+  }else if (flag == RAU_REMOTE_THIRDPARTY_RADIO_HEAD) {
+    libname=OAI_THIRDPARTY_TP_LIBNAME;
+    shlib_fdesc[0].fname="transport_init";
   }
 
   ret=load_module_shlib(libname,shlib_fdesc,1,NULL);
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index 3d92fd38ed..0cb2231fc4 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -40,6 +40,8 @@
 #define OAI_RF_LIBNAME        "oai_device"
 /* name of shared library implementing the transport */
 #define OAI_TP_LIBNAME        "oai_transpro"
+/* name of shared library implementing a third-party transport */
+#define OAI_THIRDPARTY_TP_LIBNAME        "thirdparty_transpro"
 /* name of shared library implementing the basic/rf simulator */
 #define OAI_RFSIM_LIBNAME        "rfsimulator"
 /* name of shared library implementing the basic/rf simulator */
@@ -47,7 +49,7 @@
 /* flags for BBU to determine whether the attached radio head is local or remote */
 #define RAU_LOCAL_RADIO_HEAD  0
 #define RAU_REMOTE_RADIO_HEAD 1
-
+#define RAU_REMOTE_THIRDPARTY_RADIO_HEAD 2
 #ifndef MAX_CARDS
   #define MAX_CARDS 8
 #endif
@@ -392,6 +394,10 @@ struct openair0_device_t {
    * \param arg pointer to capabilities or configuration
    */
   void (*configure_rru)(int idx, void *arg);
+  /*! \brief Callback for Third-party RRU Initialization routine
+     \param device the hardware configuration to use
+   */
+  int (*thirdparty_init)(openair0_device *device);
 };
 
 /* type of device init function, implemented in shared lib */
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
index d893c66b52..9c0a9e3f65 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
@@ -102,23 +102,15 @@ int eth_socket_init_raw(openair0_device *device) {
   eth->local_addrd_ll.sll_family   = AF_PACKET;
   eth->local_addrd_ll.sll_ifindex  = eth->if_index.ifr_ifindex;
   /* hear traffic from specific protocol*/
-  if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
-     eth->local_addrd_ll.sll_protocol = htons(0xbffe);
-  } else{ 
-     eth->local_addrc_ll.sll_protocol = htons((short)device->eth_params->my_portc);
-     eth->local_addrd_ll.sll_protocol = htons((short)device->eth_params->my_portd);
-  }
+  eth->local_addrc_ll.sll_protocol = htons((short)device->eth_params->my_portc);
+  eth->local_addrd_ll.sll_protocol = htons((short)device->eth_params->my_portd);
+  
   eth->local_addrc_ll.sll_halen    = ETH_ALEN;
   eth->local_addrc_ll.sll_pkttype  = PACKET_OTHERHOST;
   eth->local_addrd_ll.sll_halen    = ETH_ALEN;
   eth->local_addrd_ll.sll_pkttype  = PACKET_OTHERHOST;
   eth->addr_len = sizeof(struct sockaddr_ll);
   
-  if ((eth->flags != ETH_RAW_IF5_MOBIPASS ) && 
-      (bind(eth->sockfdc,(struct sockaddr *)&eth->local_addrc_ll,eth->addr_len)<0)) {
-    perror("ETHERNET: Cannot bind to socket (control)");
-    exit(0);
-  }
   if (bind(eth->sockfdd,(struct sockaddr *)&eth->local_addrd_ll,eth->addr_len)<0) {
     perror("ETHERNET: Cannot bind to socket (user)");
     exit(0);
@@ -127,12 +119,9 @@ int eth_socket_init_raw(openair0_device *device) {
  /* Construct the Ethernet header */ 
  ether_aton_r(local_mac, (struct ether_addr *)(&(eth->ehd.ether_shost)));
  ether_aton_r(remote_mac, (struct ether_addr *)(&(eth->ehd.ether_dhost)));
- if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
-   eth->ehd.ether_type = htons(0xbffe);
- } else {
-   eth->ehc.ether_type = htons((short)device->eth_params->my_portc);
-   eth->ehd.ether_type = htons((short)device->eth_params->my_portd);
- } 
+ eth->ehc.ether_type = htons((short)device->eth_params->my_portc);
+ eth->ehd.ether_type = htons((short)device->eth_params->my_portd);
+  
  printf("[%s] binding to hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"),eth->ehd.ether_shost[0],eth->ehd.ether_shost[1],eth->ehd.ether_shost[2],eth->ehd.ether_shost[3],eth->ehd.ether_shost[4],eth->ehd.ether_shost[5]);
  
  return 0;
@@ -216,8 +205,6 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam
     packet_size = RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks);    
   } else if (flags == IF4p5_PULTICK) {
     packet_size = RAW_IF4p5_PULTICK_SIZE_BYTES;    
-  } else if (flags == IF5_MOBIPASS) {
-    packet_size = RAW_IF5_MOBIPASS_SIZE_BYTES;
   } else {
     packet_size = RAW_IF4p5_PRACH_SIZE_BYTES;
   }
@@ -430,53 +417,6 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam
 }
 
 
-int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
-  // Read nblocks info from packet itself
-  
-  int bytes_received=0;
-  eth_state_t *eth = (eth_state_t*)device->priv;
-  int ret;
-
-  ssize_t packet_size =  28; //MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t ;
-//   ssize_t packet_size =  MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t);
- 
-  bytes_received = recv(eth->sockfdd,
-                        buff[0],
-                        packet_size,
-                        MSG_PEEK);
-
-  if (bytes_received ==-1) {
-          eth->num_rx_errors++;
-          perror("[MOBIPASS]ETHERNET IF5 READ (header): ");
-          exit(-1);
-  }
-
-  IF5_mobipass_header_t *test_header = (IF5_mobipass_header_t*)((uint8_t *)buff[0] + MAC_HEADER_SIZE_BYTES);
-  *timestamp = test_header->time_stamp;
-  packet_size =  MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t);
-
-  while(bytes_received < packet_size) {
-    ret = recv(eth->sockfdd,
-	       buff[0],
-	       packet_size,
-	       0);
-    if (bytes_received ==-1) {
-      eth->num_rx_errors++;
-      perror("[MOBIPASS] ETHERNET IF5 READ (payload): ");
-      return(-1);
-    } else {
-      bytes_received+=ret;
-      eth->rx_actual_nsamps = bytes_received>>1;
-      eth->rx_count++;
-    }
-  }
- 
-  eth->rx_nsamps = nsamps;
-  return(bytes_received);
-
-
-}
-
 int eth_set_dev_conf_raw(openair0_device *device) {
 
   eth_state_t *eth = (eth_state_t*)device->priv;
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
index a05cc48fbd..7965faa5d4 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
@@ -57,6 +57,10 @@ int trx_eth_start(openair0_device *device) {
 
     eth_state_t *eth = (eth_state_t*)device->priv;
 
+    if (eth->flags == ETH_UDP_IF5_ORI_MODE) {
+      AssertFatal(device->thirdparty_init != NULL, "device->thirdparty_init is null\n");
+      device->thirdparty_init(device);
+    }
     /* initialize socket */
     if (eth->flags == ETH_RAW_MODE) {
         printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n");
@@ -121,11 +125,6 @@ int trx_eth_start(openair0_device *device) {
 
 
 
-    } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
-        printf("Setting ETHERNET to RAW_IF5_MODE\n");
-        if (eth_socket_init_raw(device)!=0)   return -1;
-        if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0)  return -1;
-
     } else {
         printf("Setting ETHERNET to UDP_IF5_MODE\n");
         if (eth_socket_init_udp(device)!=0)   return -1;
@@ -368,20 +367,11 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth
     eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t));
     memset(eth, 0, sizeof(eth_state_t));
 
-    if (eth_params->transp_preference == 1) {
-        eth->flags = ETH_RAW_MODE;
-    } else if (eth_params->transp_preference == 0) {
-        eth->flags = ETH_UDP_MODE;
-    } else if (eth_params->transp_preference == 3) {
-        eth->flags = ETH_RAW_IF4p5_MODE;
-    } else if (eth_params->transp_preference == 2) {
-        eth->flags = ETH_UDP_IF4p5_MODE;
-    } else if (eth_params->transp_preference == 4) {
-        eth->flags = ETH_RAW_IF5_MOBIPASS;
-    } else {
-        printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference);
-        eth->flags = ETH_RAW_MODE;
-    }
+    eth->flags = eth_params->transp_preference;
+
+    // load third-party driver
+    if (eth->flags == ETH_UDP_IF5_ORI_MODE) load_lib(device,openair0_cfg,eth_params,RAU_REMOTE_THIRDPARTY_RADIO_HEAD);
+
 
     if (eth_params->if_compress == 0) {
         eth->compression = NO_COMPRESS;
@@ -406,7 +396,7 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth
     if (eth->flags == ETH_RAW_MODE) {
         device->trx_write_func   = trx_eth_write_raw;
         device->trx_read_func    = trx_eth_read_raw;
-    } else if (eth->flags == ETH_UDP_MODE) {
+    } else if (eth->flags == ETH_UDP_MODE || eth->flags == ETH_UDP_IF5_ORI_MODE) {
         device->trx_write_func   = trx_eth_write_udp;
         device->trx_read_func    = trx_eth_read_udp;
         device->trx_ctlsend_func = trx_eth_ctlsend_udp;
@@ -419,9 +409,6 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth
         device->trx_read_func    = trx_eth_read_udp_IF4p5;
         device->trx_ctlsend_func = trx_eth_ctlsend_udp;
         device->trx_ctlrecv_func = trx_eth_ctlrecv_udp;
-    } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
-        device->trx_write_func   = trx_eth_write_raw_IF4p5;
-        device->trx_read_func    = trx_eth_read_raw_IF5_mobipass;
     } else {
         //device->trx_write_func   = trx_eth_write_udp_IF4p5;
         //device->trx_read_func    = trx_eth_read_udp_IF4p5;
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
index 95d0029027..b0b45f6c38 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
@@ -40,11 +40,11 @@
 #ifdef OCP_FRAMEWORK
 #include "enums.h"
 #else
-#define ETH_UDP_MODE        0
-#define ETH_RAW_MODE        1
+#define ETH_UDP_MODE          0
+#define ETH_RAW_MODE          1
 #define ETH_UDP_IF4p5_MODE    2
 #define ETH_RAW_IF4p5_MODE    3
-#define ETH_RAW_IF5_MOBIPASS    4    
+#define ETH_UDP_IF5_ORI_MODE  4    
 #endif
 
 // COMMOM HEADER LENGTHS
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 89abd12499..54de6e2e95 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -2949,7 +2949,13 @@ void RCconfig_RU(void) {
 	  RC.ru[j]->if_south                     = REMOTE_IF5;
 	  RC.ru[j]->function                     = NGFI_RAU_IF5;
 	  RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
-	} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
+	}
+	else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_ori_if5") == 0) {
+	  RC.ru[j]->if_south                     = REMOTE_IF5;
+	  RC.ru[j]->function                     = NGFI_RAU_IF5;
+	  RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF5_ORI_MODE;
+	}
+	else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
 	  RC.ru[j]->if_south                     = REMOTE_IF5;
 	  RC.ru[j]->function                     = NGFI_RAU_IF5;
 	  RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
-- 
2.26.2