mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
This commit introduces ZMQ-based radio library. Each pair of RX/TX antennas is represented by a ZMQ REQ/REP socket pair which streams continuous IQ samples from radio start until stop. Usage: Simplest configuration is to connect OAI NR UE to OAI GNB with the same number of antennas - by inverting the RX and TX channels in ZMQ radio configuration the gNBs TX is mapped to UEs RX antennas and vice versa.
222 lines
5.2 KiB
C++
222 lines
5.2 KiB
C++
/*
|
|
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
|
*/
|
|
|
|
#include <gtest/gtest.h>
|
|
#include "ring_buffer.h"
|
|
|
|
TEST(CircularBuffer, simplePushPop)
|
|
{
|
|
ring_buffer cb(10);
|
|
cf_t data[10];
|
|
for (int i = 0; i < 10; i++) {
|
|
data[i] = { (float)i, (float)(i + 1)};
|
|
}
|
|
ASSERT_EQ(cb.push_samples(data, 10), 0);
|
|
|
|
cf_t read_data[10];
|
|
ASSERT_EQ(cb.pop_samples(read_data, 10), 10);
|
|
for (int i = 0; i < 10; i++) {
|
|
ASSERT_EQ(read_data[i].r, data[i].r);
|
|
ASSERT_EQ(read_data[i].i, data[i].i);
|
|
}
|
|
|
|
ASSERT_EQ(cb.size(), 0);
|
|
ASSERT_EQ(cb.pop_samples(read_data, 10), 0);
|
|
}
|
|
|
|
TEST(CircularBuffer, overflow)
|
|
{
|
|
ring_buffer cb(10);
|
|
cf_t data[15];
|
|
for (int i = 0; i < 15; i++) {
|
|
data[i] = {(float)i, (float)(i + 1)};
|
|
}
|
|
ASSERT_EQ(cb.push_samples(data, 15), 5);
|
|
cf_t read_data[10];
|
|
ASSERT_EQ(cb.pop_samples(read_data, 10), 10);
|
|
// The first 5 samples are lost due to overflow
|
|
for (int i = 0; i < 10; i++) {
|
|
ASSERT_EQ(read_data[i].r, i + 5);
|
|
ASSERT_EQ(read_data[i].i, i + 6);
|
|
}
|
|
}
|
|
|
|
TEST(CircularBuffer, partialPop)
|
|
{
|
|
ring_buffer cb(10);
|
|
cf_t data[10];
|
|
for (int i = 0; i < 10; i++) {
|
|
data[i] = {(float)i, (float)(i + 1)};
|
|
}
|
|
ASSERT_EQ(cb.push_samples(data, 10), 0);
|
|
cf_t read_data[5];
|
|
ASSERT_EQ(cb.pop_samples(read_data, 5), 5);
|
|
for (int i = 0; i < 5; i++) {
|
|
ASSERT_EQ(read_data[i].r, i);
|
|
ASSERT_EQ(read_data[i].i, i + 1);
|
|
}
|
|
ASSERT_EQ(cb.size(), 5);
|
|
ASSERT_EQ(cb.pop_samples(read_data, 5), 5);
|
|
for (int i = 0; i < 5; i++) {
|
|
ASSERT_EQ(read_data[i].r, i + 5);
|
|
ASSERT_EQ(read_data[i].i, i + 6);
|
|
}
|
|
}
|
|
|
|
TEST(CircularBuffer, popMore)
|
|
{
|
|
ring_buffer cb(10);
|
|
cf_t data[10];
|
|
for (int i = 0; i < 10; i++) {
|
|
data[i] = {(float)i, (float)(i + 1)};
|
|
}
|
|
cb.push_samples(data, 10);
|
|
cf_t read_data[15];
|
|
ASSERT_EQ(cb.pop_samples(read_data, 15), 10);
|
|
for (int i = 0; i < 10; i++) {
|
|
ASSERT_EQ(read_data[i].r, i);
|
|
ASSERT_EQ(read_data[i].i, i + 1);
|
|
}
|
|
}
|
|
|
|
TEST(CircularBuffer, newOverflow)
|
|
{
|
|
ring_buffer cb(10);
|
|
cf_t data1[8];
|
|
for (int i = 0; i < 8; i++) {
|
|
data1[i] = {(float)i, (float)(i + 1)};
|
|
}
|
|
ASSERT_EQ(cb.push_samples(data1, 8), 0);
|
|
|
|
cf_t data2[4];
|
|
for (int i = 0; i < 4; i++) {
|
|
data2[i] = {(float)(i + 8), (float)(i + 9)};
|
|
}
|
|
ASSERT_EQ(cb.push_samples(data2, 4), 2);
|
|
|
|
cf_t read_data[10];
|
|
ASSERT_EQ(cb.pop_samples(read_data, 10), 10);
|
|
// The first 2 samples are lost due to overflow
|
|
for (int i = 0; i < 8; i++) {
|
|
ASSERT_EQ(read_data[i].r, i + 2);
|
|
ASSERT_EQ(read_data[i].i, i + 3);
|
|
}
|
|
ASSERT_EQ(read_data[8].r, 10);
|
|
ASSERT_EQ(read_data[8].i, 11);
|
|
ASSERT_EQ(read_data[9].r, 11);
|
|
ASSERT_EQ(read_data[9].i, 12);
|
|
}
|
|
|
|
TEST(overflow_buffer, simplePushPop)
|
|
{
|
|
overflow_buffer pb(10);
|
|
cf_t data[10];
|
|
for (int i = 0; i < 10; i++) {
|
|
data[i] = {(float)i, (float)(i + 1)};
|
|
}
|
|
pb.push_samples(data, 10);
|
|
ASSERT_EQ(pb.size(), 10);
|
|
cf_t read_data[10];
|
|
ASSERT_EQ(pb.pop_samples(read_data, 10), 10);
|
|
for (int i = 0; i < 10; i++) {
|
|
ASSERT_EQ(read_data[i].r, i);
|
|
ASSERT_EQ(read_data[i].i, i + 1);
|
|
}
|
|
}
|
|
|
|
TEST(overflow_buffer, zeros_to_send)
|
|
{
|
|
overflow_buffer pb(10);
|
|
pb.push_zeros(10);
|
|
cf_t data[5];
|
|
for (int i = 0; i < 5; i++) {
|
|
data[i] = {(float)i, (float)(i + 1)};
|
|
}
|
|
pb.push_samples(data, 5);
|
|
ASSERT_EQ(pb.size(), 15);
|
|
cf_t read_data[10];
|
|
ASSERT_EQ(pb.pop_samples(read_data, 10), 10);
|
|
for (int i = 0; i < 10; i++) {
|
|
ASSERT_EQ(read_data[i].r, 0);
|
|
ASSERT_EQ(read_data[i].i, 0);
|
|
}
|
|
ASSERT_EQ(pb.pop_samples(read_data, 10), 5);
|
|
for (int i = 0; i < 5; i++) {
|
|
ASSERT_EQ(read_data[i].r, i);
|
|
ASSERT_EQ(read_data[i].i, i + 1);
|
|
}
|
|
}
|
|
|
|
TEST(overflow_buffer, no_zeros_to_send)
|
|
{
|
|
overflow_buffer pb(10);
|
|
cf_t data[10];
|
|
for (int i = 0; i < 10; i++) {
|
|
data[i] = {(float)i, (float)(i + 1)};
|
|
}
|
|
pb.push_samples(data, 10);
|
|
ASSERT_EQ(pb.size(), 10);
|
|
cf_t read_data[10];
|
|
ASSERT_EQ(pb.pop_samples(read_data, 10), 10);
|
|
for (int i = 0; i < 10; i++) {
|
|
ASSERT_EQ(read_data[i].r, i);
|
|
ASSERT_EQ(read_data[i].i, i + 1);
|
|
}
|
|
}
|
|
|
|
TEST(overflow_buffer, overflow)
|
|
{
|
|
overflow_buffer pb(10);
|
|
cf_t data[15];
|
|
for (int i = 0; i < 15; i++) {
|
|
data[i] = {(float)i, (float)(i + 1)};
|
|
}
|
|
pb.push_samples(data, 15);
|
|
ASSERT_EQ(pb.size(), 15);
|
|
cf_t read_data[15];
|
|
ASSERT_EQ(pb.pop_samples(read_data, 15), 15);
|
|
// The first 5 samples were lost due to overflow.
|
|
int i = 0;
|
|
for (; i < 5; i++) {
|
|
ASSERT_EQ(read_data[i].r, 0);
|
|
ASSERT_EQ(read_data[i].i, 0);
|
|
}
|
|
for (; i < 15; i++) {
|
|
ASSERT_EQ(read_data[i].r, i);
|
|
ASSERT_EQ(read_data[i].i, i + 1);
|
|
}
|
|
ASSERT_EQ(pb.size(), 0);
|
|
}
|
|
|
|
TEST(overflow_buffer, push_zeros)
|
|
{
|
|
overflow_buffer pb(10);
|
|
pb.push_zeros(5);
|
|
ASSERT_EQ(pb.size(), 5);
|
|
cf_t data[5];
|
|
for (int i = 0; i < 5; i++) {
|
|
data[i] = {(float)i, (float)(i + 1)};
|
|
}
|
|
pb.push_samples(data, 5);
|
|
ASSERT_EQ(pb.size(), 10);
|
|
cf_t read_data[10];
|
|
ASSERT_EQ(pb.pop_samples(read_data, 10), 10);
|
|
for (int i = 0; i < 10; i++) {
|
|
if (i < 5) {
|
|
ASSERT_EQ(read_data[i].r, 0);
|
|
ASSERT_EQ(read_data[i].i, 0);
|
|
} else {
|
|
ASSERT_EQ(read_data[i].r, data[i - 5].r);
|
|
ASSERT_EQ(read_data[i].i, data[i - 5].i);
|
|
}
|
|
}
|
|
ASSERT_EQ(pb.size(), 0);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|