Add layer 1 software loopback test
This commit is contained in:
parent
c8e0516e80
commit
7d5b67a257
|
@ -12,3 +12,35 @@ target_link_libraries(
|
||||||
m
|
m
|
||||||
liquid
|
liquid
|
||||||
)
|
)
|
||||||
|
|
||||||
|
#------------------------------------
|
||||||
|
|
||||||
|
add_executable(
|
||||||
|
test_layer1_loopback
|
||||||
|
../src/layer1/correlator.c
|
||||||
|
../src/layer1/correlator.h
|
||||||
|
../src/layer1/freq_est.c
|
||||||
|
../src/layer1/freq_est.h
|
||||||
|
../src/layer1/packet_mod.c
|
||||||
|
../src/layer1/packet_mod.h
|
||||||
|
../src/layer1/preamble.c
|
||||||
|
../src/layer1/preamble.h
|
||||||
|
../src/layer1/transmission.c
|
||||||
|
../src/layer1/transmission.h
|
||||||
|
../src/layer1/tx.c
|
||||||
|
../src/layer1/tx.h
|
||||||
|
../src/layer1/rx.c
|
||||||
|
../src/layer1/rx.h
|
||||||
|
../src/layer1/whitening.c
|
||||||
|
../src/layer1/whitening.h
|
||||||
|
../src/layer1/modcod.c
|
||||||
|
../src/layer1/modcod.h
|
||||||
|
../src/utils.c
|
||||||
|
layer1/test_loopback.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
test_layer1_loopback
|
||||||
|
m
|
||||||
|
liquid
|
||||||
|
)
|
||||||
|
|
161
impl/test/layer1/test_loopback.c
Normal file
161
impl/test/layer1/test_loopback.c
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <liquid/liquid.h>
|
||||||
|
|
||||||
|
#include "layer1/tx.h"
|
||||||
|
#include "layer1/rx.h"
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include "sdr/sdr.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#define RESULT_CHECK(stmt) { \
|
||||||
|
result_t res = stmt; \
|
||||||
|
if(res != OK) { \
|
||||||
|
fprintf(stderr, "Error %d in %s:%d!\n", res, __FILE__, __LINE__); \
|
||||||
|
exit(1); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_complex_array(const char *varname, float complex const *array, size_t len)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s=np.array([%f%+fj", varname, crealf(array[0]), cimagf(array[0]));
|
||||||
|
for(size_t k = 1; k < len; k++) {
|
||||||
|
fprintf(stderr, ", %f%+fj", crealf(array[k]), cimagf(array[k]));
|
||||||
|
}
|
||||||
|
fprintf(stderr, "])\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void hexdump(const uint8_t *data, size_t len)
|
||||||
|
{
|
||||||
|
static const char lut[16] = "0123456789ABCDEF";
|
||||||
|
static const size_t BYTES_PER_LINE = 16;
|
||||||
|
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
|
while(pos < len) {
|
||||||
|
size_t bytes_in_line = len - pos;
|
||||||
|
if(bytes_in_line > BYTES_PER_LINE) {
|
||||||
|
bytes_in_line = BYTES_PER_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i = 0; i < BYTES_PER_LINE; i++) {
|
||||||
|
if(i >= bytes_in_line) {
|
||||||
|
fputs(" ", stderr);
|
||||||
|
} else {
|
||||||
|
uint8_t byte = data[pos+i];
|
||||||
|
|
||||||
|
fprintf(stderr, "%c%c ", lut[byte >> 4], lut[byte & 0x0F]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs(" ", stderr);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < bytes_in_line; i++) {
|
||||||
|
uint8_t byte = data[pos+i];
|
||||||
|
|
||||||
|
if(isprint(byte)) {
|
||||||
|
putc(byte, stderr);
|
||||||
|
} else {
|
||||||
|
putc('.', stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putc('\n', stderr);
|
||||||
|
pos += bytes_in_line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void cb_rx(rx_evt_t evt, uint8_t *packet_data, size_t packet_len)
|
||||||
|
{
|
||||||
|
switch(evt)
|
||||||
|
{
|
||||||
|
case RX_EVT_CHECKSUM_ERROR:
|
||||||
|
fprintf(stderr, "Received a message of %zu bytes, but decoding failed.\n", packet_len);
|
||||||
|
fprintf(stderr, "=== FAILED PAYLOAD ===\n");
|
||||||
|
hexdump(packet_data, packet_len);
|
||||||
|
fprintf(stderr, "=======================\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RX_EVT_PACKET_RECEIVED:
|
||||||
|
fprintf(stderr, "A message of %zu bytes was decoded successfully.\n", packet_len);
|
||||||
|
fprintf(stderr, "=== DECODED PAYLOAD (%4zu bytes) ===\n", packet_len);
|
||||||
|
hexdump(packet_data, packet_len < 64 ? packet_len : 64);
|
||||||
|
fprintf(stderr, "====================================\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RX_EVT_PREAMBLE_FOUND:
|
||||||
|
fprintf(stderr, "Found preamble!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
layer1_tx_t tx;
|
||||||
|
layer1_rx_t rx;
|
||||||
|
|
||||||
|
// ** Initialize **
|
||||||
|
|
||||||
|
RESULT_CHECK(layer1_tx_init(&tx));
|
||||||
|
RESULT_CHECK(layer1_rx_init(&rx, cb_rx));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ** Generate packets **
|
||||||
|
|
||||||
|
RESULT_CHECK(layer1_tx_reset(&tx));
|
||||||
|
|
||||||
|
uint8_t packetbuf1[] = "Hello World! 1234567890";
|
||||||
|
size_t l = sizeof(packetbuf1);
|
||||||
|
|
||||||
|
fprintf(stderr, "Transmitting packet with %zd bytes.\n", l);
|
||||||
|
|
||||||
|
RESULT_CHECK(layer1_tx_add_packet_to_burst(&tx, packetbuf1, l));
|
||||||
|
|
||||||
|
uint8_t packetbuf2[] = "This is just a test message. Just writing some stuff here to create a longer packet.";
|
||||||
|
l = sizeof(packetbuf2);
|
||||||
|
|
||||||
|
fprintf(stderr, "Transmitting packet with %zd bytes.\n", l);
|
||||||
|
|
||||||
|
RESULT_CHECK(layer1_tx_add_packet_to_burst(&tx, packetbuf2, l));
|
||||||
|
|
||||||
|
RESULT_CHECK(layer1_tx_finalize_burst(&tx));
|
||||||
|
|
||||||
|
size_t burst_len = layer1_tx_get_sample_count(&tx);
|
||||||
|
const float complex *whole_burst = layer1_tx_get_sample_data(&tx);
|
||||||
|
|
||||||
|
dump_array_cf(whole_burst, burst_len, 10e-6f, "/tmp/tx.cpx");
|
||||||
|
|
||||||
|
// ** Simulate channel effects **
|
||||||
|
channel_cccf ch = channel_cccf_create();
|
||||||
|
//channel_cccf_add_awgn(ch, -30, 15);
|
||||||
|
channel_cccf_add_carrier_offset(ch, 0.01f, 1.23f);
|
||||||
|
|
||||||
|
float complex whole_burst_ch[burst_len];
|
||||||
|
channel_cccf_execute_block(ch, (float complex*)whole_burst, burst_len, whole_burst_ch);
|
||||||
|
|
||||||
|
dump_array_cf(whole_burst_ch, burst_len, 10e-6f, "/tmp/rx.cpx");
|
||||||
|
|
||||||
|
|
||||||
|
// ** Receive signal **
|
||||||
|
|
||||||
|
RESULT_CHECK(layer1_rx_process(&rx, whole_burst_ch, burst_len));
|
||||||
|
|
||||||
|
// ** Cleanup **
|
||||||
|
|
||||||
|
layer1_tx_shutdown(&tx);
|
||||||
|
layer1_rx_shutdown(&rx);
|
||||||
|
|
||||||
|
fprintf(stderr, "Done.\n");
|
||||||
|
}
|
Loading…
Reference in a new issue