diff --git a/ExtIO_NetSDR.sln b/ExtIO_NetSDR.sln
new file mode 100644
index 0000000..3e06e9b
--- /dev/null
+++ b/ExtIO_NetSDR.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2013 for Windows Desktop
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExtIO_NetSDR", "ExtIO_NetSDR\ExtIO_NetSDR.vcxproj", "{F6D8A813-8B8D-46B5-B015-B5BE1BC467BE}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F6D8A813-8B8D-46B5-B015-B5BE1BC467BE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F6D8A813-8B8D-46B5-B015-B5BE1BC467BE}.Debug|Win32.Build.0 = Debug|Win32
+ {F6D8A813-8B8D-46B5-B015-B5BE1BC467BE}.Release|Win32.ActiveCfg = Release|Win32
+ {F6D8A813-8B8D-46B5-B015-B5BE1BC467BE}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ExtIO_NetSDR/ExtIO_NetSDR.vcxproj b/ExtIO_NetSDR/ExtIO_NetSDR.vcxproj
new file mode 100644
index 0000000..d62e4e4
--- /dev/null
+++ b/ExtIO_NetSDR/ExtIO_NetSDR.vcxproj
@@ -0,0 +1,124 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {F6D8A813-8B8D-46B5-B015-B5BE1BC467BE}
+ Win32Proj
+ ExtIO_NetSDR
+ ExtIO_RFspaceNetSDR
+
+
+
+ DynamicLibrary
+ true
+ v120_xp
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v120_xp
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ false
+ ../../clsocket/src;../../tinythreadpp/source;$(IncludePath)
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;_USRDLL;EXTIO_NETSDR_EXPORTS;%(PreprocessorDefinitions)
+
+
+ Windows
+ true
+ Ws2_32.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_WINDOWS;_USRDLL;EXTIO_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ false
+ Speed
+ MultiThreaded
+ false
+ true
+
+
+ Windows
+ false
+ true
+ true
+ 2018.0
+ ..\src\ExtIO_RFspaceNetSDR.def
+ /PDBSTRIPPED
+ false
+ Ws2_32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ExtIO_NetSDR/ExtIO_NetSDR.vcxproj.filters b/ExtIO_NetSDR/ExtIO_NetSDR.vcxproj.filters
new file mode 100644
index 0000000..ffc63cc
--- /dev/null
+++ b/ExtIO_NetSDR/ExtIO_NetSDR.vcxproj.filters
@@ -0,0 +1,95 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 2b18dee..b1aa7e2 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# ExtIO_RFspaceNetSDR
Winrad/HDSDR plugin ExtIO for the RFspace NetSDR receiver
+
## Software Defined Radio (SDR) receiver
The hardware receiver was manufactured by RFspace.
@@ -13,6 +14,7 @@ Network protocol specification for the interface is available at
http://www.moetronix.com/svdownload.htm
labeled 'NetSDR Interface Spec'
+
## Origin of source code
The ExtIO was developed at PROCITEC GmbH,
@@ -24,3 +26,35 @@ They kindly gave permission to release the source code under LGPL (Lesser Genera
Authors are Sebastian Balthasar and Hayati Ayguen. On questions, contact Hayati at h_ayguen@web.de
+
+## Step-by-step installation
+
+* install your favorite SDR software, e.g. HDSDR from http://www.hdsdr.de/ .
+Other ExtIO compatible software like Winrad or Studio1 should also work.
+
+* download ExtIO_RFspaceNetSDR.DLL https://github.com/hayguen/ExtIO_RFspaceNetSDR/releases
+
+* copy downloaded file into your SDR software's installation directory (default=C:\Program Files (x86)\HDSDR).
+Do NOT try to unzip directly into this directory! Because of Windows' user rights management this will fail. Unzip somewhere else first, then copy it to the installation directory.
+
+* exit and restart SDR software and select ExtIO_RFspaceNetSDR.DLL if demanded
+
+
+## Compilation notes
+
+Besides cloning this repository, you also need to clone following libraries from same directory:
+
+* https://github.com/hayguen/tinythreadpp for threading
+
+* https://github.com/hayguen/clsocket for tcp/ip socket communication
+
+Microsoft Visual Studio Express 2013 (MSVC) IDE is used for compilation.
+Other compiler should work, when adding suitable project files or fixing CMakeLists.txt.
+
+
+## Status
+
+Compiles. In test.
+
+ExtIO control GUI for configuration is missing! To be implemented ..
+
diff --git a/src/ExtIO_Logging.cpp b/src/ExtIO_Logging.cpp
new file mode 100644
index 0000000..25d8e3e
--- /dev/null
+++ b/src/ExtIO_Logging.cpp
@@ -0,0 +1,12 @@
+
+#include "ExtIO_Logging.h"
+
+// error message, with "const char*" in IQdata,
+// intended for a log file AND a message box
+// for messages extHw_MSG_*
+
+pfnExtIOCallback gpfnExtIOCallbackPtr = nullptr;
+
+char acExtioMsg[1024] = { 0 };
+bool SDRsupportsLogging = false;
+
diff --git a/src/ExtIO_Logging.h b/src/ExtIO_Logging.h
new file mode 100644
index 0000000..4123a67
--- /dev/null
+++ b/src/ExtIO_Logging.h
@@ -0,0 +1,58 @@
+#pragma once
+
+#include "LC_ExtIO_Types.h"
+
+#ifdef _MSC_VER
+ #pragma warning(disable : 4996)
+ #define snprintf _snprintf
+#endif
+
+/* ExtIO Callback */
+extern pfnExtIOCallback gpfnExtIOCallbackPtr;
+
+// error message, with "const char*" in IQdata,
+// intended for a log file AND a message box
+// for messages extHw_MSG_*
+
+extern char acExtioMsg[1024];
+extern bool SDRsupportsLogging;
+
+
+#define SDRLOGTXT( A, TEXT ) \
+ do { \
+ if ( gpfnExtIOCallbackPtr && SDRsupportsLogging ) \
+ gpfnExtIOCallbackPtr(-1, A, 0, TEXT ); \
+ } while (0)
+
+// optional after calling gpfnExtIOCallbackPtr() ..
+// if (extHw_MSG_ERRDLG == A) \
+// setStatusCB(TEXT, true); \
+
+
+#define SDRLOG( A, TEXTFMT, ... ) \
+ do { \
+ if ( gpfnExtIOCallbackPtr && SDRsupportsLogging ) \
+ { \
+ snprintf(acExtioMsg, 1023, TEXTFMT, ##__VA_ARGS__); \
+ gpfnExtIOCallbackPtr(-1, A, 0, acExtioMsg ); \
+ } \
+ } while (0)
+
+
+// for compatibility with PROCITEC code ..
+// translate log level macros and implement LOG_PRO() macro .. similar to SDRLOG
+
+#define LOG_ERROR extHw_MSG_ERROR
+#define LOG_PROTOCOL extHw_MSG_WARNING
+#define LOG_NORMAL extHw_MSG_LOG
+#define LOG_DEBUG extHw_MSG_DEBUG
+
+#define LOG_PRO( A, TEXTFMT, ... ) \
+ do { \
+ if ( gpfnExtIOCallbackPtr && SDRsupportsLogging ) \
+ { \
+ snprintf(acExtioMsg, 1023, TEXTFMT, ##__VA_ARGS__); \
+ gpfnExtIOCallbackPtr(-1, A, 0, acExtioMsg ); \
+ } \
+ } while (0)
+
diff --git a/src/ExtIO_RFspaceNetSDR.cpp b/src/ExtIO_RFspaceNetSDR.cpp
index 55a5555..3c93201 100644
--- a/src/ExtIO_RFspaceNetSDR.cpp
+++ b/src/ExtIO_RFspaceNetSDR.cpp
@@ -1,41 +1,32 @@
#define HWNAME "RFspace"
#define HWMODEL "RFspace NetSDR"
-#define SETTINGS_IDENTIFIER "RFspace NetSDR-0.1"
-
-#define IGNORE_CONF_DATA_DEST 0
-
-#if IGNORE_CONF_DATA_DEST
-// for test with "dump_tcp_forwarding.exe -v 58666"
-#define DATA_DEST_IP "10.10.11.2"
-#define DATA_DEST_PORT 50000
-#else
-#define DATA_DEST_IP gacDataIP
-#define DATA_DEST_PORT guDataPortNo
-#endif
+#define SETTINGS_IDENTIFIER "RFspace NetSDR-0.2"
#include "ExtIO_RFspaceNetSDR.h"
#include "rfspace_netsdr_receiver.h"
-#include "common/base/baselib/base/ProLogging.h"
-#include "foreign/extio/common/ExtIO_ProLogImpl.h"
-
+#include "ExtIO_Logging.h"
//---------------------------------------------------------------------------
-#include "foreign/tinythread/tinythread.h"
+#include "procitec_replacements.h"
-#include "common/base/baselib/base/TimeMeasuring.h"
-#include "common/base/baselib/base/ProStd.h"
-#include "common/base/baselib/base/ProVersion.h"
-#include "common/base/baselib/base/ProMakros.h"
#if defined( WIN32 ) || defined( WIN64 )
-// #define WIN32_LEAN_AND_MEAN // Selten verwendete Teile der Windows-Header nicht einbinden.
-#include
+
+#define WIN32_LEAN_AND_MEAN // Selten verwendete Teile der Windows-Header nicht einbinden.
+#ifndef _WINSOCK2API_
+#define _WINSOCK2API_
+#define _WINSOCKAPI_
+#endif
+#include
#endif
+#include "tinythread.h"
+
#include
+#include
#include
#include
#include
@@ -205,36 +196,6 @@ static void ReceiverThreadProc( void* lpParameter )
}
-//---------------------------------------------------------------------------
-
-#if 0
-static void ReceptionStreamThreadProc( void* lpParameter )
-{
- (void)lpParameter;
-
- MonotonicClock oClock;
-
- uint64_t uTicksNew = 0;
- uint64_t uLastReceivedPacket = oClock.msecs();
-
- while ( 1 )
- {
- if ( !gbDataStreamActivated )
- {
- // wait for control - before binding UDP port, when using UDP protocol
- tthread::this_thread::sleep_for( tthread::chrono::milliseconds( 1 ) );
- continue;
- }
-
- gbBoundTcpDataPort = true;
- while ( 1 )
- {
- uLastReceivedPacket = oClock.msecs();
- }
- }
-}
-#endif
-
//---------------------------------------------------------------------------
static void stopThread()
@@ -669,6 +630,8 @@ enum class Setting {
ID = 0 // enum values MUST be incremental without gaps!
, CTRL_IP, CTRL_PORT // NetSDR IP/Port
, DATA_IP, DATA_PORT // myPC Data IP/Port
+ , AVAIL_SRATES
+ , AVAIL_BWS
, SAMPLERATE_IDX
, RCV_FRQ
, RCV_BW
@@ -690,6 +653,8 @@ enum class Setting {
int EXTIO_CALL ExtIoGetSetting( int idx, char* description, char* value )
{
+ int k;
+ size_t off;
if (!gpoSettings)
gpoSettings = new RFspaceNetReceiver::Settings();
@@ -710,7 +675,7 @@ int EXTIO_CALL ExtIoGetSetting( int idx, char* description, char* value )
return 0;
case Setting::DATA_IP:
- snprintf( description, 1024, "%s", "DATA IP: IP-Address of Client PC to receive streaming data" );
+ snprintf( description, 1024, "%s", "DATA_IP: IP-Address of Client PC to receive streaming data" );
snprintf( value, 1024, "%s", gpoSettings->acDataIP );
return 0;
case Setting::DATA_PORT:
@@ -718,6 +683,32 @@ int EXTIO_CALL ExtIoGetSetting( int idx, char* description, char* value )
snprintf( value, 1024, "%d", gpoSettings->uDataPortNo );
return 0;
+ case Setting::AVAIL_SRATES:
+ snprintf(description, 1024, "info: %d available samplerates - per idx", RFspaceNetReceiver::miNumSamplerates );
+ off = 0;
+ value[0] = 0;
+ for (k = 0; k < RFspaceNetReceiver::miNumSamplerates; ++k)
+ {
+ int w = snprintf(value + off, 1024 - off, "%s%d: %u", (k == 0 ? "":", "), k, unsigned(RFspaceNetReceiver::maiSamplerates[k]) );
+ if (w < 0 || w >= (1024 - int(off)))
+ break;
+ off += w;
+ }
+ return 0;
+
+ case Setting::AVAIL_BWS:
+ snprintf(description, 1024, "info: %d available bandwidths - per idx", RFspaceNetReceiver::miNumSamplerates);
+ off = 0;
+ value[0] = 0;
+ for (k = 0; k < RFspaceNetReceiver::miNumSamplerates; ++k)
+ {
+ int w = snprintf(value + off, 1024 - off, "%s%d: %u", (k == 0 ? "" : ", "), k, unsigned(RFspaceNetReceiver::maiBandwidths[k]));
+ if (w < 0 || w >= (1024 - int(off)))
+ break;
+ off += w;
+ }
+ return 0;
+
case Setting::SAMPLERATE_IDX:
snprintf( description, 1024, "%s", "SampleRateIdx" );
snprintf( value, 1024, "%d", gpoSettings->iSampleRateIdx );
@@ -729,7 +720,7 @@ int EXTIO_CALL ExtIoGetSetting( int idx, char* description, char* value )
return 0;
case Setting::RCV_BW:
- snprintf( description, 1024, "%s", "bandwidth in Hz for Receiver: 10 / 25 / 50 / 80 / 100 / 200 / 400 / 500 / 800 / 1300 / 1600 kHz" );
+ snprintf( description, 1024, "%s", "(last) bandwidth in Hz for Receiver" );
snprintf( value, 1024, "%d", gpoSettings->uiBandwidth );
return 0;
@@ -739,7 +730,7 @@ int EXTIO_CALL ExtIoGetSetting( int idx, char* description, char* value )
return 0;
case Setting::BITDEPTH_CHANGE_SMPRATE:
- snprintf( description, 1024, "%s", "Samplerate at which bitdepth is being changed from 24 to 16 bit and vice verca." );
+ snprintf( description, 1024, "%s", "Samplerate at which bitdepth is reduced from 24 to 16 bit. For samplerates <= value, you get 24 Bit, else 16 bit. From Specification: 1 333 333 Hz." );
snprintf( value, 1024, "%u", gpoSettings->iBitDepthThresSamplerate);
return 0;
@@ -754,12 +745,12 @@ int EXTIO_CALL ExtIoGetSetting( int idx, char* description, char* value )
return 0;
case Setting::IS_VUHF_RANGE:
- snprintf( description, 1024, "%s", "Is this reveiver in VUHG range ?" );
+ snprintf( description, 1024, "%s", "Is this receiver in V/UHF range ?" );
snprintf( value, 1024, "%u", gpoSettings->bIsVUHFRange);
return 0;
case Setting::COMPATIBILITY_VALUE:
- snprintf( description, 1024, "%s", "VUHF Compatibility Gain Level 0 ... 3" );
+ snprintf( description, 1024, "%s", "V/UHF Compatibility Gain Level 0 ... 3" );
snprintf( value, 1024, "%u", gpoSettings->iCompatibilityValue);
return 0;
@@ -795,12 +786,55 @@ int EXTIO_CALL ExtIoGetSetting( int idx, char* description, char* value )
return -1; // ERROR
}
+static const char * trimmedIP(const char * value, const char * logText)
+{
+ static char acBuf[1024];
+ char * pBlockStart[4] = { 0, 0, 0, 0 };
+ int k = 0;
+
+ // to first digit
+ while (value[0] && !isdigit(value[0]))
+ ++value;
+ if (!value[0])
+ {
+ LOG_PRO(LOG_ERROR, "Error in %s or empty IP address", logText);
+ return "";
+ }
+
+ for (int j = 1; j <= 4; ++j)
+ {
+ pBlockStart[j - 1] = &acBuf[k];
+
+ // j.th numeric block
+ while (value[0] && isdigit(value[0]))
+ acBuf[k++] = *value++;
+
+ // '.' ?
+ if (j < 4)
+ {
+ if (value[0] == '.')
+ ++value;
+ else
+ {
+ LOG_PRO(LOG_ERROR, "Error in %s for %d.th numeric block!", logText, j);
+ return "";
+ }
+ }
+ }
+
+ // zero termination
+ acBuf[k++] = 0;
+
+ return acBuf;
+}
+
void EXTIO_CALL ExtIoSetSetting( int idx, const char* value )
{
if (!gpoSettings)
gpoSettings = new RFspaceNetReceiver::Settings();
+ int64_t tempI64;
int tempInt;
// now we know that there's no need to save our settings into some (.ini) file,
// what won't be possible without admin rights!!!,
@@ -819,19 +853,22 @@ void EXTIO_CALL ExtIoSetSetting( int idx, const char* value )
// make identifier version specific??? - or not ==> never change order of idx!
break;
case Setting::CTRL_IP:
- snprintf( gpoSettings->acCtrlIP, 64, "%s", value );
+ snprintf(gpoSettings->acCtrlIP, 64, "%s", trimmedIP(value, "CTRL_IP"));
break;
case Setting::CTRL_PORT:
tempInt = atoi( value );
gpoSettings->uCtrlPortNo = (uint16_t)( tempInt & 0xffff );
break;
case Setting::DATA_IP:
- snprintf( gpoSettings->acDataIP, 64, "%s", value );
+ snprintf(gpoSettings->acDataIP, 64, "%s", trimmedIP(value, "DATA_IP"));
break;
case Setting::DATA_PORT:
tempInt = atoi( value );
gpoSettings->uDataPortNo = (uint16_t)( tempInt & 0xffff );
break;
+ case Setting::AVAIL_SRATES:
+ case Setting::AVAIL_BWS:
+ break;
case Setting::SAMPLERATE_IDX:
gpoSettings->iSampleRateIdx = atoi( value );
break;
@@ -848,10 +885,12 @@ void EXTIO_CALL ExtIoSetSetting( int idx, const char* value )
gpoSettings->iBitDepthThresSamplerate = atoi( value );
break;
case Setting::BAND1_RANGE_MINFREQ:
- gpoSettings->iBand_minFreq = atoi( value );
+ gpoSettings->iBand_minFreq = atol( value );
break;
case Setting::BAND1_RANGE_MAXFREQ:
- gpoSettings->iBand_maxFreq = atoi( value );
+ tempI64 = atol(value);
+ if (gpoSettings->iBand_minFreq < tempI64) // reject when min > max
+ gpoSettings->iBand_maxFreq = tempI64;
break;
case Setting::IS_VUHF_RANGE:
gpoSettings->bIsVUHFRange = atoi( value ) ? true : false;
@@ -904,7 +943,7 @@ void EXTIO_CALL ExtIoSDRInfo( int extSDRInfo, int additionalValue, void * additi
case extSDR_supports_SampleFormats:
break;
case extSDR_supports_Logging:
- gbUseProcitecEnums = false;
+ SDRsupportsLogging = true;
break;
default: ;
}
diff --git a/src/ExtIO_RFspaceNetSDR.h b/src/ExtIO_RFspaceNetSDR.h
index fd5e93e..9484a2e 100644
--- a/src/ExtIO_RFspaceNetSDR.h
+++ b/src/ExtIO_RFspaceNetSDR.h
@@ -55,7 +55,7 @@
-#include "common/functions/receiverlib/LC_ExtIO_Types.h"
+#include "LC_ExtIO_Types.h"
EXTIO_API const char * EXTIO_CALL GetBuildInfo();
EXTIO_API const char * EXTIO_CALL GetExtIOVersion();
diff --git a/src/LC_ExtIO_Types.h b/src/LC_ExtIO_Types.h
new file mode 100644
index 0000000..69d765e
--- /dev/null
+++ b/src/LC_ExtIO_Types.h
@@ -0,0 +1,546 @@
+//---------------------------------------------------------------------------
+
+#ifndef LC_ExtIO_TypesH
+#define LC_ExtIO_TypesH
+
+// last modification: 2017-04-26
+
+// specification based on http://www.sdradio.eu/weaksignals/bin/Winrad_Extio.pdf
+// linked referenced from http://www.weaksignals.com/
+
+// for C99 compiler just #include
+// MS VC++ 2008 Express does not have stdint.h Try http://msinttypes.googlecode.com/svn/trunk/stdint.h
+#include
+// for other compilers you may try http://www.azillionmonkeys.com/qed/pstdint.h
+// or try boost: http://www.boost.org/doc/libs/1_36_0/boost/cstdint.hpp
+
+/*
+ * I. INITIALIZATION + OPEN SEQUENCE
+ * =================================
+ * ExtIoSDRInfo()
+ * optional: inform ExtIO of SDR software's supported features
+ * ExtIoSetSetting()
+ * optional: previously saved settings are delivered to ExtIO
+ * call once with idx -1 to sign ExtIO that this functionality is supported,
+ * so that ExtIO may inhibit loading/storing any .ini
+ * InitHW()
+ * mandatory: initialize ExtIO. May do nothing!
+ * VersionInfo()
+ * optional: delivers SDR program name and version to ExtIO. Allows to check if some necessary
+ * functional extension is (not) supported by SDR program
+ * GetAttenuators()
+ * optional: show ExtIO, that SDR program supports controlling RF Gain/Attenuator(s)
+ * you should prefer this over determining SDR program's capabilities over VersionInfo()
+ * ExtIoGetMGCs()
+ * optional: show ExtIO, that SDR program supports controlling IF Gain/Attenuator(s)
+ * you should prefer this over determining SDR program's capabilities over VersionInfo()
+ * SetCallback()
+ * mandatory: callback function pointer is given to ExtIO. ExtIO may inform SDR program of events
+ * using this callback interface and the extHWstatusT enums
+ * OpenHW()
+ * mandatory: prepare ExtIO for start .. or fail for any reason!
+ *
+ *
+ * II. START SEQUENCE
+ * ==================
+ * StartHW()
+ * mandatory: start processing
+ *
+ *
+ * III. WORK
+ * =========
+ * SetHWLO() and many other functions ...
+ *
+ *
+ * IV. STOP SEQUENCE (== 'undo' of Start sequence)
+ * =================
+ * StopHW()
+ * mandatory: start processing
+ *
+ *
+ * V. CLOSE SEQUENCE (== 'undo' of init + stop sequence)
+ * =================
+ * ExtIoGetSetting()
+ * optional: get and save settings for next time.
+ * call ExtIoGetSetting() before CloseHW() to get correct settings.
+ * do not call without súccessful OpenHW()
+ * CloseHW()
+ * mandatory: close hardware. Processing is not started again (with StartHW),
+ * unless OpenHW() is called again
+ * this function is called only when prior OpenHW() was successful
+ * take care not to free already freed or never allocated resources
+ *
+ */
+
+// function implemented by Winrad / HDSDR; see enum extHWstatusT below
+// IQoffs is no longer used (HDSDR >= 2.75), if ever used by any ExtIO!
+// DC offset correction can be done inside HDSDR
+typedef int(__cdecl * pfnExtIOCallback) (int cnt, int status, float IQoffs, void *IQdata);
+
+// mandatory functions, which have to be implemented by ExtIO DLL
+#define EXTIO_MAX_NAME_LEN 16 /* name is displayed in Winrad/HDSDR's menu */
+#define EXTIO_MAX_MODEL_LEN 16 /* model is not used */
+typedef bool (__stdcall * pfnInitHW) (char *name, char *model, int& hwtype);
+ // name: descriptive name of the hardware.
+ // Preferably not longer than about 16 characters,
+ // as it will be used in a Winrad menu
+ // model: model code of the hardware,
+ // or its Serial Number.
+ // Keep also this field not too long,
+ // for the same reason of the previous one
+ // hwtype: see enum extHWtypeT below
+ // return: true if everything went well
+
+typedef bool (__stdcall * pfnOpenHW) (void);
+ // return: true if everything went well
+
+typedef void (__stdcall * pfnCloseHW) (void);
+typedef int (__stdcall * pfnStartHW) (long extLOfreq);
+ // return: An integer specifying how many I/Q pairs are returned
+ // by the DLL each time the callback function is invoked (see later).
+ // This information is used of course only when the input data
+ // are not coming from the sound card, but through the callback device.
+ // If the number is negative, that means that an error has occurred,
+ // Winrad interrupts the starting process and returns to the
+ // idle status.
+ // The number of I/Q pairs must be at least 512, or an integer
+ // multiple of that value,
+
+typedef void (__stdcall * pfnStopHW) (void);
+typedef void (__stdcall * pfnSetCallback) (pfnExtIOCallback funcptr);
+typedef int (__stdcall * pfnSetHWLO) (long extLOfreq); // see also SetHWLO64
+ // return values:
+ // == 0: The function did complete without errors.
+ // < 0 (a negative number N):
+ // The specified frequency is lower than the minimum that
+ // the hardware is capable to generate. The absolute value
+ // of N indicates what is the minimum supported by the HW.
+ // > 0 (a positive number N):
+ // The specified frequency is greater than the maximum
+ // that the hardware is capable to generate. The value
+ // of N indicates what is the maximum supported by the HW.
+
+typedef int (__stdcall * pfnGetStatus) (void);
+ // This entry point is meant to allow the DLL to return a status
+ // information to Winrad, upon request.
+ // Presently it is never called by Winrad, though its existence
+ // is checked when the DLL is loaded. So it must implemented,
+ // even if in a dummy way.
+ // It is meant for future expansions, for complex HW that implement
+ // e.g. a preselector or some other controls other than a simple
+ // LO frequency selection.
+ // The return value is an integer that is application dependent.
+
+// optional functions, which can be implemented by ExtIO DLL
+// for performance reasons prefer not implementing rather then implementing empty functions
+// especially for RawDataReady
+typedef long (__stdcall * pfnGetHWLO) (void); // see also GetHWLO64
+typedef long (__stdcall * pfnGetHWSR) (void);
+typedef void (__stdcall * pfnRawDataReady) (long samprate, void *Ldata, void *Rdata, int numsamples);
+typedef void (__stdcall * pfnShowGUI) (void);
+typedef void (__stdcall * pfnHideGUI) (void);
+typedef void (__stdcall * pfnSwitchGUI) (void); // new: switch visibility of GUI
+typedef void (__stdcall * pfnTuneChanged) (long tunefreq); // see also TuneChanged64
+typedef long (__stdcall * pfnGetTune) (void); // see also GetTune64
+typedef void (__stdcall * pfnModeChanged) (char mode);
+typedef char (__stdcall * pfnGetMode) (void);
+typedef void (__stdcall * pfnIFLimitsChanged)(long lowfreq, long highfreq); // see also IFLimitsChanged64
+typedef void (__stdcall * pfnFiltersChanged) (int loCut, int hiCut, int pitch); // lo/hiCut relative to tuneFreq
+typedef void (__stdcall * pfnMuteChanged) (bool muted);
+typedef void (__stdcall * pfnGetFilters) (int& loCut, int& hiCut, int& pitch);
+
+// optional functions - extended for receivers with frequency range over 2147 MHz - used from HDSDR
+// these functions 64 bit functions are prefered rather than using the 32 bit ones
+// for other Winrad derivations you should additionally implement the above "usual" 32 bit functions
+typedef int (__stdcall * pfnStartHW64) (int64_t extLOfreq); // "StartHW64" with HDSDR >= 2.14
+typedef int64_t (__stdcall * pfnSetHWLO64) (int64_t extLOfreq);
+typedef int64_t (__stdcall * pfnGetHWLO64) (void);
+typedef void (__stdcall * pfnTuneChanged64) (int64_t tunefreq);
+typedef int64_t (__stdcall * pfnGetTune64) (void);
+typedef void (__stdcall * pfnIFLimitsChanged64) (int64_t lowfreq, int64_t highfreq);
+
+// optional functions - extended for high precision
+typedef int (__stdcall * pfnStartHW_dbl) (double extLOfreq);
+typedef double (__stdcall * pfnSetHWLO_dbl) (double extLOfreq);
+typedef double (__stdcall * pfnGetHWLO_dbl) (void);
+typedef void (__stdcall * pfnTuneChanged_dbl)(double tunefreq);
+typedef double (__stdcall * pfnGetTune_dbl) (void);
+typedef void (__stdcall * pfnIFLimitsChanged_dbl) (double lowfreq, double highfreq);
+
+
+// optional functions, which can be implemented by ExtIO DLL
+// following functions may get called from HDSDR 2.13 and above
+
+// "VersionInfo" is called - when existing - after successful InitHW()
+// with this information an ExtIO may check which extHWstatusT enums are properly processed from application
+// this call shall no longer be used to determine features of the SDR
+// use "ExtIoSDRInfo" for this purpose
+typedef void (__stdcall * pfnVersionInfo) (const char * progname, int ver_major, int ver_minor);
+
+
+// "GetAttenuators" allows HDSDR to display a knob or slider for Attenuation / Amplification
+// see & use extHw_Changed_ATT enum if ATT can get changed by ExtIO dialog window or from hardware
+#define EXTIO_MAX_ATT_GAIN_VALUES 128
+typedef int (__stdcall * pfnGetAttenuators) (int idx, float * attenuation); // fill in attenuation
+ // use positive attenuation levels if signal is amplified (LNA)
+ // use negative attenuation levels if signal is attenuated
+ // sort by attenuation: use idx 0 for highest attenuation / most damping
+ // this functions is called with incrementing idx
+ // - until this functions returns != 0, which means that all attens are already delivered
+typedef int (__stdcall * pfnGetActualAttIdx)(void); // returns -1 on error
+typedef int (__stdcall * pfnSetAttenuator) (int idx); // returns != 0 on error
+
+// see extHw_TX_Request/extHw_RX_Request enums below if modechange can get triggered from user / hardware
+typedef int (__stdcall * pfnSetModeRxTx) (int modeRxTx); // see enum extHw_ModeRxTxT
+
+// preliminary TX function - not really tested!: lack of test hw
+// status:
+// 0: Samples with numIQsamples > 0 (=512) and non-NULL pointer interleavedIQ
+// 1: Reset (to suspend/stop TX thread of HDSDR) with numIQsamples == 0 and interleavedIQ == NULL
+// 2: Pause/Stop (buffer underrun) with numIQsamples == 0 and interleavedIQ == NULL
+// 3: Continue (after buffer underrun) with numIQsamples == 0 and interleavedIQ == NULL
+typedef void (__stdcall * pfnTxSamples) (int status, int numIQsamples, const short * interleavedIQ);
+
+
+// (de)activate all bandpass filter to allow "bandpass undersampling" (with external analog bandpass filter)
+// intended for future use: it may get set automatically depending on LO frequency and the "ExtIO Frequency Options"
+// deactivation of bp/lp-filters when real LO (in HDSDR) is > ADC_Samplerate/2 in undersampling mode
+typedef int (__stdcall * pfnDeactivateBP) (int deactivate);
+ // deactivate == 1 to deactivate all bandpass and lowpass filters of hardware
+ // deactivate == 0 to reactivate automatic bandpass selection depending on frequency
+
+// optional "ExtIoGetSrates" is for replacing the Soundcard Samplerate values in the Samplerate selection dialog
+// by these values supported from the SDR hardware.
+// see & use extHw_Changed_SampleRate enum ... and "GetHWSR". Enumeration API as with "GetAttenuators"
+// intended for future use - actually not implemented/called
+#define EXTIO_MAX_SRATE_VALUES 32
+typedef int (__stdcall * pfnExtIoGetSrates) (int idx, double * samplerate); // fill in possible samplerates
+ // this functions is called with incrementing idx
+ // - until this functions returns != 0, which means that all srates are already delivered
+typedef int (__stdcall * pfnExtIoGetActualSrateIdx) (void); // returns -1 on error
+typedef int (__stdcall * pfnExtIoSetSrate) (int idx); // returns != 0 on error
+
+// optional function to get 3dB bandwidth from samplerate
+typedef long (__stdcall * pfnExtIoGetBandwidth) (int srate_idx); // returns <= 0 on error
+
+// optional function to get center (= IF frequency) of 3dB band in Hz - for non I/Q receivers with 0 center
+typedef long (__stdcall * pfnExtIoGetBwCenter) (int srate_idx); // returns 0 on error, which is default
+
+// optional function to get AGC Mode: AGC_OFF (always agc_index = 0), AGC_SLOW, AGC_MEDIUM, AGC_FAST, ...
+// this functions is called with incrementing idx
+// - until this functions returns != 0, which means that all agc modes are already delivered
+#define EXTIO_MAX_AGC_VALUES 16
+typedef int (__stdcall * pfnExtIoGetAGCs) (int agc_idx, char * text); // text limited to max 16 char
+typedef int (__stdcall * pfnExtIoGetActualAGCidx)(void); // returns -1 on error
+typedef int (__stdcall * pfnExtIoSetAGC) (int agc_idx); // returns != 0 on error
+// optional: HDSDR >= 2.62
+typedef int (__stdcall * pfnExtIoShowMGC)(int agc_idx); // return 1, to continue showing MGC slider on AGC
+ // return 0, is default for not showing MGC slider
+
+// for AGC in AGC_OFF (agc_idx == 0), which is (M)anual (G)ain (C)ontrol
+// sometimes referred as "IFgain" - as in SDR-14/IP
+#define EXTIO_MAX_MGC_VALUES 128
+typedef int (__stdcall * pfnExtIoGetMGCs)(int mgc_idx, float * gain); // fill in gain
+ // sort by ascending gain: use idx 0 for lowest gain
+ // this functions is called with incrementing idx
+ // - until this functions returns != 0, which means that all gains are already delivered
+typedef int (__stdcall * pfnExtIoGetActualMgcIdx) (void); // returns -1 on error
+typedef int (__stdcall * pfnExtIoSetMGC) (int mgc_idx); // returns != 0 on error
+
+
+// not used in HDSDR - for now
+// optional function to get 3dB band of Preselectors
+// this functions is called with incrementing idx
+// - until this functions returns != 0, which means that all preselectors are already delivered
+// ExtIoSetPresel() with idx = -1 to activate automatic preselector selection
+// ExtIoSetPresel() with valid idx (>=0) deactivates automatic preselection
+typedef int (__stdcall * pfnExtIoGetPresels) ( int idx, int64_t * freq_low, int64_t * freq_high );
+typedef int (__stdcall * pfnExtIoGetActualPreselIdx) ( void ); // returns -1 on error
+typedef int (__stdcall * pfnExtIoSetPresel) ( int idx ); // returns != 0 on error
+
+// not used in HDSDR - for now
+// optional function to get frequency ranges usable with SetHWLO(),
+// f.e. the FUNcube Dongle Pro+ should deliver idx 0: low=0.15 high=250 MHz and idx 1: low=420 high=1900 MHz
+// with a gap from 250MHz to 420 MHz. see http://www.funcubedongle.com/?page_id=1073
+// if extIO is told to set a not-supported frequency with SetHWLO(), then the extIO should callback with extHw_Changed_LO
+// and set a new frequency, which is supported
+// this functions is called with incrementing idx
+// - until this functions returns != 0, which means that all frequency ranges are already delivered
+typedef int (__stdcall * pfnExtIoGetFreqRanges) ( int idx, int64_t * freq_low, int64_t * freq_high );
+
+// not used in HDSDR - for now
+// optional function to get full samplerate of A/D Converter
+// useful to know with direct samplers in bandpass undersampling mode
+// example: Perseus = 80 000 000 ; SDR-14 = 66 666 667
+// return <= 0 if undersampling not supported (when preselectors not deactivatable)
+typedef double (__stdcall * pfnExtIoGetAdcSrate) ( void );
+
+// HDSDR >= 2.51
+// optional functions to receive and set all special receiver settings (for save/restore in application)
+// allows application and profile specific settings.
+// easy to handle without problems with newer Windows versions saving a .ini file below programs as non-admin-user
+// Settings shall be zero-terminated C-Strings.
+// example settings: USB-Identifier(for opening specific device), IP/Port, AGC, Srate, ..
+// idx in 0 .. 999 => NOT more than 1000 values storable!
+// description max 1024 char
+// value max 1024 char
+// these functions are called with incrementing idx: 0, 1, ...
+// until ExtIoGetSetting() returns != 0, which means that all settings are already delivered
+typedef int (__stdcall * pfnExtIoGetSetting) ( int idx, char * description, char * value ); // will be called (at least) before exiting application
+typedef void (__stdcall * pfnExtIoSetSetting) ( int idx, const char * value ); // before calling InitHW() !!!
+ // there will be an extra call with idx = -1, if theses functions are supported by the SDR app
+ // suggestion: use index 0 as ExtIO identifier (save/check ExtIO name) to allow fast skipping of all following SetSetting calls
+ // when this identifier does not match
+
+// not used in HDSDR - for now
+// handling of VFOs - see also extHw_Changed_VFO
+// VFOindex is in 0 .. numVFO-1
+typedef void (__stdcall * pfnExtIoVFOchanged) ( int VFOindex, int numVFO, int64_t extLOfreq, int64_t tunefreq, char mode );
+typedef int (__stdcall * pfnExtIoGetVFOindex)( void ); // returns new VFOindex
+
+
+// HDSDR > 2.70
+
+// inform ExtIO on the features supported by the SDR application
+typedef void (__stdcall * pfnExtIoSDRInfo)( int extSDRInfo, int additionalValue, void * additionalPtr );
+
+// HDSDR > 2.76
+
+// inform ExtIO for unhandled keypress events. Encoding as in extHw_Unhandled_KeyPress.
+typedef void (__stdcall * pfnExtKeyPressEvent)( int modifier, int keycode );
+
+
+
+// hwtype codes to be set with pfnInitHW
+// note: "exthwUSBdataNN" don't need to be from USB. The keyword "USB" is just for historical reasons,
+// which may get removed later ..
+typedef enum
+{
+ exthwNone = 0
+ , exthwSDR14 = 1
+ , exthwSDRX = 2
+ , exthwUSBdata16 = 3 // the hardware does its own digitization and the audio data are returned to Winrad
+ // via the callback device. Data must be in 16-bit (short) format, little endian.
+ // each sample occupies 2 bytes (=16 bits) with values from -2^15 to +2^15 -1
+ , exthwSCdata = 4 // The audio data are returned via the (S)ound (C)ard managed by Winrad. The external
+ // hardware just controls the LO, and possibly a preselector, under DLL control.
+ , exthwUSBdata24 = 5 // the hardware does its own digitization and the audio data are returned to Winrad
+ // via the callback device. Data are in 24-bit integer format, little endian.
+ // each sample just occupies 3 bytes (=24 bits) with values from -2^23 to +2^23 -1
+ , exthwUSBdata32 = 6 // the hardware does its own digitization and the audio data are returned to Winrad
+ // via the callback device. Data are in 32-bit integer format, little endian.
+ // each sample occupies 4 bytes (=32 bits) but with values from -2^23 to +2^23 -1
+ , exthwUSBfloat32 = 7 // the hardware does its own digitization and the audio data are returned to Winrad
+ // via the callback device. Data are in 32-bit float format, little endian.
+ , exthwHPSDR = 8 // for HPSDR only!
+
+ // HDSDR > 2.70
+ , exthwUSBdataU8 = 9 // the hardware does its own digitization and the audio data are returned to Winrad
+ // via the callback device. Data must be in 8-bit (unsigned) format, little endian.
+ // intended for RTL2832U based DVB-T USB sticks
+ // each sample occupies 1 byte (=8 bit) with values from 0 to 255
+ , exthwUSBdataS8 = 10// the hardware does its own digitization and the audio data are returned to Winrad
+ // via the callback device. Data must be in 8-bit (signed) format, little endian.
+ // each sample occupies 1 byte (=8 bit) with values from -128 to 127
+ , exthwFullPCM32 = 11 // the hardware does its own digitization and the audio data are returned to Winrad
+ // via the callback device. Data are in 32-bit integer format, little endian.
+ // each sample occupies 4 bytes (=32 bits) with full range: from -2^31 to +2^31 -1
+} extHWtypeT;
+
+// status codes for pfnExtIOCallback; used when cnt < 0
+typedef enum
+{
+ // only processed/understood for SDR14
+ extHw_Disconnected = 0 // SDR-14/IQ not connected or powered off
+ , extHw_READY = 1 // IDLE / Ready
+ , extHw_RUNNING = 2 // RUNNING => not disconnected
+ , extHw_ERROR = 3 // ??
+ , extHw_OVERLOAD = 4 // OVERLOAD => not disconnected
+
+ // for all extIO's
+ , extHw_Changed_SampleRate = 100 // sampling speed has changed in the external HW
+ , extHw_Changed_LO = 101 // LO frequency has changed in the external HW
+ , extHw_Lock_LO = 102
+ , extHw_Unlock_LO = 103
+ , extHw_Changed_LO_Not_TUNE = 104 // CURRENTLY NOT YET IMPLEMENTED
+ // LO freq. has changed, Winrad must keep the Tune freq. unchanged
+ // (must immediately call GetHWLO() )
+ , extHw_Changed_TUNE = 105 // a change of the Tune freq. is being requested.
+ // Winrad must call GetTune() to know which value is wanted
+ , extHw_Changed_MODE = 106 // a change of demod. mode is being requested.
+ // Winrad must call GetMode() to know the new mode
+ , extHw_Start = 107 // The DLL wants Winrad to Start
+ , extHw_Stop = 108 // The DLL wants Winrad to Stop
+ , extHw_Changed_FILTER = 109 // a change in the band limits is being requested
+ // Winrad must call GetFilters()
+
+ // Above status codes are processed with Winrad 1.32.
+ // All Winrad derivation like WRplus, WinradF, WinradHD and HDSDR should understand them,
+ // but these do not provide version info with VersionInfo(progname, ver_major, ver_minor).
+
+ , extHw_Mercury_DAC_ON = 110 // enable audio output on the Mercury DAC when using the HPSDR
+ , extHw_Mercury_DAC_OFF = 111 // disable audio output on the Mercury DAC when using the HPSDR
+ , extHw_PC_Audio_ON = 112 // enable audio output on the PC sound card when using the HPSDR
+ , extHw_PC_Audio_OFF = 113 // disable audio output on the PC sound card when using the HPSDR
+
+ , extHw_Audio_MUTE_ON = 114 // the DLL is asking Winrad to mute the audio output. Also see 153
+ , extHw_Audio_MUTE_OFF = 115 // the DLL is asking Winrad to unmute the audio output. Also see 154
+
+ // Above status codes are processed with Winrad 1.33 and HDSDR
+ // Winrad 1.33 and HDSDR still do not provide their version with VersionInfo()
+
+
+ // Following status codes are processed when VersionInfo delivers
+ // 0 == strcmp(progname, "HDSDR") && ( ver_major > 2 || ( ver_major == 2 && ver_minor >= 13 ) )
+
+ // all extHw_XX_SwapIQ_YYY callbacks shall be reported after each OpenHW() call
+ , extHw_RX_SwapIQ_ON = 116 // additionaly swap IQ - this does not modify the menu point / user selection
+ , extHw_RX_SwapIQ_OFF = 117 // the user selected swapIQ is additionally applied
+ , extHw_TX_SwapIQ_ON = 118 // additionaly swap IQ - this does not modify the menu point / user selection
+ , extHw_TX_SwapIQ_OFF = 119 // the user selected swapIQ is additionally applied
+
+
+ // Following status codes (for I/Q transceivers) are processed when VersionInfo delivers
+ // 0 == strcmp(progname, "HDSDR") && ( ver_major > 2 || ( ver_major == 2 && ver_minor >= 13 ) )
+
+ , extHw_TX_Request = 120 // DLL requests TX mode / User pressed PTT
+ // exciter/transmitter must wait until SetModeRxTx() is called!
+ , extHw_RX_Request = 121 // DLL wants to leave TX mode / User released PTT
+ // exciter/transmitter must wait until SetModeRxTx() is called!
+
+ , extHw_CW_Pressed = 122 // User pressed CW key
+ , extHw_CW_Released = 123 // User released CW key
+ , extHw_PTT_as_CWkey = 124 // handle extHw_TX_Request as extHw_CW_Pressed in CW mode
+ // and extHw_RX_Request as extHw_CW_Released
+ // for further CW options see 155 .. 159
+
+ , extHw_Changed_ATT = 125 // Attenuator changed => call GetActualAttIdx()
+
+
+ // Following status codes are processed when ExtIoSDRInfo() was called with extSDR_supports_SampleFormats
+ // following status codes to change sampleformat at runtime
+ , extHw_SampleFormat_PCMU8 = 126 // as 'exthwUSBdataU8': each sample 1 byte: 0 to 255 (Realtek RTL2832U)
+ , extHw_SampleFormat_PCM16 = 127 // as 'exthwUSBdata16': each sample 2 bytes: -2^15 to +2^15 -1
+ , extHw_SampleFormat_PCM24 = 128 // as 'exthwUSBdata24': each sample 3 bytes: -2^23 to +2^23 -1
+ , extHw_SampleFormat_PCM2432 = 129 // as 'exthwUSBdata32': each sample 4 bytes: -2^23 to +2^23 -1 !!!
+ , extHw_SampleFormat_FLT32 = 130 // as 'exthwUSBfloat32': 32-bit float format, little endian
+ , extHw_SampleFormat_PCMS8 = 146 // as 'exthwUSBdataS8': each sample 1 byte: -128 to 127
+ , extHw_SampleFormat_PCM32 = 147 // as 'exthwFullPCM32': each sample 4 bytes: -2^31 to +2^31 -1
+
+ // following status codes to change channel mode at runtime
+ , extHw_RX_ChanMode_LEFT = 131 // left channel only
+ , extHw_RX_ChanMode_RIGHT = 132 // right channel only
+ , extHw_RX_ChanMode_SUM_LR = 133 // sum of left + right channel
+ , extHw_RX_ChanMode_I_Q = 134 // I/Q with left channel = Inphase and right channel = Quadrature
+ // last option set I/Q and clear internal swap as with extHw_RX_SwapIQ_OFF
+ , extHw_RX_ChanMode_Q_I = 135 // I/Q with right channel = Inphase and left channel = Quadrature
+ // last option set I/Q and internal swap as with extHw_RX_SwapIQ_ON
+
+ , extHw_Changed_RF_IF = 136 // refresh selectable attenuators and Gains
+ // => starts calling GetAttenuators(), GetAGCs() & GetMGCs()
+ , extHw_Changed_SRATES = 137 // refresh selectable samplerates => starts calling GetSamplerates()
+
+ // Following status codes are for 3rd Party Software, currently not implemented in HDSDR
+ , extHw_Changed_PRESEL = 138 // Preselector changed => call ExtIoGetActualPreselIdx()
+ , extHw_Changed_PRESELS = 139 // refresh selectable preselectors => start calling ExtIoGetPresels()
+ , extHw_Changed_AGC = 140 // AGC changed => call ExtIoGetActualAGCidx()
+ , extHw_Changed_AGCS = 141 // refresh selectable AGCs => start calling ExtIoGetAGCs()
+ , extHw_Changed_SETTINGS = 142 // settings changed, call ExtIoGetSetting()
+ , extHw_Changed_FREQRANGES = 143 // refresh selectable frequency ranges, call ExtIoGetFreqRanges()
+
+ , extHw_Changed_VFO = 144 // refresh selectable VFO => starts calling ExtIoGetVFOindex()
+
+ // Following status codes are processed when ExtIoSDRInfo() was called with extSDR_supports_MGC
+ // Following status codes are processed when VersionInfo delivers
+ // 0 == strcmp(progname, "HDSDR") && ( ver_major > 2 || ( ver_major == 2 && ver_minor >= 60 ) )
+ , extHw_Changed_MGC = 145 // MGC changed => call ExtIoGetMGC()
+
+ // 146, 147 are used above: extHw_SampleFormat_PCMS8, extHw_SampleFormat_PCM32
+
+ // Following status codes are processed when ExtIoSDRInfo() was called with extSDR_supports_Logging
+ , extHw_MSG_ERRDLG = 148 // error message, with "const char*" in IQdata,
+ // intended for a log file AND a message box
+ , extHw_MSG_ERROR = 149 // error message, for a log file - NO error dialog
+ , extHw_MSG_WARNING = 150 // warning
+ , extHw_MSG_LOG = 151 // log message
+ , extHw_MSG_DEBUG = 152 // debug message for development
+
+ , extHw_Unhandled_KeyPress = 153 // ExtIO can forward unhandleed keypress-events to the SDR application:
+ // the keycodes are pointed in void *IQdata as int * array:
+ // array[0] contains the modifiers as bitset:
+ // 1 : Ctrl
+ // 2 : Shift
+ // 4 : Alt
+ // array[1] contains the keycode
+
+ , extHw_Get_TX_PowerLevel = 154 // SDR app shall write xx into void * IQdata as ..
+ , extHw_Set_TX_PowerLevel = 155 // SDR app shall read/use .. from void * IQdata as ..
+
+ , extHw_Mic_MUTE_ON = 156 // the DLL is asking HDSDR to mute the Mic input (for TX). Also see 114
+ , extHw_Mic_MUTE_OFF = 157 // the DLL is asking HDSDR to unmute the Mic input (for TX). Also see 115
+ // these Mic_MUTE do muting before having switched to TX mode.
+
+
+ //, see extHw_CW_Pressed (=122) / extHw_CW_Released (=123)
+ , extHw_Get_CW_Speed_CPM = 158 // SDR app shall write xx into void * IQdata as ..
+ , extHw_Set_CW_Speed_CPM = 159 // SDR app shall read/use .. from void * IQdata as ..
+ , extHw_CW_Dit_Pressed = 160 // user pressed Dit. Request HDSDR to generate tone of that length.
+ , extHw_CW_Dit_Released = 161 // user released Dit
+ , extHw_CW_Dah_Pressed = 162 // user pressed Dah. Request HDSDR to generate tone of that length.
+ , extHw_CW_Dah_Released = 163 // user released Dah
+ , extHw_CW_Ext_Keying_ON = 164 // Request HDSDR to generate the I/Q-CW tone all the time
+ // for external keying in the hardware.
+ // This will let HDSDR generate I/Q tone - when in CW mode - also in RX
+ // - independent CW keys are pressed or released!
+ , extHw_CW_Ext_Keying_OFF = 165 // deactivate external keying
+
+ , extHw_CW_TX_SideTone_ON = 166 // activate CW sidetone output to RX-Output Soundcard
+ , extHw_CW_TX_SideTone_OFF = 167 // deactivate CW sidetone output
+
+
+
+ // reserved for Bonito's ECAS messages:
+ // 0x0100 - 0x03FF = 256 - 1023 -> from ExtIO to SDR-App
+ // 0x2000 = 8192 -> ECAS/Windows messages to
+
+
+} extHWstatusT;
+
+// codes for pfnSetModeRxTx:
+typedef enum
+{
+ extHw_modeRX = 0
+ , extHw_modeTX = 1
+} extHw_ModeRxTxT;
+
+
+// codes for pfnExtIoSDRInfo
+typedef enum
+{
+ extSDR_NoInfo = 0 // sign SDR features would be signed with subsequent calls
+ , extSDR_supports_Settings = 1
+ , extSDR_supports_Atten = 2 // RF Attenuation / Gain may be set via pfnSetAttenuator()
+ , extSDR_supports_TX = 3 // pfnSetModeRxTx() may be called
+ , extSDR_controls_BP = 4 // pfnDeactivateBP() may be called
+ , extSDR_supports_AGC = 5 // pfnExtIoSetAGC() may be called
+ , extSDR_supports_MGC = 6 // IF Attenuation / Gain may be set via pfnExtIoSetMGC()
+ , extSDR_supports_PCMU8 = 7 // exthwUSBdataU8 is supported
+ , extSDR_supports_PCMS8 = 8 // exthwUSBdataS8 is supported
+ , extSDR_supports_PCM32 = 9 // exthwFullPCM32 is supported
+ , extSDR_supports_Logging = 10 // extHw_MSG_* is supported
+ , extSDR_supports_SampleFormats = 11 // extHw_SampleFormat_* is supported
+ , extSDR_supports_Keys = 12 //
+ , extSDR_supports_PowerLevel = 13 //
+ , extSDR_supports_Mic_Mute = 14 //
+ , extSDR_supports_CW_Units = 15 // speed, Dit/Dah
+ , extSDR_supports_CW_SideTone = 16 //
+ , extSDR_supports_Ext_CW_Keying = 17 //
+
+} extSDR_InfoT;
+
+
+// macro to call callback function with just status extHWstatusT
+#define EXTIO_STATUS_CHANGE( CB, STATUS ) CB( -1, STATUS, 0, NULL )
+
+#endif /* LC_ExtIO_TypesH */
+
diff --git a/src/procitec_replacements.cpp b/src/procitec_replacements.cpp
new file mode 100644
index 0000000..55aa70a
--- /dev/null
+++ b/src/procitec_replacements.cpp
@@ -0,0 +1,35 @@
+
+#include "procitec_replacements.h"
+
+#ifndef _WINSOCK2API_
+#define _WINSOCK2API_
+#define _WINSOCKAPI_
+#endif
+#include
+
+uint64_t currentMSecsSinceEpoch()
+{
+ // mostly from http://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/
+
+ SYSTEMTIME st;
+ GetSystemTime(&st);
+ FILETIME ft;
+ SystemTimeToFileTime(&st, &ft);
+
+ LARGE_INTEGER date;
+ date.HighPart = ft.dwHighDateTime;
+ date.LowPart = ft.dwLowDateTime;
+
+ // Between Jan 1, 1601 and Jan 1, 1970 there are 11644473600 seconds
+ // 100-nanoseconds = milliseconds * 10000
+ LARGE_INTEGER adjust;
+ adjust.QuadPart = 11644473600000LL * 10000LL;
+
+ // removes the diff between 1970 and 1601
+ date.QuadPart -= adjust.QuadPart;
+
+ // converts back from 100-nanoseconds to milliseconds
+ uint64_t ret = uint64_t( date.QuadPart / 10000 );
+ return ret;
+}
+
diff --git a/src/procitec_replacements.h b/src/procitec_replacements.h
new file mode 100644
index 0000000..fac2a8d
--- /dev/null
+++ b/src/procitec_replacements.h
@@ -0,0 +1,153 @@
+#pragma once
+
+// missing definitions, macros and functions from following include files
+//#include "common/base/baselib/base/ProLogging.h"
+//#include "common/base/baselib/base/ByteOrder.h"
+//#include "common/base/baselib/base/ProMakros.h"
+//#include "common/base/baselib/base/ProStd.h"
+
+// hacked down all missing things
+// - strictly assuming little endian platform!
+
+#include
+#include
+
+#define NUMEL( ARR ) ( sizeof(ARR) / sizeof(ARR[0]) )
+#define ProAssert( COND ) assert( COND )
+#define PROASSERT( COND ) assert( COND )
+
+#define STRINGIZE(s) STRINGIZEL(s)
+#define STRINGIZEL(s) #s
+
+#define EXTIO_IFC_VER 2018
+#define EXTIO_VER_REV 0
+#define SCM_TAGNAME ""
+#define SCM_DATE ""
+
+#define LITTLE_INT16_T int16_t
+
+
+#pragma pack(push, 1) // exact fit - no padding
+struct LITTLE_INT24_T
+{
+ uint8_t lo;
+ uint8_t mi;
+ int8_t hi;
+};
+#pragma pack(pop) //back to whatever the previous packing mode was
+
+
+extern uint64_t currentMSecsSinceEpoch();
+
+static inline
+const char * ProVersion()
+{
+ return "?";
+}
+
+static inline
+void WRITE_LITTLE_INT8(uint8_t v, void * vp)
+{
+ uint8_t * tp = (uint8_t *)vp;
+ *tp = v;
+}
+
+static inline
+void WRITE_BIG_INT8(uint8_t v, void * vp)
+{
+ uint8_t * tp = (uint8_t *)vp;
+ *tp = v;
+}
+
+static inline
+void WRITE_LITTLE_INT16(uint16_t v, void * vp)
+{
+ uint16_t * tp = (uint16_t *)vp;
+ *tp = v;
+}
+
+static inline
+void WRITE_BIG_INT32(uint32_t v, void * vp)
+{
+ uint32_t * tp = (uint32_t *)vp;
+ uint32_t flipped = ((v & 0xFFU) << 24)
+ | ((v & 0xFF00U) << 8)
+ | ((v & 0xFF0000U) >> 8)
+ | ((v & 0xFF000000U) >> 24);
+ *tp = flipped;
+}
+
+static inline
+void WRITE_LITTLE_INT32(uint32_t v, void * vp)
+{
+ uint32_t * tp = (uint32_t *)vp;
+ *tp = v;
+}
+
+static inline
+void WRITE_LITTLE_INT64(uint64_t v, void * vp)
+{
+ uint64_t * tp = (uint64_t *)vp;
+ *tp = v;
+}
+
+
+static inline
+uint8_t READ_LITTLE_INT8( const void * vp )
+{
+ const uint8_t * tp = (const uint8_t *)vp;
+ return *tp;
+}
+
+static inline
+uint8_t READ_BIG_INT8(const void * vp)
+{
+ const uint8_t * tp = (const uint8_t *)vp;
+ return *tp;
+}
+
+static inline
+uint16_t READ_LITTLE_INT16(const void * vp)
+{
+ const uint16_t * tp = (const uint16_t *)vp;
+ return *tp;
+}
+
+static inline
+uint32_t READ_LITTLE_INT32(const void * vp)
+{
+ const uint32_t * tp = (const uint32_t *)vp;
+ return *tp;
+}
+
+static inline
+uint64_t READ_LITTLE_INT64(const void * vp)
+{
+ const uint64_t * tp = (const uint64_t *)vp;
+ return *tp;
+}
+
+static inline
+uint32_t READ_BIG_INT32(const void * vp)
+{
+ const uint32_t * tp = (const uint32_t *)vp;
+ const uint32_t v = *tp;
+ uint32_t flipped = ((v & 0xFFU) << 24)
+ | ((v & 0xFF00U) << 8)
+ | ((v & 0xFF0000U) >> 8)
+ | ((v & 0xFF000000U) >> 24);
+ return flipped;
+}
+
+
+template
+T PROCLIP(T val, T minVal, T maxVal)
+{
+ if (val < minVal)
+ return minVal;
+ else if (val > maxVal)
+ return maxVal;
+ else
+ return val;
+}
+
diff --git a/src/rfspace_netsdr_control.cpp b/src/rfspace_netsdr_control.cpp
index 82fc0b3..e7253db 100644
--- a/src/rfspace_netsdr_control.cpp
+++ b/src/rfspace_netsdr_control.cpp
@@ -1,12 +1,11 @@
#include "rfspace_netsdr_control.h"
-#include "foreign/clsocket/clsocket/src/SimpleSocket.h"
+#include "ExtIO_Logging.h"
-#include "common/base/baselib/base/ProLogging.h"
-#include "common/base/baselib/base/ByteOrder.h"
-#include "common/base/baselib/base/ProMakros.h"
-#include "common/base/baselib/base/ProStd.h"
+#include "SimpleSocket.h"
+
+#include "procitec_replacements.h"
#include
@@ -357,7 +356,7 @@ void RFspaceNetSDRControl::requestHwFwVersions(HwFw id)
return;
const unsigned int len = 5;
- const char acBuf[len] = { 5, 0x20, 4, 0, 0 };
+ char acBuf[len] = { 5, 0x20, 4, 0, 0 };
WRITE_LITTLE_INT8( uint8_t(id) , &acBuf[4] );
@@ -406,7 +405,7 @@ void RFspaceNetSDRControl::requestRcvFrequency()
return;
const unsigned int len = 5;
- const char acBuf[len] = { 5, char(msgType), 0x20, 0, 0};
+ char acBuf[len] = { 5, char(msgType), 0x20, 0, 0};
WRITE_LITTLE_INT8( channel , &acBuf[4] );
@@ -419,7 +418,7 @@ void RFspaceNetSDRControl::requestRcvFrequencyRanges()
return;
const unsigned int len = 5;
- const char acBuf[len] = { 5, char(MsgType::REQ_CTRL_RANGE), 0x20, 0, 0};
+ char acBuf[len] = { 5, char(MsgType::REQ_CTRL_RANGE), 0x20, 0, 0};
WRITE_LITTLE_INT8( channel , &acBuf[4] );
@@ -432,7 +431,7 @@ void RFspaceNetSDRControl::requestRcvADAmplScale()
return;
const unsigned int len = 5;
- const char acBuf[len] = { 5, char(msgType), 0x23, 0, 0};
+ char acBuf[len] = { 5, char(msgType), 0x23, 0, 0};
WRITE_LITTLE_INT8( channel , &acBuf[4] );
@@ -445,7 +444,7 @@ void RFspaceNetSDRControl::requestRFGain()
return;
const unsigned int len = 5;
- const char acBuf[len] = { 5, char(msgType), 0x38, 0, 0};
+ char acBuf[len] = { 5, char(msgType), 0x38, 0, 0};
WRITE_LITTLE_INT8( channel , &acBuf[4] );
@@ -469,7 +468,7 @@ void RFspaceNetSDRControl::requestRFFilterSelection()
return;
const unsigned int len = 5;
- const char acBuf[len] = { 5, char(msgType), 0x44, 0, 0};
+ char acBuf[len] = { 5, char(msgType), 0x44, 0, 0};
WRITE_LITTLE_INT8( channel , &acBuf[4] );
@@ -483,7 +482,7 @@ void RFspaceNetSDRControl::requestADMode()
const unsigned int len = 5;
- const uint8_t acBuf[len] = { 5, uint8_t(msgType), 0x8A, 0, 0 };
+ uint8_t acBuf[len] = { 5, uint8_t(msgType), 0x8A, 0, 0 };
WRITE_LITTLE_INT8( channel , &acBuf[4] );
@@ -497,7 +496,7 @@ void RFspaceNetSDRControl::requestUDPInterface()
const unsigned int len = 5;
- const uint8_t acBuf[len] = { 5, uint8_t(msgType), 0xC5, 0, 0 };
+ uint8_t acBuf[len] = { 5, uint8_t(msgType), 0xC5, 0, 0 };
WRITE_LITTLE_INT8( channel , &acBuf[4] );
@@ -908,18 +907,33 @@ void RFspaceNetSDRControl::setUDPInterface ( const char * ip, uint16_t portNum )
if ( mSocket.IsSocketInvalid() )
return;
- uint32_t ipSend = inet_addr( ip );
+ const uint32_t ipSend = CSimpleSocket::GetIPv4AddrInfoStatic(ip);
- const unsigned int len = 10;
- unsigned char acBuf[len] = { 0x0A, 0, 0xC5, 0, 0, 0, 0, 0, 0, 0 };
+ if (ipSend)
+ {
+ const unsigned int len = 10;
+ unsigned char acBuf[len] = { 0x0A, 0, 0xC5, 0, 0, 0, 0, 0, 0, 0 };
- void * wp = &acBuf[4];
- WRITE_BIG_INT32( ipSend, wp ); //BIG ENDIAN because ip and portNum already are little endian format
+ void * wp = &acBuf[4];
+ WRITE_BIG_INT32(ipSend, wp); //BIG ENDIAN because ip and portNum already are little endian format
- wp = &acBuf[8];
- WRITE_LITTLE_INT16( portNum, wp );
+ wp = &acBuf[8];
+ WRITE_LITTLE_INT16(portNum, wp);
- mSocket.Send(acBuf, len);
+ mSocket.Send(acBuf, len);
+
+ LOG_PRO(LOG_DEBUG, "Commanded NetSDR to transmit it's UDP stream to %u.%u.%u.%u:%u"
+ , unsigned((ipSend >> 24) & 0xFF)
+ , unsigned((ipSend >> 16) & 0xFF)
+ , unsigned((ipSend >> 8) & 0xFF)
+ , unsigned(ipSend & 0xFF)
+ , unsigned(portNum)
+ );
+ }
+ else
+ {
+ LOG_PRO(LOG_PROTOCOL, "Skipping NetSDR command to transmit it's UDP stream towards ??? without DATA_IP address");
+ }
}
void RFspaceNetSDRControl::setCWStartup ( uint8_t wpm, CWFreq cwFreq, const char * asciiMessage)
@@ -927,14 +941,13 @@ void RFspaceNetSDRControl::setCWStartup ( uint8_t wpm, CWFreq cwFreq, const char
if ( mSocket.IsSocketInvalid() )
return;
- int wpmMin = uint8_t(WpmMinMax::WPM_MIN);
- int wpmMax = uint8_t(WpmMinMax::WPM_MAX);
-
+ uint8_t wpmMin = uint8_t(WpmMinMax::WPM_MIN);
+ uint8_t wpmMax = uint8_t(WpmMinMax::WPM_MAX);
if( (wpm < wpmMin) || (wpm > wpmMax) )
{
wpm = PROCLIP(wpm, wpmMin, wpmMax);
- LOG_PRO( LOG_ERROR,"WPM value out of bounds --> setting to value %u", wpm);
+ LOG_PRO( LOG_ERROR,"WPM value out of bounds --> setting to value %u", unsigned(wpm));
}
uint8_t length = strlen(asciiMessage);
@@ -1777,7 +1790,6 @@ const char * getText( RFspaceNetSDRControl::RfGain e )
const char * getFilterText( int e )
{
-
switch(RFspaceNetSDRControl::RfFilterSel(e))
{
case RFspaceNetSDRControl::RfFilterSel::F_AUTO: return "Auto Selection";
@@ -1864,6 +1876,3 @@ const char * getText( uint8_t e )
}
}
-
-
-
diff --git a/src/rfspace_netsdr_receiver.cpp b/src/rfspace_netsdr_receiver.cpp
index b1391c6..cc996ec 100644
--- a/src/rfspace_netsdr_receiver.cpp
+++ b/src/rfspace_netsdr_receiver.cpp
@@ -1,21 +1,28 @@
#include "rfspace_netsdr_receiver.h"
-#include "common/base/baselib/base/ProLogging.h"
-#include "common/base/baselib/base/ProMakros.h"
-#include "common/base/baselib/base/ProStd.h"
+#include "ExtIO_Logging.h"
+#include "procitec_replacements.h"
#include
#include
#include
-//#include
-
-const uint32_t RFspaceNetReceiver::maiSamplerates[] { 12500, 32000, 62500, 100*1000, 125*1000, 250*1000, 500*1000, 625*1000, 1000*1000, 1666666, 2000*1000 };
-const uint32_t RFspaceNetReceiver::maiBandwidths[] { 10*1000, 25*1000, 50*1000, 80*1000, 100*1000, 200*1000, 400*1000, 500*1000, 800*1000, 1300*1000, 1600*1000 };
-const float RFspaceNetReceiver::mafAttenuationATTs[] = { -30.0F, -30.0F, -20.0F, -20.0F, -10.0F, -10.0F, 0.0F, 0.0F };
-const float RFspaceNetReceiver::mafActualAttenuationATTs[] = { -30.0F, -26.5F, -20.0F, -16.5F, -10.0F, -6.5F, 0.0F, 3.5F };
-const float RFspaceNetReceiver::mafAttenuationADGains[] = { 1.0F, 1.5F, 1.0F, 1.5F, 1.0F, 1.5F, 1.0F, 1.5F };
-const float RFspaceNetReceiver::mafAttenuationADGainsdB[] = { 0.0F, 3.0F, 0.0F, 3.0F, 0.0F, 3.0F, 0.0F, 3.0F };
+#define KHZ *1000
+// from NetSDR specification:
+// This parameter limited to frequencies that are integer divisions by 4 of the 80MHz A/D sample rate
+// The maximum sample rate supported is 2,000,000 Hz in the 16 bits/sample mode.(80MHz/40)
+// The maximum sample rate supported is 1,333,333 Hz in the 24 bits/sample mode.(80MHz/60)
+// The minimum sample rate supported is 32,000 Hz in the 16 or 24 bits/sample mode.( 80MHz/250)
+//
+// decim from 80 MHz A/D clock: 6400 5000 2500 1280 1000 800 640 500 400 320 256 200 160 128 100 80 64 52 48 44 40
+const uint32_t RFspaceNetReceiver::maiSamplerates[] { 12500, 16 KHZ, 32 KHZ, 62500, 80 KHZ, 100 KHZ, 125 KHZ, 160 KHZ, 200 KHZ, 250 KHZ, 312500, 400 KHZ, 500 KHZ, 625 KHZ, 800 KHZ, 1000 KHZ, 1250 KHZ, 1538461, 1666666, 1818181, 2000 KHZ };
+const uint32_t RFspaceNetReceiver::maiBandwidths[] { 10 KHZ, 12 KHZ, 25 KHZ, 50 KHZ, 64 KHZ, 80 KHZ, 100 KHZ, 128 KHZ, 160 KHZ, 200 KHZ, 250 KHZ, 320 KHZ, 400 KHZ, 500 KHZ, 640 KHZ, 800 KHZ, 1000 KHZ, 1200 KHZ, 1300 KHZ, 1400 KHZ, 1600 KHZ };
+#undef KHZ
+
+const float RFspaceNetReceiver::mafAttenuationATTs[] = { -30.0F, -30.0F, -20.0F, -20.0F, -10.0F, -10.0F, 0.0F, 0.0F };
+const float RFspaceNetReceiver::mafActualAttenuationATTs[] = { -30.0F, -26.5F, -20.0F, -16.5F, -10.0F, -6.5F, 0.0F, 3.5F };
+const float RFspaceNetReceiver::mafAttenuationADGains[] = { 1.0F, 1.5F, 1.0F, 1.5F, 1.0F, 1.5F, 1.0F, 1.5F };
+const float RFspaceNetReceiver::mafAttenuationADGainsdB[] = { 0.0F, 3.0F, 0.0F, 3.0F, 0.0F, 3.0F, 0.0F, 3.0F };
const float RFspaceNetReceiver::mafVUHFCompatibilityGainValues[] = {0, 1, 2, 3 };
const float RFspaceNetReceiver::mafVUHFMultiGainValues[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
@@ -590,7 +597,7 @@ bool RFspaceNetReceiver::startHW(int64_t LOfreq)
mpoSettings->iFrequency = LOfreq;
mSampleBufferLenInFrames = 0;
- mChangeBitRangeSmpRateIdx = getSmpRateIdx(mpoSettings->iBitDepthThresSamplerate);
+ mChangeBitRangeSmpRateIdx = getMaxSmpRateIdx(mpoSettings->iBitDepthThresSamplerate);
if( mpoSettings->iSampleRateIdx <= mChangeBitRangeSmpRateIdx)
{
@@ -784,8 +791,6 @@ void RFspaceNetReceiver::setSamplerate( int idx )
//--> give samplerate change (and sometimes therefore bitdepth change) more time.
mStartUDPTimer = 100; //in ms
mStartData = true;
-
-
}
int64_t RFspaceNetReceiver::getHWLO( void )
@@ -811,7 +816,8 @@ int RFspaceNetReceiver::getSmpRateIdx( uint32_t smpRate )
int ret = -1;
for(int idx = 0; idx < miNumSamplerates; ++idx)
{
- if(smpRate == maiSamplerates[idx])
+ int32_t delta = smpRate - maiSamplerates[idx];
+ if( -10 <= delta && delta <= 10 ) // +/- 10 Hz tolerance
{
LOG_PRO( LOG_DEBUG, "********* RFspaceNetReceiver::getSmpRateIdx(%u) --> idx: %d", smpRate, idx);
ret = idx;
@@ -820,12 +826,29 @@ int RFspaceNetReceiver::getSmpRateIdx( uint32_t smpRate )
}
if(ret == -1)
- LOG_PRO( LOG_DEBUG, "********* RFspaceNetReceiver::getSmpRateIdx(%u) --> idx: ERROR !", smpRate);
+ LOG_PRO(LOG_ERROR, "********* RFspaceNetReceiver::getSmpRateIdx(%u) --> idx: ERROR !", smpRate);
return ret;
+}
+
+
+int RFspaceNetReceiver::getMaxSmpRateIdx(uint32_t smpRate)
+{
+ int ret = -1;
+ for (int idx = 0; idx < miNumSamplerates; ++idx)
+ {
+ if (smpRate >= maiSamplerates[idx])
+ ret = idx;
+ }
+ if (ret == -1)
+ LOG_PRO(LOG_ERROR, "********* RFspaceNetReceiver::getMaxSmpRateIdx(%u) --> idx: ERROR !", smpRate);
+ else
+ LOG_PRO(LOG_DEBUG, "********* RFspaceNetReceiver::getMaxSmpRateIdx(%u) --> idx: %d", smpRate, ret);
+ return ret;
}
+
const int64_t * RFspaceNetReceiver::getFrequencyRanges(int idx)
{
if(mHasRcvFrequencyRanges)
diff --git a/src/rfspace_netsdr_receiver.h b/src/rfspace_netsdr_receiver.h
index 5fde168..e22fdeb 100644
--- a/src/rfspace_netsdr_receiver.h
+++ b/src/rfspace_netsdr_receiver.h
@@ -3,10 +3,7 @@
#include "rfspace_netsdr_control.h"
#include "rfspace_netsdr_udpdata.h"
-#include "common/functions/receiverlib/LC_ExtIO_Types.h"
-
-#include "common/base/baselib/base/ByteOrder.h"
-#include "common/base/baselib/base/ExtendedTypes.h"
+#include "LC_ExtIO_Types.h"
#include
@@ -30,17 +27,16 @@ class RFspaceNetReceiver
public:
Settings()
{
- strcpy(acCtrlIP, "10.10.11.2");
- strcpy(acDataIP, "");
- uCtrlPortNo = uDataPortNo = 50000;
- iSampleRateIdx = 0;
+ strcpy(acCtrlIP, "192.168.8.101"); // "10.10.11.2"
+ strcpy(acDataIP, "192.168.8.100"); // "" main PC: 192.168.8.100 PC2: 192.168.8.102
+ uCtrlPortNo = uDataPortNo = 50002; // 50000
+ iSampleRateIdx = 2; // 2: 32 kHz samplerate
iAttenuationIdx = 0;
- iBitDepthThresSamplerate = 0;
-
+ iBitDepthThresSamplerate = 1333333; // 1333.333 kHz == 80 MHz / 60
iBand_minFreq = 0;
- iBand_maxFreq = 0;
+ iBand_maxFreq = 34 * 1000L * 1000L; // 0 - 34 MHz
uiBandwidth = 0;
uiSamplerate = 0;
@@ -138,6 +134,7 @@ class RFspaceNetReceiver
int64_t getHWLO( void );
int getAttIdx( void );
int getSmpRateIdx( uint32_t );
+ int getMaxSmpRateIdx(uint32_t);
const int64_t * getFrequencyRanges( int idx );
void TimerProc(uint16_t waitMs);
diff --git a/src/rfspace_netsdr_udpdata.cpp b/src/rfspace_netsdr_udpdata.cpp
index 69c625f..7b18352 100644
--- a/src/rfspace_netsdr_udpdata.cpp
+++ b/src/rfspace_netsdr_udpdata.cpp
@@ -1,9 +1,8 @@
#include "rfspace_netsdr_udpdata.h"
-#include "common/base/baselib/base/ByteOrder.h"
-#include "common/base/baselib/base/ProStd.h"
-#include "common/base/baselib/base/ProLogging.h"
+#include "ExtIO_Logging.h"
+#include "procitec_replacements.h"
#define LENGTH_MASK 0x1FFF // mask for message length
@@ -63,6 +62,24 @@ bool RFspaceNetSDRUdpData::bindIfc( const char * ifc, uint16_t portNo )
resetReceiverData();
+ const uint32_t ipSend = CSimpleSocket::GetIPv4AddrInfoStatic(ifc);
+ if (!ipSend)
+ {
+ LOG_PRO(LOG_PROTOCOL, "Binding to all local interfaces without DATA_IP address '%s'", ifc);
+ ifc = "";
+ }
+ else
+ {
+ LOG_PRO(LOG_DEBUG, "Binding will be on %u.%u.%u.%u for '%s'"
+ , unsigned((ipSend >> 24) & 0xFF)
+ , unsigned((ipSend >> 16) & 0xFF)
+ , unsigned((ipSend >> 8) & 0xFF)
+ , unsigned(ipSend & 0xFF)
+ , ifc
+ );
+ }
+
+ LOG_PRO(LOG_DEBUG, "Binding UDP to interface %s:%u ..", ifc, unsigned(portNo));
bool bConnected = mSocket.Bind(ifc, portNo);
if ( bConnected )
{
@@ -71,13 +88,15 @@ bool RFspaceNetSDRUdpData::bindIfc( const char * ifc, uint16_t portNo )
uint32_t resWinSize = mSocket.SetReceiveWindowSize( paramWinSize );
if ( resWinSize < paramWinSize )
{
- LOG_PRO( LOG_DEBUG, "Error setting UDP windows size to %u - result is %u", paramWinSize, resWinSize);
+ LOG_PRO(LOG_ERROR, "Error setting UDP windows size to %u - result is %u", paramWinSize, resWinSize);
}
-
+ }
+ else
+ {
+ LOG_PRO(LOG_ERROR, "Error binding UDP to interface %s:%u", ifc, unsigned(portNo));
}
return bConnected;
- return true;
}
diff --git a/src/rfspace_netsdr_udpdata.h b/src/rfspace_netsdr_udpdata.h
index 975250c..196d385 100644
--- a/src/rfspace_netsdr_udpdata.h
+++ b/src/rfspace_netsdr_udpdata.h
@@ -4,8 +4,8 @@
#include
#include
-#include "foreign/clsocket/clsocket/src/SimpleSocket.h"
-#include "foreign/clsocket/clsocket/src/PassiveSocket.h"
+#include "SimpleSocket.h"
+#include "PassiveSocket.h"
// forward declaration
class CPassiveSocket;