Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
常顺宇
OpenXG-RAN
Commits
e1aed5af
Commit
e1aed5af
authored
Aug 16, 2016
by
Laurent Thomas
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix nettle, gnutls to use latest API version, fix eth_raw interface with errno==EAGAIN
parent
d14ed1d5
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
375 additions
and
435 deletions
+375
-435
cmake_targets/tools/build_helper
cmake_targets/tools/build_helper
+0
-61
targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
+1
-0
targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
+374
-374
No files found.
cmake_targets/tools/build_helper
View file @
e1aed5af
...
...
@@ -172,57 +172,6 @@ compilations() {
# External packages installers
############################################
install_nettle_from_source() {
nettle_install_log=$OPENAIR_DIR/cmake_targets/log/nettle_install_log.txt
echo_info "\nInstalling Nettle. The log file for nettle installation is here: $nettle_install_log "
(
cd /tmp
echo "Downloading nettle archive"
$SUDO rm -rf /tmp/nettle-2.5.tar.gz* /tmp/nettle-2.5
wget https://ftp.gnu.org/gnu/nettle/nettle-2.5.tar.gz
if [ $? -ne 0 ]; then
wget ftp://ftp.lysator.liu.se/pub/security/lsh/nettle-2.5.tar.gz
fi
if [ ! -f nettle-2.5.tar.gz ]; then
echo_error "Could not download nettle source files"
cd -
return
fi
tar -xzf nettle-2.5.tar.gz
cd nettle-2.5/
./configure --disable-openssl --enable-shared --prefix=/usr
echo "Compiling nettle"
make -j`nproc`
make check
$SUDO make install
) >& $nettle_install_log
}
install_gnutls_from_source(){
gnutls_install_log=$OPENAIR_DIR/cmake_targets/log/gnutls_install_log.txt
echo_info "\nInstalling Gnutls. The log file for Gnutls installation is here: $gnutls_install_log "
(
cd /tmp
echo "Downloading gnutls archive"
$SUDO rm -rf /tmp/gnutls-3.1.23.tar.xz* /tmp/gnutls-3.1.23
wget http://mirrors.dotsrc.org/gcrypt/gnutls/v3.1/gnutls-3.1.23.tar.xz || \
wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.1/gnutls-3.1.23.tar.xz
if [ ! -f gnutls-3.1.23.tar.xz ]; then
echo_error "Could not download gnutls source files"
cd -
return
fi
tar -xJf gnutls-3.1.23.tar.xz
cd gnutls-3.1.23/
./configure --prefix=/usr
echo "Compiling gnutls"
make -j`nproc`
$SUDO make install
)>& $gnutls_install_log
}
check_install_usrp_uhd_driver(){
#first we remove old installation
$SUDO apt-get remove -y uhd || true
...
...
@@ -384,17 +333,7 @@ check_install_oai_software() {
wget
$SUDO update-alternatives --set liblapack.so /usr/lib/atlas-base/atlas/liblapack.so
# First we remove gnutls/nettle installation and then install from sources
v=$(lsb_release -ris | tr -d '\n')
if [ "$v" == Ubuntu16.04 ] ; then
$SUDO apt-get install libgnutls-dev nettle-dev nettle-bin
else
$SUDO apt-get remove -y libgnutls-dev nettle-dev nettle-bin
install_nettle_from_source
install_gnutls_from_source
fi
install_asn1c_from_source
}
...
...
targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
View file @
e1aed5af
...
...
@@ -271,6 +271,7 @@ int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, voi
if
(
bytes_received
==-
1
)
{
eth
->
num_rx_errors
++
;
perror
(
"ETHERNET IF5 READ: "
);
if
(
errno
==
EAGAIN
)
continue
;
exit
(
-
1
);
}
else
{
/* store the timestamp value from packet's header */
...
...
targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
View file @
e1aed5af
...
...
@@ -26,7 +26,7 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file ethernet_lib.c
/*! \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
...
...
@@ -34,7 +34,7 @@
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning
* \warning
*/
#include <arpa/inet.h>
...
...
@@ -59,366 +59,366 @@ int dest_addr_len[MAX_INST];
int
trx_eth_start
(
openair0_device
*
device
)
{
eth_state_t
*
eth
=
(
eth_state_t
*
)
device
->
priv
;
/* initialize socket */
if
(
eth
->
flags
==
ETH_RAW_MODE
)
{
printf
(
"Setting ETHERNET to ETH_RAW_IF5_MODE
\n
"
);
if
(
eth_socket_init_raw
(
device
)
!=
0
)
return
-
1
;
/* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
if
(
device
->
host_type
==
BBU_HOST
)
{
if
(
eth_set_dev_conf_raw
(
device
)
!=
0
)
return
-
1
;
}
else
{
if
(
eth_get_dev_conf_raw
(
device
)
!=
0
)
return
-
1
;
}
/* adjust MTU wrt number of samples per packet */
if
(
ethernet_tune
(
device
,
MTU_SIZE
,
RAW_PACKET_SIZE_BYTES
(
device
->
openair0_cfg
->
samples_per_packet
))
!=
0
)
return
-
1
;
if
(
ethernet_tune
(
device
,
RCV_TIMEOUT
,
999999
)
!=
0
)
return
-
1
;
}
else
if
(
eth
->
flags
==
ETH_RAW_IF4p5_MODE
)
{
printf
(
"Setting ETHERNET to ETH_RAW_IF4p5_MODE
\n
"
);
if
(
eth_socket_init_raw
(
device
)
!=
0
)
return
-
1
;
/* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
if
(
device
->
host_type
==
BBU_HOST
)
{
if
(
eth_set_dev_conf_raw_IF4p5
(
device
)
!=
0
)
return
-
1
;
eth_state_t
*
eth
=
(
eth_state_t
*
)
device
->
priv
;
/* initialize socket */
if
(
eth
->
flags
==
ETH_RAW_MODE
)
{
printf
(
"Setting ETHERNET to ETH_RAW_IF5_MODE
\n
"
);
if
(
eth_socket_init_raw
(
device
)
!=
0
)
return
-
1
;
/* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
if
(
device
->
host_type
==
BBU_HOST
)
{
if
(
eth_set_dev_conf_raw
(
device
)
!=
0
)
return
-
1
;
}
else
{
if
(
eth_get_dev_conf_raw
(
device
)
!=
0
)
return
-
1
;
}
/* adjust MTU wrt number of samples per packet */
if
(
ethernet_tune
(
device
,
MTU_SIZE
,
RAW_PACKET_SIZE_BYTES
(
device
->
openair0_cfg
->
samples_per_packet
))
!=
0
)
return
-
1
;
if
(
ethernet_tune
(
device
,
RCV_TIMEOUT
,
999999
)
!=
0
)
return
-
1
;
}
else
if
(
eth
->
flags
==
ETH_RAW_IF4p5_MODE
)
{
printf
(
"Setting ETHERNET to ETH_RAW_IF4p5_MODE
\n
"
);
if
(
eth_socket_init_raw
(
device
)
!=
0
)
return
-
1
;
/* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
if
(
device
->
host_type
==
BBU_HOST
)
{
if
(
eth_set_dev_conf_raw_IF4p5
(
device
)
!=
0
)
return
-
1
;
}
else
{
if
(
eth_get_dev_conf_raw_IF4p5
(
device
)
!=
0
)
return
-
1
;
}
/* adjust MTU wrt number of samples per packet */
if
(
ethernet_tune
(
device
,
MTU_SIZE
,
RAW_IF4p5_PRACH_SIZE_BYTES
)
!=
0
)
return
-
1
;
if
(
ethernet_tune
(
device
,
RCV_TIMEOUT
,
999999
)
!=
0
)
return
-
1
;
}
else
if
(
eth
->
flags
==
ETH_UDP_IF4p5_MODE
)
{
printf
(
"Setting ETHERNET to UDP_IF4p5_MODE
\n
"
);
if
(
eth_socket_init_udp
(
device
)
!=
0
)
return
-
1
;
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
;
}
}
else
if
(
eth
->
flags
==
ETH_RAW_IF5_MOBIPASS
)
{
printf
(
"Setting ETHERNET to RAW_IF5_MODE
\n
"
);
if
(
eth_socket_init_raw
(
device
)
!=
0
)
return
-
1
;
}
else
{
if
(
eth_get_dev_conf_raw_IF4p5
(
device
)
!=
0
)
return
-
1
;
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
,
RAW_IF4p5_PRACH_SIZE_BYTES
)
!=
0
)
return
-
1
;
/* apply additional configuration */
if
(
ethernet_tune
(
device
,
SND_BUF_SIZE
,
2000000000
)
!=
0
)
return
-
1
;
if
(
ethernet_tune
(
device
,
RCV_BUF_SIZE
,
2000000000
)
!=
0
)
return
-
1
;
if
(
ethernet_tune
(
device
,
RCV_TIMEOUT
,
999999
)
!=
0
)
return
-
1
;
}
else
if
(
eth
->
flags
==
ETH_UDP_IF4p5_MODE
)
{
printf
(
"Setting ETHERNET to UDP_IF4p5_MODE
\n
"
);
if
(
eth_socket_init_udp
(
device
)
!=
0
)
return
-
1
;
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
;
}
}
else
if
(
eth
->
flags
==
ETH_RAW_IF5_MOBIPASS
)
{
printf
(
"Setting ETHERNET to RAW_IF5_MODE
\n
"
);
if
(
eth_socket_init_raw
(
device
)
!=
0
)
return
-
1
;
}
else
{
if
(
eth_socket_init_udp
(
device
)
!=
0
)
return
-
1
;
/* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
if
(
device
->
host_type
==
BBU_HOST
)
{
if
(
eth_set_dev_conf_udp
(
device
)
!=
0
)
return
-
1
;
}
else
{
if
(
eth_get_dev_conf_udp
(
device
)
!=
0
)
return
-
1
;
}
}
/* apply additional configuration */
if
(
ethernet_tune
(
device
,
SND_BUF_SIZE
,
2000000000
)
!=
0
)
return
-
1
;
if
(
ethernet_tune
(
device
,
RCV_BUF_SIZE
,
2000000000
)
!=
0
)
return
-
1
;
return
0
;
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
(
"[%s] socket for mod_id %d has been successfully closed.
\n
"
,(
device
->
host_type
==
BBU_HOST
)
?
"BBU"
:
"RRH"
,
Mod_id
);
}
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
(
"[%s] socket for mod_id %d has been successfully closed.
\n
"
,(
device
->
host_type
==
BBU_HOST
)
?
"BBU"
:
"RRH"
,
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
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
;
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
;
}
int
trx_eth_stop
(
openair0_device
*
device
)
{
return
(
0
);
return
(
0
);
}
int
trx_eth_set_freq
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
,
int
exmimo_dump_config
)
{
return
(
0
);
return
(
0
);
}
int
trx_eth_set_gains
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
)
{
return
(
0
);
return
(
0
);
}
int
trx_eth_get_stats
(
openair0_device
*
device
)
{
return
(
0
);
return
(
0
);
}
int
trx_eth_reset_stats
(
openair0_device
*
device
)
{
return
(
0
);
return
(
0
);
}
int
ethernet_tune
(
openair0_device
*
device
,
unsigned
int
option
,
int
value
)
{
eth_state_t
*
eth
=
(
eth_state_t
*
)
device
->
priv
;
int
Mod_id
=
device
->
Mod_id
;
struct
timeval
timeout
;
struct
ifreq
ifr
;
char
system_cmd
[
256
];
// char* if_name=DEFAULT_IF;
// struct in_addr ia;
// struct if_nameindex *ids;
int
ret
=
0
;
// int i=0;
/****************** socket level options ************************/
switch
(
option
)
{
case
SND_BUF_SIZE
:
/* transmit socket buffer size */
if
(
setsockopt
(
eth
->
sockfd
[
Mod_id
],
SOL_SOCKET
,
SO_SNDBUF
,
&
value
,
sizeof
(
value
)))
{
perror
(
"[ETHERNET] setsockopt()"
);
}
else
{
printf
(
"send buffer size= %d bytes
\n
"
,
value
);
}
break
;
case
RCV_BUF_SIZE
:
/* receive socket buffer size */
if
(
setsockopt
(
eth
->
sockfd
[
Mod_id
],
SOL_SOCKET
,
SO_RCVBUF
,
&
value
,
sizeof
(
value
)))
{
perror
(
"[ETHERNET] setsockopt()"
);
}
else
{
printf
(
"receive bufffer size= %d bytes
\n
"
,
value
);
}
break
;
case
RCV_TIMEOUT
:
timeout
.
tv_sec
=
value
/
1000000
;
timeout
.
tv_usec
=
value
%
1000000
;
//less than rt_period?
if
(
setsockopt
(
eth
->
sockfd
[
Mod_id
],
SOL_SOCKET
,
SO_RCVTIMEO
,
(
char
*
)
&
timeout
,
sizeof
(
timeout
)))
{
perror
(
"[ETHERNET] setsockopt()"
);
}
else
{
printf
(
"receive timeout= %u usec
\n
"
,(
unsigned
int
)
timeout
.
tv_usec
);
}
break
;
case
SND_TIMEOUT
:
timeout
.
tv_sec
=
value
/
1000000000
;
timeout
.
tv_usec
=
value
%
1000000000
;
//less than rt_period?
if
(
setsockopt
(
eth
->
sockfd
[
Mod_id
],
SOL_SOCKET
,
SO_SNDTIMEO
,
(
char
*
)
&
timeout
,
sizeof
(
timeout
)))
{
perror
(
"[ETHERNET] setsockopt()"
);
}
else
{
printf
(
"send timeout= %d,%d sec
\n
"
,(
int
)
timeout
.
tv_sec
,(
int
)
timeout
.
tv_usec
);
}
break
;
eth_state_t
*
eth
=
(
eth_state_t
*
)
device
->
priv
;
int
Mod_id
=
device
->
Mod_id
;
struct
timeval
timeout
;
struct
ifreq
ifr
;
char
system_cmd
[
256
];
// char* if_name=DEFAULT_IF;
// struct in_addr ia;
// struct if_nameindex *ids;
int
ret
=
0
;
// int i=0;
/****************** socket level options ************************/
switch
(
option
)
{
case
SND_BUF_SIZE
:
/* transmit socket buffer size */
if
(
setsockopt
(
eth
->
sockfd
[
Mod_id
],
SOL_SOCKET
,
SO_SNDBUF
,
&
value
,
sizeof
(
value
)))
{
perror
(
"[ETHERNET] setsockopt()"
);
}
else
{
printf
(
"send buffer size= %d bytes
\n
"
,
value
);
}
break
;
case
RCV_BUF_SIZE
:
/* receive socket buffer size */
if
(
setsockopt
(
eth
->
sockfd
[
Mod_id
],
SOL_SOCKET
,
SO_RCVBUF
,
&
value
,
sizeof
(
value
)))
{
perror
(
"[ETHERNET] setsockopt()"
);
}
else
{
printf
(
"receive bufffer size= %d bytes
\n
"
,
value
);
}
break
;
case
RCV_TIMEOUT
:
timeout
.
tv_sec
=
value
/
1000000
;
timeout
.
tv_usec
=
value
%
1000000
;
//less than rt_period?
if
(
setsockopt
(
eth
->
sockfd
[
Mod_id
],
SOL_SOCKET
,
SO_RCVTIMEO
,
(
char
*
)
&
timeout
,
sizeof
(
timeout
)))
{
perror
(
"[ETHERNET] setsockopt()"
);
}
else
{
printf
(
"receive timeout= %u usec
\n
"
,(
unsigned
int
)
timeout
.
tv_usec
);
}
break
;
case
SND_TIMEOUT
:
timeout
.
tv_sec
=
value
/
1000000000
;
timeout
.
tv_usec
=
value
%
1000000000
;
//less than rt_period?
if
(
setsockopt
(
eth
->
sockfd
[
Mod_id
],
SOL_SOCKET
,
SO_SNDTIMEO
,
(
char
*
)
&
timeout
,
sizeof
(
timeout
)))
{
perror
(
"[ETHERNET] setsockopt()"
);
}
else
{
printf
(
"send timeout= %d,%d sec
\n
"
,(
int
)
timeout
.
tv_sec
,(
int
)
timeout
.
tv_usec
);
}
break
;
/******************* interface level options *************************/
case
MTU_SIZE
:
/* change MTU of the eth interface */
ifr
.
ifr_addr
.
sa_family
=
AF_INET
;
strncpy
(
ifr
.
ifr_name
,
eth
->
if_name
[
Mod_id
],
sizeof
(
ifr
.
ifr_name
));
ifr
.
ifr_mtu
=
value
;
if
(
ioctl
(
eth
->
sockfd
[
Mod_id
],
SIOCSIFMTU
,(
caddr_t
)
&
ifr
)
<
0
)
perror
(
"[ETHERNET] Can't set the MTU"
);
else
printf
(
"[ETHERNET] %s MTU size has changed to %d
\n
"
,
eth
->
if_name
[
Mod_id
],
ifr
.
ifr_mtu
);
break
;
case
TX_Q_LEN
:
/* change TX queue length of eth interface */
ifr
.
ifr_addr
.
sa_family
=
AF_INET
;
strncpy
(
ifr
.
ifr_name
,
eth
->
if_name
[
Mod_id
],
sizeof
(
ifr
.
ifr_name
));
ifr
.
ifr_qlen
=
value
;
if
(
ioctl
(
eth
->
sockfd
[
Mod_id
],
SIOCSIFTXQLEN
,(
caddr_t
)
&
ifr
)
<
0
)
perror
(
"[ETHERNET] Can't set the txqueuelen"
);
else
printf
(
"[ETHERNET] %s txqueuelen size has changed to %d
\n
"
,
eth
->
if_name
[
Mod_id
],
ifr
.
ifr_qlen
);
break
;
case
MTU_SIZE
:
/* change MTU of the eth interface */
ifr
.
ifr_addr
.
sa_family
=
AF_INET
;
strncpy
(
ifr
.
ifr_name
,
eth
->
if_name
[
Mod_id
],
sizeof
(
ifr
.
ifr_name
));
ifr
.
ifr_mtu
=
value
;
if
(
ioctl
(
eth
->
sockfd
[
Mod_id
],
SIOCSIFMTU
,(
caddr_t
)
&
ifr
)
<
0
)
perror
(
"[ETHERNET] Can't set the MTU"
);
else
printf
(
"[ETHERNET] %s MTU size has changed to %d
\n
"
,
eth
->
if_name
[
Mod_id
],
ifr
.
ifr_mtu
);
break
;
case
TX_Q_LEN
:
/* change TX queue length of eth interface */
ifr
.
ifr_addr
.
sa_family
=
AF_INET
;
strncpy
(
ifr
.
ifr_name
,
eth
->
if_name
[
Mod_id
],
sizeof
(
ifr
.
ifr_name
));
ifr
.
ifr_qlen
=
value
;
if
(
ioctl
(
eth
->
sockfd
[
Mod_id
],
SIOCSIFTXQLEN
,(
caddr_t
)
&
ifr
)
<
0
)
perror
(
"[ETHERNET] Can't set the txqueuelen"
);
else
printf
(
"[ETHERNET] %s txqueuelen size has changed to %d
\n
"
,
eth
->
if_name
[
Mod_id
],
ifr
.
ifr_qlen
);
break
;
/******************* device level options *************************/
case
COALESCE_PAR
:
ret
=
snprintf
(
system_cmd
,
sizeof
(
system_cmd
),
"ethtool -C %s rx-usecs %d"
,
eth
->
if_name
[
Mod_id
],
value
);
if
(
ret
>
0
)
{
ret
=
system
(
system_cmd
);
if
(
ret
==
-
1
)
{
fprintf
(
stderr
,
"[ETHERNET] Can't start shell to execute %s %s"
,
system_cmd
,
strerror
(
errno
));
}
else
{
printf
(
"[ETHERNET] status of %s is %i
\n
"
,
WEXITSTATUS
(
ret
));
}
printf
(
"[ETHERNET] Coalesce parameters %s
\n
"
,
system_cmd
);
}
else
{
perror
(
"[ETHERNET] Can't set coalesce parameters
\n
"
);
case
COALESCE_PAR
:
ret
=
snprintf
(
system_cmd
,
sizeof
(
system_cmd
),
"ethtool -C %s rx-usecs %d"
,
eth
->
if_name
[
Mod_id
],
value
);
if
(
ret
>
0
)
{
ret
=
system
(
system_cmd
);
if
(
ret
==
-
1
)
{
fprintf
(
stderr
,
"[ETHERNET] Can't start shell to execute %s %s"
,
system_cmd
,
strerror
(
errno
));
}
else
{
printf
(
"[ETHERNET] status of %s is %i
\n
"
,
WEXITSTATUS
(
ret
));
}
printf
(
"[ETHERNET] Coalesce parameters %s
\n
"
,
system_cmd
);
}
else
{
perror
(
"[ETHERNET] Can't set coalesce parameters
\n
"
);
}
break
;
case
PAUSE_PAR
:
if
(
value
==
1
)
ret
=
snprintf
(
system_cmd
,
sizeof
(
system_cmd
),
"ethtool -A %s autoneg off rx off tx off"
,
eth
->
if_name
[
Mod_id
]);
else
if
(
value
==
0
)
ret
=
snprintf
(
system_cmd
,
sizeof
(
system_cmd
),
"ethtool -A %s autoneg on rx on tx on"
,
eth
->
if_name
[
Mod_id
]);
else
break
;
if
(
ret
>
0
)
{
ret
=
system
(
system_cmd
);
if
(
ret
==
-
1
)
{
fprintf
(
stderr
,
"[ETHERNET] Can't start shell to execute %s %s"
,
system_cmd
,
strerror
(
errno
));
}
else
{
printf
(
"[ETHERNET] status of %s is %i
\n
"
,
WEXITSTATUS
(
ret
));
}
printf
(
"[ETHERNET] Pause parameters %s
\n
"
,
system_cmd
);
}
else
{
perror
(
"[ETHERNET] Can't set pause parameters
\n
"
);
}
break
;
case
RING_PAR
:
ret
=
snprintf
(
system_cmd
,
sizeof
(
system_cmd
),
"ethtool -G %s val %d"
,
eth
->
if_name
[
Mod_id
],
value
);
if
(
ret
>
0
)
{
ret
=
system
(
system_cmd
);
if
(
ret
==
-
1
)
{
fprintf
(
stderr
,
"[ETHERNET] Can't start shell to execute %s %s"
,
system_cmd
,
strerror
(
errno
));
}
else
{
printf
(
"[ETHERNET] status of %s is %i
\n
"
,
WEXITSTATUS
(
ret
));
}
printf
(
"[ETHERNET] Ring parameters %s
\n
"
,
system_cmd
);
}
else
{
perror
(
"[ETHERNET] Can't set ring parameters
\n
"
);
}
break
;
default:
break
;
}
break
;
case
PAUSE_PAR
:
if
(
value
==
1
)
ret
=
snprintf
(
system_cmd
,
sizeof
(
system_cmd
),
"ethtool -A %s autoneg off rx off tx off"
,
eth
->
if_name
[
Mod_id
]);
else
if
(
value
==
0
)
ret
=
snprintf
(
system_cmd
,
sizeof
(
system_cmd
),
"ethtool -A %s autoneg on rx on tx on"
,
eth
->
if_name
[
Mod_id
]);
else
break
;
if
(
ret
>
0
)
{
ret
=
system
(
system_cmd
);
if
(
ret
==
-
1
)
{
fprintf
(
stderr
,
"[ETHERNET] Can't start shell to execute %s %s"
,
system_cmd
,
strerror
(
errno
));
}
else
{
printf
(
"[ETHERNET] status of %s is %i
\n
"
,
WEXITSTATUS
(
ret
));
}
printf
(
"[ETHERNET] Pause parameters %s
\n
"
,
system_cmd
);
return
0
;
}
int
transport_init
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
,
eth_params_t
*
eth_params
)
{
eth_state_t
*
eth
=
(
eth_state_t
*
)
malloc
(
sizeof
(
eth_state_t
));
memset
(
eth
,
0
,
sizeof
(
eth_state_t
));
if
(
eth_params
->
transp_preference
==
1
)
{
eth
->
flags
=
ETH_RAW_MODE
;
}
else
if
(
eth_params
->
transp_preference
==
0
)
{
eth
->
flags
=
ETH_UDP_MODE
;
}
else
if
(
eth_params
->
transp_preference
==
3
)
{
eth
->
flags
=
ETH_RAW_IF4p5_MODE
;
}
else
if
(
eth_params
->
transp_preference
==
2
)
{
eth
->
flags
=
ETH_UDP_IF4p5_MODE
;
}
else
if
(
eth_params
->
transp_preference
==
4
)
{
eth
->
flags
=
ETH_RAW_IF5_MOBIPASS
;
}
else
{
perror
(
"[ETHERNET] Can't set pause parameters
\n
"
);
printf
(
"transport_init: Unknown transport preference %d - default to RAW"
,
eth_params
->
transp_preference
);
eth
->
flags
=
ETH_RAW_MODE
;
}
break
;
case
RING_PAR
:
ret
=
snprintf
(
system_cmd
,
sizeof
(
system_cmd
),
"ethtool -G %s val %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]: Initializing openair0_device for %s ...
\n
"
,
((
device
->
host_type
==
BBU_HOST
)
?
"BBU"
:
"RRH"
));
device
->
Mod_id
=
num_devices_eth
++
;
device
->
transp_type
=
ETHERNET_TP
;
device
->
trx_start_func
=
trx_eth_start
;
device
->
trx_request_func
=
trx_eth_request
;
device
->
trx_reply_func
=
trx_eth_reply
;
device
->
trx_get_stats_func
=
trx_eth_get_stats
;
device
->
trx_reset_stats_func
=
trx_eth_reset_stats
;
device
->
trx_end_func
=
trx_eth_end
;
device
->
trx_stop_func
=
trx_eth_stop
;
device
->
trx_set_freq_func
=
trx_eth_set_freq
;
device
->
trx_set_gains_func
=
trx_eth_set_gains
;
if
(
eth
->
flags
==
ETH_RAW_MODE
)
{
device
->
trx_write_func
=
trx_eth_write_raw
;
device
->
trx_read_func
=
trx_eth_read_raw
;
}
else
if
(
eth
->
flags
==
ETH_UDP_MODE
)
{
device
->
trx_write_func
=
trx_eth_write_udp
;
device
->
trx_read_func
=
trx_eth_read_udp
;
}
else
if
(
eth
->
flags
==
ETH_RAW_IF4p5_MODE
)
{
device
->
trx_write_func
=
trx_eth_write_raw_IF4p5
;
device
->
trx_read_func
=
trx_eth_read_raw_IF4p5
;
}
else
if
(
eth
->
flags
==
ETH_UDP_IF4p5_MODE
)
{
device
->
trx_write_func
=
trx_eth_write_udp_IF4p5
;
device
->
trx_read_func
=
trx_eth_read_udp_IF4p5
;
}
else
if
(
eth
->
flags
==
ETH_RAW_IF5_MOBIPASS
)
{
device
->
trx_write_func
=
trx_eth_write_raw_IF4p5
;
device
->
trx_read_func
=
trx_eth_read_raw_IF4p5
;
}
else
{
perror
(
"[ETHERNET] Can't set ring parameters
\n
"
);
//device->trx_write_func = trx_eth_write_udp_IF4p5;
//device->trx_read_func = trx_eth_read_udp_IF4p5;
}
break
;
default:
break
;
}
return
0
;
}
eth
->
if_name
[
device
->
Mod_id
]
=
eth_params
->
local_if_name
;
device
->
priv
=
eth
;
/* device specific */
openair0_cfg
[
0
].
iq_rxrescale
=
15
;
//rescale iqs
openair0_cfg
[
0
].
iq_txshift
=
eth_params
->
iq_txshift
;
// shift
openair0_cfg
[
0
].
tx_sample_advance
=
eth_params
->
tx_sample_advance
;
int
transport_init
(
openair0_device
*
device
,
openair0_config_t
*
openair0_cfg
,
eth_params_t
*
eth_params
)
{
eth_state_t
*
eth
=
(
eth_state_t
*
)
malloc
(
sizeof
(
eth_state_t
));
memset
(
eth
,
0
,
sizeof
(
eth_state_t
));
if
(
eth_params
->
transp_preference
==
1
)
{
eth
->
flags
=
ETH_RAW_MODE
;
}
else
if
(
eth_params
->
transp_preference
==
0
)
{
eth
->
flags
=
ETH_UDP_MODE
;
}
else
if
(
eth_params
->
transp_preference
==
3
)
{
eth
->
flags
=
ETH_RAW_IF4p5_MODE
;
}
else
if
(
eth_params
->
transp_preference
==
2
)
{
eth
->
flags
=
ETH_UDP_IF4p5_MODE
;
}
else
if
(
eth_params
->
transp_preference
==
4
)
{
eth
->
flags
=
ETH_RAW_IF5_MOBIPASS
;
}
else
{
printf
(
"transport_init: Unknown transport preference %d - default to RAW"
,
eth_params
->
transp_preference
);
eth
->
flags
=
ETH_RAW_MODE
;
}
printf
(
"[ETHERNET]: Initializing openair0_device for %s ...
\n
"
,
((
device
->
host_type
==
BBU_HOST
)
?
"BBU"
:
"RRH"
));
device
->
Mod_id
=
num_devices_eth
++
;
device
->
transp_type
=
ETHERNET_TP
;
device
->
trx_start_func
=
trx_eth_start
;
device
->
trx_request_func
=
trx_eth_request
;
device
->
trx_reply_func
=
trx_eth_reply
;
device
->
trx_get_stats_func
=
trx_eth_get_stats
;
device
->
trx_reset_stats_func
=
trx_eth_reset_stats
;
device
->
trx_end_func
=
trx_eth_end
;
device
->
trx_stop_func
=
trx_eth_stop
;
device
->
trx_set_freq_func
=
trx_eth_set_freq
;
device
->
trx_set_gains_func
=
trx_eth_set_gains
;
if
(
eth
->
flags
==
ETH_RAW_MODE
)
{
device
->
trx_write_func
=
trx_eth_write_raw
;
device
->
trx_read_func
=
trx_eth_read_raw
;
}
else
if
(
eth
->
flags
==
ETH_UDP_MODE
)
{
device
->
trx_write_func
=
trx_eth_write_udp
;
device
->
trx_read_func
=
trx_eth_read_udp
;
}
else
if
(
eth
->
flags
==
ETH_RAW_IF4p5_MODE
)
{
device
->
trx_write_func
=
trx_eth_write_raw_IF4p5
;
device
->
trx_read_func
=
trx_eth_read_raw_IF4p5
;
}
else
if
(
eth
->
flags
==
ETH_UDP_IF4p5_MODE
)
{
device
->
trx_write_func
=
trx_eth_write_udp_IF4p5
;
device
->
trx_read_func
=
trx_eth_read_udp_IF4p5
;
}
else
if
(
eth
->
flags
==
ETH_RAW_IF5_MOBIPASS
)
{
device
->
trx_write_func
=
trx_eth_write_raw_IF4p5
;
device
->
trx_read_func
=
trx_eth_read_raw_IF4p5
;
}
else
{
//device->trx_write_func = trx_eth_write_udp_IF4p5;
//device->trx_read_func = trx_eth_read_udp_IF4p5;
}
eth
->
if_name
[
device
->
Mod_id
]
=
eth_params
->
local_if_name
;
device
->
priv
=
eth
;
/* device specific */
openair0_cfg
[
0
].
iq_rxrescale
=
15
;
//rescale iqs
openair0_cfg
[
0
].
iq_txshift
=
eth_params
->
iq_txshift
;
// shift
openair0_cfg
[
0
].
tx_sample_advance
=
eth_params
->
tx_sample_advance
;
/* RRH does not have any information to make this configuration atm */
if
(
device
->
host_type
==
BBU_HOST
)
{
/*Note scheduling advance values valid only for case 7680000 */
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
case
30720000
:
openair0_cfg
[
0
].
samples_per_packet
=
3840
;
break
;
case
23040000
:
openair0_cfg
[
0
].
samples_per_packet
=
2880
;
break
;
case
15360000
:
openair0_cfg
[
0
].
samples_per_packet
=
1920
;
break
;
case
7680000
:
openair0_cfg
[
0
].
samples_per_packet
=
960
;
break
;
case
1920000
:
openair0_cfg
[
0
].
samples_per_packet
=
240
;
break
;
default:
printf
(
"Error: unknown sampling rate %f
\n
"
,
openair0_cfg
[
0
].
sample_rate
);
exit
(
-
1
);
break
;
/* RRH does not have any information to make this configuration atm */
if
(
device
->
host_type
==
BBU_HOST
)
{
/*Note scheduling advance values valid only for case 7680000 */
switch
((
int
)
openair0_cfg
[
0
].
sample_rate
)
{
case
30720000
:
openair0_cfg
[
0
].
samples_per_packet
=
3840
;
break
;
case
23040000
:
openair0_cfg
[
0
].
samples_per_packet
=
2880
;
break
;
case
15360000
:
openair0_cfg
[
0
].
samples_per_packet
=
1920
;
break
;
case
7680000
:
openair0_cfg
[
0
].
samples_per_packet
=
960
;
break
;
case
1920000
:
openair0_cfg
[
0
].
samples_per_packet
=
240
;
break
;
default:
printf
(
"Error: unknown sampling rate %f
\n
"
,
openair0_cfg
[
0
].
sample_rate
);
exit
(
-
1
);
break
;
}
}
}
device
->
openair0_cfg
=&
openair0_cfg
[
0
];
return
0
;
device
->
openair0_cfg
=&
openair0_cfg
[
0
];
return
0
;
}
...
...
@@ -426,85 +426,85 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth
* 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
);
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
;
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
(
" 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 (
\n
"
,
((
eth
->
flags
&
ETH_RAW_MODE
)
?
"RAW socket mode - "
:
""
),
((
eth
->
flags
&
ETH_UDP_MODE
)
?
"UDP socket mode - "
:
""
));
printf
(
" Number of iqs dumped when displaying packets: %i
\n\n
"
,
eth
->
iqdumpcnt
);
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
(
" 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 (
\n
"
,
((
eth
->
flags
&
ETH_RAW_MODE
)
?
"RAW socket mode - "
:
""
),
((
eth
->
flags
&
ETH_UDP_MODE
)
?
"UDP socket mode - "
:
""
));
printf
(
" Number of iqs dumped when displaying packets: %i
\n\n
"
,
eth
->
iqdumpcnt
);
}
void
inline
dump_txcounters
(
openair0_device
*
device
)
{
eth_state_t
*
eth
=
(
eth_state_t
*
)
device
->
priv
;
printf
(
" Ethernet device interface %i, tx counters:
\n
"
,
device
->
openair0_cfg
->
Mod_id
);
printf
(
" Sent packets: %llu send errors: %i
\n
"
,
(
long
long
unsigned
int
)
eth
->
tx_count
,
eth
->
num_tx_errors
);
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
"
,
(
long
long
unsigned
int
)
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
"
,
(
long
long
unsigned
int
)
eth
->
rx_count
,
eth
->
num_underflows
);
}
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
"
,
(
long
long
unsigned
int
)
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
);
}
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
"
:
" "
);
}
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
"
:
" "
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment