* add RF interface to the rrh gateway
* update the openair0_init for all targets * add a tuning function for the ethernet git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7830 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -185,7 +185,7 @@ int trx_brf_set_gains(openair0_device* device) {
|
||||
|
||||
}
|
||||
|
||||
int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
|
||||
int status;
|
||||
int card=0;
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*******************************************************************************
|
||||
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@eurecom.fr
|
||||
|
||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||
|
||||
*******************************************************************************/
|
||||
/*! \file common_lib.c
|
||||
* \brief common APIs for different RF frontend device
|
||||
* \author HongliangXU, Navid Nikaein
|
||||
* \date 2015
|
||||
* \version 0.2
|
||||
* \company Eurecom
|
||||
* \maintainer: navid.nikaein@eurecom.fr
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "common_lib.h"
|
||||
|
||||
|
||||
int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
|
||||
#ifdef ETHERNET
|
||||
device->type=ETH_IF;
|
||||
device->func_type = BBU_FUNC;
|
||||
openair0_dev_init_eth(device, openair0_cfg);
|
||||
printf(" openair0_dev_init_eth ...\n");
|
||||
#elif EXMIMO
|
||||
device->type=EXMIMO_IF;
|
||||
openair0_dev_init_exmimo(device, openair0_cfg);
|
||||
printf("openair0_dev_init_exmimo...\n");
|
||||
#elif OAI_USRP
|
||||
device->type=USRP_IF;
|
||||
openair0_dev_init_usrp(device, openair0_cfg);
|
||||
printf("openair0_dev_init_usrp ...\n");
|
||||
#elif OAI_BLADERF
|
||||
device->type=BLADERF_IF;
|
||||
openair0_dev_init_bladerf(device, openair0_cfg);
|
||||
printf(" openair0_dev_init_bladerf ...\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -134,7 +134,13 @@ typedef struct {
|
||||
|
||||
|
||||
|
||||
/*!\brief device type */
|
||||
/*!\brief interface types that apply to modules (RRH_BBU/RRH_UE) created in RRH (rrh_gw.c)
|
||||
and are defined with respect to the RF device that is present in RRH
|
||||
-RRH_BBU modules have two devices, one is by default ETHERNET (will have ETH_IF) and the other one is a
|
||||
RF device (EXMIMO,USRP,BLADERF) or no device (NONE_IF).
|
||||
-RRH_UE modules have two devices one is by default ETHERNET (will have ETH_IF)
|
||||
and the other one by default not present so it will have NONE_IF
|
||||
*/
|
||||
typedef enum {
|
||||
MIN_DEV_TYPE = 0,
|
||||
/*!\brief device is ETH */
|
||||
@@ -152,10 +158,10 @@ typedef enum {
|
||||
} dev_type_t;
|
||||
|
||||
|
||||
/*!\brief type */
|
||||
/*!\brief openair0 device host type */
|
||||
typedef enum {
|
||||
MIN_FUNC_TYPE = 0,
|
||||
/*!\brief device functions within a BBU */
|
||||
/*!\brief device functions within a BBU */
|
||||
BBU_FUNC,
|
||||
/*!\brief device functions within a RRH */
|
||||
RRH_FUNC,
|
||||
@@ -264,23 +270,20 @@ extern "C"
|
||||
#endif
|
||||
|
||||
/*! \brief Initialize Openair RF target. It returns 0 if OK */
|
||||
int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg);
|
||||
//int openair0_stop(int card);
|
||||
|
||||
//ETHERNET
|
||||
/*! \brief Initialize Openair ETHERNET target. It returns 0 if OK */
|
||||
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg);
|
||||
//int openair0_stop_eth(int card);
|
||||
//int openair0_set_gains_eth(openair0_device* device, openair0_config_t *openair0_cfg);
|
||||
//int openair0_set_frequencies_eth(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config);
|
||||
|
||||
//USPRP
|
||||
int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg);
|
||||
|
||||
//USRP
|
||||
/*! \brief Get the current timestamp of USRP */
|
||||
openair0_timestamp get_usrp_time(openair0_device *device);
|
||||
|
||||
openair0_timestamp get_usrp_time(openair0_device *device);
|
||||
/*! \brief Set the RX frequency of USRP RF TARGET */
|
||||
int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
|
||||
|
||||
int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
|
||||
|
||||
//extern
|
||||
/*! \brief Initialize Openair ETHERNET target. It returns 0 if OK */
|
||||
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg);
|
||||
int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg);
|
||||
int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg);
|
||||
int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg);
|
||||
/*@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||
|
||||
*******************************************************************************/
|
||||
/*! \fileethernet_lib.c
|
||||
/*! \file ethernet_lib.c
|
||||
* \brief API to stream I/Q samples over standard ethernet
|
||||
* \author Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp
|
||||
* \date 2015
|
||||
@@ -52,25 +52,328 @@
|
||||
#include "common_lib.h"
|
||||
#include "ethernet_lib.h"
|
||||
|
||||
//#define DEBUG 1
|
||||
|
||||
int num_devices_eth = 0;
|
||||
int dest_addr_len[MAX_INST];
|
||||
char sendbuf[MAX_INST][BUF_SIZ]; /*TODO*/
|
||||
|
||||
|
||||
/* Initialization of UDP Socket to communicate with one destination */
|
||||
int ethernet_socket_init(openair0_device *device) {
|
||||
/*! \fn static int eth_socket_init(openair0_device *device)
|
||||
* \brief initialization of UDP Socket to communicate with one destination
|
||||
* \param[in] *device openair device for which the socket will be created
|
||||
* \param[out]
|
||||
* \return 0 on success, otherwise -1
|
||||
* \note
|
||||
* @ingroup _oai
|
||||
*/
|
||||
static int eth_socket_init(openair0_device *device);
|
||||
|
||||
/*! \fn static int eth_set_dev_conf(openair0_device *device)
|
||||
* \brief
|
||||
* \param[in] *device openair device
|
||||
* \param[out]
|
||||
* \return 0 on success, otherwise -1
|
||||
* \note
|
||||
* @ingroup _oai
|
||||
*/
|
||||
static int eth_set_dev_conf(openair0_device *device);
|
||||
|
||||
/*! \fn static int eth_get_dev_conf(openair0_device *device)
|
||||
* \brief
|
||||
* \param[in] *device openair device
|
||||
* \param[out]
|
||||
* \return 0 on success, otherwise -1
|
||||
* \note
|
||||
* @ingroup _oai
|
||||
*/
|
||||
static int eth_get_dev_conf(openair0_device *device);
|
||||
|
||||
|
||||
|
||||
int trx_eth_start(openair0_device *device) {
|
||||
|
||||
/* initialize socket */
|
||||
if (eth_socket_init(device)!=0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* RRH gets openair0 device configuration BBU sets openair0 device configuration*/
|
||||
if (device->func_type == BBU_FUNC) {
|
||||
return eth_set_dev_conf(device);
|
||||
} else {
|
||||
return eth_get_dev_conf(device);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int trx_eth_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {
|
||||
|
||||
int n_written=0,i;
|
||||
uint16_t header_size=sizeof(int32_t) + sizeof(openair0_timestamp);
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
int Mod_id = device->Mod_id;
|
||||
int sendto_flag =0;
|
||||
sendto_flag|=MSG_DONTWAIT;
|
||||
|
||||
for (i=0;i<cc;i++) {
|
||||
/* buff[i] points to the position in tx buffer where the payload to be sent is
|
||||
buff2 points to the position in tx buffer where the packet header will be placed */
|
||||
void *buff2 = (void*)(buff[i]-header_size);
|
||||
|
||||
/* we don't want to ovewrite with the header info the previous tx buffer data so we store it*/
|
||||
int32_t temp0 = *(int32_t *)buff2;
|
||||
openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + sizeof(int32_t));
|
||||
|
||||
n_written = 0;
|
||||
|
||||
*(int16_t *)(buff2 + sizeof(int16_t))=1+(i<<1);
|
||||
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = timestamp;
|
||||
|
||||
/* printf("[RRH]write mod_%d %d , len %d, buff %p antenna %d\n",
|
||||
Mod_id,eth->sockfd[Mod_id],(nsamps<<2)+header_size, buff2, antenna_id);*/
|
||||
|
||||
while(n_written < nsamps) {
|
||||
/* Send packet */
|
||||
if ((n_written += sendto(eth->sockfd[Mod_id],
|
||||
buff2,
|
||||
(nsamps<<2)+header_size,
|
||||
0,
|
||||
(struct sockaddr*)ð->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);
|
||||
|
||||
int i = 0;
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
int Mod_id = device->Mod_id;
|
||||
|
||||
// struct sockaddr_in *dest = &dest_addr[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) {
|
||||
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
int Mod_id = device->Mod_id;
|
||||
/*destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */
|
||||
if ( close(eth->sockfd[Mod_id]) <0 ) {
|
||||
perror("ETHERNET: Failed to close socket");
|
||||
exit(0);
|
||||
} else {
|
||||
printf("[RRH] socket for mod_id %d has been successfully closed.\n",Mod_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int trx_eth_request(openair0_device *device, void *msg, ssize_t msg_len) {
|
||||
|
||||
int Mod_id = device->Mod_id;
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
|
||||
/* BBU sends a message to RRH */
|
||||
if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)ð->dest_addr[Mod_id],dest_addr_len[Mod_id])==-1) {
|
||||
perror("ETHERNET: ");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
|
||||
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
int Mod_id = device->Mod_id;
|
||||
|
||||
/* RRH receives from BBU a message */
|
||||
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);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int eth_set_dev_conf(openair0_device *device) {
|
||||
|
||||
int Mod_id = device->Mod_id;
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
void *msg;
|
||||
ssize_t msg_len;
|
||||
|
||||
|
||||
/* a BBU client sents to RRH a set of configuration parameters (openair0_config_t)
|
||||
so that RF front end is configured appropriately and
|
||||
frame/packet size etc. can be set */
|
||||
|
||||
msg=malloc(sizeof(openair0_config_t));
|
||||
msg_len=sizeof(openair0_config_t);
|
||||
memcpy(msg,(void*)&device->openair0_cfg,msg_len);
|
||||
|
||||
if (sendto(eth->sockfd[Mod_id],msg,msg_len,0,(struct sockaddr *)ð->dest_addr[Mod_id],dest_addr_len[Mod_id])==-1) {
|
||||
perror("ETHERNET: ");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int eth_get_dev_conf(openair0_device *device) {
|
||||
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
int Mod_id = device->Mod_id;
|
||||
char str[INET_ADDRSTRLEN];
|
||||
void *msg;
|
||||
ssize_t msg_len;
|
||||
|
||||
msg=malloc(sizeof(openair0_config_t));
|
||||
msg_len=sizeof(openair0_config_t);
|
||||
|
||||
/* RRH receives from BBU openair0_config_t */
|
||||
if (recvfrom(eth->sockfd[Mod_id],
|
||||
msg,
|
||||
msg_len,
|
||||
0,
|
||||
(struct sockaddr *)ð->dest_addr[Mod_id],
|
||||
(socklen_t *)&dest_addr_len[Mod_id])==-1) {
|
||||
perror("ETHERNET: ");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
memcpy((void*)&device->openair0_cfg,msg,msg_len);
|
||||
inet_ntop(AF_INET, &(eth->dest_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
|
||||
device->openair0_cfg.remote_port =ntohs(eth->dest_addr[Mod_id].sin_port);
|
||||
device->openair0_cfg.remote_ip=str;
|
||||
/*apply additional configuration*/
|
||||
//ethernet_tune (device, RING_PAR);
|
||||
// printf("[RRH] write mod_%d %d to %s:%d\n",Mod_id,eth->sockfd[Mod_id],str,ntohs(eth->dest_addr[Mod_id].sin_port));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int trx_eth_stop(int card) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
int trx_eth_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
int trx_eth_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
int trx_eth_get_stats(openair0_device* device) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
int trx_eth_reset_stats(openair0_device* device) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static int eth_socket_init(openair0_device *device) {
|
||||
|
||||
int i = 0;
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
int Mod_id = device->Mod_id;
|
||||
char str[INET_ADDRSTRLEN];
|
||||
const char *dest_ip;
|
||||
int dest_port;
|
||||
int dest_port=0;
|
||||
|
||||
if (device->func_type == RRH_FUNC ){
|
||||
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);
|
||||
@@ -87,8 +390,9 @@ int ethernet_socket_init(openair0_device *device) {
|
||||
}
|
||||
|
||||
/* initialize destination address */
|
||||
for (i=0; i< MAX_INST; i++)
|
||||
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;
|
||||
@@ -98,359 +402,126 @@ int ethernet_socket_init(openair0_device *device) {
|
||||
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 (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 {
|
||||
} else {
|
||||
printf("[RRH] binding mod_%d to %s:%d\n",Mod_id,str,ntohs(eth->dest_addr[Mod_id].sin_port));
|
||||
}
|
||||
|
||||
}else {
|
||||
} else {
|
||||
printf("[BBU] Connecting to %s:%d\n",str,ntohs(eth->dest_addr[Mod_id].sin_port));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ethernet_socket_opt (openair0_device *device){
|
||||
|
||||
int ethernet_tune(openair0_device *device , eth_opt_t option) {
|
||||
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
int Mod_id=device->Mod_id;
|
||||
|
||||
int sndbuf_size=0, rcvbuf_size=0;
|
||||
socklen_t optlen;
|
||||
/* chang the MTU of the eth interface */
|
||||
struct ifreq ifr;
|
||||
|
||||
optlen = sizeof(int);
|
||||
|
||||
if (getsockopt(eth->sockfd[Mod_id],
|
||||
SOL_SOCKET,
|
||||
SO_SNDBUF,
|
||||
&sndbuf_size,&optlen))
|
||||
printf("error:getsockopt()\n");
|
||||
|
||||
if (getsockopt(eth->sockfd[Mod_id],
|
||||
SOL_SOCKET,
|
||||
SO_RCVBUF,
|
||||
&rcvbuf_size,&optlen))
|
||||
printf("error:getsockopt()\n");
|
||||
unsigned int sndbuf_size=0, rcvbuf_size=0;
|
||||
struct timeval snd_timeout, rcv_timeout;
|
||||
struct ifreq ifr;
|
||||
char system_cmd[256];
|
||||
char* if_name=DEFAULT_IF;
|
||||
|
||||
printf( "sndbuf_size= %d bytes rcvbuf_size= %d bytes\n", sndbuf_size,
|
||||
rcvbuf_size);
|
||||
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
//iap->ifa_name is bond1:xx
|
||||
strncpy(ifr.ifr_name, DEFAULT_IF, sizeof(ifr.ifr_name));
|
||||
ifr.ifr_mtu = device->openair0_cfg.samples_per_packet*5;
|
||||
if (ioctl(eth->sockfd[Mod_id], SIOCSIFMTU, (caddr_t)&ifr) < 0 )
|
||||
perror ("Can't set the MTU");
|
||||
else
|
||||
printf("[ETHERNET] %s MTU size has changed to %d\n",DEFAULT_IF,ifr.ifr_mtu);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int trx_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;
|
||||
|
||||
|
||||
/* send to RRH (server) required configuration parameters:
|
||||
-number of downlink RBs (so that frame/packet size can be set accordingly)
|
||||
-rx_num_0channels
|
||||
-tx_num_channels
|
||||
-rx_freq
|
||||
-tx_freq
|
||||
-rxg_mode[4]
|
||||
-rx_gain
|
||||
-tx_gain
|
||||
-rx_bw
|
||||
-tx_bw
|
||||
-autocal */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int trx_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);
|
||||
|
||||
/* receive from client (lte-softmodem) */
|
||||
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;
|
||||
//ethernet_socket_opt (device);
|
||||
// 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_request(openair0_device *device, void *msg, ssize_t msg_len) {
|
||||
|
||||
int Mod_id = device->Mod_id;
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int trx_eth_reply(openair0_device *device, void *msg, ssize_t msg_len) {
|
||||
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
int Mod_id = device->Mod_id;
|
||||
|
||||
/* receive from client (lte-softmodem) */
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ethernet_write_data(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id) {
|
||||
|
||||
int n_written;
|
||||
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;
|
||||
|
||||
/* buff[antenna_id] 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[antenna_id]-header_size); // (void*)((unsigned char *)buff[antenna_id]-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+(antenna_id<<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);
|
||||
}
|
||||
}
|
||||
|
||||
/* printf("Buffer head TX: nu=%d an_id=%d ts%d byte_send=%d \n", *(int16_t *)buff2,
|
||||
*(int16_t *)(buff2 + sizeof(int16_t)),
|
||||
*(openair0_timestamp *)(buff2 + sizeof(int32_t)),
|
||||
n_written>>2);*/
|
||||
|
||||
/* tx buffer values restored */
|
||||
*(int32_t *)buff2 = temp0;
|
||||
*(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1;
|
||||
return n_written;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int ethernet_read_data(openair0_device *device,openair0_timestamp *timestamp,void **buff, int nsamps,int antenna_id) {
|
||||
|
||||
int bytes_received;
|
||||
int block_cnt;
|
||||
int ret;
|
||||
uint16_t header_size=sizeof(int32_t) + sizeof(openair0_timestamp);
|
||||
|
||||
|
||||
/* buff[antenna_id] 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[antenna_id]-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));
|
||||
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
int Mod_id = device->Mod_id;
|
||||
|
||||
bytes_received=0;
|
||||
block_cnt=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);
|
||||
}
|
||||
/****************** socket level options ************************/
|
||||
if (option== SND_BUF_SIZE) { /* transmit socket buffer size */
|
||||
if (setsockopt(eth->sockfd[Mod_id],
|
||||
SOL_SOCKET,
|
||||
SO_SNDBUF,
|
||||
&sndbuf_size,sizeof(sndbuf_size))) {
|
||||
perror("[ETHERNET] setsockopt()");
|
||||
} else {
|
||||
bytes_received+=ret;
|
||||
printf( "sndbuf_size= %d bytes\n", sndbuf_size);
|
||||
}
|
||||
} else if (option== RCV_BUF_SIZE) { /* receive socket buffer size */
|
||||
if (setsockopt(eth->sockfd[Mod_id],
|
||||
SOL_SOCKET,
|
||||
SO_RCVBUF,
|
||||
&rcvbuf_size,sizeof(rcvbuf_size))) {
|
||||
perror("[ETHERNET] setsockopt()");
|
||||
} else {
|
||||
printf( "rcvbuf_size= %d bytes\n", rcvbuf_size);
|
||||
}
|
||||
} else if (option==RCV_TIMEOUT) {
|
||||
rcv_timeout.tv_sec = 0;
|
||||
rcv_timeout.tv_usec = 180;//less than rt_period
|
||||
if (setsockopt(eth->sockfd[Mod_id],
|
||||
SOL_SOCKET,
|
||||
SO_RCVTIMEO,
|
||||
(char *)&rcv_timeout,sizeof(rcv_timeout))) {
|
||||
perror("[ETHERNET] setsockopt()");
|
||||
} else {
|
||||
printf( "rcv_timeout= %d usecs\n", rcv_timeout.tv_usec);
|
||||
}
|
||||
} else if (option==SND_TIMEOUT) {
|
||||
snd_timeout.tv_sec = 0;
|
||||
snd_timeout.tv_usec = 180;//less than rt_period
|
||||
if (setsockopt(eth->sockfd[Mod_id],
|
||||
SOL_SOCKET,
|
||||
SO_SNDTIMEO,
|
||||
(char *)&snd_timeout,sizeof(snd_timeout))) {
|
||||
perror("[ETHERNET] setsockopt()");
|
||||
} else {
|
||||
printf( "snd_timeout= %d usecs\n", snd_timeout.tv_usec);
|
||||
}
|
||||
}
|
||||
/*
|
||||
printf("Buffer head RX: nu=%d an_id=%d ts%d byte_recv=%d\n", *(int16_t *)buff2,
|
||||
*(int16_t *)(buff2 + sizeof(int16_t)),
|
||||
*(openair0_timestamp *)(buff2 + sizeof(int32_t)),
|
||||
ret>>2);*/
|
||||
|
||||
/* 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;
|
||||
// printf("Received %d samples, timestamp = %d\n",bytes_received>>2,*(int32_t*)timestamp);
|
||||
|
||||
return nsamps;
|
||||
|
||||
}
|
||||
/******************* interface level options *************************/
|
||||
else if (option==MTU_SIZE) { /* change MTU of the eth interface */
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
strncpy(ifr.ifr_name,if_name, sizeof(ifr.ifr_name));
|
||||
ifr.ifr_mtu =8960;
|
||||
if (ioctl(eth->sockfd[Mod_id],SIOCSIFMTU,(caddr_t)&ifr) < 0 )
|
||||
perror ("[ETHERNET] Can't set the MTU");
|
||||
else
|
||||
printf("[ETHERNET] %s MTU size has changed to %d\n",DEFAULT_IF,ifr.ifr_mtu);
|
||||
} else if (option==TX_Q_LEN) { /* change TX queue length of eth interface */
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
strncpy(ifr.ifr_name,if_name, sizeof(ifr.ifr_name));
|
||||
ifr.ifr_qlen =3000 ;
|
||||
if (ioctl(eth->sockfd[Mod_id],SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 )
|
||||
perror ("[ETHERNET] Can't set the txqueuelen");
|
||||
else
|
||||
printf("[ETHERNET] %s txqueuelen size has changed to %d\n",DEFAULT_IF,ifr.ifr_qlen);
|
||||
|
||||
int trx_eth_start(openair0_device *device){
|
||||
|
||||
if (ethernet_socket_init(device)!=0) {
|
||||
return -1;
|
||||
|
||||
/******************* device level options *************************/
|
||||
} else if (option==COALESCE_PAR) {
|
||||
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs 3",DEFAULT_IF) > 0) {
|
||||
system(system_cmd);
|
||||
printf("[ETHERNET] Coalesce parameters %s\n",system_cmd);
|
||||
} else {
|
||||
perror("[ETHERNET] Can't set coalesce parameters\n");
|
||||
}
|
||||
|
||||
} else if (option==PAUSE_PAR ) {
|
||||
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",DEFAULT_IF) > 0) {
|
||||
system(system_cmd);
|
||||
printf("[ETHERNET] Pause parameters %s\n",system_cmd);
|
||||
} else {
|
||||
perror("[ETHERNET] Can't set pause parameters\n");
|
||||
}
|
||||
} else if (option==RING_PAR ) {
|
||||
if (snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s rx 4096 tx 4096",DEFAULT_IF) > 0) {
|
||||
system(system_cmd);
|
||||
printf("[ETHERNET] Ring parameters %s\n",system_cmd);
|
||||
} else {
|
||||
perror("[ETHERNET] Can't set ring parameters\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (device->func_type == BBU_FUNC ) {
|
||||
return trx_eth_set_dev_conf(device);
|
||||
}
|
||||
else{
|
||||
return trx_eth_get_dev_conf(device);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int trx_eth_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int antenna_id, int flags) {
|
||||
|
||||
return ethernet_write_data(device,timestamp,buff,nsamps,antenna_id);
|
||||
}
|
||||
|
||||
int trx_eth_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int antenna_id) {
|
||||
|
||||
return(ethernet_read_data(device,ptimestamp,buff,nsamps,antenna_id));
|
||||
|
||||
}
|
||||
|
||||
int trx_eth_stop(int card) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
int trx_eth_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
int trx_eth_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int trx_eth_get_stats(openair0_device* device) {
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
int trx_eth_reset_stats(openair0_device* device) {
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
int openair0_set_gains(openair0_device* device,
|
||||
openair0_config_t *openair0_cfg) {
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg, int dummy) {
|
||||
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void trx_eth_end(openair0_device *device) {
|
||||
|
||||
eth_state_t *eth = (eth_state_t*)device->priv;
|
||||
int Mod_id = device->Mod_id;
|
||||
/*destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */
|
||||
if ( close(eth->sockfd[Mod_id]) <0 ) {
|
||||
perror("ETHERNET: Failed to close socket");
|
||||
exit(0);
|
||||
}else {
|
||||
printf("[RRH] socket for mod_id %d has been successfully closed.",Mod_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg){
|
||||
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
|
||||
eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t));
|
||||
int card = 0;
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
#include <netinet/ether.h>
|
||||
|
||||
#define MAX_INST 4
|
||||
#define DEFAULT_IF "eth0"
|
||||
#define DEFAULT_IF "lo"
|
||||
#define BUF_SIZ 8960 /*Jumbo frame size*/
|
||||
|
||||
typedef struct {
|
||||
@@ -103,21 +103,51 @@ struct eth_meta_data{
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*!\brief packet header */
|
||||
typedef struct {
|
||||
/* packet's timestamp */
|
||||
/*!\brief packet's timestamp */
|
||||
openair0_timestamp timestamp;
|
||||
/* variable declared for alignment purposes (sample size=32 bit) */
|
||||
/*!\brief variable declared for alignment purposes (sample size=32 bit) */
|
||||
int16_t not_used;
|
||||
/* antenna port used to resynchronize*/
|
||||
/*!\brief antenna port used to resynchronize */
|
||||
int16_t antenna_id;
|
||||
} header_t;
|
||||
|
||||
/*!\brief different options for ethernet tuning in socket and driver level */
|
||||
typedef enum {
|
||||
MIN_OPT = 0,
|
||||
/*!\brief socket send buffer size in bytes */
|
||||
SND_BUF_SIZE,
|
||||
/*!\brief socket receive buffer size in bytes */
|
||||
RCV_BUF_SIZE,
|
||||
/*!\brief receiving timeout */
|
||||
RCV_TIMEOUT,
|
||||
/*!\brief sending timeout */
|
||||
SND_TIMEOUT,
|
||||
/*!\brief maximun transmission unit size in bytes */
|
||||
MTU_SIZE,
|
||||
/*!\brief TX queue length */
|
||||
TX_Q_LEN,
|
||||
/*!\brief RX/TX ring parameters of ethernet device */
|
||||
RING_PAR,
|
||||
/*!\brief interruptions coalesence mechanism of ethernet device */
|
||||
COALESCE_PAR,
|
||||
/*!\brief pause parameters of ethernet device */
|
||||
PAUSE_PAR,
|
||||
MAX_OPT
|
||||
} eth_opt_t;
|
||||
|
||||
|
||||
int ethernet_socket_init(openair0_device *device);
|
||||
|
||||
int ethernet_write_data(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id);
|
||||
|
||||
int ethernet_read_data(openair0_device *device,openair0_timestamp *timestamp,void **buff, int nsamps,int antenna_id);
|
||||
|
||||
void ethernet_socket_opt (openair0_device *device);
|
||||
/*! \fn int ethernet_tune (openair0_device *device, eth_opt_t option)
|
||||
* \brief this function allows you to configure certain ethernet parameters in socket or device level
|
||||
* \param[in] openair0 device which bears the socket
|
||||
* \param[in] name of parameter to configure
|
||||
* \return 0 on success, otherwise -1
|
||||
* \note
|
||||
* @ingroup _oai
|
||||
*/
|
||||
int ethernet_tune (openair0_device *device, eth_opt_t option);
|
||||
int ethernet_write_data(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc) ;
|
||||
int ethernet_read_data(openair0_device *device,openair0_timestamp *timestamp,void **buff, int nsamps,int cc);
|
||||
|
||||
@@ -247,7 +247,7 @@ int openair0_stop_without_reset(int card)
|
||||
#define MY_RF_MODE (RXEN + TXEN + TXLPFNORM + TXLPFEN + TXLPF25 + RXLPFNORM + RXLPFEN + RXLPF25 + LNA1ON +LNAMax + RFBBNORM + DMAMODE_RX + DMAMODE_TX)
|
||||
#define RF_MODE_BASE (LNA1ON + RFBBNORM)
|
||||
|
||||
int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
|
||||
// Initialize card
|
||||
// exmimo_config_t *p_exmimo_config;
|
||||
|
||||
@@ -154,7 +154,6 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
|
||||
|
||||
static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc)
|
||||
{
|
||||
|
||||
usrp_state_t *s = (usrp_state_t*)device->priv;
|
||||
int samples_received=0,i,j;
|
||||
int nsamps2; // aligned to upper 32 or 16 byte boundary
|
||||
@@ -182,31 +181,26 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
|
||||
// receive a single channel (e.g. from connector RF A)
|
||||
samples_received = s->rx_stream->recv(buff_tmp[0], nsamps, s->rx_md);
|
||||
}
|
||||
|
||||
|
||||
// bring RX data into 12 LSBs for softmodem RX
|
||||
for (int i=0;i<cc;i++) {
|
||||
for (int j=0; j<nsamps2; j++) {
|
||||
for (int j=0; j<nsamps2; j++) {
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
#ifdef __AVX2__
|
||||
|
||||
((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4);
|
||||
|
||||
#else
|
||||
((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4);
|
||||
|
||||
#endif
|
||||
#elif defined(__arm__)
|
||||
|
||||
((int16x8_t*)buff[i])[j] = vshrq_n_s16(buff_tmp[i][j],4);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (samples_received < nsamps) {
|
||||
printf("[recv] received %d samples out of %d\n",samples_received,nsamps);
|
||||
|
||||
}
|
||||
|
||||
//handle the error code
|
||||
switch(s->rx_md.error_code){
|
||||
case uhd::rx_metadata_t::ERROR_CODE_NONE:
|
||||
@@ -225,6 +219,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
|
||||
s->rx_count += nsamps;
|
||||
s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate);
|
||||
*ptimestamp = s->rx_timestamp;
|
||||
|
||||
return samples_received;
|
||||
}
|
||||
|
||||
@@ -334,7 +329,7 @@ int trx_usrp_reset_stats(openair0_device* device) {
|
||||
}
|
||||
|
||||
|
||||
int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg)
|
||||
int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg)
|
||||
{
|
||||
uhd::set_thread_priority_safe(1.0);
|
||||
usrp_state_t *s = (usrp_state_t*)malloc(sizeof(usrp_state_t));
|
||||
@@ -499,6 +494,5 @@ int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cf
|
||||
s->tx_forward_nsamps = 90;
|
||||
if(is_equal(s->sample_rate, (double)7.68e6))
|
||||
s->tx_forward_nsamps = 50;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user