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 0000000000..f8d1a31462
--- /dev/null
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ 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 .
+
+ 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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "common_lib.h"
+#include "ethernet_lib.h"
+
+#define DEBUG 1
+
+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 ) {
+ local_mac = device->openair0_cfg.my_addr;
+ local_port = device->openair0_cfg.my_port;
+ remote_mac = "0:0:0:0:0:0";
+ remote_port = device->openair0_cfg.my_port;
+ 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(device->openair0_cfg.my_addr, (struct ether_addr *)(&(eh.ether_shost)));
+ ether_aton_r(device->openair0_cfg.remote_addr, (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;isockfd[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;isockfd[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));
+ 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 0000000000..fe4d4db0db
--- /dev/null
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
@@ -0,0 +1,379 @@
+/*******************************************************************************
+ 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 .
+
+ 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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#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];
+
+
+ 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);
+ }
+
+ /* apply additional configuration */
+ //ethernet_tune (device,MTU_SIZE,UDP_PACKET_SIZE_BYTES(device->openair0_cfg.samples_per_packet));
+
+ /* if RRH, then I am the server, so bind */
+ if (device->host_type == RRH_HOST) {
+ 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));
+ }
+ /* if BBU, then I am a client, so connect */
+ } else {
+ printf("[%s] Connecting to %s:%d\n","BBU",str_remote,ntohs(dest_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;isockfd[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++;
+ }
+ }
+ /* 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;isockfd[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 */
+ if (prev_timestamp == -1) {
+ prev_timestamp = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
+ } else {
+ prev_timestamp =timestamp;
+ }
+ /* store the timestamp value from packet's header */
+ *timestamp = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
+ 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);
+ }
+
+ /* printf("[RRHbbb] mod_%d socket %d connected to BBU %s:%d\n", Mod_id, eth->sockfd[Mod_id], inet_ntoa(dest_addr[Mod_id].sin_addr), */
+ /* ntohs(dest_addr[Mod_id].sin_port)); */
+ 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);
+
+ /* printf("[RRH] mod_%d socket %d connected to BBU %s:%d %s:%d\n", Mod_id, eth->sockfd[Mod_id], str1, */
+ /* ntohs(dest_addr[Mod_id].sin_port),str, */
+ /* ntohs(local_addr[Mod_id].sin_port)); */
+
+ /* 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);
+ }
+
+ memcpy((void*)&device->openair0_cfg,msg,msg_len);
+
+ /* 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("[RRH2] 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 ce90d2cff9..995ced1f0d 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,186 +52,43 @@
#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) {
+
+ eth_state_t *eth = (eth_state_t*)device->priv;
/* 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);
+ 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;
+ }
+ /* 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 {
- return eth_get_dev_conf(device);
+ 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;
+ }
+ /* 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 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;isockfd[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*)ð->dest_addr[Mod_id],
- dest_addr_len[Mod_id])) < 0) {
- perror("ETHERNET WRITE");
- exit(-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;isockfd[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 *)ð->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;
- }
- }
-
-#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;
- }
- return nsamps;
-
-}
-
void trx_eth_end(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
@@ -241,7 +98,7 @@ void trx_eth_end(openair0_device *device) {
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 +110,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 *)ð->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 +119,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 +129,7 @@ int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
msg,
msg_len,
0,
- (struct sockaddr *)ð->dest_addr[Mod_id],
+ (struct sockaddr *)&dest_addr[Mod_id],
(socklen_t *)&dest_addr_len[Mod_id])==-1) {
perror("ETHERNET: ");
exit(0);
@@ -283,65 +139,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 *)ð->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 *)ð->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 +161,310 @@ 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 *)ð->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;
+ struct in_addr ia;
+ struct if_nameindex *ids;
+ int ret=0;
+ int i=0;
+
+
+ /***************** get working interface name ***************************/
+ /* /\* convert ascii ip address from config file to network binary format *\/ */
+ /* inet_aton(device->openair0_cfg.my_addr, &ia); */
+ /* /\* look for the interface used, we have its ip address *\/ */
+ /* /\* get info on all our network interfaces *\/ */
+ /* ids = if_nameindex(); */
+ /* /\* loop on these network interfaces *\/ */
+ /* for (i=0; ids[i].if_index != 0 ; i++) { */
+ /* /\* skip unamed interfaces *\/ */
+ /* if (ids[i].if_name == NULL) */
+ /* continue; */
+ /* /\* get ip address of current network interface *\/ */
+ /* strcpy(ifr.ifr_name,ids[i].if_name); */
+ /* if (-1 == ioctl(eth->sockfd[Mod_id], SIOCGIFADDR, &ifr)) { */
+ /* printf( " Interface %i: %s isn't configured (no ip addr), skipped\n",ids[i].if_index, ifr.ifr_name) ; */
+ /* continue; */
+ /* } */
+ /* /\* test if this is the interface to be used *\/ */
+ /* if ( ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr != ia.s_addr) */
+ /* continue; */
+ /* /\* store interface name *\/ */
+ /* if_name = ids[i].if_name; */
+ /* break; */
+
+ /* } */
+ /* if_freenameindex(ids); */
+ /* if( if_name == NULL) { */
+ /* printf("Unable to find interface name for %s\n",device->openair0_cfg.my_addr); */
+ /* return -1; */
+ /* } */
+ /* eth->if_name[Mod_id]=if_name; */
- /****************** socket level options ************************/
- if (option== SND_BUF_SIZE) { /* transmit socket buffer size */
+ /****************** 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, char *cfgfile) {
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;
+ int card = 0;
- printf("ETHERNET: Initializing openair0_device for %s ...\n", ((device->func_type == BBU_FUNC) ? "BBU": "RRH"));
+ /*hoedcoded!!!!*/
+ eth->flags = ETH_UDP_MODE;
+ eth->buffer_size = (unsigned int)openair0_cfg[card].samples_per_packet*sizeof(int32_t); // buffer size = 4096 for sample_len of 1024
+
+ 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;
+
+ 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;
+ }
+ /*hoedcoded!!!!*/
+ eth->if_name[device->Mod_id] = "eth0";
+ device->priv = eth;
memcpy((void*)&device->openair0_cfg,(void*)openair0_cfg,sizeof(openair0_config_t));
+
+ /*iqoffset*/
+ /*keep conf*/
+ /*usrsignal */
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(" Delay: %i, Forward samples: %u \n" ,
+ device->openair0_cfg.tx_delay, device->openair0_cfg.tx_forward_nsamps);
+ 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 - ":""),
+ ((eth->flags & ETH_LOOP_MODE) ? "loopback 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
#include
@@ -47,61 +49,95 @@
#include
#include
-#define MAX_INST 4
-#define DEFAULT_IF "lo"
-#define BUF_SIZ 8960 /*Jumbo frame size*/
+#define MAX_INST 4
+#define DEFAULT_IF "lo"
+#define ETH_RAW_MODE 1
+#define ETH_UDP_MODE (1<<1)
+#define ETH_LOOP_MODE (1<<2)
+
+#define TX_FLAG 1
+#define RX_FLAG 0
+
+
+#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))
+/*
+#define RRH_DEST_MAC0 0x74
+#define RRH_DEST_MAC1 0xd4
+#define RRH_DEST_MAC2 0x35
+#define RRH_DEST_MAC3 0xcc
+#define RRH_DEST_MAC4 0x88
+#define RRH_DEST_MAC5 0x45
+
+#define BBU_DEST_MAC0 0xd4
+#define BBU_DEST_MAC1 0xbe
+#define BBU_DEST_MAC2 0xd9
+#define BBU_DEST_MAC3 0x22
+#define BBU_DEST_MAC4 0x0a
+#define BBU_DEST_MAC5 0xac
+*/
+
+/*!\brief opaque ethernet data structure */
typedef struct {
-
- // 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)
-
+
+ /*!\brief socket file desc */
int sockfd[MAX_INST];
- struct sockaddr_in dest_addr[MAX_INST];
-
+ /*!\brief interface name */
+ char *if_name[MAX_INST];
+ /*!\brief buffer size */
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 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
// --------------------------------
- int num_underflows;
- int num_overflows;
- int num_seq_errors;
- int num_rx_errors;
- int num_tx_errors;
+
+ /*!\brief number of I/Q samples to be printed */
+ int iqdumpcnt;
- uint64_t tx_actual_nsamps; // actual number of samples transmitted
+ /*!\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;
+
+ /*!\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 */
@@ -138,9 +174,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 ;
+
+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, eth_opt_t option)
+
+/*! \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 +212,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/RT/USER/UE_transport_IQ.c b/targets/RT/USER/UE_transport_IQ.c
index a52e3654ae..055b45ba72 100644
--- a/targets/RT/USER/UE_transport_IQ.c
+++ b/targets/RT/USER/UE_transport_IQ.c
@@ -284,7 +284,7 @@ void *rrh_UE_thread(void *arg) {
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,
+ 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,
diff --git a/targets/RT/USER/eNB_transport_IQ.c b/targets/RT/USER/eNB_transport_IQ.c
index fffe93ab5f..0b4b6c5fc6 100644
--- a/targets/RT/USER/eNB_transport_IQ.c
+++ b/targets/RT/USER/eNB_transport_IQ.c
@@ -140,17 +140,17 @@ 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 (1==0) {
/* if a RF iterface is added to RRH module get the configuration parameters sent from eNB */
- if (mod_enb->devs->type != NONE_IF ) {
+if (mod_enb->devs->type != NONE_DEV ) {
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->type == EXMIMO_DEV ) {
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;
@@ -172,7 +172,7 @@ void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag) {
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
}
- else if (mod_enb->devs->type == USRP_IF) {
+ else if (mod_enb->devs->type == USRP_DEV) {
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;
@@ -194,7 +194,7 @@ void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag) {
mod_enb->devs->openair0_cfg.tx_delay = 8;
}
}
- else if(mod_enb->devs->type == BLADERF_IF) {
+ else if(mod_enb->devs->type == BLADERF_DEV) {
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;
@@ -221,24 +221,42 @@ void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag) {
check_dev_config(mod_enb);
/* initialize and configure the RF device */
- if (openair0_device_init(mod_enb->devs, &mod_enb->devs->openair0_cfg)<0){
+ 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 {
- LOG_I(RRH,"RF device has been successfully initialized.\n");
- }
-
- /* start RF device */
- if (mod_enb->devs->type == EXMIMO_IF ) {
-
} 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");
+ LOG_I(RRH,"RF device has been successfully initialized.\n");
+ }
+
}
-
+
+ } else {
+
+ memcpy((void*)&mod_enb->devs->openair0_cfg,(void *)&mod_enb->eth_dev.openair0_cfg,sizeof(openair0_config_t));
+
+ /* 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");
+ }
+
+ }
+ }
+ }
+
/* create main eNB module thread
main_rrh_eNB_thread allocates memory
for TX/RX buffers and creates TX/RX
@@ -287,14 +305,14 @@ void *rrh_eNB_thread(void *arg) {
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);
+ LOG_D(RRH,"i=%d rx_buffer_eNB[i]=%p tmp= %p samples_per_frame=%d\n",i,rx_buffer_eNB[i],tmp, samples_per_frame);
}
/* tx_buffer_eNB points to the beginning of data */
for (i=0; ieth_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);
+ LOG_D(RRH,"i= %d tx_buffer_eNB[i]=%p tmp= %p samples_per_frame=%d\n",i,tx_buffer_eNB[i],tmp, samples_per_frame);
}
/* dummy initialization for TX/RX buffers */
for (i=0; ieth_dev.openair0_cfg.rx_num_channels; i++) {
@@ -353,7 +371,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 +423,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;
@@ -463,7 +482,7 @@ void *rrh_eNB_rx_thread(void *arg) {
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 );
@@ -506,7 +525,7 @@ void *rrh_eNB_rx_thread(void *arg) {
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,
@@ -533,7 +552,7 @@ void *rrh_eNB_rx_thread(void *arg) {
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 +578,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,17 +596,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) {
- pthread_cond_wait(&sync_trx_cond,&sync_trx_mutex);
- }
- sync_trx=1;
- 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 +618,7 @@ void *rrh_eNB_rx_thread(void *arg) {
return 0;
}
+/* Receive from eNB and transmit to RF */
void *rrh_eNB_tx_thread(void *arg) {
@@ -660,45 +670,13 @@ void *rrh_eNB_tx_thread(void *arg) {
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);
-
- 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; ieth_dev.openair0_cfg.tx_num_channels; i++) tx_eNB[i] = (void*)&tx_buffer_eNB[i][tx_pos]; //RF!!!!!
@@ -715,7 +693,7 @@ void *rrh_eNB_tx_thread(void *arg) {
}
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)*/
@@ -733,7 +711,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 ) {
@@ -755,9 +733,7 @@ void *rrh_eNB_tx_thread(void *arg) {
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);
+
}
/* wrap around tx buffer index */
@@ -784,8 +760,7 @@ static void calc_rt_period_ns( openair0_config_t openair0_cfg) {
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);
@@ -802,7 +777,7 @@ static void check_dev_config( rrh_module_t *mod_enb) {
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",
+ 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",
mod_enb->devs->openair0_cfg.Mod_id,
mod_enb->devs->openair0_cfg.log_level,
mod_enb->devs->openair0_cfg.num_rb_dl,
@@ -836,11 +811,7 @@ static void check_dev_config( rrh_module_t *mod_enb) {
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
+ mod_enb->devs->openair0_cfg.autocal[0]
);
printf("----------------------------------------------------------------------------\n");
diff --git a/targets/RT/USER/rrh_gw.c b/targets/RT/USER/rrh_gw.c
index 39b726ae07..c479c2a211 100644
--- a/targets/RT/USER/rrh_gw.c
+++ b/targets/RT/USER/rrh_gw.c
@@ -51,9 +51,9 @@
#include
#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"
@@ -72,7 +72,8 @@
-char rrh_ip[20] = "192.168.12.242"; // there is code to detect the my ip address
+char rrh_ip[20] = "0.0.0.0"; // there is code to detect my ip address
+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";
+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,45 @@ 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;
+ /* 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");
+ }
+
+ /* if use setrunnig parameters we should keep in device->priv keep if_name and raw/udp flag*/
/* 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)<0,NULL) {
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));
-
-#ifdef EXMIMO
+ memset(oai_dv,0,sizeof(openair0_device));
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_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 +237,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 +249,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 +269,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,49 +292,48 @@ 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);
- }
+ }
}
}
-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 +341,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, 2: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");
}