diff --git a/impl/CMakeLists.txt b/impl/CMakeLists.txt index a819d87..a71b356 100644 --- a/impl/CMakeLists.txt +++ b/impl/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.20) project (hamnet70 VERSION 0.1 LANGUAGES C) set(CMAKE_C_STANDARD 99) -set(CMAKE_C_FLAGS "-Wall -pedantic -Wextra -DDEBUG_LIQUID") +set(CMAKE_C_FLAGS "-Wall -pedantic -Wextra -DDEBUG_LIQUID -fsanitize=address") include_directories(src) @@ -55,8 +55,8 @@ set(sources src/layer2/ham64.h src/layer2/connection.c src/layer2/connection.h - src/sdr/sdr.c - src/sdr/sdr.h + src/sdr/sdr_sxceiver.c + src/sdr/sdr_sxceiver.h ) include_directories( @@ -75,7 +75,7 @@ target_link_libraries( rt fftw3f fec - hackrf + SoapySDR ) add_subdirectory(test) diff --git a/impl/src/main.c b/impl/src/main.c index b011776..ff42625 100644 --- a/impl/src/main.c +++ b/impl/src/main.c @@ -35,7 +35,7 @@ #include "layer2/tundev.h" -#include "sdr/sdr.h" +#include "sdr/sdr_sxceiver.h" #include "config.h" @@ -149,14 +149,7 @@ void cb_rx(rx_evt_t evt, const struct layer1_rx_s *rx, uint8_t *packet_data, siz static result_t transmit(sdr_ctx_t *sdr, const float complex *samples, size_t len) { - size_t to_transmit_rf = len * SDR_OVERSAMPLING; - float complex *rf_samples = malloc(sizeof(*rf_samples) * to_transmit_rf); - - RESULT_CHECK(sdr_baseband_to_rf(sdr, samples, len, rf_samples, &to_transmit_rf)); - - result_t result = sdr_transmit(sdr, rf_samples, to_transmit_rf, 100000); - - free(rf_samples); + result_t result = sdr_transmit(sdr, samples, len, 100000); fprintf(stderr, "t"); return result; @@ -256,7 +249,7 @@ int main(int argc, char **argv) // there is a packet to be (re)transmitted. // check free buffer space (50 ms required corresponding to 5000 baseband symbols) - size_t buffer_free_space_samples = sdr_get_tx_buffer_free_space(&sdr); + size_t buffer_free_space_samples = 1000000; // FIXME! sdr_get_tx_buffer_free_space(&sdr); LOG(LVL_DEBUG, "TX buffer free: %zu", buffer_free_space_samples); @@ -318,7 +311,6 @@ int main(int argc, char **argv) on_air = true; } else if(on_air) { // TX on, but no more bursts to send LOG(LVL_INFO, "TX -> RX"); - RESULT_CHECK(sdr_flush_tx_buffer(&sdr)); RESULT_CHECK(layer1_rx_reset(&rx)); RESULT_CHECK(sdr_stop_tx(&sdr)); @@ -343,7 +335,7 @@ int main(int argc, char **argv) size_t n_rf_samples = CHUNKSIZE_RF; size_t n_bb_samples = CHUNKSIZE_BB; - if(sdr_receive(&sdr, rf_samples, &n_rf_samples, 100000, SDR_OVERSAMPLING) != OK) { + if(sdr_receive(&sdr, bb_samples, &n_bb_samples, 100000) != OK) { rx_retries++; LOG(LVL_INFO, "sdr_receive() failed %d times.", rx_retries); if(rx_retries >= 3) { @@ -382,8 +374,6 @@ int main(int argc, char **argv) fprintf(stderr, "r"); - RESULT_CHECK(sdr_rf_to_baseband(&sdr, rf_samples, n_rf_samples, bb_samples, &n_bb_samples)); - RESULT_CHECK(layer1_rx_process(&rx, bb_samples, n_bb_samples)); } else { rx_retries = 0; diff --git a/impl/src/sdr/sdr_sxceiver.c b/impl/src/sdr/sdr_sxceiver.c index 7d7e617..01f5967 100644 --- a/impl/src/sdr/sdr_sxceiver.c +++ b/impl/src/sdr/sdr_sxceiver.c @@ -10,14 +10,14 @@ #include "config.h" -#include "sdr.h" +#include "sdr_sxceiver.h" void soapy_log_handler(const SoapySDRLogLevel logLevel, const char *message) { fprintf(stderr, "soapy [%d]: %s\n", logLevel, message); } -static void close_streams(sdr_sxceiver_ctx_t *ctx) +static void close_streams(sdr_ctx_t *ctx) { if(ctx->rx_stream) { SoapySDRDevice_deactivateStream(ctx->sdr, ctx->rx_stream, 0, 0); @@ -31,7 +31,7 @@ static void close_streams(sdr_sxceiver_ctx_t *ctx) } -result_t sdr_sxceiver_init(sdr_sxceiver_ctx_t *ctx) +result_t sdr_init(sdr_ctx_t *ctx) { size_t length; @@ -76,6 +76,7 @@ result_t sdr_sxceiver_init(sdr_sxceiver_ctx_t *ctx) } //query device info + SoapySDRRange *ranges; char** names = SoapySDRDevice_listAntennas(ctx->sdr, SOAPY_SDR_RX, 0, &length); fprintf(stderr, "sdr: Rx antennas: "); for (size_t i = 0; i < length; i++) fprintf(stderr, "%s, ", names[i]); @@ -84,17 +85,20 @@ result_t sdr_sxceiver_init(sdr_sxceiver_ctx_t *ctx) names = SoapySDRDevice_listGains(ctx->sdr, SOAPY_SDR_RX, 0, &length); fprintf(stderr, "sdr: Rx gains: "); - for (size_t i = 0; i < length; i++) fprintf(stderr, "%s, ", names[i]); + for (size_t i = 0; i < length; i++) { + SoapySDRRange range = SoapySDRDevice_getGainRange(ctx->sdr, SOAPY_SDR_RX, i); + fprintf(stderr, "%s [%.3lf .. %.3lf / %.3lf], ", names[i], range.minimum, range.maximum, range.step); + } fprintf(stderr, "\n"); SoapySDRStrings_clear(&names, length); - SoapySDRRange *ranges = SoapySDRDevice_getFrequencyRange(ctx->sdr, SOAPY_SDR_RX, 0, &length); + ranges = SoapySDRDevice_getFrequencyRange(ctx->sdr, SOAPY_SDR_RX, 0, &length); fprintf(stderr, "sdr: Rx freq ranges: "); for (size_t i = 0; i < length; i++) fprintf(stderr, "[%g Hz -> %g Hz], ", ranges[i].minimum, ranges[i].maximum); fprintf(stderr, "\n"); free(ranges); - char** names = SoapySDRDevice_listAntennas(ctx->sdr, SOAPY_SDR_TX, 0, &length); + names = SoapySDRDevice_listAntennas(ctx->sdr, SOAPY_SDR_TX, 0, &length); fprintf(stderr, "sdr: Tx antennas: "); for (size_t i = 0; i < length; i++) fprintf(stderr, "%s, ", names[i]); fprintf(stderr, "\n"); @@ -102,11 +106,14 @@ result_t sdr_sxceiver_init(sdr_sxceiver_ctx_t *ctx) names = SoapySDRDevice_listGains(ctx->sdr, SOAPY_SDR_TX, 0, &length); fprintf(stderr, "sdr: Tx gains: "); - for (size_t i = 0; i < length; i++) fprintf(stderr, "%s, ", names[i]); + for (size_t i = 0; i < length; i++) { + SoapySDRRange range = SoapySDRDevice_getGainRange(ctx->sdr, SOAPY_SDR_TX, i); + fprintf(stderr, "%s [%.3lf .. %.3lf / %.3lf], ", names[i], range.minimum, range.maximum, range.step); + } fprintf(stderr, "\n"); SoapySDRStrings_clear(&names, length); - SoapySDRRange *ranges = SoapySDRDevice_getFrequencyRange(ctx->sdr, SOAPY_SDR_TX, 0, &length); + ranges = SoapySDRDevice_getFrequencyRange(ctx->sdr, SOAPY_SDR_TX, 0, &length); fprintf(stderr, "sdr: Tx freq ranges: "); for (size_t i = 0; i < length; i++) fprintf(stderr, "[%g Hz -> %g Hz], ", ranges[i].minimum, ranges[i].maximum); fprintf(stderr, "\n"); @@ -150,7 +157,7 @@ result_t sdr_sxceiver_init(sdr_sxceiver_ctx_t *ctx) } -result_t sdr_sxceiver_destroy(sdr_sxceiver_ctx_t *ctx) +result_t sdr_destroy(sdr_ctx_t *ctx) { close_streams(ctx); @@ -165,15 +172,10 @@ result_t sdr_sxceiver_destroy(sdr_sxceiver_ctx_t *ctx) } -result_t sdr_sxceiver_start_rx(sdr_sxceiver_ctx_t *ctx) +result_t sdr_start_rx(sdr_ctx_t *ctx) { - if(SoapySDRDevice_activateStream(ctx->sdr, ctx->rx_stream, 0, 0, 0) != 0) { - fprintf(stderr, "sdr: activateStream fail: %s\n", SoapySDRDevice_lastError()); - return ERR_SOAPY; - } - // set gains - if(SoapySDRDevice_setGainElement(ctx->sdr, SOAPY_SDR_RX, 0, "AMP", SDR_GAIN_RX_AMP) != 0) { + if(SoapySDRDevice_setGainElement(ctx->sdr, SOAPY_SDR_RX, 0, "PGA", SDR_GAIN_RX_PGA) != 0) { fprintf(stderr, "sdr: setGainElement fail: %s\n", SoapySDRDevice_lastError()); return ERR_SOAPY; } @@ -183,8 +185,8 @@ result_t sdr_sxceiver_start_rx(sdr_sxceiver_ctx_t *ctx) return ERR_SOAPY; } - if(SoapySDRDevice_setGainElement(ctx->sdr, SOAPY_SDR_RX, 0, "VGA", SDR_GAIN_RX_VGA) != 0) { - fprintf(stderr, "sdr: setGainElement fail: %s\n", SoapySDRDevice_lastError()); + if(SoapySDRDevice_activateStream(ctx->sdr, ctx->rx_stream, 0, 0, 0) != 0) { + fprintf(stderr, "sdr: activateStream fail: %s\n", SoapySDRDevice_lastError()); return ERR_SOAPY; } @@ -192,15 +194,15 @@ result_t sdr_sxceiver_start_rx(sdr_sxceiver_ctx_t *ctx) } -result_t sdr_sxceiver_start_tx(sdr_sxceiver_ctx_t *ctx, size_t burst_size) +result_t sdr_start_tx(sdr_ctx_t *ctx, size_t burst_size) { // set gain - if(SoapySDRDevice_setGainElement(ctx->sdr, SOAPY_SDR_TX, 0, "AMP", SDR_GAIN_TX_AMP) != 0) { + if(SoapySDRDevice_setGainElement(ctx->sdr, SOAPY_SDR_TX, 0, "DAC", SDR_GAIN_TX_DAC) != 0) { fprintf(stderr, "sdr: setGainElement fail: %s\n", SoapySDRDevice_lastError()); return ERR_SOAPY; } - if(SoapySDRDevice_setGainElement(ctx->sdr, SOAPY_SDR_TX, 0, "LNA", SDR_GAIN_TX_LNA) != 0) { + if(SoapySDRDevice_setGainElement(ctx->sdr, SOAPY_SDR_TX, 0, "MIXER", SDR_GAIN_TX_MIXER) != 0) { fprintf(stderr, "sdr: setGainElement fail: %s\n", SoapySDRDevice_lastError()); return ERR_SOAPY; } @@ -214,7 +216,7 @@ result_t sdr_sxceiver_start_tx(sdr_sxceiver_ctx_t *ctx, size_t burst_size) } -result_t sdr_sxceiver_stop_rx(sdr_sxceiver_ctx_t *ctx) +result_t sdr_stop_rx(sdr_ctx_t *ctx) { if(SoapySDRDevice_deactivateStream(ctx->sdr, ctx->rx_stream, 0, 0) != 0) { fprintf(stderr, "sdr: activateStream fail: %s\n", SoapySDRDevice_lastError()); @@ -225,7 +227,7 @@ result_t sdr_sxceiver_stop_rx(sdr_sxceiver_ctx_t *ctx) } -result_t sdr_sxceiver_stop_tx(sdr_sxceiver_ctx_t *ctx) +result_t sdr_stop_tx(sdr_ctx_t *ctx) { if(SoapySDRDevice_deactivateStream(ctx->sdr, ctx->tx_stream, 0, 0) != 0) { fprintf(stderr, "sdr: activateStream fail: %s\n", SoapySDRDevice_lastError()); @@ -236,7 +238,7 @@ result_t sdr_sxceiver_stop_tx(sdr_sxceiver_ctx_t *ctx) } -result_t sdr_sxceiver_transmit(sdr_sxceiver_ctx_t *ctx, const float complex *samples, size_t nsamples, long timeout_us) +result_t sdr_transmit(sdr_ctx_t *ctx, const float complex *samples, size_t nsamples, long timeout_us) { if(ctx->tx_stream == NULL) { return ERR_INVALID_STATE; @@ -244,7 +246,8 @@ result_t sdr_sxceiver_transmit(sdr_sxceiver_ctx_t *ctx, const float complex *sam void *buffs[] = {(void*)samples}; - int ret = SoapySDRDevice_writeStream(ctx->sdr, ctx->tx_stream, (const void* const*)buffs, nsamples, 0, 0, timeout_us); + int flags = 0; + int ret = SoapySDRDevice_writeStream(ctx->sdr, ctx->tx_stream, (const void* const*)buffs, nsamples, &flags, 0, timeout_us); if(ret <= 0) { fprintf(stderr, "sdr: writeStream fail: %s\n", SoapySDRDevice_lastError()); @@ -255,7 +258,7 @@ result_t sdr_sxceiver_transmit(sdr_sxceiver_ctx_t *ctx, const float complex *sam } -result_t sdr_sxceiver_receive(sdr_sxceiver_ctx_t *ctx, float complex *samples, size_t *nsamples, long timeout_us) +result_t sdr_receive(sdr_ctx_t *ctx, float complex *samples, size_t *nsamples, long timeout_us) { if(ctx->rx_stream == NULL) { return ERR_INVALID_STATE; @@ -263,7 +266,9 @@ result_t sdr_sxceiver_receive(sdr_sxceiver_ctx_t *ctx, float complex *samples, s void *buffs[] = {(void*)samples}; - int ret = SoapySDRDevice_readStream(ctx->sdr, ctx->rx_stream, (void* const*)buffs, *nsamples, 0, 0, timeout_us); + long long timeNs; + int flags; + int ret = SoapySDRDevice_readStream(ctx->sdr, ctx->rx_stream, (void* const*)buffs, *nsamples, &flags, &timeNs, timeout_us); if(ret <= 0) { fprintf(stderr, "sdr: readStream fail: %s\n", SoapySDRDevice_lastError());