#include #include #include #include #include #include #include "layer1/tx.h" #include "layer1/rx.h" #include "logger.h" #include "utils.h" #define RESULT_CHECK(stmt) { \ result_t res = stmt; \ if(res != OK) { \ LOG(LVL_ERR, "Error %d in %s:%d!", 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, const layer1_rx_t *rx, uint8_t *packet_data, size_t packet_len) { (void)rx; switch(evt) { case RX_EVT_CHECKSUM_ERROR: LOG(LVL_ERR, "Received a message of %zu bytes, but decoding failed.", packet_len); LOG(LVL_INFO, "=== FAILED PAYLOAD ==="); hexdump(packet_data, packet_len); LOG(LVL_INFO, "======================="); break; case RX_EVT_PACKET_RECEIVED: LOG(LVL_INFO, "A message of %zu bytes was decoded successfully.", packet_len); LOG(LVL_INFO, "=== DECODED PAYLOAD (%4zu bytes) ===", packet_len); hexdump(packet_data, packet_len < 64 ? packet_len : 64); LOG(LVL_INFO, "===================================="); break; case RX_EVT_HEADER_ERROR: LOG(LVL_ERR, "Header decoding failed!"); break; case RX_EVT_PREAMBLE_FOUND: LOG(LVL_INFO, "Found preamble!"); break; case RX_EVT_PACKET_DEBUG_INFO_COMPLETE: // FIXME: print debug info break; } } int main(void) { layer1_tx_t tx; layer1_rx_t rx; // ** Initialize ** logger_init(); srand(time(NULL)); 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); LOG(LVL_INFO, "Transmitting packet with %zd bytes.", 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); LOG(LVL_INFO, "Transmitting packet with %zd bytes.", 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, 10); //channel_cccf_add_carrier_offset(ch, 0.05f, 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); LOG(LVL_INFO, "Done."); }