From 152d2f02f609134d48a87c7bc62c644fe13a2350 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Sat, 5 Mar 2022 21:38:05 +0100 Subject: [PATCH] Basic transmitter-only main loop --- impl/src/main.c | 186 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 147 insertions(+), 39 deletions(-) diff --git a/impl/src/main.c b/impl/src/main.c index b472478..a4dcb30 100644 --- a/impl/src/main.c +++ b/impl/src/main.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -7,7 +8,10 @@ #include +#include #include +#include +#include #include "utils.h" #include "layer1/tx.h" @@ -15,6 +19,10 @@ #include "layer2/tundev.h" +#include "sdr/sdr.h" + +#include "config.h" + #define RESULT_CHECK(stmt) { \ result_t res = stmt; \ if(res != OK) { \ @@ -108,11 +116,65 @@ void cb_rx(rx_evt_t evt, uint8_t *packet_data, size_t packet_len) } +static int debug_fd; + + +#define CHUNKSIZE_BB 512 +#define CHUNKSIZE_RF (CHUNKSIZE_BB * SDR_OVERSAMPLING) +static result_t transmit_in_chunks(sdr_ctx_t *sdr, const float complex *samples, size_t len) +{ + size_t transmitted = 0; + unsigned retry_counter = 0; + + float complex rf_samples[CHUNKSIZE_RF]; + + while(transmitted < len) { + size_t to_transmit_bb = len - transmitted; + if(to_transmit_bb > CHUNKSIZE_BB) { + to_transmit_bb = CHUNKSIZE_BB; + } + + RESULT_CHECK(sdr_baseband_to_rf(sdr, samples + transmitted, to_transmit_bb, rf_samples, CHUNKSIZE_RF)); + + size_t to_transmit_rf = to_transmit_bb * SDR_OVERSAMPLING; + + result_t result = sdr_transmit(sdr, rf_samples, to_transmit_rf, 100000); + + if(result != OK) { + retry_counter++; + fprintf(stderr, "sdr_transmit failed %d times\n", retry_counter); + + if(retry_counter > 3) { + return result; + } else { + continue; + } + } + + write(debug_fd, rf_samples, to_transmit_rf*sizeof(rf_samples[0])); + + fprintf(stderr, "t"); + + transmitted += to_transmit_bb; + + retry_counter = 0; + } + + return OK; +} + + int main(void) { layer1_tx_t tx; layer1_rx_t rx; + sdr_ctx_t sdr; + + bool on_air = false; + + debug_fd = open("/tmp/dump.cf32", O_CREAT | O_WRONLY | O_TRUNC); + // ** Initialize ** char devname[IFNAMSIZ] = "hamnet70"; @@ -122,68 +184,114 @@ int main(void) return 1; } + RESULT_CHECK(sdr_init(&sdr)); + RESULT_CHECK(layer1_tx_init(&tx)); RESULT_CHECK(layer1_rx_init(&rx, cb_rx)); - // channel emulation - channel_cccf channel = channel_cccf_create(); - - float snr = 15.0f; - channel_cccf_add_awgn(channel, -snr, snr); - channel_cccf_add_carrier_offset(channel, 0.20f, 1.00f); - //channel_cccf_add_shadowing(channel, 1.00f, 0.1f); - // ** Process packets ** - uint8_t packetbuf[2048]; + struct pollfd pfd; + memset(&pfd, 0, sizeof(pfd)); + + pfd.fd = m_tunfd; + pfd.events = POLLIN; + + RESULT_CHECK(sdr_start_rx(&sdr)); + + unsigned rx_retries = 0; + + float complex zeros[1024]; + memset(zeros, 0, sizeof(zeros)); + while(m_running) { - int ret = read(m_tunfd, packetbuf, sizeof(packetbuf)); - if(ret < 0) { - perror("read"); - break; - } else if(ret == 0) { - // no more data - break; + if(on_air || !layer1_rx_is_busy(&rx)) { + int ret = poll(&pfd, 1, 0); + if(ret < 0) { + perror("poll"); + break; + } else if(ret > 0) { + // there is a packet to be read. + uint8_t packetbuf[2048]; + ret = read(m_tunfd, packetbuf, sizeof(packetbuf)); + if(ret < 0) { + perror("read"); + break; + } else if(ret == 0) { + // no more data + break; + } + + fprintf(stderr, "Transmitting packet with %d bytes.\n", ret); + + RESULT_CHECK(layer1_tx_reset(&tx)); + + // ** Modulate packet ** + + RESULT_CHECK(layer1_tx_add_packet_to_burst(&tx, packetbuf, ret)); + 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"); + + if(!on_air) { + RESULT_CHECK(sdr_start_tx(&sdr)); + } + + RESULT_CHECK(transmit_in_chunks(&sdr, whole_burst, burst_len)); + + on_air = true; + } else if(on_air) { // ret == 0 + //RESULT_CHECK(sdr_start_rx(&sdr)); + //on_air = false; + fprintf(stderr, "z"); + sdr_transmit(&sdr, zeros, sizeof(zeros)/sizeof(zeros[0]), 100000); + } } - fprintf(stderr, "Transmitting packet with %d bytes.\n", ret); + if(!on_air) { + // ** Receive signal ** - RESULT_CHECK(layer1_tx_reset(&tx)); + float complex rf_samples[CHUNKSIZE_RF]; + float complex bb_samples[CHUNKSIZE_BB]; - // ** Modulate packet ** + size_t n_rf_samples = CHUNKSIZE_RF; + size_t n_bb_samples; - RESULT_CHECK(layer1_tx_add_packet_to_burst(&tx, packetbuf, ret)); - RESULT_CHECK(layer1_tx_finalize_burst(&tx)); + if(sdr_receive(&sdr, rf_samples, &n_rf_samples, 100000) != OK) { + rx_retries++; + fprintf(stderr, "sdr_receive() failed %d times.\n", rx_retries); + if(rx_retries >= 3) { + break; + } else { + continue; + } + } - size_t burst_len = layer1_tx_get_sample_count(&tx); - const float complex *whole_burst = layer1_tx_get_sample_data(&tx); + rx_retries = 0; - dump_array_cf(whole_burst, burst_len, 1.0f, "/tmp/tx.cpx"); + fprintf(stderr, "r"); - // ** Apply channel distortions ** + RESULT_CHECK(sdr_rf_to_baseband(&sdr, rf_samples, n_rf_samples, bb_samples, CHUNKSIZE_BB)); - float complex msg_received[burst_len]; + n_bb_samples = n_rf_samples / SDR_OVERSAMPLING; - channel_cccf_execute_block(channel, whole_burst, burst_len, msg_received); - - // scale the entire signal to give the AGC something to do - for(size_t i = 0; i < burst_len; i++) { - msg_received[i] *= 0.02f; + RESULT_CHECK(layer1_rx_process(&rx, bb_samples, n_bb_samples)); + } else { + rx_retries = 0; } - - dump_array_cf(msg_received, burst_len, 1.0f, "/tmp/rx.cpx"); - - // ** Receive signal ** - - RESULT_CHECK(layer1_rx_process(&rx, msg_received, burst_len)); } - // ** Cleanup ** + close(debug_fd); - channel_cccf_destroy(channel); + // ** Cleanup ** layer1_tx_shutdown(&tx); layer1_rx_shutdown(&rx); + sdr_destroy(&sdr); + fprintf(stderr, "Done.\n"); }