From 1a9eb30355c3eb2f467a2344943a084b9506ad85 Mon Sep 17 00:00:00 2001 From: hayati ayguen Date: Sun, 6 May 2018 01:10:59 +0200 Subject: [PATCH] fixed setup: better handling of erroneous IP address or missing device * (windows) error dialog message, when connection fails added connection timeout, default: 1000 ms * fixed changing samplerate * fixed buffer space, when using WRITE_LITTLE_INT64() to write just 5 bytes Signed-off-by: hayati ayguen --- ExtIO_NetSDR/ExtIO_NetSDR.vcxproj | 2 +- README.md | 16 +++- config_Default-profile.reg | Bin 0 -> 1830 bytes config_NetSDR-profile.reg | Bin 0 -> 1844 bytes docs/README.txt | 7 ++ src/ExtIO_RFspaceNetSDR.cpp | 73 +++++++++------ src/procitec_replacements.h | 6 +- src/rfspace_netsdr_control.cpp | 145 +++++++++++------------------- src/rfspace_netsdr_control.h | 70 +++++++++------ src/rfspace_netsdr_receiver.cpp | 118 +++++++++++++----------- src/rfspace_netsdr_receiver.h | 25 ++++-- src/rfspace_netsdr_udpdata.cpp | 17 ++-- 12 files changed, 264 insertions(+), 215 deletions(-) create mode 100644 config_Default-profile.reg create mode 100644 config_NetSDR-profile.reg create mode 100644 docs/README.txt diff --git a/ExtIO_NetSDR/ExtIO_NetSDR.vcxproj b/ExtIO_NetSDR/ExtIO_NetSDR.vcxproj index d62e4e4..cb15d77 100644 --- a/ExtIO_NetSDR/ExtIO_NetSDR.vcxproj +++ b/ExtIO_NetSDR/ExtIO_NetSDR.vcxproj @@ -81,7 +81,7 @@ false true true - 2018.0 + 2018.1 ..\src\ExtIO_RFspaceNetSDR.def /PDBSTRIPPED false diff --git a/README.md b/README.md index b1aa7e2..bbe83ca 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # ExtIO_RFspaceNetSDR Winrad/HDSDR plugin ExtIO for the RFspace NetSDR receiver +URL: https://github.com/hayguen/ExtIO_RFspaceNetSDR ## Software Defined Radio (SDR) receiver @@ -37,6 +38,16 @@ Other ExtIO compatible software like Winrad or Studio1 should also work. * 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. +* Edit one of config_Default-profile.reg (or config_NetSDR-profile.reg) with a Text-Editor, +e.g. Notepad++. Enter your IP address(es) and check if you need to modify the portnumber. +Use config_Default-profile.reg if you start HDSDR with it's installed shortcut. + +* With a custom 'NetSDR' profile, +see https://sites.google.com/site/g4zfqradio/installing-and-using-hdsdr#Advanced , +you might edit config_NetSDR-profile.reg + +* Then doubleclick to import those settings, when HDSDR is closed + * exit and restart SDR software and select ExtIO_RFspaceNetSDR.DLL if demanded @@ -49,7 +60,7 @@ Besides cloning this repository, you also need to clone following libraries from * 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. +Other compilers (gcc/mingw) should work, when adding suitable project files or fixing CMakeLists.txt. ## Status @@ -58,3 +69,6 @@ Compiles. In test. ExtIO control GUI for configuration is missing! To be implemented .. +Workaround by editing Windows' registry directly with 'regedit.exe' for use with HDSDR. + Registry path: HKEY_CURRENT_USER\Software\HDSDR\ExtIO_RFspaceNetSDR.dll + diff --git a/config_Default-profile.reg b/config_Default-profile.reg new file mode 100644 index 0000000000000000000000000000000000000000..9f6ab8dc636a7bf7938d13c3f8c1c37f7813ac74 GIT binary patch literal 1830 zcmcJP;cpT_5XI-SiT}ffFKA*LuPsK6eyGrfrluvd)EG6*35UH19N|F3KVJR4T`s`2 zv6yHsdw07#JNxF%oB8$gouxLio@F+-+?=&7u`jIUHnoW@SUF-hWtK5_cE$dL-IV!= zdChk1DbGWD;Kv7R+9_w=+qKoLgTFSjGrMHou?zm&_K|O9eSFR>##_Ql(;BQc{O*x` zXYa($In%adZX09Q#qNwTUE1w}Yryl#-&^r0B2F~0$+4b*ag239TCvww0nxd~(&qaX z^e5J`m&@;t9pbU)@#J`L9;35r34_}}QN^ym{`=c^GBSF~|*?=NF)d2~}yXFk^Pa_-3A%!c-PiB%c-U(pJ4Iog`f zn6$Ib%l<9e&y)!{cKz7aZb-f%xcWv z4kPG);BAy&#~6BrEy$AtlQh${8`it_m3NPM71ih7`VcHr{w8>r-=GqQUW;3Tar={;rK29k{!T>@!*fuSDl$}sI4!fk&iTQXoQpxRu&tK<75k51GC`d& zk%>c9Z0y-C*Yi5Q#~Zp*jAah)R$%QOHtKLN;!&21?jlvCs3Bo*#($9+X-Pdw{Z#fk z+2enmece|^rmEkpjEK(g=iYV!C(@%7Dji5`;z?-cs5151bkw`LxfoS@#b*O>JTeR*u+BnPtqKU9vx6H)TFz zUb9_$%yZxF`SISG_L?*A?8@ra!C#x%sa-Jd*g5}g`@lD|K0fCb<1JyOX$@8ze)p7> z>F?Q*ePecFXLxAaF?WwS)x~DrZWojTo{t_y#bb&%(ZDXpdII7xegf`_y|fDW&OEX< z-#5f^Vl8{V{O;Hx9(x{LjtA!vJFAv3xD6Cl?D|Wl6qit@_LaA|>w3<_YX;Iv3F#$K z4Qz&OKo{9F+k@T6p4d~q8WC|t8z=YvGRBriHwAU(V;wK&j%?0sXrGo?m7o6=tuU9P zt@(^eN$b4q-w|DdEL||Jw#r={epBKbp#w**>%66F=d--Zl_THEQbIXlL$9y}d2(QqX1aFGde^@2?lG@Y1G%?81k04a3Et&5sKlYy;+CLX z?GzTF;yT#0{0-~+l=5WhsGG6BQxU}Q92BMc3{@dc%j~aney}CyVo)q>tEGR%{sWjy zP-jeJ;!qVEd$!BU>NhJRqBH!tx1Ga@^eBZ&2hy5&5}G-xOuaT8^{(D7M%5j!Jyt1K z>hFPGRUzf}S;_F|xcPv0s2laB!iQ9UjEy>7e#`Ch`hvde=!Zq8d&F$vS#s2vx_;sR ymB*$1gcw52+`O&8RA@d0ry>g#C4Qxjh_UaV)wgNisnZqnfzg}HhjZZ_tbYO3)Fnp% literal 0 HcmV?d00001 diff --git a/docs/README.txt b/docs/README.txt new file mode 100644 index 0000000..a155d62 --- /dev/null +++ b/docs/README.txt @@ -0,0 +1,7 @@ + +NetSDR Interface Specification from +http://www.moetronix.com/svdownload.htm + +SDRNetSetup Utility Source Code Link +https://sourceforge.net/projects/sdrnetsetup/ + diff --git a/src/ExtIO_RFspaceNetSDR.cpp b/src/ExtIO_RFspaceNetSDR.cpp index 3c93201..a8b9579 100644 --- a/src/ExtIO_RFspaceNetSDR.cpp +++ b/src/ExtIO_RFspaceNetSDR.cpp @@ -1,7 +1,7 @@ #define HWNAME "RFspace" #define HWMODEL "RFspace NetSDR" -#define SETTINGS_IDENTIFIER "RFspace NetSDR-0.2" +#define SETTINGS_IDENTIFIER "RFspace NetSDR-0.5" #include "ExtIO_RFspaceNetSDR.h" #include "rfspace_netsdr_receiver.h" @@ -275,15 +275,19 @@ bool EXTIO_CALL InitHW( char* name, char* model, int& type ) gbInitHW = true; } - return gbInitHW; } //--------------------------------------------------------------------------- -bool EXTIO_CALL OpenHW( void ) +bool EXTIO_CALL OpenHW(void) { - LOG_PRO( LOG_DEBUG, "OpenHW() called" ); + LOG_PRO(LOG_DEBUG, "OpenHW() called .. returning gbInitHw = %s", (gbInitHW ? "true" : "false")); + return gbInitHW; // open on demand! +} +//--------------------------------------------------------------------------- +static bool InternalOpenHW(void) +{ bool bOpenOK = true; if ( gbInitHW ) { @@ -298,6 +302,7 @@ bool EXTIO_CALL OpenHW( void ) { gpoReceiver->setExtIoCallback(gpfnExtIOCallbackPtr); stopThread(); + LOG_PRO(LOG_DEBUG, "InternalOpenHW(): trying to open/connect device .."); bOpenOK = gpoReceiver->openHW(gpoSettings); if (bOpenOK) startThread(); @@ -305,17 +310,18 @@ bool EXTIO_CALL OpenHW( void ) { delete gpoReceiver; gpoReceiver = nullptr; + +#if defined( WIN32 ) || defined( WIN64 ) + char acMsg[1024]; + snprintf(acMsg, 1023, "Error connecting to %s:%u", gpoSettings->acCtrlIP, unsigned(gpoSettings->uCtrlPortNo)); + ::MessageBoxA(0, acMsg, "Error", MB_OK); +#endif } + LOG_PRO(LOG_DEBUG, "InternalOpenHW() returns gbInitHW && bOpenOK = %s && %s", (gbInitHW ? "true" : "false"), (bOpenOK ? "true" : "false")); } } } - //EXTIO_STATUS_CHANGE( gpfnExtIOCallbackPtr, extHw_Changed_ATT ); - - LOG_PRO( LOG_DEBUG, "OpenHW() returns gbInitHW && bOpenOK = %s && %s", (gbInitHW ? "true":"false"), (bOpenOK ? "true":"false") ); - - // in the above statement, F->handle is the window handle of the panel displayed - // by the DLL, if such a panel exists return gbInitHW && bOpenOK; } @@ -331,6 +337,10 @@ int64_t EXTIO_CALL StartHW64( int64_t LOfreq ) { LOG_PRO( LOG_DEBUG, "StartHW64() called" ); + const bool bConnected = InternalOpenHW(); + if (!bConnected && gpfnExtIOCallbackPtr) + EXTIO_STATUS_CHANGE(gpfnExtIOCallbackPtr, extHw_Stop); + if ( !gbInitHW || !gpoReceiver ) return 0; @@ -427,12 +437,10 @@ long EXTIO_CALL GetHWLO( void ) long EXTIO_CALL GetHWSR( void ) { LOG_PRO( LOG_DEBUG, "GetHWSR() called"); - if ( !gpoReceiver ) - return 0; if (!gpoSettings) gpoSettings = new RFspaceNetReceiver::Settings(); long srate = long(gpoSettings->uiSamplerate); - LOG_PRO( LOG_DEBUG, "GetHWSR(): %ld Hz", srate ); + LOG_PRO(LOG_DEBUG, "GetHWSR(): %ld Hz", srate); return long(srate); } @@ -574,7 +582,7 @@ int EXTIO_CALL ExtIoGetSrates( int srate_idx, double* samplerate ) if( srate_idx >= 0 && srate_idx < RFspaceNetReceiver::miNumSamplerates) { - *samplerate = gpoReceiver->maiSamplerates[srate_idx]; + *samplerate = RFspaceNetReceiver::srate_bws[srate_idx].srate; return 0; } else @@ -595,10 +603,11 @@ int EXTIO_CALL ExtIoGetActualSrateIdx( void ) int EXTIO_CALL ExtIoSetSrate( int srate_idx ) { LOG_PRO( LOG_DEBUG, "************************************** ExtIoSetSrate(%d)*********************************", srate_idx); + int clippedIdx = PROCLIP(srate_idx, 0, RFspaceNetReceiver::miNumSamplerates - 1); if ( gpoReceiver ) { - gpoReceiver->setSamplerate(srate_idx); - return 0; + gpoReceiver->setSamplerate(clippedIdx); + return (srate_idx == clippedIdx ? 0 : 1); } else { @@ -606,8 +615,8 @@ int EXTIO_CALL ExtIoSetSrate( int srate_idx ) gpoSettings = new RFspaceNetReceiver::Settings(); LOG_PRO( LOG_DEBUG, "************************************** ExtIoSetSrate(): receiver does not exist. set settings *********************************"); - gpoSettings->iSampleRateIdx = srate_idx; - return 1; + gpoSettings->iSampleRateIdx = clippedIdx; + return (srate_idx == clippedIdx ? 0 : 1); } } @@ -616,7 +625,7 @@ long EXTIO_CALL ExtIoGetBandwidth( int srate_idx ) long bandwidth; if( srate_idx >= 0 && srate_idx < RFspaceNetReceiver::miNumSamplerates) { - bandwidth = long(gpoReceiver->maiBandwidths[srate_idx]); + bandwidth = long(RFspaceNetReceiver::srate_bws[srate_idx].bw); return bandwidth; } else @@ -630,6 +639,7 @@ 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 + , CONNECT_TIMEOUT_MILLIS , AVAIL_SRATES , AVAIL_BWS , SAMPLERATE_IDX @@ -675,7 +685,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 - or leave empty. As checked 'Use Alternative Data Destination UDP Address' in SpectraVue" ); snprintf( value, 1024, "%s", gpoSettings->acDataIP ); return 0; case Setting::DATA_PORT: @@ -683,13 +693,18 @@ int EXTIO_CALL ExtIoGetSetting( int idx, char* description, char* value ) snprintf( value, 1024, "%d", gpoSettings->uDataPortNo ); return 0; + case Setting::CONNECT_TIMEOUT_MILLIS: + snprintf(description, 1024, "%s", "Connection timeout in milliseconds"); + snprintf(value, 1024, "%d", gpoSettings->nConnectTimeoutMillis); + 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]) ); + int w = snprintf(value + off, 1024 - off, "%s%d: %u", (k == 0 ? "" : ", "), k, unsigned(RFspaceNetReceiver::srate_bws[k].srate)); if (w < 0 || w >= (1024 - int(off))) break; off += w; @@ -702,7 +717,7 @@ int EXTIO_CALL ExtIoGetSetting( int idx, char* description, char* value ) 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])); + int w = snprintf(value + off, 1024 - off, "%s%d: %u", (k == 0 ? "" : ", "), k, unsigned(RFspaceNetReceiver::srate_bws[k].bw)); if (w < 0 || w >= (1024 - int(off))) break; off += w; @@ -760,7 +775,7 @@ int EXTIO_CALL ExtIoGetSetting( int idx, char* description, char* value ) return 0; case Setting::GAIN_CONTROL_MODE: - snprintf( description, 1024, "%s", "Usage of AGC in VUHF Frequency Range" ); + snprintf( description, 1024, "%s", "Usage of AGC in V/UHF Frequency Range" ); snprintf( value, 1024, "%u", gpoSettings->bUseVUHFAutoMode); return 0; @@ -778,6 +793,7 @@ int EXTIO_CALL ExtIoGetSetting( int idx, char* description, char* value ) snprintf( description, 1024, "%s", "IF Output Gain Level Value" ); snprintf( value, 1024, "%u", gpoSettings->iIFOutputValue); return 0; + case Setting::NUM: // no break default: @@ -813,7 +829,7 @@ static const char * trimmedIP(const char * value, const char * logText) if (j < 4) { if (value[0] == '.') - ++value; + acBuf[k++] = *value++; else { LOG_PRO(LOG_ERROR, "Error in %s for %d.th numeric block!", logText, j); @@ -866,6 +882,9 @@ void EXTIO_CALL ExtIoSetSetting( int idx, const char* value ) tempInt = atoi( value ); gpoSettings->uDataPortNo = (uint16_t)( tempInt & 0xffff ); break; + case Setting::CONNECT_TIMEOUT_MILLIS: + gpoSettings->nConnectTimeoutMillis = atoi(value); + break; case Setting::AVAIL_SRATES: case Setting::AVAIL_BWS: break; @@ -908,13 +927,13 @@ void EXTIO_CALL ExtIoSetSetting( int idx, const char* value ) break;*/ case Setting::LNA_VALUE: gpoSettings->iLNAValue = atoi( value ); - break; + break; case Setting::MIXER_VALUE: gpoSettings->iMixerValue = atoi( value ); - break; + break; case Setting::IFOUTPUT_VALUE: gpoSettings->iIFOutputValue = atoi( value ); - break; + break; case Setting::NUM: // no break default: diff --git a/src/procitec_replacements.h b/src/procitec_replacements.h index fac2a8d..db37ffa 100644 --- a/src/procitec_replacements.h +++ b/src/procitec_replacements.h @@ -20,7 +20,7 @@ #define STRINGIZEL(s) #s #define EXTIO_IFC_VER 2018 -#define EXTIO_VER_REV 0 +#define EXTIO_VER_REV 1 #define SCM_TAGNAME "" #define SCM_DATE "" @@ -73,7 +73,7 @@ void WRITE_BIG_INT32(uint32_t v, void * vp) uint32_t flipped = ((v & 0xFFU) << 24) | ((v & 0xFF00U) << 8) | ((v & 0xFF0000U) >> 8) - | ((v & 0xFF000000U) >> 24); + | (((v & 0xFF000000U) >> 24) & 0xFFU); *tp = flipped; } @@ -135,7 +135,7 @@ uint32_t READ_BIG_INT32(const void * vp) uint32_t flipped = ((v & 0xFFU) << 24) | ((v & 0xFF00U) << 8) | ((v & 0xFF0000U) >> 8) - | ((v & 0xFF000000U) >> 24); + | (((v & 0xFF000000U) >> 24) & 0xFFU); return flipped; } diff --git a/src/rfspace_netsdr_control.cpp b/src/rfspace_netsdr_control.cpp index e7253db..7fe6fff 100644 --- a/src/rfspace_netsdr_control.cpp +++ b/src/rfspace_netsdr_control.cpp @@ -246,13 +246,11 @@ void RFspaceNetSDRControl::resetReceiverData() if(i<=4) mRcvFrequencyRanges[i] = 0; } - - } -bool RFspaceNetSDRControl::connect( const char * ip, unsigned portNo ) +bool RFspaceNetSDRControl::connect(const char * ip, unsigned portNo, int nConnectTimeoutMillis) { if ( mSocket.IsSocketPeerOpen() ) @@ -270,13 +268,15 @@ bool RFspaceNetSDRControl::connect( const char * ip, unsigned portNo ) resetReceiverData(); + if (nConnectTimeoutMillis > 0) + mSocket.SetConnectTimeoutMillis(nConnectTimeoutMillis); + + mSocket.SetNonblocking(); bool bConnected = mSocket.Open( ip, portNo ); if ( bConnected ) { - - mSocket.SetNonblocking(); - //request information about General Control at initial connection + mSocket.WaitUntilWritable(500); requestOptions(); requestTargetName(); requestTargetSerialNum(); @@ -284,7 +284,6 @@ bool RFspaceNetSDRControl::connect( const char * ip, unsigned portNo ) requestHwFwVersions(RFspaceNetSDRControl::HwFw::BOOT_CODE); requestProductId(); requestStatus(); - } return bConnected; @@ -756,12 +755,12 @@ void RFspaceNetSDRControl::setRcvFreq( int64_t rcvFreqHz) if ( mSocket.IsSocketInvalid() ) return; - const unsigned int len = 10; - unsigned char acBuf[len] = { 0x0A, 0, 0x20, 0, 0, 0, 0, 0, 0, 0 }; + // 0 1 2 3 4 5 + unsigned char acBuf[len+8] = { 0x0A, 0, 0x20, 0, 0, 0, 0, 0, 0, 0 }; void * wp = &acBuf[4]; WRITE_LITTLE_INT8( channel , wp ); //write channel information to byte #5 - wp = &acBuf[len-5]; + wp = &acBuf[5]; WRITE_LITTLE_INT64( rcvFreqHz , wp ); //write frequency to last 5 bytes of buffer mSocket.Send(acBuf, len); @@ -915,7 +914,7 @@ void RFspaceNetSDRControl::setUDPInterface ( const char * ip, uint16_t portNum ) 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 + WRITE_LITTLE_INT32(ipSend, wp); // spec 4.4.6 writes "little endian"! wp = &acBuf[8]; WRITE_LITTLE_INT16(portNum, wp); @@ -1530,36 +1529,34 @@ void RFspaceNetSDRControl::parseVUHFGains( ) ///////////////////////////////////////////////////////////////////////////////////////////////// //********************************** PRINT FUNCTIONS ******************************************** -void RFspaceNetSDRControl::printText( const Options & opt ) +void RFspaceNetSDRControl::printText(const Options & opt, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "Receiver Options Information : "); - LOG_PRO( LOG_DEBUG, "Sound Enabled : %s ", opt.Sound_Enabled ? "Yes" : "No" ); - LOG_PRO( LOG_DEBUG, "ReflockBoard Present : %s ", opt.ReflockBoard_Present ? "Yes" : "No" ); - LOG_PRO( LOG_DEBUG, "DownConverterBoard Present : %s ", opt.DownConverterBoard_Present ? "Yes" : "No" ); - LOG_PRO( LOG_DEBUG, "UpConverterBoard Present : %s ", opt.UpConverterBoard_Present ? "Yes" : "No" ); - LOG_PRO( LOG_DEBUG, "X2Board Present : %s ", opt.X2Board_Present ? "Yes" : "No" ); - LOG_PRO( LOG_DEBUG, "MainBoardVariant : %u ", opt.MainBoardVariant); - LOG_PRO( LOG_DEBUG, "ReflockBoardVariant : %u ", opt.ReflockBoardVariant); - LOG_PRO( LOG_DEBUG, "DownConverterBoardVariant : %u ", opt.DownConverterBoardVariant); - LOG_PRO( LOG_DEBUG, "UpConverterBoardVariant : %u ", opt.UpConverterBoardVariant); + LOG_PRO(LOG_DEBUG, "%s Receiver Options Information :", pacPreText); + LOG_PRO( LOG_DEBUG, " Sound Enabled : %s", opt.Sound_Enabled ? "Yes" : "No" ); + LOG_PRO( LOG_DEBUG, " ReflockBoard Present : %s", opt.ReflockBoard_Present ? "Yes" : "No" ); + LOG_PRO( LOG_DEBUG, " DownConverterBoard Present : %s", opt.DownConverterBoard_Present ? "Yes" : "No" ); + LOG_PRO( LOG_DEBUG, " UpConverterBoard Present : %s", opt.UpConverterBoard_Present ? "Yes" : "No" ); + LOG_PRO( LOG_DEBUG, " X2Board Present : %s", opt.X2Board_Present ? "Yes" : "No" ); + LOG_PRO( LOG_DEBUG, " MainBoardVariant : %u", opt.MainBoardVariant); + LOG_PRO( LOG_DEBUG, " ReflockBoardVariant : %u", opt.ReflockBoardVariant); + LOG_PRO( LOG_DEBUG, " DownConverterBoardVariant : %u", opt.DownConverterBoardVariant); + LOG_PRO( LOG_DEBUG, " UpConverterBoardVariant : %u", opt.UpConverterBoardVariant); } -void RFspaceNetSDRControl::printUDPStateText( const bool & state ) +void RFspaceNetSDRControl::printUDPStateText(const bool & state, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "UDP State Information : "); - LOG_PRO( LOG_DEBUG, "UDP State : %s", state ? "RUNNING" : "IDLE" ); + LOG_PRO(LOG_DEBUG, "%s UDP State '%s'", pacPreText, state ? "RUNNING" : "IDLE"); } -void RFspaceNetSDRControl::printBitDepthText( const int & bitDepth ) +void RFspaceNetSDRControl::printBitDepthText(const int & bitDepth, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "UDP Bit Depth Information : "); - LOG_PRO( LOG_DEBUG, "UDP Bit Depth : %uBit ", bitDepth); + LOG_PRO(LOG_DEBUG, "%s UDP Bit Depth: %u Bit", pacPreText, bitDepth); } /* -void RFspaceNetSDRControl::printText( const RcvFrequencies & rcvFreq) +void RFspaceNetSDRControl::printText(const RcvFrequencies & rcvFreq, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "Receiver Frequency Information : "); + LOG_PRO( LOG_DEBUG, "%s Receiver Frequency Information : ", pacPreText); LOG_PRO( LOG_DEBUG, "Channel 1 NCO-Frequency : %lu Hz", rcvFreq.Chn1_Freq ); LOG_PRO( LOG_DEBUG, "Channel 2 NCO-Frequency : %lu Hz", rcvFreq.Chn2_Freq ); LOG_PRO( LOG_DEBUG, "****************************************************************************************** "); @@ -1574,77 +1571,64 @@ void RFspaceNetSDRControl::printText( const RcvFrequencies & rcvFreq) LOG_PRO( LOG_DEBUG, "Range: Channel 2, Band 2 VCO- Frequency : %lu Hz", rcvFreq.Chn2_Bnd2_VCO_DwnConvFreq ); } */ -void RFspaceNetSDRControl::printRcvFreqText( const uint64_t & rcvFreq) +void RFspaceNetSDRControl::printRcvFreqText(const uint64_t & rcvFreq, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "Receiver Frequency Information :"); - LOG_PRO( LOG_DEBUG, "Frequency: %luHz", rcvFreq ); + LOG_PRO(LOG_DEBUG, "%s Frequency: %lu Hz", pacPreText, (unsigned long)(rcvFreq)); } -void RFspaceNetSDRControl::printFilterText( const int & filtSel) +void RFspaceNetSDRControl::printFilterText(const int & filtSel, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "RF FilterSelect Information : "); - LOG_PRO( LOG_DEBUG, "Filter Select: %s", getFilterText(filtSel) ); + LOG_PRO(LOG_DEBUG, "%s Filter Select: %s", pacPreText, getFilterText(filtSel)); } -void RFspaceNetSDRControl::printText( const bool & dithering) +void RFspaceNetSDRControl::printText(const bool & dithering, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "AD Dither Information : "); - LOG_PRO( LOG_DEBUG, "Dithering: %s", dithering ? "ON" : "OFF" ); + LOG_PRO(LOG_DEBUG, "%s A/D Dithering: %s", pacPreText, dithering ? "ON" : "OFF"); } -void RFspaceNetSDRControl::printText( const float & gain) +void RFspaceNetSDRControl::printText(const float & gain, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "AD Gain Information : "); - if(gain != -1) - LOG_PRO( LOG_DEBUG, "Gain: %.1f", gain ); + if (gain != -1) + LOG_PRO(LOG_DEBUG, "%s A/D Gain: %.1f", pacPreText, gain); else - LOG_PRO( LOG_ERROR, "ERROR! Passed invalid channel argument. Please choose < 1 > or < 2 > in the get function"); + LOG_PRO(LOG_ERROR, "%s A/D Gain: ERROR!", pacPreText); } -void RFspaceNetSDRControl::printText( const RfGain & gain ) +void RFspaceNetSDRControl::printText(const RfGain & gain, const char * pacPreText) { - { - LOG_PRO( LOG_DEBUG, "RF Gain Information :"); - LOG_PRO( LOG_DEBUG, "RFGain: %s", getText(gain) ); - } + LOG_PRO(LOG_DEBUG, "%s RF Gain: %s", pacPreText, getText(gain)); } -void RFspaceNetSDRControl::printText( const VUHFGains & vuhfGains ) +void RFspaceNetSDRControl::printText(const VUHFGains & vuhfGains, const char * pacPreText) { - { - LOG_PRO( LOG_DEBUG, "VUHF Gain Information :"); - LOG_PRO( LOG_DEBUG, "VUHF AutoMode: %s", vuhfGains.isAGCMode ? "ON" : "OFF" ); - LOG_PRO( LOG_DEBUG, "VUHF LNA Gain: %u", vuhfGains.LNAGainLevel ); - LOG_PRO( LOG_DEBUG, "VUHF Mix Gain: %u", vuhfGains.MixerGainLevel ); - LOG_PRO( LOG_DEBUG, "VUHF IF Gain: %u", vuhfGains.IFOutputGainLevel ); - } + LOG_PRO(LOG_DEBUG, "%s V/UHF Gain Information :", pacPreText); + LOG_PRO( LOG_DEBUG, " V/UHF AutoMode: %s", vuhfGains.isAGCMode ? "ON" : "OFF" ); + LOG_PRO( LOG_DEBUG, " V/UHF LNA Gain: %u", vuhfGains.LNAGainLevel ); + LOG_PRO( LOG_DEBUG, " V/UHF Mix Gain: %u", vuhfGains.MixerGainLevel ); + LOG_PRO( LOG_DEBUG, " V/UHF IF Gain: %u", vuhfGains.IFOutputGainLevel ); } -void RFspaceNetSDRControl::printText( const IQOutSmpRate & smpRate ) +void RFspaceNetSDRControl::printText(const IQOutSmpRate & smpRate, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "IQ Output Sample Rate Information :"); - LOG_PRO( LOG_DEBUG, "IQ Output Sample Rate: %s", getText(smpRate) ); + LOG_PRO(LOG_DEBUG, "%s IQ Sample Rate: %u Hz", pacPreText, unsigned(smpRate)); } -void RFspaceNetSDRControl::printText( const UDPPacketSize & packetSize ) +void RFspaceNetSDRControl::printText(const UDPPacketSize & packetSize, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "IQ UDP Packet Size Information : "); - LOG_PRO( LOG_DEBUG, "UDP Packet Size: %s", getText(packetSize) ); + LOG_PRO(LOG_DEBUG, "%s UDP Packet Size: %s", pacPreText, getText(packetSize)); } -void RFspaceNetSDRControl::printUDPIPText( const char * ip ) +void RFspaceNetSDRControl::printUDPIPText(const char * ip, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "UDP IP Information : "); - LOG_PRO( LOG_DEBUG, "UDP IP : %s", ip); + LOG_PRO(LOG_DEBUG, "%s UDP IP : %s", pacPreText, ip); } -void RFspaceNetSDRControl::printUDPPortNumText( const unsigned portNum ) +void RFspaceNetSDRControl::printUDPPortNumText(const unsigned portNum, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "UDP Port Number Information : "); LOG_PRO( LOG_DEBUG, "UDP Port Number : %u", portNum); } -void RFspaceNetSDRControl::printText( const CWStartup & cwStartup) +void RFspaceNetSDRControl::printText(const CWStartup & cwStartup, const char * pacPreText) { uint8_t len = sizeof(cwStartup.asciiMessage); @@ -1658,12 +1642,10 @@ void RFspaceNetSDRControl::printText( const CWStartup & cwStartup) LOG_PRO( LOG_DEBUG, "CW wpm: %u", cwStartup.cw_wpm); LOG_PRO( LOG_DEBUG, "CW Frequency: %s", getText(cwStartup.eCwFreq)); LOG_PRO( LOG_DEBUG, "CW Message: '%s'", stringMessage.c_str()); - } -void RFspaceNetSDRControl::printText( const uint8_t & chnMode) +void RFspaceNetSDRControl::printText(const uint8_t & chnMode, const char * pacPreText) { - LOG_PRO( LOG_DEBUG, "Receiver Channel Setup Information : "); LOG_PRO( LOG_DEBUG, "Receiver Channel Setup: %s", getText(chnMode)); } @@ -1820,25 +1802,6 @@ const char * getText( RFspaceNetSDRControl::ADGain e) } } -const char * getText( RFspaceNetSDRControl::IQOutSmpRate e) -{ - switch (e) - { - case RFspaceNetSDRControl::IQOutSmpRate::SR_12_5kHz: return "12.5 kHz"; - case RFspaceNetSDRControl::IQOutSmpRate::SR_32kHz: return "32 kHz"; - case RFspaceNetSDRControl::IQOutSmpRate::SR_62_5kHz: return "62.5 kHz"; - case RFspaceNetSDRControl::IQOutSmpRate::SR_100kHz: return "100 kHz"; - case RFspaceNetSDRControl::IQOutSmpRate::SR_125kHz: return "125 kHz"; - case RFspaceNetSDRControl::IQOutSmpRate::SR_250kHz: return "250 kHz"; - case RFspaceNetSDRControl::IQOutSmpRate::SR_500kHz: return "500 kHz"; - case RFspaceNetSDRControl::IQOutSmpRate::SR_625kHz: return "625 kHz"; - case RFspaceNetSDRControl::IQOutSmpRate::SR_1000kHz: return "1 MHz"; - case RFspaceNetSDRControl::IQOutSmpRate::SR_1666kHz: return "1.66 MHz"; - case RFspaceNetSDRControl::IQOutSmpRate::SR_2000kHz: return "2 MHz"; - default : return "ERROR"; - } -} - const char * getText( RFspaceNetSDRControl::UDPPacketSize e) { switch (e) diff --git a/src/rfspace_netsdr_control.h b/src/rfspace_netsdr_control.h index 8fdbc83..daa566a 100644 --- a/src/rfspace_netsdr_control.h +++ b/src/rfspace_netsdr_control.h @@ -61,20 +61,33 @@ class RFspaceNetSDRControl // 4.2.8 A/D Modes *************** enum class ADGain : uint8_t { ADGain_1_5 = 0x02, ADGain_1 = 0x00 }; + // A/D Converter frequency = 80 MHz + static const uint32_t ADC_FREQ = 80 * 1000 * 1000; // 4.2.9I/Q Output Data Sample Rate *************** + // this enum has to be in sync with RFspaceNetReceiver::srate_bws[] enum class IQOutSmpRate : uint32_t { - SR_12_5kHz = 80*1000*1000/6400 - , SR_32kHz = 80*1000*1000/2500 - , SR_62_5kHz = 80*1000*1000/1280 - , SR_100kHz = 80*1000*1000/800 - , SR_125kHz = 80*1000*1000/640 - , SR_250kHz = 80*1000*1000/320 - , SR_500kHz = 80*1000*1000/160 - , SR_625kHz = 80*1000*1000/128 - , SR_1000kHz = 80*1000*1000/80 - , SR_1666kHz = 80*1000*1000/48 - , SR_2000kHz = 80*1000*1000/40 + SR_12kHz = ADC_FREQ / 6400 + , SR_16kHz = ADC_FREQ / 5000 + , SR_32kHz = ADC_FREQ / 2500 + , SR_62kHz = ADC_FREQ / 1280 + , SR_80kHz = ADC_FREQ / 1000 + , SR_100kHz = ADC_FREQ / 800 + , SR_125kHz = ADC_FREQ / 640 + , SR_160kHz = ADC_FREQ / 500 + , SR_200kHz = ADC_FREQ / 400 + , SR_250kHz = ADC_FREQ / 320 + , SR_312kHz = ADC_FREQ / 256 + , SR_400kHz = ADC_FREQ / 200 + , SR_500kHz = ADC_FREQ / 160 + , SR_625kHz = ADC_FREQ / 128 + , SR_800kHz = ADC_FREQ / 100 + , SR_1000kHz = ADC_FREQ / 80 + , SR_1250kHz = ADC_FREQ / 64 + , SR_1538kHz = ADC_FREQ / 52 + , SR_1666kHz = ADC_FREQ / 48 + , SR_1818kHz = ADC_FREQ / 44 + , SR_2000kHz = ADC_FREQ / 40 }; // 4.4.2 Data Output Packet Size *************** @@ -94,7 +107,7 @@ class RFspaceNetSDRControl RFspaceNetSDRControl(RFspaceNetSDRControl::CallbackIfc * pCB = nullptr); ~RFspaceNetSDRControl(); - bool connect( const char * ip, unsigned portNo ); + bool connect(const char * ip, unsigned portNo, int nConnectTimeoutMillis = -1 ); bool close(); bool connected() const; @@ -158,23 +171,26 @@ class RFspaceNetSDRControl const char * getRcvChannelSetupText( uint8_t setup ) const; const char * getRcvChannelText( uint8_t chn ) const; +private: + // PRINT-TEXT FUNCTIONS - static void printText( const Options & ); - static void printUDPStateText( const bool & ); - static void printBitDepthText( const int & ); - static void printRcvFreqText( const uint64_t & ); - static void printFilterText( const int & ); // hätte man auch "PrintText" belassen können, da Datentyp int bisher einmalig - static void printText( const bool & ); - static void printText( const float & ); - static void printText( const IQOutSmpRate & ); - static void printText( const UDPPacketSize & ); - static void printText( const RfGain & ); - static void printUDPIPText( const char * ip ); - static void printUDPPortNumText( const unsigned ); - static void printText( const CWStartup & ); - static void printText( const uint8_t & ); - static void printText( const VUHFGains &); + static void printText(const Options &, const char * pacPreText = "received from device:"); + static void printUDPStateText(const bool &, const char * pacPreText = "received from device:"); + static void printBitDepthText(const int &, const char * pacPreText = "received from device:"); + static void printRcvFreqText(const uint64_t &, const char * pacPreText = "received from device:"); + static void printFilterText(const int &, const char * pacPreText = "received from device:"); + static void printText(const bool &, const char * pacPreText = "received from device:"); + static void printText(const float &, const char * pacPreText = "received from device:"); + static void printText(const IQOutSmpRate &, const char * pacPreText = "received from device:"); + static void printText(const UDPPacketSize &, const char * pacPreText = "received from device:"); + static void printText(const RfGain &, const char * pacPreText = "received from device:"); + static void printUDPIPText(const char * ip, const char * pacPreText = "received from device:"); + static void printUDPPortNumText(const unsigned, const char * pacPreText = "received from device:"); + static void printText(const CWStartup &, const char * pacPreText = "received from device:"); + static void printText(const uint8_t &, const char * pacPreText = "received from device:"); + static void printText(const VUHFGains &, const char * pacPreText = "received from device:"); +public: // STRUCT-DECLARATIONS //************************************************************** diff --git a/src/rfspace_netsdr_receiver.cpp b/src/rfspace_netsdr_receiver.cpp index cc996ec..1c36a52 100644 --- a/src/rfspace_netsdr_receiver.cpp +++ b/src/rfspace_netsdr_receiver.cpp @@ -7,18 +7,44 @@ #include #include -#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 }; +// these tables have to be in sync with RFspaceNetSDRControl::IQOutSmpRate !!! + +#define KHZ *1000 + +const RFspaceNetReceiver::srate_bw RFspaceNetReceiver::srate_bws[] = +{ + { 6400, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_12kHz ), 12500, 10 KHZ, "12.5 kHz" } // 0 +, { 5000, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_16kHz ), 16 KHZ, 12 KHZ, "16 kHz" } +, { 2500, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_32kHz ), 32 KHZ, 25 KHZ, "32 kHz" } +, { 1280, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_62kHz ), 62500, 50 KHZ, "62.5 kHz" } +, { 1000, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_80kHz ), 80 KHZ, 64 KHZ, "80 kHz" } +, { 800, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_100kHz ), 100 KHZ, 80 KHZ, "100 kHz" } // 5 +, { 640, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_125kHz ), 125 KHZ, 100 KHZ, "125 kHz" } +, { 500, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_160kHz ), 160 KHZ, 128 KHZ, "160 kHz" } +, { 400, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_200kHz ), 200 KHZ, 160 KHZ, "200 kHz" } +, { 320, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_250kHz ), 250 KHZ, 200 KHZ, "250 kHz" } +, { 256, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_312kHz ), 312500, 250 KHZ, "312.5 kHz" } // 10 +, { 200, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_400kHz ), 400 KHZ, 320 KHZ, "400 kHz" } +, { 160, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_500kHz ), 500 KHZ, 400 KHZ, "500 kHz" } +, { 128, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_625kHz ), 625 KHZ, 500 KHZ, "625 kHz" } +, { 100, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_800kHz ), 800 KHZ, 640 KHZ, "800 kHz" } +, { 80, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_1000kHz), 1000 KHZ, 800 KHZ, "1 MHz" } // 15 +, { 64, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_1250kHz), 1250 KHZ, 1000 KHZ, "1.25 MHz" } +, { 52, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_1538kHz), 1538461, 1200 KHZ, "1.538 MHz" } +, { 48, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_1666kHz), 1666666, 1300 KHZ, "1.666 MHz" } +, { 44, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_1818kHz), 1818181, 1400 KHZ, "1.818 MHz" } +, { 40, uint32_t(RFspaceNetSDRControl::IQOutSmpRate::SR_2000kHz), 2000 KHZ, 1600 KHZ, "2 MHz" } // 20 +}; + #undef KHZ +// 0 1 2 3 4 5 6 7 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 }; @@ -38,7 +64,7 @@ const RFspaceNetSDRControl::RfGain RFspaceNetReceiver::mVUHF_RFGainAttenuations[ const int RFspaceNetReceiver::miNumAttenuations = (int)( NUMEL(mafAttenuationATTs) ); const int RFspaceNetReceiver::miNumCompatibilityGains = (int)( sizeof(mafVUHFCompatibilityGainValues) / sizeof(mafVUHFCompatibilityGainValues[0]) ); const int RFspaceNetReceiver::miNumMultiGains = (int)( sizeof(mafVUHFMultiGainValues) / sizeof(mafVUHFMultiGainValues[0]) ); -const int RFspaceNetReceiver::miNumSamplerates = (int)( sizeof(maiSamplerates) / sizeof(maiSamplerates[0]) ); +const int RFspaceNetReceiver::miNumSamplerates = (int)(sizeof(srate_bws) / sizeof(srate_bws[0])); #define NORMALIZE_DATA 0 @@ -223,7 +249,7 @@ void RFspaceNetReceiver::receiveRfspaceNetSDRUdpData( const int fmt, const void { if ( mLastReportedBitDepth != extHw_SampleFormat_PCM16 ) { - LOG_PRO( LOG_DEBUG, "SEND STATUS CHANGE OF 16 BIT DATA TO RCM !" ); + LOG_PRO( LOG_DEBUG, "SEND STATUS CHANGE OF 16 BIT DATA TO SDR !" ); EXTIO_STATUS_CHANGE(mExtIOCallbackPtr , extHw_SampleFormat_PCM16 ); mLastReportedBitDepth = extHw_SampleFormat_PCM16; mSampleBufferLenInFrames = 0; @@ -260,7 +286,7 @@ void RFspaceNetReceiver::receiveRfspaceNetSDRUdpData( const int fmt, const void if ( mLastReportedBitDepth != extHw_SampleFormat_PCM24 ) { - LOG_PRO( LOG_DEBUG, "SEND STATUS CHANGE OF 24 BIT DATA TO RCM !" ); + LOG_PRO( LOG_DEBUG, "SEND STATUS CHANGE OF 24 BIT DATA TO SDR !" ); EXTIO_STATUS_CHANGE(mExtIOCallbackPtr , extHw_SampleFormat_PCM24 ); mLastReportedBitDepth = extHw_SampleFormat_PCM24; mSampleBufferLenInFrames = 0; @@ -448,7 +474,7 @@ void RFspaceNetReceiver::receiveRFspaceNetSDRControlInfo(Info info) mpoSettings->uiSamplerate = actualIQSmpRate; mpoSettings->uiLastReportedSamplerate = mpoSettings->uiSamplerate; mpoSettings->iSampleRateIdx = getSmpRateIdx(actualIQSmpRate); - mpoSettings->uiBandwidth = maiBandwidths[mpoSettings->iSampleRateIdx]; + mpoSettings->uiBandwidth = srate_bws[mpoSettings->iSampleRateIdx].bw; LOG_PRO( LOG_ERROR, " RECEIVED CALLBACK WITH UNEXPECTED IQ_OUT_SAMPLERATE : %u Hz", actualIQSmpRate); EXTIO_STATUS_CHANGE(mExtIOCallbackPtr , extHw_Changed_SampleRate ); } @@ -506,7 +532,7 @@ bool RFspaceNetReceiver::openHW(Settings * poSettings) mpoSettings = poSettings; - bool bTCPConnOK = rcv.connect( mpoSettings->acCtrlIP, mpoSettings->uCtrlPortNo ); + bool bTCPConnOK = rcv.connect( mpoSettings->acCtrlIP, mpoSettings->uCtrlPortNo, mpoSettings->nConnectTimeoutMillis ); if ( !bTCPConnOK ) { LOG_PRO( LOG_ERROR, "Error connecting to receiver %s:%u for control", mpoSettings->acCtrlIP, mpoSettings->uCtrlPortNo ); @@ -516,9 +542,9 @@ bool RFspaceNetReceiver::openHW(Settings * poSettings) poSettings->bIsTCPConnected = true; int samplerateIdx = poSettings->iSampleRateIdx; - samplerateIdx = PROCLIP(samplerateIdx, 0, int(NUMEL(maiSamplerates))); + samplerateIdx = PROCLIP(samplerateIdx, 0, int(NUMEL(srate_bws))); - poSettings->uiSamplerate = maiSamplerates[samplerateIdx]; + poSettings->uiSamplerate = srate_bws[samplerateIdx].srate; LOG_PRO( LOG_DEBUG, "********************************** RFspaceNetReceiver::openHW() : SENDING SAMPLERATE FREQUENCY TO NETSDR: %dHz (idx: %d)", poSettings->uiSamplerate, poSettings->iSampleRateIdx); poSettings->iSampleRateIdx = samplerateIdx; @@ -592,36 +618,27 @@ bool RFspaceNetReceiver::startHW(int64_t LOfreq) } rcv.setUDPInterface( mpoSettings->acDataIP, mpoSettings->uDataPortNo ); - rcv.setRcvFreq( LOfreq ); + mpoSettings->bIsSocketBound = true; + } - mpoSettings->iFrequency = LOfreq; + mSampleBufferLenInFrames = 0; - mSampleBufferLenInFrames = 0; - mChangeBitRangeSmpRateIdx = getMaxSmpRateIdx(mpoSettings->iBitDepthThresSamplerate); + mChangeBitRangeSmpRateIdx = getMaxSmpRateIdx(mpoSettings->iBitDepthThresSamplerate); - if( mpoSettings->iSampleRateIdx <= mChangeBitRangeSmpRateIdx) - { - //24 Bit - mOutBitSize = 8 * sizeof(LITTLE_INT24_T); - rcv.start24BitDataStream(); - LOG_PRO( LOG_DEBUG, "****************RFspaceNetReceiver::startHW(%dHz): START 24 BIT DATA STREAM *********************************", LOfreq); - } - else - { - //16 Bit - mOutBitSize = 8 * sizeof(LITTLE_INT16_T); - rcv.start16BitDataStream(); - LOG_PRO( LOG_DEBUG, "****************RFspaceNetReceiver::startHW(%dHz): START 16 BIT DATA STREAM *********************************", LOfreq); - } + rcv.setRcvFreq(LOfreq); + mpoSettings->iFrequency = LOfreq; - mpoSettings->bIsSocketBound = true; - return true; + setSamplerate(mpoSettings->iSampleRateIdx); + + if (!mStartData) + { + //restart udp data (24bit/16bit) after "mStartUDPTimer" ms in "TimerProc" --> NetSDR sometimes streams wrong bitrate (although claiming it would stream the right bitrate). + //--> give samplerate change (and sometimes therefore bitdepth change) more time. + mStartUDPTimer = 100; //in ms + mStartData = true; } - else - setSamplerate( mpoSettings->iSampleRateIdx); return true; - } @@ -757,7 +774,7 @@ void RFspaceNetReceiver::setGain( int idx ) void RFspaceNetReceiver::setSamplerate( int idx ) { - int numSamplerates = int(NUMEL(maiSamplerates)); + int numSamplerates = int(NUMEL(srate_bws)); if ( idx < 0 || idx > numSamplerates ) { @@ -766,31 +783,33 @@ void RFspaceNetReceiver::setSamplerate( int idx ) idx = newIdx; } + mpoSettings->iSampleRateIdx = idx; + mpoSettings->uiSamplerate = srate_bws[idx].srate; + mpoSettings->uiBandwidth = srate_bws[idx].bw; + bool bOk = false; bool bIsStreaming = rcv.isUDPDataStreamRunning(&bOk); if (bIsStreaming && bOk) { - mpoSettings->iSampleRateIdx = idx; - mpoSettings->uiSamplerate = maiSamplerates[idx]; - mpoSettings->uiBandwidth = maiBandwidths[idx]; - LOG_PRO( LOG_DEBUG, "************************************** RFspaceNetReceiver::setSamplerate(): send ChangedSamplerate-Callback *********************************"); EXTIO_STATUS_CHANGE(mExtIOCallbackPtr , extHw_Changed_SampleRate ); mpoSettings->uiLastReportedSamplerate = mpoSettings->uiSamplerate; - return; } - LOG_PRO( LOG_DEBUG, "************************************** RFspaceNetReceiver::setSamplerate(): ready to set Samplerate and Bitdepth! *********************************"); + // currently not streaming: + LOG_PRO(LOG_DEBUG, "************************************** RFspaceNetReceiver::setSamplerate(%u): set Samplerate ************************", mpoSettings->uiSamplerate); rcv.setIQOutSmpRate(RFspaceNetSDRControl::IQOutSmpRate(mpoSettings->uiSamplerate)); - LOG_PRO( LOG_DEBUG, " Report new Samplerate %u Hz", mpoSettings->uiSamplerate); - //restart udp data (24bit/16bit) after "mStartUDPTimer" ms in "TimerProc" --> NetSDR sometimes streams wrong bitrate (although claiming it would stream the right bitrate). - //--> give samplerate change (and sometimes therefore bitdepth change) more time. - mStartUDPTimer = 100; //in ms - mStartData = true; + if (0) // next startHW() should do + { + //restart udp data (24bit/16bit) after "mStartUDPTimer" ms in "TimerProc" --> NetSDR sometimes streams wrong bitrate (although claiming it would stream the right bitrate). + //--> give samplerate change (and sometimes therefore bitdepth change) more time. + mStartUDPTimer = 100; //in ms + mStartData = true; + } } int64_t RFspaceNetReceiver::getHWLO( void ) @@ -816,7 +835,7 @@ int RFspaceNetReceiver::getSmpRateIdx( uint32_t smpRate ) int ret = -1; for(int idx = 0; idx < miNumSamplerates; ++idx) { - int32_t delta = smpRate - maiSamplerates[idx]; + int32_t delta = smpRate - srate_bws[idx].srate; if( -10 <= delta && delta <= 10 ) // +/- 10 Hz tolerance { LOG_PRO( LOG_DEBUG, "********* RFspaceNetReceiver::getSmpRateIdx(%u) --> idx: %d", smpRate, idx); @@ -837,7 +856,7 @@ int RFspaceNetReceiver::getMaxSmpRateIdx(uint32_t smpRate) int ret = -1; for (int idx = 0; idx < miNumSamplerates; ++idx) { - if (smpRate >= maiSamplerates[idx]) + if (smpRate >= srate_bws[idx].srate) ret = idx; } if (ret == -1) @@ -875,9 +894,8 @@ void RFspaceNetReceiver::TimerProc(uint16_t waitMs) if(mStartUDPTimer <= 0) { - - setGain(mpoSettings->iControlValue); mStartData = false; + setGain(mpoSettings->iControlValue); if( mpoSettings->iSampleRateIdx <= mChangeBitRangeSmpRateIdx ) { rcv.start24BitDataStream(); diff --git a/src/rfspace_netsdr_receiver.h b/src/rfspace_netsdr_receiver.h index e22fdeb..6a7232d 100644 --- a/src/rfspace_netsdr_receiver.h +++ b/src/rfspace_netsdr_receiver.h @@ -28,20 +28,20 @@ class RFspaceNetReceiver Settings() { 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 + strcpy(acDataIP, ""); // "" main PC: 192.168.8.100 PC2: 192.168.8.102 + uCtrlPortNo = uDataPortNo = 50000; // 50000 / 50002 iSampleRateIdx = 2; // 2: 32 kHz samplerate - iAttenuationIdx = 0; + iAttenuationIdx = 6; // 6: 0 dB - no ATT & no ADC Gain iBitDepthThresSamplerate = 1333333; // 1333.333 kHz == 80 MHz / 60 iBand_minFreq = 0; iBand_maxFreq = 34 * 1000L * 1000L; // 0 - 34 MHz - uiBandwidth = 0; - uiSamplerate = 0; + uiBandwidth = 10000; + uiSamplerate = 12500; uiLastReportedSamplerate = 0; - iFrequency = 0; + iFrequency = 7 * 1000 * 1000; iLNAValue = 0; iMixerValue = 0; iIFOutputValue = 0; @@ -54,7 +54,7 @@ class RFspaceNetReceiver bUseVUHFAutoMode = true; mfGainCompensationFactor = 1.0F; - + nConnectTimeoutMillis = 1000; } char acCtrlIP[64]; @@ -92,10 +92,17 @@ class RFspaceNetReceiver float mfGainCompensationFactor; + int nConnectTimeoutMillis; }; - static const uint32_t maiSamplerates[]; - static const uint32_t maiBandwidths[]; + static const struct srate_bw { + uint32_t decim; + uint32_t srate; + uint32_t srateval; + uint32_t bw; + const char * srateTxt; + } srate_bws[]; + static const int miNumSamplerates; static const float mafAttenuationATTs[]; diff --git a/src/rfspace_netsdr_udpdata.cpp b/src/rfspace_netsdr_udpdata.cpp index 7b18352..1fa5724 100644 --- a/src/rfspace_netsdr_udpdata.cpp +++ b/src/rfspace_netsdr_udpdata.cpp @@ -108,7 +108,7 @@ bool RFspaceNetSDRUdpData::poll( ) while (1) { - int rx = mSocket.Receive( MAX_UDP_LEN, &mRxBuffer[0] ); + int rx = mSocket.Receive( MAX_UDP_LEN, &mRxBuffer[0] ); if ( rx > 0 ) { @@ -122,20 +122,24 @@ bool RFspaceNetSDRUdpData::poll( ) } return true; - } } bool RFspaceNetSDRUdpData::processReceivedDataMessage(unsigned rxLen) { - if ( rxLen < 2 + 2 + 384 ) - return false; - - void * wp = &mRxBuffer[0]; + const void * wp = &mRxBuffer[0]; const uint16_t uControlItemCode = READ_LITTLE_INT16( wp ); wp = &mRxBuffer[2]; const uint16_t uSequenceNum = READ_LITTLE_INT16( wp ); + + if (rxLen < 2 + 2 + 384) + { + LOG_PRO(LOG_PROTOCOL, "received too small UDP packet of length %u with %s control item 0x%x" + , rxLen, (rxLen >= 2 ? "valid" : "invalid"), unsigned(uControlItemCode)); + return false; + } + bool bProcessed = true; // assume so if ( uSequenceNum != uExpectedSequenceNum ) @@ -228,6 +232,7 @@ bool RFspaceNetSDRUdpData::processReceivedDataMessage(unsigned rxLen) break; default: + LOG_PRO(LOG_PROTOCOL, "received UDP packet with unknown control item 0x%x length %u", unsigned(uControlItemCode), rxLen); bProcessed = false; }