Commit e4e825e3 authored by Joanne Hugé's avatar Joanne Hugé Committed by Joanne Hugé

Reorganize files

parent fbb32c56
test-eNB/client private
test-eNB/server
*.swp *.swp
*.swo *.swo
*.so *.so
......
# SPDX-License-Identifier: BSD-3-Clause # SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2014 Intel Corporation # Copyright(c) 2010-2014 Intel Corporation
CC=gcc -m64 -msse4.1 CC=gcc -m64 -mavx2
CXX=g++ -m64 -msse4.1 CXX=g++ -m64 -mavx2
CFLAGS=-O2 -fno-strict-aliasing -Wall -pedantic CFLAGS=-O3 -fno-strict-aliasing -Wall -pedantic -g
CFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE CFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
CFLAGS +=-DALLOW_EXPERIMENTAL_API CFLAGS +=-DALLOW_EXPERIMENTAL_API
CFLAGS+=-MMD -g CFLAGS+=-MMD -g
......
USER = af_xdp
LIBBPF = ${HOME}/ecpri/xdp/libbpf-build/usr
SRCDIR = "."
SRCS = $(USER).c
OBJS = $(SRCS:%.c=%.o)
ifeq ($(DEBUG),)
CFLAGS = -O2
else
CFLAGS = -Og -g -Wall -Wextra
endif
CFLAGS += -MD -MP
CFLAGS += -I $(SRCDIR)
CFLAGS += -std=gnu99
LDFLAGS += -pthread -L$(LIBBPF)/lib64 -l:libbpf.a -lelf -lz
CFLAGS += -I $(LIBBPF)/include
vpath %.c $(SRCDIR)
$(USER): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $@
-include $(subst .c,.d,$(SRCS))
clean:
$(RM) -rf bin
$(RM) $(OBJS) $(USER) $(subst .c,.d,$(SRCS))
.PHONY: clean
This diff is collapsed.
#!/bin/bash
set -e
xdp_off() {
ip link set dev ens9f1np1 xdp off
}
tx_packets() {
ethtool -S ens9f1np1|grep -v ": 0"|grep "tx_packets:"|awk '{print $2;}';
}
xdp_off;
make clean && make;
A=$(tx_packets)
nice -n -20 chrt 99 ./af_xdp;
B=$(tx_packets)
echo "Ethtool tx packets sent: $((B -A))";
xdp_off;
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2014 Intel Corporation
CC=gcc -m64 -msse4.1
CXX=g++ -m64 -msse4.1
CFLAGS=-O2 -fno-strict-aliasing
CFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
CFLAGS+=-MMD -g
CXXFLAGS=$(CFLAGS)
# binary name
APP = dpdk-recv-send
# all source are stored in SRCS-y
SRCS-y := $(APP).c
PKGCONF ?= pkg-config
# Build using pkg-config variables if possible
ifneq ($(shell $(PKGCONF) --exists libdpdk && echo 0),0)
$(error "no installation of DPDK found")
endif
all: shared
.PHONY: shared
shared: build/$(APP)-shared
ln -sf $(APP)-shared build/$(APP)
dpdk-recv-send.so: dpdk-recv-send.o
$(CC) -shared $(LDFLAGS) $(LDFLAGS_SHARED) -o $@ $<
PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null)
CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk)
LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) -lpthread -lm
CFLAGS += -DALLOW_EXPERIMENTAL_API
build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
%.o: %.c
$(CC) $(CFLAGS) $(SRCS-y) -fpic -c -o $@
build:
@mkdir -p $@
.PHONY: clean
clean:
rm -rf build
rm -f *.o *.d *.so
This diff is collapsed.
#!/bin/bash
set -e
tx_packets() {
ethtool -S ens9f1np1|grep -v ": 0"|grep "tx_packets:"|awk '{print $2;}';
}
make;
#A=$(tx_packets)
nice -n -20 chrt 99 build/dpdk-recv-send -l 28 -b 0000:04:00.0 -b 0000:5e:00.0 -b 0000:5e:00.1;
#B=$(tx_packets)
#echo "Ethtool tx packets sent: $((B -A))";
CC=gcc
CFLAGS=-O2
CFLAGS+=-g
PROG=raw_socket
OBJ=$(PROG).o
all: $(PROG)
clean:
rm -f $(PROG) *.o *~
$(PROG): $(OBJ)
$(CC) $(LDFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $^
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <getopt.h>
#include <immintrin.h>
#include <inttypes.h>
#include <limits.h>
#include <linux/if_packet.h>
#include <math.h>
#include <netdb.h>
#include <netinet/ether.h>
#include <netinet/in.h>
#include <net/if.h>
#include <pthread.h>
#include <sched.h>
#include <semaphore.h>
#include <signal.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
static void log_error(const char * section, const char * msg, ...) {
time_t t;
struct tm ts;
char line[256];
va_list arglist;
time(&t);
ts = *localtime(&t);
strftime(line, 80, "%m-%d %H:%M:%S", &ts);
sprintf(line + strlen(line), " ERROR [%s] ", section);
va_start(arglist, msg);
vsprintf(line + strlen(line), msg, arglist);
va_end(arglist);
puts(line);
exit(EXIT_FAILURE);
}
static void log_info(const char * section, const char * msg, ...) {
time_t t;
struct tm ts;
char line[256];
va_list arglist;
time(&t);
ts = *localtime(&t);
strftime(line, 80, "%m-%d %H:%M:%S", &ts);
sprintf(line + strlen(line), " INFO [%s] ", section);
va_start(arglist, msg);
vsprintf(line + strlen(line), msg, arglist);
va_end(arglist);
puts(line);
}
static int latency_target_fd = -1;
static int32_t latency_target_value = 0;
void set_latency_target(void) {
struct stat s;
int err;
errno = 0;
err = stat("/dev/cpu_dma_latency", &s);
if (err == -1) {
error(EXIT_FAILURE, errno, "WARN: stat /dev/cpu_dma_latency failed");
return;
}
errno = 0;
latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR);
if (latency_target_fd == -1) {
error(EXIT_FAILURE, errno, "WARN: open /dev/cpu_dma_latency");
return;
}
errno = 0;
err = write(latency_target_fd, &latency_target_value, 4);
if (err < 1) {
error(EXIT_FAILURE, errno, "# error setting cpu_dma_latency to %d!",
latency_target_value);
close(latency_target_fd);
return;
}
printf("# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
}
// Counters
static volatile int64_t sent_frame_count;
// Network
static int send_sockfd;
static struct sockaddr_ll connect_sk_addr;
// Timestamps utils
#define NSEC_PER_SEC INT64_C(1000000000)
static struct timespec int_to_ts(int64_t t) {
struct timespec ts;
ts.tv_sec = t / NSEC_PER_SEC;
ts.tv_nsec = t - (ts.tv_sec * NSEC_PER_SEC);
return ts;
}
static int64_t ts_to_int(struct timespec ts) {
return ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec;
}
static void add_ns(struct timespec *t, int64_t ns) {
t->tv_nsec += ns;
while (t->tv_nsec >= ((int64_t)NSEC_PER_SEC)) {
t->tv_sec += 1;
t->tv_nsec -= NSEC_PER_SEC;
}
}
static int64_t calcdiff_ns(struct timespec t1, struct timespec t2) {
int64_t diff;
diff = NSEC_PER_SEC * ((int)t1.tv_sec - (int)t2.tv_sec);
diff += ((int)t1.tv_nsec - (int)t2.tv_nsec);
return diff;
}
#define PACKET_SIZE 262
#define NB_PACKETS 2000000
int main() {
uint8_t dst_mac[6] = "\xb8\x59\x9f\x07\x7d\xdb";
uint8_t src_mac[6] = "\x04\x09\xa5\x0f\x9f\x4c";
char * network_if = "ens9f1np1";
uint8_t packet[PACKET_SIZE];
uint8_t buffer[PACKET_SIZE * 1024];
struct ether_header *eh = (struct ether_header *) packet;
int if_index;
struct timespec initial, end;
int64_t sent;
int64_t duration_ns;
int k = 0;
struct mmsghdr msgh[1024];
struct iovec msgv[1024];
//set_latency_target();
memset((uint8_t *) packet, 0, PACKET_SIZE);
if (!(if_index = if_nametoindex(network_if))) {
perror("if_nametoindex");
return 1;
}
if ((send_sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {
perror("Socket Error");
return 1;
}
connect_sk_addr.sll_ifindex = if_index;
connect_sk_addr.sll_halen = ETH_ALEN;
for(int i = 0; i < 6; i++)
connect_sk_addr.sll_addr[i] = dst_mac[i];
for(int i = 0; i < 6; i++)
eh->ether_shost[i] = src_mac[i];
for(int i = 0; i < 6; i++)
eh->ether_dhost[i] = dst_mac[i];
/* Ethertype field */
eh->ether_type = htons(0xaefe);
for(int i = 0; i < 1024; i++)
memcpy(buffer + (i * PACKET_SIZE), packet, PACKET_SIZE);
memset(msgv, 0, sizeof(msgv));
memset(msgh, 0, sizeof(msgh));
for(int j = 0; j < 1024; j++) {
msgh[j].msg_hdr.msg_name = &connect_sk_addr;
msgh[j].msg_hdr.msg_namelen = sizeof(connect_sk_addr);
msgh[j].msg_hdr.msg_iov = &msgv[j];
msgh[j].msg_hdr.msg_iovlen = 1;
}
for(int j = 0; j < 1024; j++) {
msgv[j].iov_base = buffer + (j * PACKET_SIZE);
msgv[j].iov_len = PACKET_SIZE;
}
clock_gettime(CLOCK_TAI, &initial);
for(int i = 0; sent < NB_PACKETS; i++) {
int ret = sendmmsg(send_sockfd, msgh, 1024, 0);
if(ret < 1024)
error(EXIT_FAILURE, errno, "sendmmsg error (returned %d)", ret);
sent += ret;
}
clock_gettime(CLOCK_TAI, &end);
duration_ns = calcdiff_ns(end, initial);
log_info("STATS", "Duration: %" PRIi64 " us", duration_ns / 1000);
log_info("STATS", "Packets sent: %" PRIi64 " / %" PRIi64, sent, NB_PACKETS);
log_info("STATS", "pps: %" PRIi64, (sent * NSEC_PER_SEC) / duration_ns);
return 0;
}
#!/bin/bash
set -e
tx_packets() {
ethtool -S ens9f1np1|grep -v ": 0"|grep "tx_packets:"|awk '{print $2;}';
}
make clean && make;
A=$(tx_packets)
nice -n -20 chrt 99 ./raw_socket;
B=$(tx_packets)
echo "Ethtool tx packets sent: $((B -A))";
This diff is collapsed.
int start_udp(TRXEcpriState * s) {
struct addrinfo server_hints, client_hints, *server_info, *client_info, *p;
int rv;
char ip_string[INET6_ADDRSTRLEN];
if(init_buffers()) {
fprintf(stderr, "Init buffer failed\n");
exit(EXIT_FAILURE);
}
memset((uint8_t *) ecpri_packet, 0, MAX_PACKET_SIZE);
memset((uint8_t *) empty_ecpri_packet, 0, MAX_PACKET_SIZE);
memset(&server_hints, 0, sizeof server_hints);
memset(&client_hints, 0, sizeof client_hints);
server_hints.ai_family = AF_UNSPEC;
server_hints.ai_socktype = SOCK_DGRAM;
client_hints.ai_family = AF_INET;
client_hints.ai_socktype = SOCK_DGRAM;
client_hints.ai_flags = AI_PASSIVE;
if ((rv = getaddrinfo(NULL, s->rec_port, &client_hints, &client_info)) != 0) {
fprintf(stderr, "client getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
if ((recv_sockfd = socket(client_info->ai_family, client_info->ai_socktype,
client_info->ai_protocol)) == -1) {
perror("client: socket");
return 1;
}
if ((send_sockfd = socket(client_info->ai_family, client_info->ai_socktype,
client_info->ai_protocol)) == -1) {
perror("client: socket");
return 1;
}
if (bind(recv_sockfd, client_info->ai_addr, client_info->ai_addrlen) == -1) {
close(recv_sockfd);
perror("client: connect");
return 1;
}
freeaddrinfo(client_info);
if ((rv = getaddrinfo(s->re_ip, s->re_port, &server_hints, &server_info)) != 0) {
fprintf(stderr, "server getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
for(p = server_info; p != NULL; p = p->ai_next) {
if (connect(send_sockfd, p->ai_addr, p->ai_addrlen) == -1) {
perror("client: connect");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "client: failed to connect\n");
return 1;
}
inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), ip_string, sizeof ip_string);
log_info("TRX_ECPRI", "Connected to %s\n", ip_string);
freeaddrinfo(server_info);
_start();
return 0;
}
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <getopt.h>
#include <immintrin.h>
#include <inttypes.h>
#include <limits.h>
#include <linux/if_packet.h>
#include <math.h>
#include <netdb.h>
#include <netinet/ether.h>
#include <netinet/in.h>
#include <net/if.h>
#include <pthread.h>
#include <sched.h>
#include <semaphore.h>
#include <signal.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
/* Note: src and dst must be 16 byte aligned */
static void float_to_int16(int16_t *dst, const float *src, int n, float mult)
{
const __m128 *p;
__m128i *q, a0, a1;
__m128 mult1;
mult1 = _mm_set1_ps(mult);
p = (const void *)src;
q = (void *)dst;
while (n >= 16) {
a0 = _mm_cvtps_epi32(p[0] * mult1);
a1 = _mm_cvtps_epi32(p[1] * mult1);
q[0] = _mm_packs_epi32(a0, a1);
a0 = _mm_cvtps_epi32(p[2] * mult1);
a1 = _mm_cvtps_epi32(p[3] * mult1);
q[1] = _mm_packs_epi32(a0, a1);
p += 4;
q += 2;
n -= 16;
}
if (n >= 8) {
a0 = _mm_cvtps_epi32(p[0] * mult1);
a1 = _mm_cvtps_epi32(p[1] * mult1);
q[0] = _mm_packs_epi32(a0, a1);
p += 2;
q += 1;
n -= 8;
}
if (n != 0) {
/* remaining samples (n <= 7) */
do {
a0 = _mm_cvtps_epi32(_mm_load_ss((float *)p) * mult);
*(int16_t *)q = _mm_cvtsi128_si32 (_mm_packs_epi32(a0, a0));
p = (__m128 *)((float *)p + 1);
q = (__m128i *)((int16_t *)q + 1);
n--;
} while (n != 0);
}
}
/* Note: src and dst must be 16 byte aligned */
static void int16_to_float(float *dst, const int16_t *src, int len, float mult)
{
__m128i a0, a1, a, b, sign;
__m128 mult1;
mult1 = _mm_set1_ps(mult);
while (len >= 8) {
a = *(__m128i *)&src[0];
#ifdef SSE4
a0 = _mm_cvtepi16_epi32(a);
#else
// Fix for CPU without SSE4.1
a0 = _mm_unpacklo_epi16(a, a);
a0 = _mm_srai_epi32(a0, 16);
#endif
b = _mm_srli_si128(a, 8);
#ifdef SSE4
a1 = _mm_cvtepi16_epi32(b);
#else
a1 = _mm_unpacklo_epi16(b, b);
a1 = _mm_srai_epi32(a1, 16);
#endif
*(__m128 *)&dst[0] = _mm_cvtepi32_ps(a0) * mult1;
*(__m128 *)&dst[4] = _mm_cvtepi32_ps(a1) * mult1;
dst += 8;
src += 8;
len -= 8;
}
/* remaining data */
while (len != 0) {
_mm_store_ss(&dst[0], _mm_cvtsi32_ss(_mm_setzero_ps(), src[0]) * mult1);
dst++;
src++;
len--;
}
}
/* Compr_bf1 */
static inline int max_int(int a, int b)
{
if (a > b)
return a;
else
return b;
}
static inline int min_int(int a, int b)
{
if (a < b)
return a;
else
return b;
}
static inline int clamp_int(int val, int min_val, int max_val)
{
if (val < min_val)
return min_val;
else if (val > max_val)
return max_val;
else
return val;
}
/* 1 <= n_bits <= 7 */
static void encode_put_bits(uint8_t *buf, int bit_offset, int n_bits, unsigned int val)
{
int shift, n;
shift = bit_offset & 7;
buf[bit_offset >> 3] |= val << shift;
n = 8 - shift;
if (n > 0)
buf[(bit_offset >> 3) + 1] |= val >> n;
}
/* 1 <= n_bits <= 7 */
static int decode_get_bits(const uint8_t *buf, int bit_offset, int n_bits)
{
int shift, n, v;
shift = bit_offset & 7;
n = 8 - shift;
v = buf[bit_offset >> 3];
if (n_bits > n)
v |= buf[(bit_offset >> 3) + 1] << 8;
return (v >> shift) & ((1 << n_bits) - 1);
}
#define BLOCK_LEN 8
#define CMULT_BITS 7
#define CMULT 181
/* CPRI frame format for 122.88 MHz with 4 channels using bit rate
option 7 (9.8304 Gb/s):
data byte offset
0 Channel 0. One BF1 block containing I0, Q0, I1, Q1, ..., I31, Q31.
60 Channel 1
120 Channel 2
180 Channel 3
*/
/* take 64 * 16 bit I or Q values as input and return 60 bytes into obuf.
When using a smaller sample bit width, the samples should be
appropriately scaled (e.g. multiplied by 2 for a bit width =
15). */
static void encode_bf1(uint8_t *obuf, const int16_t *samples)
{
int e, vmax, v, block_num, i, e1, m;
memset(obuf, 0, 4 + 7 * BLOCK_LEN);
/* the compressed data contains 8 blocks of 8 I or Q components. Each
block is compressed independently but the corresponding values
and output bits are interleaved. */
for(block_num = 0; block_num < 8; block_num++) {
vmax = 0;
for(i = 0; i < BLOCK_LEN; i++) {
vmax = max_int(vmax, abs(samples[i * 8 + block_num]));
}
vmax = min_int(vmax, (1 << 15) - 1);
/* 0 <= vmax <= 2^15-1 */
e = 8;
while (vmax < (1 << 14) && e > 0) {
vmax <<= 1;
e--;
}
if (e <= 1) {
e1 = e;
m = 1;
} else {
m = (vmax >= (CMULT << (14 - CMULT_BITS)));
e1 = e * 2 + m - 2;
}
encode_put_bits(obuf, block_num * 32, 4, e1); /* store the exponent */
for(i = 0; i < BLOCK_LEN; i++) {
v = samples[i * 8 + block_num];
v = v << (8 - e);
if (!m)
v = v * CMULT;
else
v = v << CMULT_BITS;
/* quantize on 7 bits using two's complement notation */
v = (v + (1 << (8 + CMULT_BITS))) >> (9 + CMULT_BITS);
v = clamp_int(v, -64, 63);
v = v & 0x7f;
if (i < 4)
encode_put_bits(obuf, block_num * 32 + 4 + i * 7, 7, v);
else
encode_put_bits(obuf, 8 * 32 + block_num * 28 + (i - 4) * 7, 7, v);
}
}
}
/* Take 60 bytes as input and return 64 values of sample_bit_width bits
(14 <= sample_bit_width <= 16) */
static void decode_bf1(int16_t *samples, const uint8_t *ibuf, int sample_bit_width)
{
int e, v, e1, m, shift, bias;
int block_num, i;
shift = (15 - sample_bit_width) + CMULT_BITS + 1;
bias = (1 << shift) >> 1;
for(block_num = 0; block_num < 8; block_num++) {
e1 = decode_get_bits(ibuf, block_num * 32, 4);
if (e1 <= 1) {
e = e1;
m = 1;
} else {
e1 += 2;
m = e1 & 1;
e = e1 >> 1;
}
for(i = 0; i < BLOCK_LEN; i++) {
if (i < 4)
v = decode_get_bits(ibuf, block_num * 32 + 4 + i * 7, 7);
else
v = decode_get_bits(ibuf, 8 * 32 + block_num * 28 + (i - 4) * 7, 7);
/* sign extend two's complement 7 bit value to 32 bits */
v = (int32_t)((uint32_t)v << (32 - 7)) >> (32 - 7);
/* multiply by the scale */
v = v << e;
if (!m)
v = v * CMULT;
else
v = v << (CMULT_BITS + 1);
/* shift and round */
v = (v + bias) >> shift;
samples[i * 8 + block_num] = v;
}
}
}
char in[256];
char out[256];
int main(int argc, char ** argv) {
int compress, tx;
int16_t int16_samples[64];
const float mult = 1. / 32767.;
if(argc != 2)
fprintf(stderr, "Wrong argument number");
compress = (argv[1][0] == 'c');
freopen(NULL, "rb", stdin);
fread(in, compress ? (64 * 4) : 60 , 1, stdin);
fclose(stdin);
if(compress) {
float_to_int16(int16_samples, (float *) in, 64, 32767);
encode_bf1(out, int16_samples);
} else {
decode_bf1(int16_samples, in, 16);
int16_to_float((float *) out, int16_samples, 64, mult);
}
freopen(NULL, "wb", stdout);
fwrite(out, compress ? 60 : (64 * 4), 1, stdout);
fclose(stdout);
return 0;
}
import subprocess
import struct
import random
def float_to_byte(float_list):
iq_samples_bytes = bytearray(64 * 4)
for i in range(64):
b = struct.pack('f', float_list[i])
for j in range(4):
iq_samples_bytes[i * 4 + j] = b[j]
return bytes(iq_samples_bytes)
def byte_to_float(b):
float_list = []
for i in range(64):
x = struct.unpack('f', b[4 * i:4 * (i+1)])[0]
float_list.append(x)
return float_list
def compress(b):
s = subprocess.run(
["./bf1", "c"],
input=b,
capture_output=True,
)
return s.stdout
def decompress(b):
s = subprocess.run(["./bf1", "d"],
input=b,
capture_output=True,
)
return s.stdout
iq_samples = [0.2 * (random.randint(1,1000) / 1000.0) for i in range(64)]
iq_samples2 = byte_to_float(decompress(compress(float_to_byte(iq_samples))))
d = []
for i in range(64):
d.append(abs(iq_samples[i]-iq_samples2[i]))
print("{}% accuracy".format(100 - 100 * max(d) / max(map(abs, iq_samples))))
/* DPDK */ /* DPDK */
#define BURST_SIZE 16
#define MEMPOOL_CACHE_SIZE 256 #define MEMPOOL_CACHE_SIZE 256
#define RTE_TEST_RX_DESC_DEFAULT 1024 #define RTE_TEST_RX_DESC_DEFAULT 1024
#define RTE_TEST_TX_DESC_DEFAULT 1024 #define RTE_TEST_TX_DESC_DEFAULT 1024
...@@ -8,7 +7,6 @@ static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; ...@@ -8,7 +7,6 @@ static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
struct rte_mempool *mbuf_pool; struct rte_mempool *mbuf_pool;
struct rte_ether_addr s_addr; struct rte_ether_addr s_addr;
struct rte_ether_addr d_addr; struct rte_ether_addr d_addr;
int8_t tx_data[BURST_SIZE][TX_PACKET_SIZE];
static const struct rte_eth_conf port_conf_default = { static const struct rte_eth_conf port_conf_default = {
.rxmode = { .max_lro_pkt_size = RTE_ETHER_MAX_LEN } .rxmode = { .max_lro_pkt_size = RTE_ETHER_MAX_LEN }
}; };
...@@ -57,6 +55,7 @@ static void init_dpdk(int argc, char ** argv) { ...@@ -57,6 +55,7 @@ static void init_dpdk(int argc, char ** argv) {
argv += ret; argv += ret;
nb_mbufs = RTE_MAX((nb_rxd + nb_txd + BURST_SIZE + MEMPOOL_CACHE_SIZE), 8192U); nb_mbufs = RTE_MAX((nb_rxd + nb_txd + BURST_SIZE + MEMPOOL_CACHE_SIZE), 8192U);
nb_mbufs = 1024U * 16;
mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", nb_mbufs, mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", nb_mbufs,
MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); MEMPOOL_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Dummy transceiver driver (receives zeros and sync to real time)
*
* Copyright (C) 2012-2021 Amarisoft
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <inttypes.h>
#include <string.h>
#include <getopt.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include <sys/time.h>
#include "trx_driver.h"
typedef int BOOL;
typedef struct {
int sample_rate;
int tx_channel_count;
int rx_channel_count;
int64_t rx_timestamp;
int64_t rx_count;
int64_t tx_count;
BOOL dump_max;
float max_sample;
int sat_count;
int64_t last_disp_time;
} TRXDummyState;
static int64_t get_time_us(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
}
static void trx_dummy_end(TRXState *s1)
{
TRXDummyState *s = s1->opaque;
printf("rx_count: %" PRId64 "\n", s->rx_count);
printf("tx_count: %" PRId64 "\n", s->tx_count);
free(s);
}
static inline int64_t ts_to_time(TRXDummyState *s, int64_t ts)
{
int n, r;
n = (ts / s->sample_rate);
r = (ts % s->sample_rate);
return (int64_t)n * 1000000 + (((int64_t)r * 1000000) / s->sample_rate);
}
static void trx_dummy_write(TRXState *s1, trx_timestamp_t timestamp, const void **samples, int count, int flags, int rf_port_index)
{
TRXDummyState *s = s1->opaque;
if (!(flags & TRX_WRITE_FLAG_PADDING) && s->dump_max) {
const float *tab;
int i, j;
float v_max, v;
v_max = s->max_sample;
for(j = 0; j < s->tx_channel_count; j++) {
tab = (const float *)samples[j];
for(i = 0; i < count * 2; i++) {
v = fabsf(tab[i]);
/* Note: 1.0 corresponds to the maximum value */
if (v >= 1.0)
s->sat_count++;
if (v > v_max) {
v_max = v;
}
}
}
s->max_sample = v_max;
if ((get_time_us() - s->last_disp_time) >= 2000000) {
printf("max_sample=%0.3f sat=%d\n", s->max_sample, s->sat_count);
s->max_sample = 0;
s->sat_count = 0;
s->last_disp_time = get_time_us();
}
}
s->tx_count += count;
}
static int trx_dummy_read(TRXState *s1, trx_timestamp_t *ptimestamp, void **psamples, int count, int rf_port)
{
TRXDummyState *s = s1->opaque;
int64_t end_time, d;
TRXComplex *samples;
int j;
*ptimestamp = s->rx_timestamp;
s->rx_timestamp += count;
s->rx_count += count;
end_time = ts_to_time(s, s->rx_timestamp);
/* Since we don't have a real sample source, we just return zero
samples and use the PC real time clock as time source */
for(;;) {
d = end_time - get_time_us();
if (d <= 0)
break;
if (d > 10000)
d = 10000;
usleep(d);
}
for(j = 0; j < s->rx_channel_count; j++) {
samples = psamples[j];
memset(samples, 0, count * sizeof(TRXComplex));
}
return count;
}
/* This function can be used to automatically set the sample
rate. Here we don't implement it, so the user has to force a given
sample rate with the "sample_rate" configuration option */
static int trx_dummy_get_sample_rate(TRXState *s, TRXFraction *psample_rate,
int *psample_rate_num, int sample_rate_min)
{
return -1;
}
static int trx_dummy_start(TRXState *s1, const TRXDriverParams *p)
{
TRXDummyState *s = s1->opaque;
struct timeval tv;
if (p->rf_port_count != 1)
return -1; /* only one TX port is supported */
s->sample_rate = p->sample_rate[0].num / p->sample_rate[0].den;
s->tx_channel_count = p->tx_channel_count;
s->rx_channel_count = p->rx_channel_count;
gettimeofday(&tv, NULL);
/* compute first RX timetamp in sample rate units */
s->rx_timestamp = (int64_t)tv.tv_sec * s->sample_rate +
((int64_t)tv.tv_usec * s->sample_rate / 1000000);
s->last_disp_time = get_time_us();
return 0;
}
int trx_driver_init(TRXState *s1)
{
TRXDummyState *s;
double val;
if (s1->trx_api_version != TRX_API_VERSION) {
fprintf(stderr, "ABI compatibility mismatch between LTEENB and TRX driver (LTEENB ABI version=%d, TRX driver ABI version=%d)\n",
s1->trx_api_version, TRX_API_VERSION);
return -1;
}
s = malloc(sizeof(TRXDummyState));
memset(s, 0, sizeof(*s));
s->dump_max = 0;
/* option to dump the maximum sample value */
if (trx_get_param_double(s1, &val, "dump_max") >= 0)
s->dump_max = (val != 0);
s1->opaque = s;
s1->trx_end_func = trx_dummy_end;
s1->trx_write_func = trx_dummy_write;
s1->trx_read_func = trx_dummy_read;
s1->trx_start_func = trx_dummy_start;
s1->trx_get_sample_rate_func = trx_dummy_get_sample_rate;
return 0;
}
import subprocess
import struct
import random
import os
import hashlib
def _hash(x):
return hashlib.sha256(repr(x).encode()).hexdigest()[:8]
def print_hash(name, x):
print("{:<32}: {}".format(name, _hash(x)))
def parse_binary(b):
return ''.join(map(lambda x:format(int(x), '0>2x'), b))
def parse_frame(buf):
c = [0]
def b(c, n):
ret = buf[c[0]:c[0]+n]
c[0] += n
return ret
dst_mac = b(c, 6)
src_mac = b(c, 6)
ether_type = b(c, 2)
ecpri_common_header = b(c, 4)
pc_id = b(c, 2)
seq_id = b(c, 2)
iq_samples = b(c, 240)
avg = sum(map(lambda x:int(x), iq_samples))
s = '''
dst_mac, src_mac, ether_type: {}, {}, {}
ecpri_common_header: {}
pc_id, seq_id: {}, {}
IQ samples: {}'''.format(
parse_binary(dst_mac),
parse_binary(src_mac),
parse_binary(ether_type),
parse_binary(ecpri_common_header),
parse_binary(pc_id),
parse_binary(seq_id),
parse_binary(iq_samples))[1:]
return (avg == 0, s)
def read_trace(name, n):
log_directory = '/root/ecpri-logs'
file_name = '{}/{}'.format(log_directory, name)
n = min(n * 262, os.path.getsize(file_name))
f = open(file_name, "rb")
data = f.read(n)
f.close()
print(name + ", frame number = " + str(n / 262))
return data
def print_frame(data):
n = len(data)
frame_len = 262
for i in range(int(n / frame_len)):
empty, s = parse_frame(data[i * frame_len:(i+1) * frame_len])
if empty:
continue
print("Frame example:\n\n{}\n".format(s))
break
def analyze_tdd(data):
null_frames = 0
tdd_switch_list = []
prev_empty = False
prev_i = 0
n = len(data)
frame_len = 262
for i in range(int(n / frame_len)):
empty, s = parse_frame(data[i * frame_len:(i+1) * frame_len])
if i > 0 and empty != prev_empty:
tdd_switch_list.append(i-prev_i)
prev_i = i
null_frames += empty
prev_empty = empty
tdd_switch_list.append(i-prev_i)
print('Frame analyzed: ' + str(i))
total_frames = int(n / frame_len)
ratio = total_frames / null_frames if null_frames > 0 else 'inf'
print('TDD ratio: {}\n'.format(ratio))
print('TDD switch list: ' + ', '.join(map(str, tdd_switch_list)) + '\n')
def print_frame_list(data, start, end):
n = len(data)
frame_len = 262
end = int(n / frame_len) if end == -1 else end
end = min(int(n / frame_len), end)
for i in range(start, end):
empty, s = parse_frame(data[i * frame_len:(i+1) * frame_len])
print(s)
print('')
def print_iq_list(data, start, end, tx=False):
n = len(data)
frame_len = 64 * 4
end = int(n / frame_len) if end == -1 else end
end = min(int(n / frame_len), end)
for i in range(start * 4, end * 4, 4):
iq = data[i * frame_len:(i+1) * frame_len]
iq_packed = []
k = 0
h = _hash(iq)
prev_x = 2
for x in map(lambda x: int(x != 0), iq):
if x == prev_x:
iq_packed[-1][0] += 1
else:
iq_packed.append([1, str(x) * 2])
prev_x = x
print(h + " " + " ".join(map(lambda x: "{}*{}".format(*x), iq_packed)))
def read_trx_trace(name, n, channels):
log_directory = '/root/ecpri-logs'
file_name = '{}/{}'.format(log_directory, name)
n = min(n * (4 * channels * 64), os.path.getsize(file_name))
f = open(file_name, "rb")
data = f.read(n)
f.close()
print(name + ", frame number = " + str(n / (4 * channels * 64)))
return data
def analyze_trx_tdd(data, channels):
null_frames = 0
tdd_switch_list = []
prev_empty = False
prev_i = 0
n = len(data)
frame_len = channels * 4 * 64
max_iq_sample = 0
min_iq_sample = 0
avg_iq_sample = 0
for i in range(int(n / frame_len)):
iq_samples = data[i * frame_len:(i+1) * frame_len]
iq_samples = [struct.unpack('f', iq_samples[4*j:4*(j+1)])[0] for j in range(int(len(iq_samples) / 4))]
iq_samples_abs_avg = sum(map(abs, iq_samples))
max_iq_sample = max(max_iq_sample, max(iq_samples))
min_iq_sample = min(min_iq_sample, min(iq_samples))
avg_iq_sample += iq_samples_abs_avg
empty = iq_samples_abs_avg < 0.1
if i == 0:
first_tdd_period = empty
if i > 0 and empty != prev_empty:
tdd_switch_list.append(i-prev_i)
prev_i = i
null_frames += empty
prev_empty = empty
tdd_switch_list.append(i-prev_i)
avg_iq_sample /= (n / frame_len) * (64 * channels)
print('Max IQ sample: {}, Min IQ sample: {}'.format(max_iq_sample, min_iq_sample))
print('Avg IQ sample: {}'.format(avg_iq_sample))
print('Frame analyzed: ' + str(i))
total_frames = int(n / frame_len)
ratio = total_frames / null_frames if null_frames > 0 else 'inf'
print('TDD ratio: {}\n'.format(ratio))
print('TDD switch list: ' + ', '.join(map(str, tdd_switch_list)) + '\n')
print('First TDD period: ' + "Not emitting" if first_tdd_period else "emitting")
BF1_PATH="../bf1/bf1"
def float_to_byte(float_list):
iq_samples_bytes = bytearray(64 * 4)
for i in range(64):
b = struct.pack('f', float_list[i])
for j in range(4):
iq_samples_bytes[i * 4 + j] = b[j]
return bytes(iq_samples_bytes)
def byte_to_float(b):
float_list = []
for i in range(64):
x = struct.unpack('f', b[4 * i:4 * (i+1)])[0]
float_list.append(x)
return float_list
def compress(data):
s = subprocess.run(
[BF1_PATH, "c"],
input=data,
capture_output=True,
)
return s.stdout
def decompress(data):
s = subprocess.run([BF1_PATH, "d"],
input=data,
capture_output=True,
)
return s.stdout
def open_all(n):
return (
read_trace('tx.trace', n),
read_trace('rx.trace', n),
read_trx_trace('trxw.trace', n, 4),
read_trx_trace('trxr.trace', n, 1),
)
def analyze_all_tdd(n=0, data=None):
if data:
tx_data, rx_data, trxw_data, trxr_data = data
print("TX")
analyze_tdd(tx_data)
print("RX")
analyze_tdd(rx_data)
print("TRXW")
analyze_trx_tdd(trxw_data, 4)
print("TRXR")
analyze_trx_tdd(trxr_data, 1)
else:
data = read_trace('rx.trace', n)
analyze_tdd(data)
data = read_trace('tx.trace', n)
analyze_tdd(data)
data = read_trx_trace('trxw.trace', n, 4)
analyze_trx_tdd(data, 4)
data = read_trx_trace('trxr.trace', n, 1)
analyze_trx_tdd(data, 1)
def check_tx_trxw(n=0, data=None):
if data:
tx_data, rx_data, trxw_data, trxr_data = data
else:
tx_data = read_trace('tx.trace', n)
trxw_data = read_trx_trace('trxw.trace', n, 4)
for i in range(int(min(len(tx_data) / 262, len(trxw_data) / (64 * 4 * 4)))):
for j in range(1):
k = i * 4 + j
tx_iq = tx_data[(i * 262 + 22 + j * 60):(i * 262 + 22 + (j+1) * 60)]
trxw_iq = trxw_data[(k * (64 * 4)):((k+1) * (64 * 4))]
tx_iq_d = decompress(tx_iq)
trxw_iq_d = compress(trxw_iq)
if (_hash(tx_iq) != _hash(trxw_iq_d)) or (_hash(trxw_iq) != _hash(tx_iq_d)):
print((i,j))
print_hash("TX", tx_iq)
print_hash("TRX compressed", trxw_iq_d)
print_hash("TRX", trxw_iq)
print_hash("TX decompressed", tx_iq_d)
def print_all(n=0, data=None):
if data:
tx_data, rx_data, trxw_data, trxr_data = data
print('TX_DATA')
print_frame_list(tx_data, 0, 10)
print('RX_DATA')
print_frame_list(rx_data, 0, 10)
print('TRXW_DATA')
print('TRXR_DATA')
print_iq_list(trxr_data, 0, 10)
data = open_all(100000)
#check_tx_trxw(data=data)
#print_all(data=data)
analyze_all_tdd(data=data)
export PTP_INSTALL="/root/linuxptp"
export INTERFACE="ens9f0"
export DPDK_INSTALL="/root/dpdk-21.11"
export LTEENB="/root/enb/lteenb"
export ENB_CONFIG="enb.cfg"
export LOG_DIRECTORY="/root/ecpri-logs"
export LD_LIBRARY_PATH="/root/ecpri-priv:/root/enb:$LD_LIBRARY_PATH"
export AMARISOFT_PATH="/root/.amarisoft"
export PTP_INSTALL="/root/linuxptp"
export INTERFACE="ens9f0"
export DPDK_INSTALL="/root/dpdk-stable-20.11.3"
export LTEENB="/root/enb/lteenb"
export ENB_CONFIG="enb-hfr.cfg"
export LOG_DIRECTORY="/home/hfr/ecpri-logs"
export LD_LIBRARY_PATH="/root/ecpri-priv:/root/enb:$LD_LIBRARY_PATH"
export AMARISOFT_PATH="/root/.amarisoft"
#!/bin/bash
DIR=$(dirname $(realpath $0))
cd $DPDK_INSTALL/usertools;
python3 dpdk-hugepages.py --setup 2G;
cd $DIR/.. && make;
ln -sf $DIR/../libtrx_ecpri_dpdk.so $(dirname $LTEENB)/trx_ecpri.so
chrt -f 97 taskset -c 39 phc2sys -m -c $INTERFACE -s CLOCK_REALTIME -O0 -f $PTP_INSTALL/configs/G.8275.1.cfg
chrt -f 97 taskset -c 38 ptp4l -H -i $INTERFACE -m -f $PTP_INSTALL/configs/G.8275.1.cfg
#!/bin/bash
PRIV="/root/ecpri-priv"
PUBL="/root/trx-ecpri"
rsync -ah --delete --exclude .git $PRIV/ $PUBL/;
rm -rf \
$PUBL/private.c\
$PUBL/trx_driver.h\
$PUBL/push-public.sh\
$PUBL/test-eNB/private.c\
$PUBL/test-eNB/trx_driver.h\
;
#!/bin/bash
DIR=$(dirname $(realpath $0))
$DIR/stop-cpri.sh
systemctl start lte
#!/bin/bash
DIR=$(dirname $(realpath $0))
systemctl stop lte;
$DIR/stop-ecpri.sh;
cd $DIR/..;
#make clean;
make &&
#$DIR/launch-ptp > $LOG_DIRECTORY/ptp.log 2> $LOG_DIRECTORY/ptp.error &
#$DIR/launch-phc2sys > $LOG_DIRECTORY/phc2sys.log 2> $LOG_DIRECTORY/phc2sys.error &
$LTEENB $DIR/../enb-configs/$ENB_CONFIG
#!/bin/bash
systemctl stop lte
#!/bin/bash
ECPRI_PID=$(ps aux | grep test-dpdk-ecpri | grep -v grep | awk '{print $2;}')
if [ -n "$ECPRI_PID" ]; then
kill $ECPRI_PID;
fi
LTE_PID=$(ps -ec -o pid,cmd | grep lteenb | grep -v grep | awk '{print $1;}')
if [ -n "$LTE_PID" ]; then
kill -9 $LTE_PID;
fi
killall ptp4l 2> /dev/null;
killall phc2sys 2> /dev/null;
# Copyright (C) 2014-2021 Amarisoft
# TRX Makefile version 2021-07-12
CC=gcc -m64 -msse4.1
CXX=g++ -m64 -msse4.1
CFLAGS=-O2 -fno-strict-aliasing -Wall -pedantic -std=gnu17
CFLAGS +=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
CFLAGS += -DALLOW_EXPERIMENTAL_API
CXXFLAGS=$(CFLAGS)
LIB=trx_ecpri_dpdk
LIBDIR=/root/ecpri-priv
LDFLAGS=-l$(LIB)
PROG=test-dpdk-ecpri
all: $(PROG)
$(PROG): $(PROG).o
$(CC) -L$(LIBDIR) -o $@ $< $(LDFLAGS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f $(PROG) *.o *~ *.d
-include $(wildcard *.d)
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <getopt.h>
#include <immintrin.h>
#include <inttypes.h>
#include <limits.h>
#include <linux/if_packet.h>
#include <math.h>
#include <netdb.h>
#include <netinet/ether.h>
#include <netinet/in.h>
#include <net/if.h>
#include <pthread.h>
#include <sched.h>
#include <semaphore.h>
#include <signal.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "trx_driver.h"
typedef struct {
const char * re_mac;
const char * rec_mac;
const char * rec_if;
const char * dpdk_options;
const char * log_directory;
int recv_affinity;
int send_affinity;
int encode_affinity;
int decode_affinity;
int statistic_affinity;
int ecpri_period;
int flow_id;
int sample_rate;
int trace_period;
} TRXEcpriState;
static void log_error(const char * section, const char * msg, ...) {
time_t t;
struct tm ts;
char line[256];
va_list arglist;
time(&t);
ts = *localtime(&t);
strftime(line, 80, "%m-%d %H:%M:%S", &ts);
sprintf(line + strlen(line), " ERROR [%s] ", section);
va_start(arglist, msg);
vsprintf(line + strlen(line), msg, arglist);
va_end(arglist);
puts(line);
exit(EXIT_FAILURE);
}
static void log_info(const char * section, const char * msg, ...) {
time_t t;
struct tm ts;
char line[256];
va_list arglist;
time(&t);
ts = *localtime(&t);
strftime(line, 80, "%m-%d %H:%M:%S", &ts);
sprintf(line + strlen(line), " INFO [%s] ", section);
va_start(arglist, msg);
vsprintf(line + strlen(line), msg, arglist);
va_end(arglist);
puts(line);
}
// Timestamps utils
#define NSEC_PER_SEC INT64_C(1000000000)
static struct timespec int_to_ts(int64_t t) {
struct timespec ts;
ts.tv_sec = t / NSEC_PER_SEC;
ts.tv_nsec = t - (ts.tv_sec * NSEC_PER_SEC);
return ts;
}
static int64_t ts_to_int(struct timespec ts) {
return ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec;
}
static void add_ns(struct timespec *t, int64_t ns) {
t->tv_nsec += ns;
while (t->tv_nsec >= ((int64_t)NSEC_PER_SEC)) {
t->tv_sec += 1;
t->tv_nsec -= NSEC_PER_SEC;
}
}
static int64_t calcdiff_ns(struct timespec t1, struct timespec t2) {
int64_t diff;
diff = NSEC_PER_SEC * ((int)t1.tv_sec - (int)t2.tv_sec);
diff += ((int)t1.tv_nsec - (int)t2.tv_nsec);
return diff;
}
TRXState s1;
float ** tx_samples_zeroes;
float ** tx_samples_ones;
float ** rx_samples;
void dummy_enb_init(TRXState *s1, TRXEcpriState *s);
static void enb(TRXState *s1, TRXEcpriState * s);
int main(int argc, char * argv[]) {
(void) argc;
(void) argv;
TRXEcpriState *s;
// Lock all current and future pages from preventing of being paged to
// swap
if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
log_error("TRX_ECPRI", "mlockall failed");
}
s = malloc(sizeof(TRXEcpriState));
memset(s, 0, sizeof(*s));
#if 0
// tiogapass-003 MT27710
s->rec_mac = "b8:59:9f:07:7e:2a";
//s->re_mac = "04:09:a5:0f:9f:4c"; // Lille M6424 Switch
s->re_mac = "b8:59:9f:07:86:42"; // tiogapass-004 MT27710
//s->re_mac = "b4:96:91:a7:1c:f4"; // tiogapass-004 XXV710DA2T port0
s->rec_if = "ens9f0";
s->dpdk_options = "-l 10,20 -b 0000:04:00.0 -b 0000:5e:00.1 ";
#endif
#if 0
// tiogapass-003 MT27710 port1
s->rec_mac = "b8:59:9f:07:7e:2b";
s->re_mac = "04:09:a5:0f:9f:4c"; // Lille M6424 Switch
//s->re_mac = "b8:59:9f:07:86:42"; // tiogapass-004 MT27710
//s->re_mac = "b4:96:91:a7:1c:f5"; // tiogapass-004 XXV710DA2T port1
s->rec_if = "ens9f1";
s->dpdk_options = "-l 10,20 -b 0000:04:00.0 -b 0000:5e:00.0 ";
#endif
#if 0
// hfr-tiogapass-001 MT27710
s->rec_mac = "b8:59:9f:07:82:ca";
s->re_mac = "04:09:a5:0f:76:1c"; // HFR M6424 switch
s->rec_if = "ens9f0";
s->dpdk_options = "-l 10,20 -b 0000:04:00.0 -b 0000:18:00.0 -b 0000:18:00.1 -b 0000:5e:00.1 ";
#endif
#if 0
// hfr-tiogapass-001 XXV710DA2T
s->rec_mac = "b4:96:91:a7:1b:28";
s->re_mac = "04:09:a5:0f:76:1c"; // HFR M6424 switch
s->rec_if = "ens1f0";
s->dpdk_options = "-l 10,20 -b 0000:04:00.0 -b 0000:18:00.1 -b 0000:5e:00.0 -b 0000:5e:00.1 ";
#endif
#if 0
// tiogapass-004 MT27710
s->rec_mac = "b8:59:9f:07:86:42";
s->re_mac = "04:09:a5:0f:9f:4a"; // Lille M6424 Switch
//s->re_mac = "b8:59:9f:07:7e:2a"; // tiogapass-003 MT27710
s->rec_if = "ens9f0";
s->dpdk_options = "-l 10,20 -b 0000:04:00.0 -b 0000:3b:00.0 -b 0000:3b:00.1 -b 0000:5e:00.1 ";
#endif
#if 0
// tiogapass-004 MT27710 port1
s->rec_mac = "b8:59:9f:07:86:43";
//s->re_mac = "04:09:a5:0f:9f:4c"; // Lille M6424 Switch
s->re_mac = "b8:59:9f:07:0e:2b"; // tiogapass-003 MT27710 port 1
s->rec_if = "ens9f1";
s->dpdk_options = "-l 10,20 -b 0000:04:00.0 -b 0000:3b:00.0 -b 0000:3b:00.1 -b 0000:5e:00.0 ";
#endif
#if 0
// tiogapass-004 XXV710DA2T
s->rec_mac = "b4:96:91:a7:1c:f4";
s->re_mac = "04:09:a5:0f:9f:4c"; // Lille M6424 Switch
s->re_mac = "b8:59:9f:07:7e:2a"; // tiogapass-003 MT27710
s->rec_if = "ens5f0";
s->dpdk_options = "-l 10,20 -b 0000:04:00.0 -b 0000:3b:00.1 -b 0000:5e:00.0 -b 0000:5e:00.1 ";
#endif
//s->recv_affinity = 39;
//s->send_affinity = 38;
//s->prepare_affinity = 37;
//s->decompress_affinity = 36;
//s->statistic_affinity = 35;
//s->ecpri_period = 800;
//s->flow_id = 0;
//s->sample_rate = 122880000;
//s->trace_file = "/root/ecpri-logs/rx.trace";
//s->stats_file = "/root/ecpri-logs/ecpri.stats";
//s->trace_period = 1000000;
// enb.cfg
s->rec_mac = "b8:59:9f:07:86:42";
s->re_mac = "04:09:a5:0f:9f:4a";
s->rec_if = "ens9f0";
s->dpdk_options = "-l 10,20 -b 0000:04:00.0 -b 0000:3b:00.0 -b 0000:3b:00.1 -b 0000:5e:00.1 ";
s->recv_affinity = 39;
s->send_affinity = 38;
s->encode_affinity = 37;
s->decode_affinity = 36;
s->statistic_affinity = 35;
s->ecpri_period = 800;
s->flow_id = 0;
s->trace_period = 10000000;
s->log_directory = "/root/ecpri-logs";
log_info("TEST-DPDK-ECPRI", "Starting test...\n");
log_info("TEST-DPDK-ECPRI", "rec-mac: %s, re-mac: %s, rec-if: %s", s->rec_mac, s->re_mac, s->rec_if);
dummy_enb_init(&s1, s);
enb(&s1, s);
}
static void enb(TRXState * s1, TRXEcpriState * s) {
struct timespec next;
trx_timestamp_t ptimestamp;
int64_t p = 100000 * 10;
int m = 1;
int64_t first_rx_ts;
clock_gettime(CLOCK_TAI, &next);
tx_samples_zeroes = (float**) malloc(sizeof(float*) * 4);
tx_samples_ones = (float**) malloc(sizeof(float*) * 4);
rx_samples = (float**) malloc(sizeof(float*) * 4);
for(int i = 0; i < 4; i++) {
tx_samples_zeroes[i] = (float*) malloc(sizeof(float) * 65536);
tx_samples_ones[i] = (float*) malloc(sizeof(float) * 65536);
rx_samples[i] = (float*) malloc(sizeof(float) * 65536);
for(int j = 0; j < 65536; j++) {
tx_samples_zeroes[i][j] = 0.0f;
tx_samples_ones[i][j] = 1.0f;
}
}
for(int i = 0;; i++) {
int64_t tx_timestamp = 256 * (INT64_C(3840000) * ((int64_t) p * i + p)) / (INT64_C(1000000000));
add_ns(&next, p);
s1->trx_read_func2(s1, &ptimestamp, rx_samples, 32, 0, NULL);
if(i == 0)
first_rx_ts = ptimestamp;
s1->trx_write_func2(s1, first_rx_ts + 2*i*32, tx_samples_zeroes, 32, 0, NULL);
s1->trx_read_func2(s1, &ptimestamp, rx_samples, 32, 0, NULL);
s1->trx_write_func2(s1, first_rx_ts + (2*i + 1)*32, tx_samples_ones, 32, 0, NULL);
clock_nanosleep(CLOCK_TAI, TIMER_ABSTIME, &next, NULL);
}
}
#!/bin/bash
export LD_LIBRARY_PATH="/root/ecpri-priv:$LD_LIBRARY_PATH"
cd .. &&
make &&
cd test-eNB &&
make all &&
./test-dpdk-ecpri
#ifndef TRX_ECPRI_H
#define TRX_ECPRI_H
typedef struct {
const char * re_mac;
const char * rec_mac;
const char * rec_if;
int recv_affinity;
int send_affinity;
int prepare_affinity;
int decompress_affinity;
int ecpri_period;
int flow_id;
int sample_rate;
} TRXEcpriState;
int start(TRXEcpriState * s);
void log_error(const char * section, const char * msg, ...) {
time_t t;
struct tm ts;
char line[256];
va_list arglist;
time(&t);
ts = *localtime(&t);
strftime(line, 80, "%m-%d %H:%M:%S", &ts);
sprintf(line + strlen(line), " ERROR [%s] ", section);
va_start(arglist, msg);
vsprintf(line + strlen(line), msg, arglist);
va_end(arglist);
puts(line);
exit(EXIT_FAILURE);
}
void log_info(const char * section, const char * msg, ...) {
time_t t;
struct tm ts;
char line[256];
va_list arglist;
time(&t);
ts = *localtime(&t);
strftime(line, 80, "%m-%d %H:%M:%S", &ts);
sprintf(line + strlen(line), " INFO [%s] ", section);
va_start(arglist, msg);
vsprintf(line + strlen(line), msg, arglist);
va_end(arglist);
puts(line);
}
#ifdef DEBUG
void log_debug(const char * section, const char * msg, ...) {
time_t t;
struct tm ts;
char line[256];
va_list arglist;
time(&t);
ts = *localtime(&t);
strftime(line, 80, "%m-%d %H:%M:%S", &ts);
sprintf(line + strlen(line), " DEBUG [%s] ", section);
va_start(arglist, msg);
vsprintf(line + strlen(line), msg, arglist);
va_end(arglist);
puts(line);
}
#else
#define log_debug(...)
#endif
#endif
This diff is collapsed.
...@@ -36,6 +36,7 @@ static inline void log_limit(const char * section, const char * msg, ...) { ...@@ -36,6 +36,7 @@ static inline void log_limit(const char * section, const char * msg, ...) {
puts(line); puts(line);
} }
#if 0
static void log_info(const char * section, const char * msg, ...) { static void log_info(const char * section, const char * msg, ...) {
time_t t; time_t t;
struct tm ts; struct tm ts;
...@@ -51,6 +52,11 @@ static void log_info(const char * section, const char * msg, ...) { ...@@ -51,6 +52,11 @@ static void log_info(const char * section, const char * msg, ...) {
va_end(arglist); va_end(arglist);
puts(line); puts(line);
} }
#else
static void log_info(const char * section, const char * msg, ...) {
return;
}
#endif
#ifdef DEBUG #ifdef DEBUG
static void log_debug(const char * section, const char * msg, ...) { static void log_debug(const char * section, const char * msg, ...) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment