2021-10-17 19:26:38 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <assert.h>
|
2022-01-30 20:05:20 +01:00
|
|
|
#include <math.h>
|
2021-10-17 19:26:38 +02:00
|
|
|
#include <liquid/liquid.h>
|
|
|
|
|
|
|
|
#include "utils.h"
|
2022-02-13 21:29:35 +01:00
|
|
|
#include "layer1/tx.h"
|
2022-02-16 20:52:46 +01:00
|
|
|
#include "layer1/rx.h"
|
2022-02-13 21:29:35 +01:00
|
|
|
|
|
|
|
#define RESULT_CHECK(stmt) { \
|
|
|
|
result_t res = stmt; \
|
|
|
|
if(res != OK) { \
|
|
|
|
printf("Error %d in %s:%d!", res, __FILE__, __LINE__); \
|
|
|
|
exit(1); \
|
|
|
|
} \
|
|
|
|
}
|
2022-02-01 21:35:43 +01:00
|
|
|
|
2022-02-03 22:18:24 +01:00
|
|
|
void print_complex_array(const char *varname, float complex const *array, size_t len)
|
|
|
|
{
|
|
|
|
printf("%s=np.array([%f%+fj", varname, crealf(array[0]), cimagf(array[0]));
|
|
|
|
for(size_t k = 1; k < len; k++) {
|
|
|
|
printf(", %f%+fj", crealf(array[k]), cimagf(array[k]));
|
|
|
|
}
|
|
|
|
printf("])\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-02-16 20:52:46 +01:00
|
|
|
void cb_rx(rx_evt_t evt, uint8_t *packet_data, size_t packet_len)
|
2022-02-12 21:58:53 +01:00
|
|
|
{
|
2022-02-16 20:52:46 +01:00
|
|
|
switch(evt)
|
|
|
|
{
|
|
|
|
case RX_EVT_CHECKSUM_ERROR:
|
|
|
|
printf("Received a message of %zu bytes, but decoding failed.\n", packet_len);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RX_EVT_PACKET_RECEIVED:
|
|
|
|
printf("=== DECODED PAYLOAD ===\n");
|
|
|
|
printf("%s\n", packet_data);
|
|
|
|
printf("=======================\n");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RX_EVT_PREAMBLE_FOUND:
|
|
|
|
printf("Found preamble!");
|
|
|
|
break;
|
|
|
|
}
|
2022-02-12 21:58:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-17 19:26:38 +02:00
|
|
|
int main(void)
|
|
|
|
{
|
|
|
|
uint8_t msg_org[] = "Hello Liquid! This is the message to transmit. Hopefully it can be decoded correctly...";
|
|
|
|
|
2022-02-16 20:52:46 +01:00
|
|
|
// ** Modulate packet **
|
|
|
|
|
2022-02-13 21:29:35 +01:00
|
|
|
layer1_tx_t tx;
|
|
|
|
|
|
|
|
RESULT_CHECK(layer1_tx_init(&tx));
|
|
|
|
RESULT_CHECK(layer1_tx_add_packet_to_burst(&tx, msg_org, sizeof(msg_org)));
|
|
|
|
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, 1.0f, "/tmp/tx.cpx");
|
|
|
|
|
2022-02-16 20:52:46 +01:00
|
|
|
// ** Apply channel distortions **
|
2021-10-17 19:26:38 +02:00
|
|
|
|
|
|
|
channel_cccf channel = channel_cccf_create();
|
|
|
|
|
2022-02-16 20:52:46 +01:00
|
|
|
float snr = 8.0f;
|
2021-10-17 19:26:38 +02:00
|
|
|
channel_cccf_add_awgn(channel, -snr, snr);
|
2022-01-30 20:23:41 +01:00
|
|
|
channel_cccf_add_carrier_offset(channel, 0.20f, 1.00f);
|
2021-10-17 19:26:38 +02:00
|
|
|
|
|
|
|
// channel
|
2022-01-29 22:36:41 +01:00
|
|
|
float complex msg_received[burst_len];
|
2021-10-17 19:26:38 +02:00
|
|
|
|
2022-01-29 22:36:41 +01:00
|
|
|
//memcpy(msg_received, whole_burst, sizeof(whole_burst)); // no noise in channel
|
2021-10-17 19:26:38 +02:00
|
|
|
|
2022-01-29 22:36:41 +01:00
|
|
|
channel_cccf_execute_block(channel, whole_burst, burst_len, msg_received);
|
|
|
|
dump_array_cf(msg_received, burst_len, 1.0f, "/tmp/rx.cpx");
|
2021-10-17 19:26:38 +02:00
|
|
|
|
2022-02-16 20:52:46 +01:00
|
|
|
// ** RX starts here **
|
2021-10-17 19:26:38 +02:00
|
|
|
|
2022-02-16 20:52:46 +01:00
|
|
|
layer1_rx_t rx;
|
2022-01-30 20:05:20 +01:00
|
|
|
|
2022-02-16 20:52:46 +01:00
|
|
|
RESULT_CHECK(layer1_rx_init(&rx, cb_rx));
|
2022-01-30 20:05:20 +01:00
|
|
|
|
2022-02-16 20:52:46 +01:00
|
|
|
RESULT_CHECK(layer1_rx_process(&rx, msg_received, burst_len));
|
2021-10-17 19:26:38 +02:00
|
|
|
|
2022-02-16 20:52:46 +01:00
|
|
|
// cleanup
|
2021-10-17 19:26:38 +02:00
|
|
|
|
|
|
|
channel_cccf_destroy(channel);
|
|
|
|
|
2022-02-16 20:52:46 +01:00
|
|
|
layer1_tx_shutdown(&tx);
|
|
|
|
layer1_rx_shutdown(&rx);
|
|
|
|
|
2021-10-17 19:26:38 +02:00
|
|
|
printf("Done.\n");
|
|
|
|
}
|