zmq: extend test to 4 trx, w/wo decimation

This commit is contained in:
Robert Falkenberg 2022-01-26 11:23:43 +01:00
parent b4bbbc902a
commit cceae68958
1 changed files with 121 additions and 62 deletions

View File

@ -17,18 +17,22 @@
#include <complex.h>
#include <pthread.h>
#include <srsran/phy/common/phy_common.h>
#include <srsran/phy/utils/vector.h>
#include <stdlib.h>
#include <zmq.h>
#define NOF_RX_ANT 1
#define PRINT_SAMPLES 1
#define COMPARE_BITS 0
#define COMPARE_EPSILON (1e-6f)
#define NOF_RX_ANT 4
#define NUM_SF (500)
#define SF_LEN (1920)
#define RF_BUFFER_SIZE (SF_LEN * NUM_SF)
#define TX_OFFSET_MS (4)
static cf_t ue_rx_buffer[RF_BUFFER_SIZE];
static cf_t enb_tx_buffer[RF_BUFFER_SIZE];
static cf_t enb_rx_buffer[RF_BUFFER_SIZE];
static cf_t ue_rx_buffer[NOF_RX_ANT][RF_BUFFER_SIZE];
static cf_t enb_tx_buffer[NOF_RX_ANT][RF_BUFFER_SIZE];
static cf_t enb_rx_buffer[NOF_RX_ANT][RF_BUFFER_SIZE];
static srsran_rf_t ue_radio, enb_radio;
pthread_t rx_thread;
@ -53,13 +57,15 @@ void* ue_rx_thread_function(void* args)
uint32_t num_rxed_samps = 0;
for (uint32_t i = 0; i < num_slots; ++i) {
void* data_ptr[SRSRAN_MAX_PORTS] = {NULL};
data_ptr[0] = &ue_rx_buffer[i * num_samps_per_slot];
for (uint32_t c = 0; c < NOF_RX_ANT; c++) {
data_ptr[c] = &ue_rx_buffer[c][i * num_samps_per_slot];
}
num_rxed_samps += srsran_rf_recv_with_time_multi(&ue_radio, data_ptr, num_samps_per_slot, true, NULL, NULL);
}
printf("received %d samples.\n", num_rxed_samps);
printf("closing ue norf device\n");
printf("closing ue zmq device\n");
srsran_rf_close(&ue_radio);
return NULL;
@ -78,16 +84,23 @@ void enb_tx_function(const char* tx_args, bool timed_tx)
}
// generate random tx data
for (int c = 0; c < NOF_RX_ANT; c++) {
for (int i = 0; i < RF_BUFFER_SIZE; i++) {
enb_tx_buffer[i] = ((float)rand() / (float)RAND_MAX) + _Complex_I * ((float)rand() / (float)RAND_MAX);
enb_tx_buffer[c][i] = ((float)rand() / (float)RAND_MAX) + _Complex_I * ((float)rand() / (float)RAND_MAX);
}
}
// send data subframe per subframe
uint32_t num_txed_samples = 0;
// initial transmission without ts
void* data_ptr[SRSRAN_MAX_PORTS] = {NULL};
data_ptr[0] = &enb_tx_buffer[num_txed_samples];
cf_t tx_buffer[NOF_RX_ANT][SF_LEN];
for (int c = 0; c < NOF_RX_ANT; c++) {
memcpy(&tx_buffer[c], &enb_tx_buffer[c][num_txed_samples], SF_LEN * sizeof (cf_t));
data_ptr[c] = &tx_buffer[c][0];
}
int ret = srsran_rf_send_multi(&enb_radio, (void**)data_ptr, SF_LEN, true, true, false);
num_txed_samples += SF_LEN;
@ -96,11 +109,16 @@ void enb_tx_function(const char* tx_args, bool timed_tx)
for (uint32_t i = 0; i < NUM_SF - ((timed_tx) ? TX_OFFSET_MS : 1); ++i) {
// first recv samples
data_ptr[0] = enb_rx_buffer;
for (int c = 0; c < NOF_RX_ANT; c++) {
data_ptr[c] = enb_rx_buffer[c];
}
srsran_rf_recv_with_time_multi(&enb_radio, data_ptr, SF_LEN, true, &rx_time.full_secs, &rx_time.frac_secs);
// prepare data buffer
data_ptr[0] = &enb_tx_buffer[num_txed_samples];
for (int c = 0; c < NOF_RX_ANT; c++) {
memcpy(&tx_buffer[c], &enb_tx_buffer[c][num_txed_samples], SF_LEN * sizeof (cf_t));
data_ptr[c] = &tx_buffer[c][0];
}
if (timed_tx) {
// timed tx relative to receive time (this will cause a cap in the rx'ed samples at the UE resulting in 3 zero
@ -148,6 +166,8 @@ int run_test(const char* rx_args, const char* tx_args, bool timed_tx)
// wait for rx thread
pthread_join(rx_thread, NULL);
// channel-wise comparison
for (int c = 0; c < NOF_RX_ANT; c++) {
// subframe-wise compare tx'ed and rx'ed data (stop 3 subframes earlier for timed tx)
for (uint32_t i = 0; i < NUM_SF - (timed_tx ? 3 : 0); ++i) {
uint32_t sf_offet = 0;
@ -156,18 +176,37 @@ int run_test(const char* rx_args, const char* tx_args, bool timed_tx)
sf_offet = (TX_OFFSET_MS - 1) * SF_LEN;
}
#if 0
// print first 3 samples for each SF
#if PRINT_SAMPLES
// print first 10 samples for each SF
printf("enb_tx_buffer sf%d:\n", i);
srsran_vec_fprint_c(stdout, &enb_tx_buffer[i * SF_LEN], 3);
srsran_vec_fprint_c(stdout, &enb_tx_buffer[c][i * SF_LEN], 10);
printf("ue_rx_buffer sf%d:\n", i);
srsran_vec_fprint_c(stdout, &ue_rx_buffer[sf_offet + i * SF_LEN], 3);
srsran_vec_fprint_c(stdout, &ue_rx_buffer[c][sf_offet + i * SF_LEN], 10);
#endif
if (memcmp(&ue_rx_buffer[sf_offet + i * SF_LEN], &enb_tx_buffer[i * SF_LEN], SF_LEN) != 0) {
#if COMPARE_BITS
int d = memcmp(&ue_rx_buffer[sf_offet + i * SF_LEN], &enb_tx_buffer[i * SF_LEN], SF_LEN);
if (d) {
d = d > 0 ? d : -d;
fprintf(stderr, "data mismatch in subframe %d, sample %d\n", i, d);
printf("enb_tx_buffer sf%d:\n", i);
srsran_vec_fprint_c(stdout, &enb_tx_buffer[i * SF_LEN + d], 10);
printf("ue_rx_buffer sf%d:\n", i);
srsran_vec_fprint_c(stdout, &ue_rx_buffer[sf_offet + i * SF_LEN + d], 10);
goto exit;
}
#else
srsran_vec_sub_ccc(&ue_rx_buffer[c][sf_offet + i * SF_LEN],
&enb_tx_buffer[c][i * SF_LEN],
&ue_rx_buffer[c][sf_offet + i * SF_LEN],
SF_LEN);
uint32_t max_ix = srsran_vec_max_abs_ci(&ue_rx_buffer[c][sf_offet + i * SF_LEN], SF_LEN);
if (cabsf(ue_rx_buffer[c][sf_offet + i * SF_LEN + max_ix]) > COMPARE_EPSILON) {
fprintf(stderr, "data mismatch in subframe %d\n", i);
goto exit;
}
#endif
}
}
ret = SRSRAN_SUCCESS;
@ -195,56 +234,76 @@ int param_test(const char* args_param, const int num_channels)
int main()
{
// two Rx ports
if (param_test("rx_port=ipc://dl0,rx_port1=ipc://dl1", 2)) {
fprintf(stderr, "Param test failed!\n");
return SRSRAN_ERROR;
}
// // two Rx ports
// if (param_test("rx_port=ipc://dl0,rx_port1=ipc://dl1", 2)) {
// fprintf(stderr, "Param test failed!\n");
// return SRSRAN_ERROR;
// }
// multiple rx ports, no channel index provided
if (param_test("rx_port=ipc://dl0,rx_port=ipc://dl1,rx_port=ipc://dl2,rx_port=ipc://dl3,base_srate=1.92e6", 4)) {
fprintf(stderr, "Param test failed!\n");
return SRSRAN_ERROR;
}
// // multiple rx ports, no channel index provided
// if (param_test("rx_port=ipc://dl0,rx_port=ipc://dl1,rx_port=ipc://dl2,rx_port=ipc://dl3,base_srate=1.92e6", 4)) {
// fprintf(stderr, "Param test failed!\n");
// return SRSRAN_ERROR;
// }
// One Rx, one Tx and all generic options
if (param_test("rx_port0=tcp://"
"localhost:2000,rx_format=sc16,tx_format=sc16,tx_type=pub,rx_type=sub,base_srate=1.92e6,id=test",
1)) {
fprintf(stderr, "Param test failed!\n");
return SRSRAN_ERROR;
}
// // One Rx, one Tx and all generic options
// if (param_test("rx_port0=tcp://"
// "localhost:2000,rx_format=sc16,tx_format=sc16,tx_type=pub,rx_type=sub,base_srate=1.92e6,id=test",
// 1)) {
// fprintf(stderr, "Param test failed!\n");
// return SRSRAN_ERROR;
// }
// 1 port, 2 antennas, MIMO freq config
if (param_test(
"tx_port0=tcp://*:2001,tx_port1=tcp://*:2003,rx_port0=tcp://localhost:2000,rx_port1=tcp://"
"localhost:2002,id=ue,base_srate=23.04e6,tx_freq0=2510e6,tx_freq1=2510e6,rx_freq0=2630e6,,rx_freq1=2630e6",
2)) {
fprintf(stderr, "Param test failed!\n");
return SRSRAN_ERROR;
}
// // 1 port, 2 antennas, MIMO freq config
// if (param_test(
// "tx_port0=tcp://*:2001,tx_port1=tcp://*:2003,rx_port0=tcp://localhost:2000,rx_port1=tcp://"
// "localhost:2002,id=ue,base_srate=23.04e6,tx_freq0=2510e6,tx_freq1=2510e6,rx_freq0=2630e6,,rx_freq1=2630e6",
// 2)) {
// fprintf(stderr, "Param test failed!\n");
// return SRSRAN_ERROR;
// }
#if NOF_RX_ANT == 1
// single tx, single rx with continuous transmissions (no timed tx) using IPC transport
if (run_test("rx_port=ipc://link1,id=ue,base_srate=1.92e6", "tx_port=ipc://link1,id=enb,base_srate=1.92e6", false) !=
SRSRAN_SUCCESS) {
fprintf(stderr, "Single tx, single rx test failed!\n");
return -1;
}
#endif
// two trx radios with continous tx (no timed tx) using TCP transport for both directions
if (run_test("tx_port=tcp://*:5554,rx_port=tcp://"
"localhost:5555,id=ue,base_srate=1.92e6,log_trx_timeout=true,trx_timeout_ms=1000",
"rx_port=tcp://localhost:5554,tx_port=tcp://*:5555,id=enb,base_srate=1.92e6",
// up to 4 trx radios with continous tx (no decimation, no timed tx)
if (run_test("tx_port=tcp://*:5554,tx_port=tcp://*:5556,tx_port=tcp://*:5558,tx_port=tcp://*:5560,rx_port=tcp://"
"localhost:5555,rx_port=tcp://localhost:5557,rx_port=tcp://localhost:5559,rx_port=tcp://"
"localhost:5561,id=ue,base_srate=1.92e6,log_trx_timeout=true,trx_timeout_ms=1000",
"rx_port=tcp://localhost:5554,rx_port=tcp://localhost:5556,rx_port=tcp://localhost:5558,rx_port=tcp://"
"localhost:5560,tx_port=tcp://*:5555,tx_port=tcp://*:5557,tx_port=tcp://*:5559,tx_port=tcp://"
"*:5561,id=enb,base_srate=1.92e6",
false) != SRSRAN_SUCCESS) {
fprintf(stderr, "Two TRx radio test failed!\n");
fprintf(stderr, "Multi TRx radio test failed!\n");
return -1;
}
// two trx radios with continous tx (no timed tx) using TCP for UL (UE tx) and IPC for eNB DL (eNB tx)
if (run_test("tx_port=tcp://*:5554,rx_port=ipc://dl,id=ue,base_srate=1.92e6",
"rx_port=tcp://localhost:5554,tx_port=ipc://dl,id=enb,base_srate=1.92e6",
// up to 4 trx radios with continous tx (timed tx) using TCP for UL (UE tx) and IPC for eNB DL (eNB tx)
if (run_test("tx_port=tcp://*:5554,tx_port=tcp://*:5556,tx_port=tcp://*:5558,tx_port=tcp://*:5560,rx_port=ipc://"
"dl0,rx_port=ipc://dl1,rx_port=ipc://dl2,rx_port=ipc://dl3,id=ue,base_srate=1.92e6",
"rx_port=tcp://localhost:5554,rx_port=tcp://localhost:5556,rx_port=tcp://localhost:5558,rx_port=tcp://"
"localhost:5560,tx_port=ipc://dl0,tx_port=ipc://dl1,tx_port=ipc://dl2,tx_port=ipc://"
"dl3,id=enb,base_srate=1.92e6",
true) != SRSRAN_SUCCESS) {
fprintf(stderr, "Two TRx radio test with timed tx failed!\n");
fprintf(stderr, "Multi TRx radio test with timed tx failed!\n");
return -1;
}
// up to 4 trx radios with continous tx (timed tx) using TCP for UL (UE tx) and IPC for eNB DL (eNB tx)
// with decimation 23.04e6 <-> 1.92e6
if (run_test("tx_port=tcp://*:5554,tx_port=tcp://*:5556,tx_port=tcp://*:5558,tx_port=tcp://*:5560,rx_port=ipc://"
"dl0,rx_port=ipc://dl1,rx_port=ipc://dl2,rx_port=ipc://dl3,id=ue,base_srate=23.04e6",
"rx_port=tcp://localhost:5554,rx_port=tcp://localhost:5556,rx_port=tcp://localhost:5558,rx_port=tcp://"
"localhost:5560,tx_port=ipc://dl0,tx_port=ipc://dl1,tx_port=ipc://dl2,tx_port=ipc://"
"dl3,id=enb,base_srate=23.04e6",
true) != SRSRAN_SUCCESS) {
fprintf(stderr, "Multi TRx radio test with timed tx and decimation failed!\n");
return -1;
}