1. update ethernet library-raw/udp modes supported 2. rrh_gw UE/eNB_trasport files updated accordingly
This commit is contained in:
@@ -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 <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 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;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));
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -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 <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_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;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;
|
||||||
|
|
||||||
|
*(int16_t *)(buff2 + sizeof(int16_t))=1+(i<<1);
|
||||||
|
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = timestamp;
|
||||||
|
|
||||||
|
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 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 */
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
/*! \file ethernet_lib.c
|
/*! \file ethernet_lib.c
|
||||||
* \brief API to stream I/Q samples over standard ethernet
|
* \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
|
* \date 2015
|
||||||
* \version 0.2
|
* \version 0.2
|
||||||
* \company Eurecom
|
* \company Eurecom
|
||||||
@@ -52,186 +52,43 @@
|
|||||||
#include "common_lib.h"
|
#include "common_lib.h"
|
||||||
#include "ethernet_lib.h"
|
#include "ethernet_lib.h"
|
||||||
|
|
||||||
//#define DEBUG 1
|
|
||||||
|
|
||||||
int num_devices_eth = 0;
|
int num_devices_eth = 0;
|
||||||
|
struct sockaddr_in dest_addr[MAX_INST];
|
||||||
int dest_addr_len[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) {
|
int trx_eth_start(openair0_device *device) {
|
||||||
|
|
||||||
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||||
|
|
||||||
/* initialize socket */
|
/* initialize socket */
|
||||||
if (eth_socket_init(device)!=0) {
|
if ((eth->flags & ETH_RAW_MODE) != 0 ) {
|
||||||
return -1;
|
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) {
|
||||||
/* RRH gets openair0 device configuration BBU sets openair0 device configuration*/
|
if(eth_set_dev_conf_raw(device)!=0) return -1;
|
||||||
if (device->func_type == BBU_FUNC) {
|
} else {
|
||||||
return eth_set_dev_conf(device);
|
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 {
|
} 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;
|
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*)ð->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;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 *)ð->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) {
|
void trx_eth_end(openair0_device *device) {
|
||||||
|
|
||||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
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");
|
perror("ETHERNET: Failed to close socket");
|
||||||
exit(0);
|
exit(0);
|
||||||
} else {
|
} 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;
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||||
|
|
||||||
/* BBU sends a message to RRH */
|
/* 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: ");
|
perror("ETHERNET: ");
|
||||||
exit(0);
|
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) {
|
int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
|
||||||
|
|
||||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
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,
|
||||||
msg_len,
|
msg_len,
|
||||||
0,
|
0,
|
||||||
(struct sockaddr *)ð->dest_addr[Mod_id],
|
(struct sockaddr *)&dest_addr[Mod_id],
|
||||||
(socklen_t *)&dest_addr_len[Mod_id])==-1) {
|
(socklen_t *)&dest_addr_len[Mod_id])==-1) {
|
||||||
perror("ETHERNET: ");
|
perror("ETHERNET: ");
|
||||||
exit(0);
|
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) {
|
int trx_eth_stop(int card) {
|
||||||
return(0);
|
return(0);
|
||||||
@@ -364,186 +161,310 @@ int trx_eth_reset_stats(openair0_device* device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int eth_socket_init(openair0_device *device) {
|
int ethernet_tune(openair0_device *device, unsigned int option, int value) {
|
||||||
|
|
||||||
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) {
|
|
||||||
|
|
||||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||||
int Mod_id=device->Mod_id;
|
int Mod_id=device->Mod_id;
|
||||||
|
struct timeval timeout;
|
||||||
unsigned int sndbuf_size=0, rcvbuf_size=0;
|
|
||||||
struct timeval snd_timeout, rcv_timeout;
|
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
char system_cmd[256];
|
char system_cmd[256];
|
||||||
char* if_name=DEFAULT_IF;
|
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 ************************/
|
/****************** socket level options ************************/
|
||||||
if (option== SND_BUF_SIZE) { /* transmit socket buffer size */
|
switch(option) {
|
||||||
|
case SND_BUF_SIZE: /* transmit socket buffer size */
|
||||||
if (setsockopt(eth->sockfd[Mod_id],
|
if (setsockopt(eth->sockfd[Mod_id],
|
||||||
SOL_SOCKET,
|
SOL_SOCKET,
|
||||||
SO_SNDBUF,
|
SO_SNDBUF,
|
||||||
&sndbuf_size,sizeof(sndbuf_size))) {
|
&value,sizeof(value))) {
|
||||||
perror("[ETHERNET] setsockopt()");
|
perror("[ETHERNET] setsockopt()");
|
||||||
} else {
|
} else {
|
||||||
printf( "sndbuf_size= %d bytes\n", sndbuf_size);
|
printf("send buffer size= %d bytes\n",value);
|
||||||
}
|
}
|
||||||
} else if (option== RCV_BUF_SIZE) { /* receive socket buffer size */
|
break;
|
||||||
|
|
||||||
|
case RCV_BUF_SIZE: /* receive socket buffer size */
|
||||||
if (setsockopt(eth->sockfd[Mod_id],
|
if (setsockopt(eth->sockfd[Mod_id],
|
||||||
SOL_SOCKET,
|
SOL_SOCKET,
|
||||||
SO_RCVBUF,
|
SO_RCVBUF,
|
||||||
&rcvbuf_size,sizeof(rcvbuf_size))) {
|
&value,sizeof(value))) {
|
||||||
perror("[ETHERNET] setsockopt()");
|
perror("[ETHERNET] setsockopt()");
|
||||||
} else {
|
} else {
|
||||||
printf( "rcvbuf_size= %d bytes\n", rcvbuf_size);
|
printf("receive bufffer size= %d bytes\n",value);
|
||||||
}
|
}
|
||||||
} else if (option==RCV_TIMEOUT) {
|
break;
|
||||||
rcv_timeout.tv_sec = 0;
|
|
||||||
rcv_timeout.tv_usec = 180;//less than rt_period
|
case RCV_TIMEOUT:
|
||||||
|
timeout.tv_sec = value/1000000000;
|
||||||
|
timeout.tv_usec = value%1000000000;//less than rt_period?
|
||||||
if (setsockopt(eth->sockfd[Mod_id],
|
if (setsockopt(eth->sockfd[Mod_id],
|
||||||
SOL_SOCKET,
|
SOL_SOCKET,
|
||||||
SO_RCVTIMEO,
|
SO_RCVTIMEO,
|
||||||
(char *)&rcv_timeout,sizeof(rcv_timeout))) {
|
(char *)&timeout,sizeof(timeout))) {
|
||||||
perror("[ETHERNET] setsockopt()");
|
perror("[ETHERNET] setsockopt()");
|
||||||
} else {
|
} 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) {
|
break;
|
||||||
snd_timeout.tv_sec = 0;
|
|
||||||
snd_timeout.tv_usec = 180;//less than rt_period
|
case SND_TIMEOUT:
|
||||||
|
timeout.tv_sec = value/1000000000;
|
||||||
|
timeout.tv_usec = value%1000000000;//less than rt_period?
|
||||||
if (setsockopt(eth->sockfd[Mod_id],
|
if (setsockopt(eth->sockfd[Mod_id],
|
||||||
SOL_SOCKET,
|
SOL_SOCKET,
|
||||||
SO_SNDTIMEO,
|
SO_SNDTIMEO,
|
||||||
(char *)&snd_timeout,sizeof(snd_timeout))) {
|
(char *)&timeout,sizeof(timeout))) {
|
||||||
perror("[ETHERNET] setsockopt()");
|
perror("[ETHERNET] setsockopt()");
|
||||||
} else {
|
} else {
|
||||||
printf( "snd_timeout= %d usecs\n", snd_timeout.tv_usec);
|
printf( "send timeout= %d,%d sec\n",timeout.tv_sec,timeout.tv_usec);
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
/******************* interface level options *************************/
|
|
||||||
else if (option==MTU_SIZE) { /* change MTU of the eth interface */
|
/******************* interface level options *************************/
|
||||||
|
case MTU_SIZE: /* change MTU of the eth interface */
|
||||||
ifr.ifr_addr.sa_family = AF_INET;
|
ifr.ifr_addr.sa_family = AF_INET;
|
||||||
strncpy(ifr.ifr_name,if_name, sizeof(ifr.ifr_name));
|
strncpy(ifr.ifr_name,eth->if_name[Mod_id], sizeof(ifr.ifr_name));
|
||||||
ifr.ifr_mtu =8960;
|
ifr.ifr_mtu =value;
|
||||||
if (ioctl(eth->sockfd[Mod_id],SIOCSIFMTU,(caddr_t)&ifr) < 0 )
|
if (ioctl(eth->sockfd[Mod_id],SIOCSIFMTU,(caddr_t)&ifr) < 0 )
|
||||||
perror ("[ETHERNET] Can't set the MTU");
|
perror ("[ETHERNET] Can't set the MTU");
|
||||||
else
|
else
|
||||||
printf("[ETHERNET] %s MTU size has changed to %d\n",DEFAULT_IF,ifr.ifr_mtu);
|
printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name[Mod_id],ifr.ifr_mtu);
|
||||||
} else if (option==TX_Q_LEN) { /* change TX queue length of eth interface */
|
break;
|
||||||
|
|
||||||
|
case TX_Q_LEN: /* change TX queue length of eth interface */
|
||||||
ifr.ifr_addr.sa_family = AF_INET;
|
ifr.ifr_addr.sa_family = AF_INET;
|
||||||
strncpy(ifr.ifr_name,if_name, sizeof(ifr.ifr_name));
|
strncpy(ifr.ifr_name,eth->if_name[Mod_id], sizeof(ifr.ifr_name));
|
||||||
ifr.ifr_qlen =3000 ;
|
ifr.ifr_qlen =value;
|
||||||
if (ioctl(eth->sockfd[Mod_id],SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 )
|
if (ioctl(eth->sockfd[Mod_id],SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 )
|
||||||
perror ("[ETHERNET] Can't set the txqueuelen");
|
perror ("[ETHERNET] Can't set the txqueuelen");
|
||||||
else
|
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 *************************/
|
/******************* device level options *************************/
|
||||||
} else if (option==COALESCE_PAR) {
|
case COALESCE_PAR:
|
||||||
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs 3",DEFAULT_IF) > 0) {
|
ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs %d",eth->if_name[Mod_id],value);
|
||||||
system(system_cmd);
|
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);
|
printf("[ETHERNET] Coalesce parameters %s\n",system_cmd);
|
||||||
} else {
|
} else {
|
||||||
perror("[ETHERNET] Can't set coalesce parameters\n");
|
perror("[ETHERNET] Can't set coalesce parameters\n");
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (option==PAUSE_PAR ) {
|
case PAUSE_PAR:
|
||||||
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",DEFAULT_IF) > 0) {
|
if (value==1) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",eth->if_name[Mod_id]);
|
||||||
system(system_cmd);
|
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);
|
printf("[ETHERNET] Pause parameters %s\n",system_cmd);
|
||||||
} else {
|
} else {
|
||||||
perror("[ETHERNET] Can't set pause parameters\n");
|
perror("[ETHERNET] Can't set pause parameters\n");
|
||||||
}
|
}
|
||||||
} else if (option==RING_PAR ) {
|
break;
|
||||||
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s rx 4096 tx 4096",DEFAULT_IF) > 0) {
|
|
||||||
system(system_cmd);
|
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);
|
printf("[ETHERNET] Ring parameters %s\n",system_cmd);
|
||||||
} else {
|
} else {
|
||||||
perror("[ETHERNET] Can't set ring parameters\n");
|
perror("[ETHERNET] Can't set ring parameters\n");
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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));
|
eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t));
|
||||||
int card = 0;
|
|
||||||
memset(eth, 0, sizeof(eth_state_t));
|
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
|
int card = 0;
|
||||||
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"));
|
/*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->Mod_id = num_devices_eth++;
|
||||||
|
device->transp_type = ETHERNET_TP;
|
||||||
device->trx_start_func = trx_eth_start;
|
device->trx_start_func = trx_eth_start;
|
||||||
device->trx_request_func = trx_eth_request;
|
device->trx_request_func = trx_eth_request;
|
||||||
device->trx_reply_func = trx_eth_reply;
|
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_get_stats_func = trx_eth_get_stats;
|
||||||
device->trx_reset_stats_func = trx_eth_reset_stats;
|
device->trx_reset_stats_func = trx_eth_reset_stats;
|
||||||
device->trx_end_func = trx_eth_end;
|
device->trx_end_func = trx_eth_end;
|
||||||
device->trx_stop_func = trx_eth_stop;
|
device->trx_stop_func = trx_eth_stop;
|
||||||
device->trx_set_freq_func = trx_eth_set_freq;
|
device->trx_set_freq_func = trx_eth_set_freq;
|
||||||
device->trx_set_gains_func = trx_eth_set_gains;
|
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));
|
memcpy((void*)&device->openair0_cfg,(void*)openair0_cfg,sizeof(openair0_config_t));
|
||||||
|
|
||||||
|
/*iqoffset*/
|
||||||
|
/*keep conf*/
|
||||||
|
/*usrsignal */
|
||||||
return 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(" 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<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" : " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
* \note
|
* \note
|
||||||
* \warning
|
* \warning
|
||||||
*/
|
*/
|
||||||
|
#ifndef ETHERNET_LIB_H
|
||||||
|
#define ETHERNET_LIB_H
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <linux/if_packet.h>
|
#include <linux/if_packet.h>
|
||||||
@@ -47,61 +49,95 @@
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netinet/ether.h>
|
#include <netinet/ether.h>
|
||||||
|
|
||||||
#define MAX_INST 4
|
#define MAX_INST 4
|
||||||
#define DEFAULT_IF "lo"
|
#define DEFAULT_IF "lo"
|
||||||
#define BUF_SIZ 8960 /*Jumbo frame size*/
|
|
||||||
|
|
||||||
|
#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 {
|
typedef struct {
|
||||||
|
|
||||||
// opaque eth data struct
|
/*!\brief socket file desc */
|
||||||
//struct eth_if *dev;
|
|
||||||
// An empty ("") or NULL device identifier will result in the first encountered device being opened (using the first discovered backend)
|
|
||||||
|
|
||||||
int sockfd[MAX_INST];
|
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 buffer_size;
|
||||||
unsigned int timeout_ns;
|
/*!\brief timeout ms */
|
||||||
|
unsigned int rx_timeout_ms;
|
||||||
//struct eth_metadata meta_rx;
|
/*!\brief timeout ms */
|
||||||
//struct eth_metadata meta_tx;
|
unsigned int tx_timeout_ms;
|
||||||
|
/*!\brief runtime flags */
|
||||||
unsigned int sample_rate;
|
uint32_t flags;
|
||||||
// time offset between transmiter timestamp and receiver timestamp;
|
/*!\ time offset between transmiter timestamp and receiver timestamp */
|
||||||
double tdiff;
|
double tdiff;
|
||||||
// use brf_time_offset to get this value
|
/*!\ calibration */
|
||||||
int tx_forward_nsamps; //166 for 20Mhz
|
int tx_forward_nsamps;
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
// Debug and output control
|
// Debug and output control
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
int num_underflows;
|
|
||||||
int num_overflows;
|
/*!\brief number of I/Q samples to be printed */
|
||||||
int num_seq_errors;
|
int iqdumpcnt;
|
||||||
int num_rx_errors;
|
|
||||||
int num_tx_errors;
|
|
||||||
|
|
||||||
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 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 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;
|
uint64_t rx_count;
|
||||||
//openair0_timestamp rx_timestamp;
|
|
||||||
|
|
||||||
} eth_state_t;
|
} 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 */
|
/*!\brief packet header */
|
||||||
@@ -138,9 +174,37 @@ typedef enum {
|
|||||||
MAX_OPT
|
MAX_OPT
|
||||||
} eth_opt_t;
|
} 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
|
* \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] openair0 device which bears the socket
|
||||||
* \param[in] name of parameter to configure
|
* \param[in] name of parameter to configure
|
||||||
@@ -148,6 +212,37 @@ typedef enum {
|
|||||||
* \note
|
* \note
|
||||||
* @ingroup _oai
|
* @ingroup _oai
|
||||||
*/
|
*/
|
||||||
int ethernet_tune (openair0_device *device, eth_opt_t option);
|
int ethernet_tune(openair0_device *device, unsigned int option, int value);
|
||||||
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);
|
|
||||||
|
|
||||||
|
/*! \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
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ void *rrh_UE_thread(void *arg) {
|
|||||||
tx_buffer_UE[i]=(tmp+4*sizeof(int32_t));
|
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.remote_port,
|
||||||
dev->eth_dev.openair0_cfg.num_rb_dl,
|
dev->eth_dev.openair0_cfg.num_rb_dl,
|
||||||
dev->eth_dev.openair0_cfg.rx_num_channels,
|
dev->eth_dev.openair0_cfg.rx_num_channels,
|
||||||
|
|||||||
@@ -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;
|
RT_flag_eNB=RT_flag;
|
||||||
NRT_flag_eNB=NRT_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
|
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 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));
|
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)*/
|
/* 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 ) {
|
if ( mod_enb->devs->openair0_cfg.num_rb_dl == 100 ) {
|
||||||
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
|
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
|
||||||
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
|
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;
|
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 ) {
|
if ( mod_enb->devs->openair0_cfg.num_rb_dl == 100 ) {
|
||||||
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
|
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
|
||||||
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
|
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;
|
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 ) {
|
if ( mod_enb->devs->openair0_cfg.num_rb_dl == 100 ) {
|
||||||
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
|
mod_enb->devs->openair0_cfg.samples_per_packet = 2048;
|
||||||
mod_enb->devs->openair0_cfg.tx_forward_nsamps = 175;
|
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);
|
check_dev_config(mod_enb);
|
||||||
|
|
||||||
/* initialize and configure the RF device */
|
/* 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");
|
LOG_E(RRH,"Exiting, cannot initialize RF device.\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG_I(RRH,"RF device has been successfully initialized.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* start RF device */
|
|
||||||
if (mod_enb->devs->type == EXMIMO_IF ) {
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (mod_enb->devs->trx_start_func(mod_enb->devs)!=0)
|
LOG_I(RRH,"RF device has been successfully initialized.\n");
|
||||||
LOG_E(RRH,"Unable to initiate RF device.\n");
|
}
|
||||||
}
|
|
||||||
LOG_I(RRH,"RF device has been initiated.\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
|
/* create main eNB module thread
|
||||||
main_rrh_eNB_thread allocates memory
|
main_rrh_eNB_thread allocates memory
|
||||||
for TX/RX buffers and creates TX/RX
|
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));
|
tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32));
|
||||||
memset(tmp,0,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)) );
|
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 */
|
/* 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));
|
tmp=(void *)malloc16(sizeof(int32_t)*(samples_per_frame + 32));
|
||||||
memset(tmp,0,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)) );
|
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 */
|
/* 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++) {
|
||||||
@@ -353,7 +371,7 @@ void *rrh_eNB_thread(void *arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* create timer thread; when no RF device is present a software clock is generated */
|
/* 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;
|
int error_code_timer;
|
||||||
pthread_t main_timer_proc_thread;
|
pthread_t main_timer_proc_thread;
|
||||||
@@ -405,10 +423,11 @@ void *rrh_eNB_thread(void *arg) {
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Receive from RF and transmit to RRH */
|
||||||
|
|
||||||
void *rrh_eNB_rx_thread(void *arg) {
|
void *rrh_eNB_rx_thread(void *arg) {
|
||||||
|
|
||||||
/* measuremnt related vars */
|
/* measurement related vars */
|
||||||
struct timespec time0,time1,time2;
|
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;
|
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;
|
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 );
|
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);
|
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_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_RX_LHWCNT, last_hw_counter );
|
||||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_CNT, s_cnt );
|
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);
|
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 );
|
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 );
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_RF, 1 );
|
||||||
/* Read operation to RF device (RX)*/
|
/* Read operation to RF device (RX)*/
|
||||||
if ( dev->devs->trx_read_func (dev->devs,
|
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 );
|
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 */
|
/* 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;
|
timestamp_rx+=spp_eth;
|
||||||
last_hw_counter=hw_counter;
|
last_hw_counter=hw_counter;
|
||||||
}
|
}
|
||||||
@@ -559,7 +578,7 @@ void *rrh_eNB_rx_thread(void *arg) {
|
|||||||
}
|
}
|
||||||
if (s_period++ == PRINTF_PERIOD) {
|
if (s_period++ == PRINTF_PERIOD) {
|
||||||
s_period=0;
|
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);
|
next_rx_pos=(rx_pos+spp_eth);
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX, 0 );
|
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
|
} // while
|
||||||
|
|
||||||
subframe++;
|
subframe++;
|
||||||
@@ -609,6 +618,7 @@ void *rrh_eNB_rx_thread(void *arg) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Receive from eNB and transmit to RF */
|
||||||
|
|
||||||
void *rrh_eNB_tx_thread(void *arg) {
|
void *rrh_eNB_tx_thread(void *arg) {
|
||||||
|
|
||||||
@@ -660,45 +670,13 @@ void *rrh_eNB_tx_thread(void *arg) {
|
|||||||
while (rrh_exit == 0) {
|
while (rrh_exit == 0) {
|
||||||
while (tx_pos < (1 + subframe)*samples_per_subframe) {
|
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_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_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_HW_SUBFRAME, subframe );
|
||||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_PCK, pck_tx );
|
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);
|
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]; //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 );
|
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]);
|
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 );
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF, 1 );
|
||||||
/* Write operation to RF device (TX)*/
|
/* 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 );
|
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 ) {
|
if (loopback ==1 ) {
|
||||||
@@ -755,9 +733,7 @@ void *rrh_eNB_tx_thread(void *arg) {
|
|||||||
pck_tx++;
|
pck_tx++;
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX, 0 );
|
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 */
|
/* 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) {
|
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.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.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.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("\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.Mod_id,
|
||||||
mod_enb->devs->openair0_cfg.log_level,
|
mod_enb->devs->openair0_cfg.log_level,
|
||||||
mod_enb->devs->openair0_cfg.num_rb_dl,
|
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_gain_offset[3],
|
||||||
mod_enb->devs->openair0_cfg.rx_bw,
|
mod_enb->devs->openair0_cfg.rx_bw,
|
||||||
mod_enb->devs->openair0_cfg.tx_bw,
|
mod_enb->devs->openair0_cfg.tx_bw,
|
||||||
mod_enb->devs->openair0_cfg.autocal[0],
|
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("----------------------------------------------------------------------------\n");
|
printf("----------------------------------------------------------------------------\n");
|
||||||
|
|||||||
+65
-67
@@ -51,9 +51,9 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "common_lib.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 "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"
|
#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
|
int rrh_port = 50000; // has to be an option
|
||||||
|
|
||||||
/* log */
|
/* log */
|
||||||
@@ -86,7 +87,7 @@ int16_t ue_log_level = LOG_INFO;
|
|||||||
int16_t ue_log_verbosity = LOG_MED;
|
int16_t ue_log_verbosity = LOG_MED;
|
||||||
|
|
||||||
|
|
||||||
/* flags definitions */
|
/* flag definitions */
|
||||||
uint8_t eNB_flag=0;
|
uint8_t eNB_flag=0;
|
||||||
uint8_t UE_flag=0;
|
uint8_t UE_flag=0;
|
||||||
uint8_t EXMIMO_flag=0;
|
uint8_t EXMIMO_flag=0;
|
||||||
@@ -102,10 +103,8 @@ uint8_t measurements_flag=0;
|
|||||||
- default ethernet interface is local */
|
- default ethernet interface is local */
|
||||||
uint8_t num_eNB_mod=0;
|
uint8_t num_eNB_mod=0;
|
||||||
uint8_t num_UE_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 *enb_array;
|
||||||
rrh_module_t *ue_array;
|
rrh_module_t *ue_array;
|
||||||
@@ -128,14 +127,14 @@ static void print_help(void);
|
|||||||
*/
|
*/
|
||||||
static rrh_module_t new_module(unsigned int id);
|
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
|
* \brief retrieves IP address from the specified network interface
|
||||||
* \param[in] name of network interface
|
* \param[in] name of network interface
|
||||||
* \return 0
|
* \return 0
|
||||||
* \note
|
* \note
|
||||||
* @ingroup _oai
|
* @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;
|
rrh_mod.measurements=measurements_flag;
|
||||||
|
|
||||||
/* each module is associated with an ethernet device */
|
/* 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 */
|
/* ethernet device is functioning within RRH */
|
||||||
rrh_mod.eth_dev.func_type=RRH_FUNC;
|
rrh_mod.eth_dev.host_type=RRH_HOST;
|
||||||
/* specify IP address */
|
/* get IP and MAC address */
|
||||||
get_ip_address(if_name);
|
get_address(if_name,eth_mode);
|
||||||
openair0_cfg.my_ip=&rrh_ip[0];
|
|
||||||
openair0_cfg.my_port=rrh_port;
|
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 */
|
/* 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");
|
LOG_E(RRH,"Exiting, cannot initialize ethernet interface.\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate space and specify associated RF device */
|
/* allocate space and specify associated RF device */
|
||||||
openair0_device *oai_dv = (openair0_device *)malloc(sizeof(openair0_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=oai_dv;
|
||||||
rrh_mod.devs->type=EXMIMO_IF;
|
rrh_mod.devs->type=NONE_DEV;
|
||||||
LOG_I(RRH,"Setting RF device to EXMIMO\n");
|
rrh_mod.devs->transp_type=NONE_TP;
|
||||||
#elif OAI_USRP
|
rrh_mod.devs->host_type=RRH_HOST;
|
||||||
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
|
|
||||||
|
|
||||||
return rrh_mod;
|
return rrh_mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void debug_init(void) {
|
static void debug_init(void) {
|
||||||
|
|
||||||
// log initialization
|
/* log initialization */
|
||||||
logInit();
|
logInit();
|
||||||
set_glog(glog_level, glog_verbosity);
|
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(ENB_LOG, enb_log_level, enb_log_verbosity, 1);
|
||||||
//set_comp_log(UE_LOG, ue_log_level, ue_log_verbosity, 1);
|
//set_comp_log(UE_LOG, ue_log_level, ue_log_verbosity, 1);
|
||||||
|
|
||||||
// vcd initialization
|
/* vcd initialization */
|
||||||
if (ouput_vcd) {
|
if (ouput_vcd) {
|
||||||
vcd_signal_dumper_init("/tmp/openair_dump_rrh.vcd");
|
vcd_signal_dumper_init("/tmp/openair_dump_rrh.vcd");
|
||||||
|
|
||||||
@@ -253,7 +249,7 @@ static void get_options(int argc, char *argv[]) {
|
|||||||
|
|
||||||
int opt;
|
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) {
|
switch (opt) {
|
||||||
case 'n':
|
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);
|
printf("RRH interface name is set to %s\n", if_name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'm':
|
||||||
|
eth_mode=atoi(optarg);
|
||||||
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
//rrh_log_level=atoi(optarg);
|
//rrh_log_level=atoi(optarg);
|
||||||
break;
|
break;
|
||||||
@@ -293,49 +292,48 @@ static void get_options(int argc, char *argv[]) {
|
|||||||
loopback_flag=1;
|
loopback_flag=1;
|
||||||
break;
|
break;
|
||||||
case 't':
|
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;
|
measurements_flag=1;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'h':
|
||||||
/* force to use this target*/
|
print_help();
|
||||||
hardware_target=1;
|
exit(-1);
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
print_help();
|
|
||||||
exit(-1);
|
|
||||||
default: /* '?' */
|
default: /* '?' */
|
||||||
//fprintf(stderr, "Usage: \n", argv[0]);
|
//fprintf(stderr, "Usage: \n", argv[0]);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_ip_address(char* if_name) {
|
static int get_address(char* if_name, uint8_t flag) {
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
struct ifreq ifr;
|
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 */
|
/* 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" */
|
/* I want IP address attached to "if_name" */
|
||||||
strncpy(ifr.ifr_name, if_name, IFNAMSIZ-1);
|
strncpy(ifr.ifr_name, if_name, IFNAMSIZ-1);
|
||||||
|
|
||||||
if ( ioctl(fd, SIOCGIFADDR, &ifr)<0 ) {
|
if (flag==ETH_UDP_MODE) {
|
||||||
perror("IOCTL:");
|
if ( ioctl(fd, SIOCGIFADDR, &ifr)<0 ) {
|
||||||
exit(-1);
|
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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,19 +341,19 @@ static int get_ip_address(char* if_name) {
|
|||||||
static void print_help(void) {
|
static void print_help(void) {
|
||||||
|
|
||||||
puts("Usage: \n");
|
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("Options:\n");
|
||||||
puts("\t -n create eNB module\n");
|
puts("\t -n create eNB module\n");
|
||||||
puts("\t -u create UE module\n");
|
puts("\t -u create UE module\n");
|
||||||
puts("\t -g define global log level\n");
|
puts("\t -g define global log level\n");
|
||||||
puts("\t -i set the RRH interface (default lo)\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 -r define rrh log level\n");
|
||||||
puts("\t -e define eNB log level\n");
|
puts("\t -e define eNB log level\n");
|
||||||
puts("\t -x enable real time bahaviour\n");
|
puts("\t -x enable real time bahaviour\n");
|
||||||
puts("\t -v enable vcd dump\n");
|
puts("\t -v enable vcd dump\n");
|
||||||
puts("\t -l enable loopback mode\n");
|
puts("\t -l enable loopback mode\n");
|
||||||
puts("\t -t enable measurements\n");
|
puts("\t -t enable measurements\n");
|
||||||
puts("\t -w force to use specified HW\n");
|
|
||||||
puts("\t -h display info\n");
|
puts("\t -h display info\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user