diff --git a/plugins/samplesource/CMakeLists.txt b/plugins/samplesource/CMakeLists.txt index 15c150253..7451854a4 100644 --- a/plugins/samplesource/CMakeLists.txt +++ b/plugins/samplesource/CMakeLists.txt @@ -4,10 +4,10 @@ add_subdirectory(fileinput) add_subdirectory(testsource) add_subdirectory(localinput) -if(ENABLE_FOBOS AND WIN32) +if(ENABLE_FOBOS AND (WIN32 OR (UNIX AND NOT APPLE))) add_subdirectory(fobos) else() - message(STATUS "Not building fobos input (ENABLE_FOBOS=${ENABLE_FOBOS} WIN32=${WIN32})") + message(STATUS "Not building fobos input (ENABLE_FOBOS=${ENABLE_FOBOS} WIN32=${WIN32} UNIX=${UNIX} APPLE=${APPLE})") endif() if (CM256CC_FOUND AND (HAS_SSE3 OR HAS_NEON)) diff --git a/plugins/samplesource/fobos/CMakeLists.txt b/plugins/samplesource/fobos/CMakeLists.txt index 7f063752b..8e30a2439 100644 --- a/plugins/samplesource/fobos/CMakeLists.txt +++ b/plugins/samplesource/fobos/CMakeLists.txt @@ -5,6 +5,68 @@ option(FOBOS_DEBUG_FILE_LOG "Write Fobos SDR diagnostic log file" OFF) # Fobos SDR runtime packages. On Windows official builds these are expected # to come from external/windows/fobos-sdr and external/windows/fobos-regular # in the SDRangel Windows dependency repo. +# +# On Linux the plugin is intended to runtime-load libfobos_sdr.so / libfobos.so. +# CMake still verifies headers and libraries early so developer builds fail with +# a clear diagnostic instead of a hidden runtime loader error. +if(UNIX AND NOT APPLE) + find_package(PkgConfig QUIET) + if(PkgConfig_FOUND) + pkg_check_modules(FOBOS_SDR_PC QUIET libfobos_sdr) + pkg_check_modules(FOBOS_REGULAR_PC QUIET libfobos) + endif() + + set(FOBOS_SDR_INCLUDE_DIR "${FOBOS_SDR_INCLUDE_DIR}" CACHE PATH "Fobos SDR Agile include directory") + set(FOBOS_SDR_LIBRARY "${FOBOS_SDR_LIBRARY}" CACHE FILEPATH "Fobos SDR Agile runtime library") + set(FOBOS_REGULAR_INCLUDE_DIR "${FOBOS_REGULAR_INCLUDE_DIR}" CACHE PATH "Fobos SDR regular include directory") + set(FOBOS_REGULAR_LIBRARY "${FOBOS_REGULAR_LIBRARY}" CACHE FILEPATH "Fobos SDR regular runtime library") + + if(NOT FOBOS_SDR_INCLUDE_DIR AND DEFINED ENV{FOBOS_SDR_DIR}) + set(FOBOS_SDR_INCLUDE_DIR "$ENV{FOBOS_SDR_DIR}/include" CACHE PATH "Fobos SDR Agile include directory" FORCE) + endif() + if(NOT FOBOS_SDR_LIBRARY AND DEFINED ENV{FOBOS_SDR_DIR}) + set(FOBOS_SDR_LIBRARY "$ENV{FOBOS_SDR_DIR}/lib/libfobos_sdr.so" CACHE FILEPATH "Fobos SDR Agile runtime library" FORCE) + endif() + + if(NOT FOBOS_REGULAR_INCLUDE_DIR AND DEFINED ENV{FOBOS_DIR}) + set(FOBOS_REGULAR_INCLUDE_DIR "$ENV{FOBOS_DIR}/include" CACHE PATH "Fobos SDR regular include directory" FORCE) + endif() + if(NOT FOBOS_REGULAR_LIBRARY AND DEFINED ENV{FOBOS_DIR}) + set(FOBOS_REGULAR_LIBRARY "$ENV{FOBOS_DIR}/lib/libfobos.so" CACHE FILEPATH "Fobos SDR regular runtime library" FORCE) + endif() + + if(NOT FOBOS_SDR_INCLUDE_DIR AND FOBOS_SDR_PC_INCLUDE_DIRS) + list(GET FOBOS_SDR_PC_INCLUDE_DIRS 0 FOBOS_SDR_INCLUDE_DIR) + set(FOBOS_SDR_INCLUDE_DIR "${FOBOS_SDR_INCLUDE_DIR}" CACHE PATH "Fobos SDR Agile include directory" FORCE) + endif() + if(NOT FOBOS_REGULAR_INCLUDE_DIR AND FOBOS_REGULAR_PC_INCLUDE_DIRS) + list(GET FOBOS_REGULAR_PC_INCLUDE_DIRS 0 FOBOS_REGULAR_INCLUDE_DIR) + set(FOBOS_REGULAR_INCLUDE_DIR "${FOBOS_REGULAR_INCLUDE_DIR}" CACHE PATH "Fobos SDR regular include directory" FORCE) + endif() + + if(NOT FOBOS_SDR_LIBRARY AND FOBOS_SDR_PC_LIBRARY_DIRS) + list(GET FOBOS_SDR_PC_LIBRARY_DIRS 0 FOBOS_SDR_LIBRARY_DIR) + set(FOBOS_SDR_LIBRARY "${FOBOS_SDR_LIBRARY_DIR}/libfobos_sdr.so" CACHE FILEPATH "Fobos SDR Agile runtime library" FORCE) + endif() + if(NOT FOBOS_REGULAR_LIBRARY AND FOBOS_REGULAR_PC_LIBRARY_DIRS) + list(GET FOBOS_REGULAR_PC_LIBRARY_DIRS 0 FOBOS_REGULAR_LIBRARY_DIR) + set(FOBOS_REGULAR_LIBRARY "${FOBOS_REGULAR_LIBRARY_DIR}/libfobos.so" CACHE FILEPATH "Fobos SDR regular runtime library" FORCE) + endif() + + if(NOT EXISTS "${FOBOS_SDR_INCLUDE_DIR}/fobos_sdr.h") + message(FATAL_ERROR "Fobos SDR Agile header not found: ${FOBOS_SDR_INCLUDE_DIR}/fobos_sdr.h") + endif() + if(NOT EXISTS "${FOBOS_SDR_LIBRARY}") + message(FATAL_ERROR "Fobos SDR Agile runtime library not found: ${FOBOS_SDR_LIBRARY}") + endif() + if(NOT EXISTS "${FOBOS_REGULAR_INCLUDE_DIR}/fobos.h") + message(FATAL_ERROR "Fobos SDR regular header not found: ${FOBOS_REGULAR_INCLUDE_DIR}/fobos.h") + endif() + if(NOT EXISTS "${FOBOS_REGULAR_LIBRARY}") + message(FATAL_ERROR "Fobos SDR regular runtime library not found: ${FOBOS_REGULAR_LIBRARY}") + endif() +endif() + if(WIN32) set(FOBOS_SDR_INCLUDE_DIR "${FOBOS_SDR_INCLUDE_DIR}" CACHE PATH "Fobos SDR Agile include directory") set(FOBOS_SDR_LIBRARY "${FOBOS_SDR_LIBRARY}" CACHE FILEPATH "Fobos SDR Agile import library") @@ -80,7 +142,7 @@ if(NOT BUILD_SHARED_LIBS) set_property(GLOBAL APPEND PROPERTY STATIC_PLUGINS_PROPERTY ${TARGET_NAME}) endif() -if(WIN32) +if(WIN32 OR UNIX) target_include_directories(${TARGET_NAME} PRIVATE ${FOBOS_SDR_INCLUDE_DIR} ${FOBOS_REGULAR_INCLUDE_DIR}) endif() diff --git a/plugins/samplesource/fobos/fobosgui.cpp b/plugins/samplesource/fobos/fobosgui.cpp index f682e5bbf..a12106ffb 100644 --- a/plugins/samplesource/fobos/fobosgui.cpp +++ b/plugins/samplesource/fobos/fobosgui.cpp @@ -40,7 +40,7 @@ #include #include -#include "ui_FOBOSgui.h" +#include "ui_fobosgui.h" #include "gui/colormapper.h" #include "gui/glspectrum.h" #include "gui/basicdevicesettingsdialog.h" @@ -50,7 +50,7 @@ #include "dsp/dspcommands.h" #include "util/db.h" -#include "FOBOSgui.h" +#include "fobosgui.h" #include "device/deviceapi.h" #include "device/deviceuiset.h" diff --git a/plugins/samplesource/fobos/fobosgui.h b/plugins/samplesource/fobos/fobosgui.h index 21c2cea13..2c024376e 100644 --- a/plugins/samplesource/fobos/fobosgui.h +++ b/plugins/samplesource/fobos/fobosgui.h @@ -26,8 +26,8 @@ #include "util/messagequeue.h" -#include "FOBOSsettings.h" -#include "FOBOSinput.h" +#include "fobossettings.h" +#include "fobosinput.h" class DeviceUISet; diff --git a/plugins/samplesource/fobos/fobosinput.cpp b/plugins/samplesource/fobos/fobosinput.cpp index b7cc7639a..d75adbecf 100644 --- a/plugins/samplesource/fobos/fobosinput.cpp +++ b/plugins/samplesource/fobos/fobosinput.cpp @@ -30,9 +30,9 @@ #include "SWGDeviceSettings.h" #include "SWGDeviceState.h" -#include "FOBOSinput.h" +#include "fobosinput.h" #include "device/deviceapi.h" -#include "FOBOSworker.h" +#include "fobosworker.h" #include "dsp/dspcommands.h" MESSAGE_CLASS_DEFINITION(FOBOSInput::MsgConfigureFOBOS, Message) diff --git a/plugins/samplesource/fobos/fobosinput.h b/plugins/samplesource/fobos/fobosinput.h index dab176a38..1f18c26db 100644 --- a/plugins/samplesource/fobos/fobosinput.h +++ b/plugins/samplesource/fobos/fobosinput.h @@ -27,7 +27,7 @@ #include #include -#include "FOBOSsettings.h" +#include "fobossettings.h" class DeviceAPI; class FOBOSWorker; diff --git a/plugins/samplesource/fobos/fobosplugin.cpp b/plugins/samplesource/fobos/fobosplugin.cpp index 2ff729de7..555f580df 100644 --- a/plugins/samplesource/fobos/fobosplugin.cpp +++ b/plugins/samplesource/fobos/fobosplugin.cpp @@ -22,12 +22,12 @@ #include "plugin/pluginapi.h" #ifdef SERVER_MODE -#include "FOBOSinput.h" +#include "fobosinput.h" #else -#include "FOBOSgui.h" +#include "fobosgui.h" #endif -#include "FOBOSplugin.h" -#include "FOBOSwebapiadapter.h" +#include "fobosplugin.h" +#include "foboswebapiadapter.h" const PluginDescriptor FOBOSPlugin::m_pluginDescriptor = { QStringLiteral("FOBOS"), diff --git a/plugins/samplesource/fobos/fobossettings.cpp b/plugins/samplesource/fobos/fobossettings.cpp index 57c19177e..648e7994a 100644 --- a/plugins/samplesource/fobos/fobossettings.cpp +++ b/plugins/samplesource/fobos/fobossettings.cpp @@ -19,7 +19,7 @@ #include #include "util/simpleserializer.h" -#include "FOBOSsettings.h" +#include "fobossettings.h" FOBOSSettings::FOBOSSettings() { diff --git a/plugins/samplesource/fobos/foboswebapiadapter.cpp b/plugins/samplesource/fobos/foboswebapiadapter.cpp index 0bdf7bc30..52ac4d690 100644 --- a/plugins/samplesource/fobos/foboswebapiadapter.cpp +++ b/plugins/samplesource/fobos/foboswebapiadapter.cpp @@ -21,8 +21,8 @@ /////////////////////////////////////////////////////////////////////////////////// #include "SWGDeviceSettings.h" -#include "FOBOSinput.h" -#include "FOBOSwebapiadapter.h" +#include "fobosinput.h" +#include "foboswebapiadapter.h" FOBOSWebAPIAdapter::FOBOSWebAPIAdapter() {} diff --git a/plugins/samplesource/fobos/foboswebapiadapter.h b/plugins/samplesource/fobos/foboswebapiadapter.h index f6a9b0726..c2e2f1e22 100644 --- a/plugins/samplesource/fobos/foboswebapiadapter.h +++ b/plugins/samplesource/fobos/foboswebapiadapter.h @@ -21,7 +21,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include "device/devicewebapiadapter.h" -#include "FOBOSsettings.h" +#include "fobossettings.h" class FOBOSWebAPIAdapter : public DeviceWebAPIAdapter { diff --git a/plugins/samplesource/fobos/fobosworker.cpp b/plugins/samplesource/fobos/fobosworker.cpp index 30812d6f8..6be5807a1 100644 --- a/plugins/samplesource/fobos/fobosworker.cpp +++ b/plugins/samplesource/fobos/fobosworker.cpp @@ -8,12 +8,17 @@ #include #include +#include +#include +#include #include #include #include #include #include +#include #include +#include #include #ifdef _WIN32 @@ -28,8 +33,13 @@ namespace #if defined(FOBOS_DEBUG_FILE_LOG) static const char* kLogPath = "sdrangel_fobos_source.log"; #endif +#ifdef _WIN32 static const char* kAgileDll = "fobos_sdr.dll"; static const char* kRegularDll = "fobos.dll"; +#else + static const char* kAgileDll = "libfobos_sdr.so"; + static const char* kRegularDll = "libfobos.so"; +#endif static const uint32_t kSyncComplexBufferLength = 65536; // Sync read block size, about 8.2 ms at 8 MS/s static const uint32_t kSyncFloatStorage = kSyncComplexBufferLength * 2u; // interleaved float I/Q static const uint32_t kFifoChunkComplexLength = kSyncComplexBufferLength; // One FIFO write per read block @@ -46,10 +56,71 @@ namespace static const bool kDefaultExternalClock = false; #ifdef _WIN32 + using FobosLibraryHandle = HMODULE; +#else + using DWORD = unsigned long; + using HMODULE = void*; + using FobosLibraryHandle = HMODULE; + static QString g_lastLibraryError; + + static void SetLastError(DWORD) {} + static DWORD GetLastError() { return 0; } + + static QString linuxRuntimeCandidate(const char* envName, const char* libName) + { + const char* root = std::getenv(envName); + if (!root || !*root) { + return QString(); + } + return QString::fromLocal8Bit(root) + QStringLiteral("/lib/") + QString::fromLatin1(libName); + } + + static HMODULE LoadLibraryA(const char* name) + { + QStringList candidates; + const QString libName = QString::fromLatin1(name ? name : ""); + + if (libName.contains(QStringLiteral("fobos_sdr"))) { + const QString envPath = linuxRuntimeCandidate("FOBOS_SDR_DIR", "libfobos_sdr.so"); + if (!envPath.isEmpty()) { candidates << envPath; } + } + + if (libName.contains(QStringLiteral("fobos")) && !libName.contains(QStringLiteral("fobos_sdr"))) { + const QString envPath = linuxRuntimeCandidate("FOBOS_DIR", "libfobos.so"); + if (!envPath.isEmpty()) { candidates << envPath; } + } + + candidates << libName; + + for (const QString& candidate : candidates) { + QLibrary* lib = new QLibrary(candidate); + if (lib->load()) { + g_lastLibraryError.clear(); + return static_cast(lib); + } + g_lastLibraryError = QStringLiteral("%1: %2").arg(candidate, lib->errorString()); + delete lib; + } + + return nullptr; + } + + static QFunctionPointer GetProcAddress(HMODULE handle, const char* symbol) + { + QLibrary* lib = static_cast(handle); + return lib ? lib->resolve(symbol) : nullptr; + } + + static void Sleep(unsigned int msec) + { + std::this_thread::sleep_for(std::chrono::milliseconds(msec)); + } +#endif + static QMutex g_sessionMutex; - static HMODULE g_agileLibrary = nullptr; // DLL is process-scoped; device is not. - static HMODULE g_regularLibrary = nullptr; // regular/classic DLL, process-scoped as well. - static bool g_deviceBusy = false; // prevent two SDRangel device sets from using one Fobos. + static FobosLibraryHandle g_agileLibrary = nullptr; // runtime library is process-scoped; device is not. + static FobosLibraryHandle g_regularLibrary = nullptr; // regular/classic runtime library, process-scoped as well. + static bool g_deviceBusy = false; // prevent two SDRangel device sets from using one Fobos. static void formatLastError(DWORD err, char* out, size_t outSize) { @@ -57,6 +128,7 @@ namespace return; } out[0] = '\0'; +#ifdef _WIN32 DWORD n = FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, @@ -73,8 +145,12 @@ namespace --n; } } - } +#else + (void) err; + const QByteArray bytes = g_lastLibraryError.toLocal8Bit(); + std::snprintf(out, outSize, "%s", bytes.constData()); #endif + } } FOBOSWorker::FOBOSWorker(SampleSinkFifo* sampleFifo, QObject* parent) : @@ -110,9 +186,8 @@ FOBOSWorker::FOBOSWorker(SampleSinkFifo* sampleFifo, QObject* parent) : m_readerActive(false), m_readerFinished(false), m_dev(nullptr), - m_runtimeBackend(FobosRuntimeBackend::None) -#ifdef _WIN32 - , m_libraryHandle(nullptr), + m_runtimeBackend(FobosRuntimeBackend::None), + m_libraryHandle(nullptr), m_errorName(nullptr), m_closeDev(nullptr), m_readSync(nullptr), @@ -133,9 +208,8 @@ FOBOSWorker::FOBOSWorker(SampleSinkFifo* sampleFifo, QObject* parent) : m_regularSetUserGpo(nullptr), m_regularSetClkSource(nullptr), m_regularSetLnaGain(nullptr), - m_regularSetVgaGain(nullptr) -#endif - , m_totalReads(0), + m_regularSetVgaGain(nullptr), + m_totalReads(0), m_totalSamples(0), m_totalWritten(0), m_failedReads(0) @@ -180,7 +254,6 @@ void FOBOSWorker::stopWork() m_stopRequested.store(true); m_running.store(false); -#ifdef _WIN32 bool readerJoined = true; // Do not call stop_sync while read_sync is active. @@ -204,7 +277,6 @@ void FOBOSWorker::stopWork() } cleanupAfterReaderJoined(readerJoined); -#endif } void FOBOSWorker::setSamplerate(int samplerate) @@ -346,7 +418,6 @@ void FOBOSWorker::setPattern2() {} bool FOBOSWorker::runAgileStart() { -#ifdef _WIN32 logLine("============================================================"); logLine("SDRangel Fobos SDR Agile native source"); logTimestamp(); @@ -639,17 +710,11 @@ bool FOBOSWorker::runAgileStart() logLine("reader_thread=STARTED"); emit backendStatusChanged(QStringLiteral("Agile"), agileBackendDetails); return true; -#else - logLine("Fobos SDR Agile dynamic runtime backend is currently implemented for Windows only"); - m_running.store(false); - return false; -#endif } bool FOBOSWorker::runRegularStart() { -#ifdef _WIN32 logLine("============================================================"); logLine("SDRangel Fobos SDR regular native source"); logTimestamp(); @@ -872,15 +937,10 @@ bool FOBOSWorker::runRegularStart() logLine("regular_reader_thread=STARTED"); emit backendStatusChanged(QStringLiteral("Regular"), regularBackendDetails); return true; -#else - m_running.store(false); - return false; -#endif } int FOBOSWorker::callSetFrequency(fobos_dev_t* dev, double valueHz) { -#ifdef _WIN32 if (m_runtimeBackend == FobosRuntimeBackend::Regular && m_regularSetFrequency) { double actual = 0.0; int r = m_regularSetFrequency(dev, valueHz, &actual); @@ -890,13 +950,11 @@ int FOBOSWorker::callSetFrequency(fobos_dev_t* dev, double valueHz) if (m_setFrequency) { return m_setFrequency(dev, valueHz); } -#endif return -9999; } int FOBOSWorker::callSetSamplerate(fobos_dev_t* dev, double valueHz) { -#ifdef _WIN32 if (m_runtimeBackend == FobosRuntimeBackend::Regular && m_regularSetSamplerate) { double actual = 0.0; @@ -907,13 +965,11 @@ int FOBOSWorker::callSetSamplerate(fobos_dev_t* dev, double valueHz) { return m_setSamplerate(dev, valueHz); } -#endif return -9999; } int FOBOSWorker::callSetDirectSampling(fobos_dev_t* dev, int inputMode) { -#ifdef _WIN32 const int direct = (inputMode == 0) ? 0 : 1; if (m_runtimeBackend == FobosRuntimeBackend::Regular && m_regularSetDirectSampling) { return m_regularSetDirectSampling(dev, static_cast(direct)); @@ -921,13 +977,11 @@ int FOBOSWorker::callSetDirectSampling(fobos_dev_t* dev, int inputMode) if (m_setDirectSampling) { return m_setDirectSampling(dev, direct); } -#endif return 0; } int FOBOSWorker::callSetAutoBandwidth(fobos_dev_t* dev, unsigned int bandwidthPercent) { -#ifdef _WIN32 if (m_runtimeBackend == FobosRuntimeBackend::Regular) { (void) dev; (void) bandwidthPercent; @@ -937,59 +991,50 @@ int FOBOSWorker::callSetAutoBandwidth(fobos_dev_t* dev, unsigned int bandwidthPe const double ratio = static_cast(bandwidthPercent) * 0.01; return m_setAutoBandwidth(dev, ratio); } -#endif return 0; } int FOBOSWorker::callSetGpo(fobos_dev_t* dev, unsigned int gpoMask) { -#ifdef _WIN32 if (m_runtimeBackend == FobosRuntimeBackend::Regular && m_regularSetUserGpo) { return m_regularSetUserGpo(dev, static_cast(gpoMask & 0xffu)); } if (m_setUserGpo) { return m_setUserGpo(dev, gpoMask & 0xffu); } -#endif return 0; } int FOBOSWorker::callSetClockSource(fobos_dev_t* dev, bool externalClock) { -#ifdef _WIN32 if (m_runtimeBackend == FobosRuntimeBackend::Regular && m_regularSetClkSource) { return m_regularSetClkSource(dev, externalClock ? 1 : 0); } if (m_setClkSource) { return m_setClkSource(dev, externalClock ? 1 : 0); } -#endif return 0; } int FOBOSWorker::callSetLnaGain(fobos_dev_t* dev, unsigned int lnaGain) { -#ifdef _WIN32 if (m_runtimeBackend == FobosRuntimeBackend::Regular && m_regularSetLnaGain) { return m_regularSetLnaGain(dev, lnaGain); } if (m_setLnaGain) { return m_setLnaGain(dev, lnaGain); } -#endif return -9999; } int FOBOSWorker::callSetVgaGain(fobos_dev_t* dev, unsigned int vgaGain) { -#ifdef _WIN32 if (m_runtimeBackend == FobosRuntimeBackend::Regular && m_regularSetVgaGain) { return m_regularSetVgaGain(dev, vgaGain); } if (m_setVgaGain) { return m_setVgaGain(dev, vgaGain); } -#endif return -9999; } @@ -998,6 +1043,9 @@ void FOBOSWorker::readerLoop() #ifdef _WIN32 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); logLine("reader_thread_priority=THREAD_PRIORITY_HIGHEST"); +#else + logLine("reader_thread_priority=DEFAULT_PORTABLE"); +#endif fobos_dev_t* dev = m_dev.load(); if (!dev || !m_readSync) { logLine("reader_loop=ABORT no_device_or_readSync"); @@ -1187,12 +1235,10 @@ void FOBOSWorker::readerLoop() m_readerActive.store(false); m_readerFinished.store(true); -#endif } void FOBOSWorker::cleanupAfterReaderJoined(bool readerJoined) { -#ifdef _WIN32 fobos_dev_t* dev = m_dev.load(); if (!dev) { @@ -1222,14 +1268,17 @@ void FOBOSWorker::cleanupAfterReaderJoined(bool readerJoined) logLine("freelibrary_call=SKIPPED_PROCESS_SCOPED_DLL"); logLine("source_result=STOPPED_CLEANLY_READER_JOINED_CLOSE_DONE"); -#endif } void FOBOSWorker::logLine(const char* fmt, ...) const { #if defined(FOBOS_DEBUG_FILE_LOG) FILE* f = nullptr; +#ifdef _WIN32 fopen_s(&f, kLogPath, "a"); +#else + f = std::fopen(kLogPath, "a"); +#endif if (!f) { return; } @@ -1254,12 +1303,10 @@ void FOBOSWorker::logTimestamp() const const char* FOBOSWorker::errorName(int code) const { -#ifdef _WIN32 if (m_errorName) { const char* s = m_errorName(code); return s ? s : "null_error_name"; } -#endif return "error_name_unavailable"; } diff --git a/plugins/samplesource/fobos/fobosworker.h b/plugins/samplesource/fobos/fobosworker.h index fbedc1329..9b158217d 100644 --- a/plugins/samplesource/fobos/fobosworker.h +++ b/plugins/samplesource/fobos/fobosworker.h @@ -14,6 +14,12 @@ #include #include +#ifdef _WIN32 +#define FOBOS_WORKER_CALL __cdecl +#else +#define FOBOS_WORKER_CALL +#endif + #include "dsp/samplesinkfifo.h" #include "fobossettings.h" @@ -61,46 +67,44 @@ signals: void backendStatusChanged(const QString& backend, const QString& details); private: -#ifdef _WIN32 - using fobos_sdr_get_api_info_t = int (__cdecl *)(char* lib_version, char* drv_version); - using fobos_sdr_get_device_count_t = int (__cdecl *)(); - using fobos_sdr_list_devices_t = int (__cdecl *)(char* serials); - using fobos_sdr_open_t = int (__cdecl *)(fobos_dev_t** out_dev, uint32_t index); - using fobos_sdr_close_t = int (__cdecl *)(fobos_dev_t* dev); - using fobos_sdr_get_board_info_t = int (__cdecl *)(fobos_dev_t* dev, char* hw_revision, char* fw_version, char* manufacturer, char* product, char* serial); - using fobos_sdr_error_name_t = const char* (__cdecl *)(int error_code); - using fobos_sdr_set_frequency_t = int (__cdecl *)(fobos_dev_t* dev, double value_hz); - using fobos_sdr_set_samplerate_t = int (__cdecl *)(fobos_dev_t* dev, double value_hz); - using fobos_sdr_get_samplerates_t = int (__cdecl *)(fobos_dev_t* dev, double* values, uint32_t* count); - using fobos_sdr_set_direct_sampling_t = int (__cdecl *)(fobos_dev_t* dev, int value); - using fobos_sdr_set_auto_bandwidth_t = int (__cdecl *)(fobos_dev_t* dev, double value); - using fobos_sdr_set_user_gpo_t = int (__cdecl *)(fobos_dev_t* dev, uint32_t value); - using fobos_sdr_set_clk_source_t = int (__cdecl *)(fobos_dev_t* dev, int value); - using fobos_sdr_set_lna_gain_t = int (__cdecl *)(fobos_dev_t* dev, unsigned int value); - using fobos_sdr_set_vga_gain_t = int (__cdecl *)(fobos_dev_t* dev, unsigned int value); - using fobos_sdr_start_sync_t = int (__cdecl *)(fobos_dev_t* dev, uint32_t buf_length); - using fobos_sdr_read_sync_t = int (__cdecl *)(fobos_dev_t* dev, float* buf, uint32_t* actual_buf_length); - using fobos_sdr_stop_sync_t = int (__cdecl *)(fobos_dev_t* dev); + using fobos_sdr_get_api_info_t = int (FOBOS_WORKER_CALL *)(char* lib_version, char* drv_version); + using fobos_sdr_get_device_count_t = int (FOBOS_WORKER_CALL *)(); + using fobos_sdr_list_devices_t = int (FOBOS_WORKER_CALL *)(char* serials); + using fobos_sdr_open_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t** out_dev, uint32_t index); + using fobos_sdr_close_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev); + using fobos_sdr_get_board_info_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, char* hw_revision, char* fw_version, char* manufacturer, char* product, char* serial); + using fobos_sdr_error_name_t = const char* (FOBOS_WORKER_CALL *)(int error_code); + using fobos_sdr_set_frequency_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, double value_hz); + using fobos_sdr_set_samplerate_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, double value_hz); + using fobos_sdr_get_samplerates_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, double* values, uint32_t* count); + using fobos_sdr_set_direct_sampling_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, int value); + using fobos_sdr_set_auto_bandwidth_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, double value); + using fobos_sdr_set_user_gpo_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, uint32_t value); + using fobos_sdr_set_clk_source_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, int value); + using fobos_sdr_set_lna_gain_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, unsigned int value); + using fobos_sdr_set_vga_gain_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, unsigned int value); + using fobos_sdr_start_sync_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, uint32_t buf_length); + using fobos_sdr_read_sync_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, float* buf, uint32_t* actual_buf_length); + using fobos_sdr_stop_sync_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev); - using fobos_rx_get_api_info_t = int (__cdecl *)(char* lib_version, char* drv_version); - using fobos_rx_get_device_count_t = int (__cdecl *)(); - using fobos_rx_list_devices_t = int (__cdecl *)(char* serials); - using fobos_rx_open_t = int (__cdecl *)(fobos_dev_t** out_dev, uint32_t index); - using fobos_rx_close_t = int (__cdecl *)(fobos_dev_t* dev); - using fobos_rx_get_board_info_t = int (__cdecl *)(fobos_dev_t* dev, char* hw_revision, char* fw_version, char* manufacturer, char* product, char* serial); - using fobos_rx_error_name_t = const char* (__cdecl *)(int error_code); - using fobos_rx_set_frequency_t = int (__cdecl *)(fobos_dev_t* dev, double value_hz, double* actual_hz); - using fobos_rx_set_samplerate_t = int (__cdecl *)(fobos_dev_t* dev, double value_hz, double* actual_hz); - using fobos_rx_get_samplerates_t = int (__cdecl *)(fobos_dev_t* dev, double* values, unsigned int* count); - using fobos_rx_set_direct_sampling_t = int (__cdecl *)(fobos_dev_t* dev, unsigned int enabled); - using fobos_rx_set_user_gpo_t = int (__cdecl *)(fobos_dev_t* dev, uint8_t value); - using fobos_rx_set_clk_source_t = int (__cdecl *)(fobos_dev_t* dev, int value); - using fobos_rx_set_lna_gain_t = int (__cdecl *)(fobos_dev_t* dev, unsigned int value); - using fobos_rx_set_vga_gain_t = int (__cdecl *)(fobos_dev_t* dev, unsigned int value); - using fobos_rx_start_sync_t = int (__cdecl *)(fobos_dev_t* dev, uint32_t buf_length); - using fobos_rx_read_sync_t = int (__cdecl *)(fobos_dev_t* dev, float* buf, uint32_t* actual_buf_length); - using fobos_rx_stop_sync_t = int (__cdecl *)(fobos_dev_t* dev); -#endif + using fobos_rx_get_api_info_t = int (FOBOS_WORKER_CALL *)(char* lib_version, char* drv_version); + using fobos_rx_get_device_count_t = int (FOBOS_WORKER_CALL *)(); + using fobos_rx_list_devices_t = int (FOBOS_WORKER_CALL *)(char* serials); + using fobos_rx_open_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t** out_dev, uint32_t index); + using fobos_rx_close_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev); + using fobos_rx_get_board_info_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, char* hw_revision, char* fw_version, char* manufacturer, char* product, char* serial); + using fobos_rx_error_name_t = const char* (FOBOS_WORKER_CALL *)(int error_code); + using fobos_rx_set_frequency_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, double value_hz, double* actual_hz); + using fobos_rx_set_samplerate_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, double value_hz, double* actual_hz); + using fobos_rx_get_samplerates_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, double* values, unsigned int* count); + using fobos_rx_set_direct_sampling_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, unsigned int enabled); + using fobos_rx_set_user_gpo_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, uint8_t value); + using fobos_rx_set_clk_source_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, int value); + using fobos_rx_set_lna_gain_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, unsigned int value); + using fobos_rx_set_vga_gain_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, unsigned int value); + using fobos_rx_start_sync_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, uint32_t buf_length); + using fobos_rx_read_sync_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev, float* buf, uint32_t* actual_buf_length); + using fobos_rx_stop_sync_t = int (FOBOS_WORKER_CALL *)(fobos_dev_t* dev); bool runAgileStart(); bool runRegularStart(); @@ -158,7 +162,6 @@ private: std::thread m_readerThread; FobosRuntimeBackend m_runtimeBackend; -#ifdef _WIN32 void* m_libraryHandle; fobos_sdr_error_name_t m_errorName; fobos_sdr_close_t m_closeDev; @@ -182,7 +185,6 @@ private: fobos_rx_set_clk_source_t m_regularSetClkSource; fobos_rx_set_lna_gain_t m_regularSetLnaGain; fobos_rx_set_vga_gain_t m_regularSetVgaGain; -#endif uint64_t m_totalReads; uint64_t m_totalSamples;