Merge branch 'master' into shuttle

half-duplex
Phil Taylor 2021-06-30 09:22:44 +01:00
commit eb81196238
20 zmienionych plików z 2471 dodań i 1503 usunięć

287
CHANGELOG
Wyświetl plik

@ -1,5 +1,292 @@
# CHANGELOG
- 20210611
Update udpserver.cpp
Use global watchdog rather than per-connection
Report when users are disconnected by the watchdog
Use watchdog to cleanup lost server connections
Fix crash on disconnect
Make status update after disconnection
More server disconnection cleanup
Improve server disconnection/cleanup
- 20210610
remove spaces when adding extra server users
Update udpserver.cpp
Allow both encoded and plain text passwords
Lots of fixes to server setup table
Hopefully fix the occasional 0xe1 packet from hitting the pty
Add more info for server connections
Make sure that user is authenticated before allowing CIV/Audio
Use correct location for statusupdate!
Indicate when TX is not available
Show server connection status in taskbar (only for USB connected rigs)
- 20210609
Allow sender or receiver to be 0xe1 in server
Always forward wfview traffic to wfview clients
- 20210608
Truncate wfview.log on open
Detect radio baudrate in server mode
Comment out rtaudio if not being used
Baud rate calculations are now only happening when baud rate is received
and reasonable.
- 20210607
Check that we have at least 1 audio channel available.
Improve audio cleanup
Add extra debugging for UDP server CIV
Make only MacOS use buffered audio
Improve mac audio
- 20210606
Fix TX Audio on Linux
Various fixes to udpserver
Make QTMultimedia default
Fix to allow rtaudio to compile again
- 20210605
Add latency check to TX audio
Fix incorrect use of latency setting
- 20210604
Stop silly compile warning
Change udpserver to use new audiosetup struct properly.
Fix audio device selection
Fix for txaudio
Add QtMultimedia as default audio
- 20210603
Hopefully fix hang on exit when trying to close audio thread.
- 20210602
Use heap based rtaudio for enumeration
Catch possible exception when closing non-existent stream
Fix mac audio
Fix mac crash on closing audio
Make sure audio is deleted in destructor
Force specific rtaudio API depending on platform.
Linux now uses librtuadio-dev where available
Removing local rtaudio code and using library instead.
revert to ALSA for now
Tell rtaudio not to hog device
Update audiohandler.cpp
Select chunksize based on native sample rate
Force 48K sample rate when 44100 is detected.
change linux compiler directive to allow new-aligned
Tidy up server mutexes
Fix server high CPU on disconnect
- 20210601
Stop deleting audio after last client disconects
Change udpserver packet handling to be similar to udphandler
Update udpserver.cpp
Let buffer keep filling.
Change to 10ms poll time for server rx audio
Mutex work in udpserver
Fix for crash when remote requests tone.
- 20210531
IC-7700 support
Open pty non-blocking
Fix for crashing pty on mac
Fix compile issue after merge
- 20210530
Keep the theme during resize. TODO: preference for wf theme
Removing my own uninformed sidenote.
Waterfal length may now be adjusted. Let's see what range of length
seems good and limit the control accordingly. Also there may be a memory
leak in the prepareWf() function where the colormap is created when the
image is resized.
CIV may now be changed as-needed while running.
Remove various compiler warnings and tidy up.
add silence if audio has stopped
- 20210529
fix for mac/linux compiler
Detect number of device channels and convert accordingly
Lots more changes for rtaudio compatibility
Small change to show default audio devices
- 20210528
More chair movements.
More arranging of the chairs. Also fixed a minor bug that prevented the
"Manual" serial device entry on my system.
Cleaning up the main constructor for wfmain.
Add some startup logging
Update audiohandler.cpp
Update udphandler.cpp
Change toolbar display formatting
Use preferred sample rate rather than force 48000
- 20210527
Allow higher latency
udpserver fixes
Update udpserver.cpp
Fix for tx audio channels
Add tx audio
add asound lib to linux build
fix qmake file
Use ring buffer with rtaudio to eliminate mutexes
- 20210525
Update INSTALL_PREBUILT_BINARY.md
move ulaw to dedicated header
add rtaudio as submodule
add opus-tools as submodule
Add mutex for audio buffer
- 20210523
Fixes for linux build
First working rtaudio (output only)
Link can now be clicked.
Added helpful text to settings tab.
Allow entry to Server Setup for either radio connection type.
Minor change to clarify roll of Server Setup
- 20210522
Add debugging and fix silly error in audiooutput combobox
reenable audio buffers
Attempt to fix crash
Make only first client have TX audio
Stop audiohandler re-enumerating devices on connect.
Stop preamps/attenuators lists growing every time we reconnect.
Try increasing audio device buffer size
- 20210521
Changed method for adding modes to rigs and populating the rig menu.
This should be easier to maintain and better in the long run.
"Hopefully" fix annoying UDP server crash on client disconnect!
Fix for TX audio in udp server
Fix for stuttering audio on mac
Fixed missing break in switchs.
Typo in message about CI-V
Dynamic timing update for all baud rates and connection types.
Fixed support for 9600 baud and lower speeds.
- 20210521
Add baud rate detection for remote rigs

Wyświetl plik

@ -21,11 +21,11 @@ redhat7 -- no qt support
Debian 11 (Debian 10 is outdated)
Fedora 33
Fedora 34
mint 20.1
mint 20.1 (and up?)
openSUSE 15.x
openSUSE Tumbleweed
SLES 15.x
Ubuntu 20.04.2
Ubuntu 20.04.2 and up (?)
~~~
@ -63,6 +63,10 @@ wfview
sudo apt install libqcustomplot2.0 libqt5multimedia5 libqt5serialport5
sudo ln -s /usr/lib64/libqcustomplot-qt5.so.2 /usr/lib64/libqcustomplot.so.2
wfview
note: if the above symlink fails, use the following line to fix the library link:
sudo ln -s /lib/x86_64-linux-gnu/libqcustomplot.so.2.0.1 /lib/x86_64-linux-gnu/libqcustomplot.so.2
~~~
### openSUSE/Tumbleweed/SLES:
@ -76,6 +80,11 @@ wfview
sudo apt install libqcustomplot2.0 libqt5multimedia5 libqt5serialport5
sudo ln -s /usr/lib/x86_64-linux-gnu/libqcustomplot.so.2.0.1 /usr/lib/x86_64-linux-gnu/libqcustomplot.so.2
wfview
note: if the above symlink fails, use the following line to fix the library link:
sudo ln -s /lib/x86_64-linux-gnu/libqcustomplot.so.2.0.1 /lib/x86_64-linux-gnu/libqcustomplot.so.2
~~~

14
WHATSNEW 100644
Wyświetl plik

@ -0,0 +1,14 @@
The following highlights are in this dot-release:
added IC7700
fixes and improvements to audio
ability to choose between rtaudio and qtmultimedia (default) as compile time option
fixes and lots of improvements at the usb-server end
waterfall length can be adjusted now
no need to restart to change CIV address
seamless changing rigs without restart
started support for older rigs like the 718
wf display disappears when there is no wf capable rig
IC R8600 support improved
for older rigs added a polling timing box to keep stuff keeping smooth

Wyświetl plik

@ -118,8 +118,16 @@ void commHandler::receiveDataIn()
}
}
if(inPortData.startsWith("\xFE\xFE"))
{
if(inPortData.contains("\xFC"))
{
//qInfo(logSerial()) << "Transaction contains collision data. Dumping.";
//printHex(inPortData, false, true);
port->commitTransaction();
return;
}
if(inPortData.endsWith("\xFD"))
{
// good!

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,339 @@
/* Copyright (C) 2007-2008 Jean-Marc Valin
* Copyright (C) 2008 Thorvald Natvig
* Copyright (C) 2011 Texas Instruments
* author Jyri Sarha
*/
/**
@file resample_neon.h
@brief Resampler functions (NEON version)
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef FIXED_POINT
#if defined(__aarch64__)
static inline int32_t saturate_32bit_to_16bit(int32_t a) {
int32_t ret;
asm ("fmov s0, %w[a]\n"
"sqxtn h0, s0\n"
"sxtl v0.4s, v0.4h\n"
"fmov %w[ret], s0\n"
: [ret] "=r" (ret)
: [a] "r" (a)
: "v0" );
return ret;
}
#elif defined(__thumb2__)
static inline int32_t saturate_32bit_to_16bit(int32_t a) {
int32_t ret;
asm ("ssat %[ret], #16, %[a]"
: [ret] "=r" (ret)
: [a] "r" (a)
: );
return ret;
}
#else
static inline int32_t saturate_32bit_to_16bit(int32_t a) {
int32_t ret;
asm ("vmov.s32 d0[0], %[a]\n"
"vqmovn.s32 d0, q0\n"
"vmov.s16 %[ret], d0[0]\n"
: [ret] "=r" (ret)
: [a] "r" (a)
: "q0");
return ret;
}
#endif
#undef WORD2INT
#define WORD2INT(x) (saturate_32bit_to_16bit(x))
#define OVERRIDE_INNER_PRODUCT_SINGLE
/* Only works when len % 4 == 0 and len >= 4 */
#if defined(__aarch64__)
static inline int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len)
{
int32_t ret;
uint32_t remainder = len % 16;
len = len - remainder;
asm volatile (" cmp %w[len], #0\n"
" b.ne 1f\n"
" ld1 {v16.4h}, [%[b]], #8\n"
" ld1 {v20.4h}, [%[a]], #8\n"
" subs %w[remainder], %w[remainder], #4\n"
" smull v0.4s, v16.4h, v20.4h\n"
" b.ne 4f\n"
" b 5f\n"
"1:"
" ld1 {v16.4h, v17.4h, v18.4h, v19.4h}, [%[b]], #32\n"
" ld1 {v20.4h, v21.4h, v22.4h, v23.4h}, [%[a]], #32\n"
" subs %w[len], %w[len], #16\n"
" smull v0.4s, v16.4h, v20.4h\n"
" smlal v0.4s, v17.4h, v21.4h\n"
" smlal v0.4s, v18.4h, v22.4h\n"
" smlal v0.4s, v19.4h, v23.4h\n"
" b.eq 3f\n"
"2:"
" ld1 {v16.4h, v17.4h, v18.4h, v19.4h}, [%[b]], #32\n"
" ld1 {v20.4h, v21.4h, v22.4h, v23.4h}, [%[a]], #32\n"
" subs %w[len], %w[len], #16\n"
" smlal v0.4s, v16.4h, v20.4h\n"
" smlal v0.4s, v17.4h, v21.4h\n"
" smlal v0.4s, v18.4h, v22.4h\n"
" smlal v0.4s, v19.4h, v23.4h\n"
" b.ne 2b\n"
"3:"
" cmp %w[remainder], #0\n"
" b.eq 5f\n"
"4:"
" ld1 {v18.4h}, [%[b]], #8\n"
" ld1 {v22.4h}, [%[a]], #8\n"
" subs %w[remainder], %w[remainder], #4\n"
" smlal v0.4s, v18.4h, v22.4h\n"
" b.ne 4b\n"
"5:"
" saddlv d0, v0.4s\n"
" sqxtn s0, d0\n"
" sqrshrn h0, s0, #15\n"
" sxtl v0.4s, v0.4h\n"
" fmov %w[ret], s0\n"
: [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b),
[len] "+r" (len), [remainder] "+r" (remainder)
:
: "cc", "v0",
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23");
return ret;
}
#else
static inline int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len)
{
int32_t ret;
uint32_t remainder = len % 16;
len = len - remainder;
asm volatile (" cmp %[len], #0\n"
" bne 1f\n"
" vld1.16 {d16}, [%[b]]!\n"
" vld1.16 {d20}, [%[a]]!\n"
" subs %[remainder], %[remainder], #4\n"
" vmull.s16 q0, d16, d20\n"
" beq 5f\n"
" b 4f\n"
"1:"
" vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
" vld1.16 {d20, d21, d22, d23}, [%[a]]!\n"
" subs %[len], %[len], #16\n"
" vmull.s16 q0, d16, d20\n"
" vmlal.s16 q0, d17, d21\n"
" vmlal.s16 q0, d18, d22\n"
" vmlal.s16 q0, d19, d23\n"
" beq 3f\n"
"2:"
" vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
" vld1.16 {d20, d21, d22, d23}, [%[a]]!\n"
" subs %[len], %[len], #16\n"
" vmlal.s16 q0, d16, d20\n"
" vmlal.s16 q0, d17, d21\n"
" vmlal.s16 q0, d18, d22\n"
" vmlal.s16 q0, d19, d23\n"
" bne 2b\n"
"3:"
" cmp %[remainder], #0\n"
" beq 5f\n"
"4:"
" vld1.16 {d16}, [%[b]]!\n"
" vld1.16 {d20}, [%[a]]!\n"
" subs %[remainder], %[remainder], #4\n"
" vmlal.s16 q0, d16, d20\n"
" bne 4b\n"
"5:"
" vaddl.s32 q0, d0, d1\n"
" vadd.s64 d0, d0, d1\n"
" vqmovn.s64 d0, q0\n"
" vqrshrn.s32 d0, q0, #15\n"
" vmov.s16 %[ret], d0[0]\n"
: [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b),
[len] "+r" (len), [remainder] "+r" (remainder)
:
: "cc", "q0",
"d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23");
return ret;
}
#endif // !defined(__aarch64__)
#elif defined(FLOATING_POINT)
#if defined(__aarch64__)
static inline int32_t saturate_float_to_16bit(float a) {
int32_t ret;
asm ("fcvtas s1, %s[a]\n"
"sqxtn h1, s1\n"
"sxtl v1.4s, v1.4h\n"
"fmov %w[ret], s1\n"
: [ret] "=r" (ret)
: [a] "w" (a)
: "v1");
return ret;
}
#else
static inline int32_t saturate_float_to_16bit(float a) {
int32_t ret;
asm ("vmov.f32 d0[0], %[a]\n"
"vcvt.s32.f32 d0, d0, #15\n"
"vqrshrn.s32 d0, q0, #15\n"
"vmov.s16 %[ret], d0[0]\n"
: [ret] "=r" (ret)
: [a] "r" (a)
: "q0");
return ret;
}
#endif
#undef WORD2INT
#define WORD2INT(x) (saturate_float_to_16bit(x))
#define OVERRIDE_INNER_PRODUCT_SINGLE
/* Only works when len % 4 == 0 and len >= 4 */
#if defined(__aarch64__)
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
{
float ret;
uint32_t remainder = len % 16;
len = len - remainder;
asm volatile (" cmp %w[len], #0\n"
" b.ne 1f\n"
" ld1 {v16.4s}, [%[b]], #16\n"
" ld1 {v20.4s}, [%[a]], #16\n"
" subs %w[remainder], %w[remainder], #4\n"
" fmul v1.4s, v16.4s, v20.4s\n"
" b.ne 4f\n"
" b 5f\n"
"1:"
" ld1 {v16.4s, v17.4s, v18.4s, v19.4s}, [%[b]], #64\n"
" ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [%[a]], #64\n"
" subs %w[len], %w[len], #16\n"
" fmul v1.4s, v16.4s, v20.4s\n"
" fmul v2.4s, v17.4s, v21.4s\n"
" fmul v3.4s, v18.4s, v22.4s\n"
" fmul v4.4s, v19.4s, v23.4s\n"
" b.eq 3f\n"
"2:"
" ld1 {v16.4s, v17.4s, v18.4s, v19.4s}, [%[b]], #64\n"
" ld1 {v20.4s, v21.4s, v22.4s, v23.4s}, [%[a]], #64\n"
" subs %w[len], %w[len], #16\n"
" fmla v1.4s, v16.4s, v20.4s\n"
" fmla v2.4s, v17.4s, v21.4s\n"
" fmla v3.4s, v18.4s, v22.4s\n"
" fmla v4.4s, v19.4s, v23.4s\n"
" b.ne 2b\n"
"3:"
" fadd v16.4s, v1.4s, v2.4s\n"
" fadd v17.4s, v3.4s, v4.4s\n"
" cmp %w[remainder], #0\n"
" fadd v1.4s, v16.4s, v17.4s\n"
" b.eq 5f\n"
"4:"
" ld1 {v18.4s}, [%[b]], #16\n"
" ld1 {v22.4s}, [%[a]], #16\n"
" subs %w[remainder], %w[remainder], #4\n"
" fmla v1.4s, v18.4s, v22.4s\n"
" b.ne 4b\n"
"5:"
" faddp v1.4s, v1.4s, v1.4s\n"
" faddp %[ret].4s, v1.4s, v1.4s\n"
: [ret] "=w" (ret), [a] "+r" (a), [b] "+r" (b),
[len] "+r" (len), [remainder] "+r" (remainder)
:
: "cc", "v1", "v2", "v3", "v4",
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23");
return ret;
}
#else
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
{
float ret;
uint32_t remainder = len % 16;
len = len - remainder;
asm volatile (" cmp %[len], #0\n"
" bne 1f\n"
" vld1.32 {q4}, [%[b]]!\n"
" vld1.32 {q8}, [%[a]]!\n"
" subs %[remainder], %[remainder], #4\n"
" vmul.f32 q0, q4, q8\n"
" bne 4f\n"
" b 5f\n"
"1:"
" vld1.32 {q4, q5}, [%[b]]!\n"
" vld1.32 {q8, q9}, [%[a]]!\n"
" vld1.32 {q6, q7}, [%[b]]!\n"
" vld1.32 {q10, q11}, [%[a]]!\n"
" subs %[len], %[len], #16\n"
" vmul.f32 q0, q4, q8\n"
" vmul.f32 q1, q5, q9\n"
" vmul.f32 q2, q6, q10\n"
" vmul.f32 q3, q7, q11\n"
" beq 3f\n"
"2:"
" vld1.32 {q4, q5}, [%[b]]!\n"
" vld1.32 {q8, q9}, [%[a]]!\n"
" vld1.32 {q6, q7}, [%[b]]!\n"
" vld1.32 {q10, q11}, [%[a]]!\n"
" subs %[len], %[len], #16\n"
" vmla.f32 q0, q4, q8\n"
" vmla.f32 q1, q5, q9\n"
" vmla.f32 q2, q6, q10\n"
" vmla.f32 q3, q7, q11\n"
" bne 2b\n"
"3:"
" vadd.f32 q4, q0, q1\n"
" vadd.f32 q5, q2, q3\n"
" cmp %[remainder], #0\n"
" vadd.f32 q0, q4, q5\n"
" beq 5f\n"
"4:"
" vld1.32 {q6}, [%[b]]!\n"
" vld1.32 {q10}, [%[a]]!\n"
" subs %[remainder], %[remainder], #4\n"
" vmla.f32 q0, q6, q10\n"
" bne 4b\n"
"5:"
" vadd.f32 d0, d0, d1\n"
" vpadd.f32 d0, d0, d0\n"
" vmov.f32 %[ret], d0[0]\n"
: [ret] "=r" (ret), [a] "+r" (a), [b] "+r" (b),
[len] "+l" (len), [remainder] "+l" (remainder)
:
: "cc", "q0", "q1", "q2", "q3",
"q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11");
return ret;
}
#endif // defined(__aarch64__)
#endif

Wyświetl plik

@ -2,127 +2,127 @@
* Copyright (C) 2008 Thorvald Natvig
*/
/**
@file resample_sse.h
@brief Resampler functions (SSE version)
@file resample_sse.h
@brief Resampler functions (SSE version)
*/
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <xmmintrin.h>
#define OVERRIDE_INNER_PRODUCT_SINGLE
static inline float inner_product_single(const float *a, const float *b, unsigned int len)
static inline float inner_product_single(const float* a, const float* b, unsigned int len)
{
unsigned int i;
float ret;
__m128 sum = _mm_setzero_ps();
for (i=0;i<len;i+=8)
{
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i)));
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4)));
}
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
_mm_store_ss(&ret, sum);
return ret;
int i;
float ret;
__m128 sum = _mm_setzero_ps();
for (i = 0; i < len; i += 8)
{
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a + i), _mm_loadu_ps(b + i)));
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a + i + 4), _mm_loadu_ps(b + i + 4)));
}
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
_mm_store_ss(&ret, sum);
return ret;
}
#define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
static inline float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
unsigned int i;
float ret;
__m128 sum = _mm_setzero_ps();
__m128 f = _mm_loadu_ps(frac);
for(i=0;i<len;i+=2)
{
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample)));
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample)));
}
sum = _mm_mul_ps(f, sum);
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
_mm_store_ss(&ret, sum);
return ret;
static inline float interpolate_product_single(const float* a, const float* b, unsigned int len, const spx_uint32_t oversample, float* frac) {
int i;
float ret;
__m128 sum = _mm_setzero_ps();
__m128 f = _mm_loadu_ps(frac);
for (i = 0; i < len; i += 2)
{
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a + i), _mm_loadu_ps(b + i * oversample)));
sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a + i + 1), _mm_loadu_ps(b + (i + 1) * oversample)));
}
sum = _mm_mul_ps(f, sum);
sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
_mm_store_ss(&ret, sum);
return ret;
}
#ifdef __SSE2__
#ifdef USE_SSE2
#include <emmintrin.h>
#define OVERRIDE_INNER_PRODUCT_DOUBLE
static inline double inner_product_double(const float *a, const float *b, unsigned int len)
static inline double inner_product_double(const float* a, const float* b, unsigned int len)
{
unsigned int i;
double ret;
__m128d sum = _mm_setzero_pd();
__m128 t;
for (i=0;i<len;i+=8)
{
t = _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i));
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
int i;
double ret;
__m128d sum = _mm_setzero_pd();
__m128 t;
for (i = 0; i < len; i += 8)
{
t = _mm_mul_ps(_mm_loadu_ps(a + i), _mm_loadu_ps(b + i));
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
t = _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4));
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
}
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
_mm_store_sd(&ret, sum);
return ret;
t = _mm_mul_ps(_mm_loadu_ps(a + i + 4), _mm_loadu_ps(b + i + 4));
sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
}
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
_mm_store_sd(&ret, sum);
return ret;
}
#define OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
static inline double interpolate_product_double(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
unsigned int i;
double ret;
__m128d sum;
__m128d sum1 = _mm_setzero_pd();
__m128d sum2 = _mm_setzero_pd();
__m128 f = _mm_loadu_ps(frac);
__m128d f1 = _mm_cvtps_pd(f);
__m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f,f));
__m128 t;
for(i=0;i<len;i+=2)
{
t = _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample));
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
static inline double interpolate_product_double(const float* a, const float* b, unsigned int len, const spx_uint32_t oversample, float* frac) {
int i;
double ret;
__m128d sum;
__m128d sum1 = _mm_setzero_pd();
__m128d sum2 = _mm_setzero_pd();
__m128 f = _mm_loadu_ps(frac);
__m128d f1 = _mm_cvtps_pd(f);
__m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f, f));
__m128 t;
for (i = 0; i < len; i += 2)
{
t = _mm_mul_ps(_mm_load1_ps(a + i), _mm_loadu_ps(b + i * oversample));
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
t = _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample));
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
}
sum1 = _mm_mul_pd(f1, sum1);
sum2 = _mm_mul_pd(f2, sum2);
sum = _mm_add_pd(sum1, sum2);
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
_mm_store_sd(&ret, sum);
return ret;
t = _mm_mul_ps(_mm_load1_ps(a + i + 1), _mm_loadu_ps(b + (i + 1) * oversample));
sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
}
sum1 = _mm_mul_pd(f1, sum1);
sum2 = _mm_mul_pd(f2, sum2);
sum = _mm_add_pd(sum1, sum2);
sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
_mm_store_sd(&ret, sum);
return ret;
}
#endif
#endif

Wyświetl plik

@ -362,6 +362,10 @@ void rigCommander::setSpectrumBounds(double startFreq, double endFreq, unsigned
if(startFreq > 400.0)
freqRange++;
break;
case modelR8600:
freqRange = 1;
edgeNumber = 1;
break;
default:
return;
break;
@ -429,7 +433,7 @@ void rigCommander::setScopeSpan(char span)
// See ICD, page 165, "19-12".
// 2.5k = 0
// 5k = 2, etc.
if((span <0 ) || (span >7))
if((span <0 ) || (span >9))
return;
QByteArray payload;
@ -464,6 +468,12 @@ void rigCommander::setScopeSpan(char span)
case 7:
freq = 500.0E-3;
break;
case 8:
freq = 1000.0E-3;
break;
case 9:
freq = 2500.0E-3;
break;
default:
return;
break;
@ -1090,6 +1100,12 @@ void rigCommander::parseData(QByteArray dataInput)
// payload = getpayload(data); // or something
// parse (payload); // recursive ok?
payloadIn = data.right(data.length() - 4);
if(payloadIn.contains("\xFE"))
{
//qDebug(logRig()) << "Corrupted data contains FE within message body: ";
//printHex(payloadIn);
break;
}
parseCommand();
break;
case '\x00':
@ -1100,9 +1116,15 @@ void rigCommander::parseData(QByteArray dataInput)
// This is an echo of our own broadcast request.
// The data are "to 00" and "from E1"
// Don't use it!
qDebug(logRig()) << "Caught it! Found the echo'd broadcast request from us!";
qDebug(logRig()) << "Caught it! Found the echo'd broadcast request from us! Rig has not responded to broadcast query yet.";
} else {
payloadIn = data.right(data.length() - 4);
payloadIn = data.right(data.length() - 4); // Removes FE FE E0 94 part
if(payloadIn.contains("\xFE"))
{
//qDebug(logRig()) << "Corrupted data contains FE within message body: ";
//printHex(payloadIn);
break;
}
parseCommand();
}
break;
@ -1320,9 +1342,9 @@ void rigCommander::parseLevels()
break;
default:
qInfo(logRig()) << "Unknown control level (0x14) received at register " << payloadIn[1] << " with level " << level;
qInfo(logRig()) << "Unknown control level (0x14) received at register " << QString("0x%1").arg((int)payloadIn[1],2,16) << " with level " << QString("0x%1").arg((int)level,2,16) << ", int=" << (int)level;
printHex(payloadIn);
break;
}
return;
}
@ -2474,7 +2496,6 @@ void rigCommander::parseDetailedRegisters1A05()
default:
break;
}
}
void rigCommander::parseWFData()
@ -2549,6 +2570,14 @@ mode_info rigCommander::createMode(mode_kind m, unsigned char reg, QString name)
return mode;
}
centerSpanData rigCommander::createScopeCenter(centerSpansType s, QString name)
{
centerSpanData csd;
csd.cstype = s;
csd.name = name;
return csd;
}
void rigCommander::determineRigCaps()
{
//TODO: Determine available bands (low priority, rig will reject out of band requests anyway)
@ -2577,6 +2606,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasDD = false;
rigCaps.hasDV = false;
rigCaps.hasDataModes = true; // USB-D, LSB-D, etc
rigCaps.hasATU = false;
rigCaps.hasCTCSS = false;
@ -2585,7 +2615,14 @@ void rigCommander::determineRigCaps()
rigCaps.spectSeqMax = 0;
rigCaps.spectAmpMax = 0;
rigCaps.spectLenMax = 0;
rigCaps.scopeCenterSpans = { createScopeCenter(cs2p5k, "±2.5k"), createScopeCenter(cs5k, "±5k"),
createScopeCenter(cs10k, "±10k"), createScopeCenter(cs25k, "±25k"),
createScopeCenter(cs50k, "±50k"), createScopeCenter(cs100k, "±100k"),
createScopeCenter(cs250k, "±250k"), createScopeCenter(cs500k, "±500k")
};
rigCaps.hasFDcomms = true; // false for older radios
// Clear inputs/preamps/attenuators lists in case we have re-connected.
rigCaps.preamps.clear();
@ -2601,6 +2638,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasAntennaSel = false;
rigCaps.hasTransmit = true;
rigCaps.hasPTTCommand = true;
// Common, reasonable defaults for most supported HF rigs:
rigCaps.bsr[band160m] = 0x01;
@ -2663,6 +2701,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasEthernet = true;
rigCaps.hasWiFi = false;
rigCaps.hasTransmit = false;
rigCaps.hasPTTCommand = false;
rigCaps.hasCTCSS = true;
rigCaps.hasDTCS = true;
rigCaps.hasDV = true;
@ -2683,6 +2722,7 @@ void rigCommander::determineRigCaps()
createMode(modeP25, 0x16, "P25"), createMode(modedPMR, 0x18, "dPMR"),
createMode(modeNXDN_VN, 0x19, "NXDN-VN"), createMode(modeNXDN_N, 0x20, "NXDN-N"),
createMode(modeDCR, 0x21, "DCR")});
rigCaps.scopeCenterSpans.insert(rigCaps.scopeCenterSpans.end(), {createScopeCenter(cs1M, "±1M"), createScopeCenter(cs2p5M, "±2.5M")});
break;
case model9700:
rigCaps.modelName = QString("IC-9700");
@ -2717,6 +2757,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = false;
rigCaps.hasDD = false;
rigCaps.hasDV = false;
rigCaps.hasCTCSS = true;
@ -2832,6 +2873,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = false;
rigCaps.hasATU = true;
rigCaps.hasCTCSS = true;
rigCaps.hasDTCS = true;
@ -2852,6 +2894,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = true;
rigCaps.hasATU = true;
rigCaps.hasCTCSS = true;
rigCaps.hasDTCS = true;
@ -2872,6 +2915,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = false;
rigCaps.hasATU = true;
rigCaps.hasCTCSS = true;
rigCaps.hasDTCS = true;
@ -2897,6 +2941,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = false;
rigCaps.hasATU = true;
rigCaps.hasCTCSS = true;
rigCaps.hasDTCS = true;
@ -2939,7 +2984,10 @@ void rigCommander::determineRigCaps()
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = false;
rigCaps.hasATU = true;
rigCaps.hasPTTCommand = false;
rigCaps.hasDataModes = false;
rigCaps.attenuators.push_back('\x20');
rigCaps.bands = standardHF;
rigCaps.bands.insert(rigCaps.bands.end(), standardVU.begin(), standardVU.end());
@ -2947,6 +2995,28 @@ void rigCommander::determineRigCaps()
rigCaps.modes = commonModes;
rigCaps.modes.insert(rigCaps.modes.end(), createMode(modeWFM, 0x06, "WFM"));
break;
case model718:
rigCaps.modelName = QString("IC-718");
rigCaps.hasSpectrum = false;
rigCaps.inputs.clear();
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = false;
rigCaps.hasATU = false;
rigCaps.hasPTTCommand = false;
rigCaps.hasDataModes = false;
rigCaps.attenuators.push_back('\x20');
rigCaps.preamps.push_back('\x01');
rigCaps.bands = {band10m, band10m, band12m,
band15m, band17m, band20m, band30m,
band40m, band60m, band80m, band160m, bandGen};
rigCaps.modes = { createMode(modeLSB, 0x00, "LSB"), createMode(modeUSB, 0x01, "USB"),
createMode(modeAM, 0x02, "AM"),
createMode(modeCW, 0x03, "CW"), createMode(modeCW_R, 0x07, "CW-R"),
createMode(modeRTTY, 0x04, "RTTY"), createMode(modeRTTY_R, 0x08, "RTTY-R")
};
break;
case model756pro:
rigCaps.modelName = QString("IC-756 Pro");
rigCaps.hasSpectrum = false;
@ -2954,6 +3024,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = false;
rigCaps.hasATU = true;
rigCaps.preamps.push_back('\x01');
rigCaps.preamps.push_back('\x02');
@ -2971,6 +3042,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = false;
rigCaps.hasATU = true;
rigCaps.preamps.push_back('\x01');
rigCaps.preamps.push_back('\x02');
@ -2988,6 +3060,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = false;
rigCaps.hasATU = true;
rigCaps.preamps.push_back('\x01');
rigCaps.preamps.push_back('\x02');
@ -3008,6 +3081,7 @@ void rigCommander::determineRigCaps()
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = false;
rigCaps.hasPreamp = false;
rigCaps.hasAntennaSel = false;
rigCaps.attenuators.push_back('\x10');

Wyświetl plik

@ -377,6 +377,7 @@ private:
void printHex(const QByteArray &pdata);
void printHex(const QByteArray &pdata, bool printVert, bool printHoriz);
mode_info createMode(mode_kind m, unsigned char reg, QString name);
centerSpanData createScopeCenter(centerSpansType s, QString name);
commHandler* comm = Q_NULLPTR;
pttyHandler* ptty = Q_NULLPTR;

Wyświetl plik

@ -52,8 +52,11 @@ model_kind determineRadioModel(unsigned char rigID)
case model705:
rig = model705;
break;
case model756proiii:
rig = model756proiii;
case model718:
rig = model718;
break;
case model910h:
rig = model910h;
break;
case model756pro:
rig = model756pro;
@ -61,6 +64,9 @@ model_kind determineRadioModel(unsigned char rigID)
case model756proii:
rig = model756proii;
break;
case model756proiii:
rig = model756proiii;
break;
default:
rig = modelUnknown;
break;

Wyświetl plik

@ -28,6 +28,7 @@ enum model_kind {
model9700 = 0xA2,
model705 = 0xA4,
model706 = 0x58,
model718 = 0x5E,
model756pro = 0x5C,
model756proii = 0x64,
model756proiii = 0x6E,
@ -67,6 +68,24 @@ enum bandType { band23cm=0,
bandGen
};
enum centerSpansType {
cs2p5k = 0,
cs5k = 1,
cs10k = 2,
cs25k = 3,
cs50k = 4,
cs100k = 5,
cs250k = 6,
cs500k = 7,
cs1M = 8,
cs2p5M = 9
};
struct centerSpanData {
centerSpansType cstype;
QString name;
};
model_kind determineRadioModel(unsigned char rigID);
struct rigCapabilities {
@ -80,6 +99,7 @@ struct rigCapabilities {
bool hasLan; // OEM ethernet or wifi connection
bool hasEthernet;
bool hasWiFi;
bool hasFDcomms;
QVector<rigInput> inputs;
@ -96,13 +116,16 @@ struct rigCapabilities {
bool hasDTCS;
bool hasTransmit;
bool hasPTTCommand;
bool hasAttenuator;
bool hasPreamp;
bool hasAntennaSel;
bool hasDataModes;
std::vector <unsigned char> attenuators;
std::vector <unsigned char> preamps;
std::vector <unsigned char> antennas;
std::vector <centerSpanData> scopeCenterSpans;
std::vector <bandType> bands;
unsigned char bsr[20] = {0};

Wyświetl plik

@ -57,6 +57,10 @@ void udpServer::init()
udpAudio = new QUdpSocket(this);
udpAudio->bind(config.audioPort);
QUdpSocket::connect(udpAudio, &QUdpSocket::readyRead, this, &udpServer::audioReceived);
wdTimer = new QTimer();
connect(wdTimer, &QTimer::timeout, this, &udpServer::watchdog);
wdTimer->start(500);
}
udpServer::~udpServer()
@ -76,10 +80,6 @@ udpServer::~udpServer()
client->pingTimer->stop();
delete client->pingTimer;
}
if (client->wdTimer != Q_NULLPTR) {
client->wdTimer->stop();
delete client->wdTimer;
}
if (client->retransmitTimer != Q_NULLPTR) {
client->retransmitTimer->stop();
@ -213,10 +213,6 @@ void udpServer::controlReceived()
connect(current->idleTimer, &QTimer::timeout, this, std::bind(&udpServer::sendControl, this, current, (quint8)0x00, (quint16)0x00));
current->idleTimer->start(100);
current->wdTimer = new QTimer();
connect(current->wdTimer, &QTimer::timeout, this, std::bind(&udpServer::watchdog, this, current));
//current->wdTimer->start(1000);
current->retransmitTimer = new QTimer();
connect(current->retransmitTimer, &QTimer::timeout, this, std::bind(&udpServer::sendRetransmitRequest, this, current));
current->retransmitTimer->start(RETRANSMIT_PERIOD);
@ -242,8 +238,15 @@ void udpServer::controlReceived()
{
qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received 'disconnect' request";
sendControl(current, 0x00, in->seq);
//current->wdTimer->stop(); // Keep watchdog running to delete stale connection.
if (current->audioClient != Q_NULLPTR) {
deleteConnection(&audioClients, current->audioClient);
}
if (current->civClient != Q_NULLPTR) {
deleteConnection(&civClients, current->civClient);
}
deleteConnection(&controlClients, current);
return;
}
break;
}
@ -315,14 +318,12 @@ void udpServer::controlReceived()
passcode(user.username, usercomp);
QByteArray passcomp;
passcode(user.password, passcomp);
if (!strcmp(in->username, usercomp.constData()) && !strcmp(in->password, passcomp.constData()))
if (!strcmp(in->username, usercomp.constData()) && (!strcmp(in->password, user.password.toUtf8()) || !strcmp(in->password, passcomp.constData())))
{
current->isAuthenticated = true;
current->user = user;
break;
}
}
// Generate login response
current->rxSeq = in->seq;
@ -423,11 +424,11 @@ void udpServer::controlReceived()
break;
}
}
// Report current connections:
emit haveNetworkStatus(QString("<pre>Server connections: Control:%1 CI-V:%2 Audio:%3</pre>").arg(controlClients.size()).arg(civClients.size()).arg(audioClients.size()));
commonReceived(&controlClients, current, r);
// Connection "may" have been deleted so check before calling common function.
if (current != Q_NULLPTR) {
commonReceived(&controlClients, current, r);
}
}
}
@ -445,22 +446,6 @@ void udpServer::civReceived()
QDateTime now = QDateTime::currentDateTime();
bool userOK = false;
foreach(CLIENT * client, controlClients)
{
if (client != Q_NULLPTR)
{
if (client->ipAddress == datagram.senderAddress() && client->isAuthenticated)
{
userOK = true;
}
}
}
if (!userOK)
{
qDebug(logUdpServer()) << "user is NOT authenticated but attempted CI-V connection!";
}
foreach(CLIENT * client, civClients)
{
if (client != Q_NULLPTR)
@ -469,13 +454,25 @@ void udpServer::civReceived()
{
current = client;
}
}
}
if (current == Q_NULLPTR)
{
current = new CLIENT();
foreach(CLIENT* client, controlClients)
{
if (client != Q_NULLPTR)
{
if (client->ipAddress == datagram.senderAddress() && client->isAuthenticated && client->civClient == Q_NULLPTR)
{
current->controlClient = client;
client->civClient = current;
}
}
}
current->type = "CIV";
current->civId = 0;
current->connected = true;
@ -495,10 +492,6 @@ void udpServer::civReceived()
connect(current->idleTimer, &QTimer::timeout, this, std::bind(&udpServer::sendControl, this, current, 0x00, (quint16)0x00));
//current->idleTimer->start(100); // Start idleTimer after receiving iamready.
current->wdTimer = new QTimer();
connect(current->wdTimer, &QTimer::timeout, this, std::bind(&udpServer::watchdog, this, current));
//current->wdTimer->start(1000);
current->retransmitTimer = new QTimer();
connect(current->retransmitTimer, &QTimer::timeout, this, std::bind(&udpServer::sendRetransmitRequest, this, current));
current->retransmitTimer->start(RETRANSMIT_PERIOD);
@ -510,6 +503,11 @@ void udpServer::civReceived()
}
if (current->controlClient == Q_NULLPTR || !current->controlClient->isAuthenticated)
{
return;
}
switch (r.length())
{
/* case (CONTROL_SIZE):
@ -598,22 +596,6 @@ void udpServer::audioReceived()
QDateTime now = QDateTime::currentDateTime();
bool userOK = false;
foreach(CLIENT * client, controlClients)
{
if (client != Q_NULLPTR)
{
if (client->ipAddress == datagram.senderAddress() && client->isAuthenticated)
{
userOK = true;
}
}
}
if (!userOK)
{
qDebug(logUdpServer()) << "user is NOT authenticated but attempted CI-V connection!";
}
foreach(CLIENT * client, audioClients)
{
if (client != Q_NULLPTR)
@ -627,6 +609,17 @@ void udpServer::audioReceived()
if (current == Q_NULLPTR)
{
current = new CLIENT();
foreach(CLIENT* client, controlClients)
{
if (client != Q_NULLPTR)
{
if (client->ipAddress == datagram.senderAddress() && client->isAuthenticated && client->audioClient == Q_NULLPTR)
{
current->controlClient = client;
client->audioClient = current;
}
}
}
current->type = "Audio";
current->connected = true;
current->timeConnected = QDateTime::currentDateTime();
@ -641,10 +634,6 @@ void udpServer::audioReceived()
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, &audioClients, current, (quint16)0x00, false));
current->pingTimer->start(100);
current->wdTimer = new QTimer();
connect(current->wdTimer, &QTimer::timeout, this, std::bind(&udpServer::watchdog, this, current));
//current->wdTimer->start(1000);
current->retransmitTimer = new QTimer();
connect(current->retransmitTimer, &QTimer::timeout, this, std::bind(&udpServer::sendRetransmitRequest, this, current));
current->retransmitTimer->start(RETRANSMIT_PERIOD);
@ -913,7 +902,8 @@ void udpServer::sendControl(CLIENT* c, quint8 type, quint16 seq)
void udpServer::sendPing(QList<CLIENT*>* l, CLIENT* c, quint16 seq, bool reply)
{
// Also use to detect "stale" connections
Q_UNUSED(l);
/*
QDateTime now = QDateTime::currentDateTime();
if (c->lastHeard.secsTo(now) > STALE_CONNECTION)
@ -923,6 +913,7 @@ void udpServer::sendPing(QList<CLIENT*>* l, CLIENT* c, quint16 seq, bool reply)
return;
}
*/
//qInfo(logUdpServer()) << c->ipAddress.toString() << ": Sending Ping";
@ -981,8 +972,6 @@ void udpServer::sendLoginResponse(CLIENT* c, bool allowed)
c->pingTimer->stop();
if (c->retransmitTimer != Q_NULLPTR)
c->retransmitTimer->stop();
if (c->wdTimer != Q_NULLPTR)
c->wdTimer->stop();
}
else {
strcpy(p.connection, "WFVIEW");
@ -1226,10 +1215,56 @@ void udpServer::sendTokenResponse(CLIENT* c, quint8 type)
#define PURGE_SECONDS 60
void udpServer::watchdog(CLIENT* c)
void udpServer::watchdog()
{
Q_UNUSED(c);
// Do something!
QDateTime now = QDateTime::currentDateTime();
foreach(CLIENT * client, audioClients)
{
if (client != Q_NULLPTR)
{
if (client->lastHeard.secsTo(now) > STALE_CONNECTION)
{
qInfo(logUdpServer()) << client->ipAddress.toString() << "(" << client->type << "): Deleting stale connection ";
deleteConnection(&audioClients, client);
}
}
else {
qInfo(logUdpServer()) << "Current client is NULL!";
}
}
foreach(CLIENT* client, civClients)
{
if (client != Q_NULLPTR)
{
if (client->lastHeard.secsTo(now) > STALE_CONNECTION)
{
qInfo(logUdpServer()) << client->ipAddress.toString() << "(" << client->type << "): Deleting stale connection ";
deleteConnection(&civClients, client);
}
}
else {
qInfo(logUdpServer()) << "Current client is NULL!";
}
}
foreach(CLIENT* client, controlClients)
{
if (client != Q_NULLPTR)
{
if (client->lastHeard.secsTo(now) > STALE_CONNECTION)
{
qInfo(logUdpServer()) << client->ipAddress.toString() << "(" << client->type << "): Deleting stale connection ";
deleteConnection(&controlClients, client);
}
}
else {
qInfo(logUdpServer()) << "Current client is NULL!";
}
}
emit haveNetworkStatus(QString("<pre>Server connections: Control:%1 CI-V:%2 Audio:%3</pre>").arg(controlClients.size()).arg(civClients.size()).arg(audioClients.size()));
}
void udpServer::sendStatus(CLIENT* c)
@ -1511,7 +1546,7 @@ void udpServer::sendRetransmitRequest(CLIENT* c)
void udpServer::deleteConnection(QList<CLIENT*>* l, CLIENT* c)
{
qInfo(logUdpServer()) << "Deleting connection to: " << c->ipAddress.toString() << ":" << QString::number(c->port);
qInfo(logUdpServer()) << "Deleting" << c->type << "connection to: " << c->ipAddress.toString() << ":" << QString::number(c->port);
if (c->idleTimer != Q_NULLPTR) {
c->idleTimer->stop();
delete c->idleTimer;
@ -1520,10 +1555,6 @@ void udpServer::deleteConnection(QList<CLIENT*>* l, CLIENT* c)
c->pingTimer->stop();
delete c->pingTimer;
}
if (c->wdTimer != Q_NULLPTR) {
c->wdTimer->stop();
delete c->wdTimer;
}
if (c->retransmitTimer != Q_NULLPTR) {
c->retransmitTimer->stop();

Wyświetl plik

@ -94,7 +94,6 @@ private:
QTimer* pingTimer;
QTimer* idleTimer;
QTimer* wdTimer;
QTimer* retransmitTimer;
// Only used for audio.
@ -117,6 +116,9 @@ private:
quint8 civId;
bool isAuthenticated;
CLIENT* controlClient = Q_NULLPTR;
CLIENT* civClient = Q_NULLPTR;
CLIENT* audioClient = Q_NULLPTR;
};
void controlReceived();
@ -132,7 +134,7 @@ private:
void sendTokenResponse(CLIENT* c,quint8 type);
void sendStatus(CLIENT* c);
void sendRetransmitRequest(CLIENT* c);
void watchdog(CLIENT* c);
void watchdog();
void sendRxAudio();
void deleteConnection(QList<CLIENT*> *l, CLIENT* c);
@ -175,6 +177,7 @@ private:
quint8 txCodec = 0;
QHostAddress hasTxAudio;
QTimer* wdTimer;
};

Wyświetl plik

@ -2,11 +2,15 @@
#include "ui_udpserversetup.h"
#include "logcategories.h"
extern void passcode(QString in,QByteArray& out);
udpServerSetup::udpServerSetup(QWidget* parent) :
QDialog(parent),
ui(new Ui::udpServerSetup)
{
ui->setupUi(this);
addUserLine("", "", 0); // Create a blank row if we never receive config.
// Get any stored config information from the main form.
SERVERCONFIG config;
emit serverConfig(config,false); // Just send blank server config.
@ -29,43 +33,22 @@ void udpServerSetup::receiveServerConfig(SERVERCONFIG conf)
int row = 0;
for (int i = 0; i < ui->usersTable->rowCount(); i++)
{
ui->usersTable->removeRow(i);
}
foreach (SERVERUSER user, conf.users)
{
if (user.username != "" && user.password != "")
{
if (ui->usersTable->rowCount() <= row) {
ui->usersTable->insertRow(ui->usersTable->rowCount());
}
ui->usersTable->setItem(row, 0, new QTableWidgetItem(user.username));
ui->usersTable->setItem(row, 1, new QTableWidgetItem(user.password));
QComboBox* comboBox = new QComboBox();
comboBox->insertItems(0, { "Full User","Full with no TX","Monitor only" });
comboBox->setCurrentIndex(user.userType);
ui->usersTable->setCellWidget(row, 2, comboBox);
addUserLine(user.username, user.password, user.userType);
row++;
}
}
// Delete any rows no longer needed
int count=0;
for (count = row; count <= ui->usersTable->rowCount(); count++)
{
if (count == conf.users.count()) {
ui->usersTable->insertRow(ui->usersTable->rowCount());
QComboBox* comboBox = new QComboBox();
comboBox->insertItems(0, { "Full User","Full with no TX","Monitor only" });
ui->usersTable->setCellWidget(count, 2, comboBox);
}
else if (count > conf.users.count()) {
ui->usersTable->removeRow(count);
}
}
if (count == 0) {
ui->usersTable->insertRow(ui->usersTable->rowCount());
QComboBox* comboBox = new QComboBox();
comboBox->insertItems(0, { "Full User","Full with no TX","Monitor only" });
ui->usersTable->setCellWidget(count, 2, comboBox);
if (row == 0) {
addUserLine("", "", 0);
}
}
@ -83,11 +66,12 @@ void udpServerSetup::accept()
for (int row = 0; row < ui->usersTable->model()->rowCount(); row++)
{
if (ui->usersTable->item(row, 0) != NULL && ui->usersTable->item(row, 1) != NULL)
if (ui->usersTable->item(row, 0) != NULL)
{
SERVERUSER user;
user.username = ui->usersTable->item(row, 0)->text();
user.password = ui->usersTable->item(row, 1)->text();
QLineEdit* password = (QLineEdit*)ui->usersTable->cellWidget(row, 1);
user.password = password->text();
QComboBox* comboBox = (QComboBox*)ui->usersTable->cellWidget(row, 2);
user.userType = comboBox->currentIndex();
config.users.append(user);
@ -106,13 +90,38 @@ void udpServerSetup::accept()
void udpServerSetup::on_usersTable_cellClicked(int row, int col)
{
qInfo() << "Clicked on " << row << "," << col;
if (row == ui->usersTable->model()->rowCount() - 1 && ui->usersTable->item(row, 0) != NULL && ui->usersTable->item(row, 1) != NULL) {
ui->usersTable->insertRow(ui->usersTable->rowCount());
QComboBox* comboBox = new QComboBox();
comboBox->insertItems(0, { "Full User","Full with no TX","Monitor only" });
userTypes.append(comboBox);
ui->usersTable->setCellWidget(ui->usersTable->rowCount() - 1, 2, comboBox);
if (row == ui->usersTable->model()->rowCount() - 1 && ui->usersTable->item(row, 0) != NULL) {
addUserLine("", "", 0);
}
}
}
void udpServerSetup::onPasswordChanged()
{
int row = sender()->property("row").toInt();
QLineEdit* password = (QLineEdit*)ui->usersTable->cellWidget(row, 1);
QByteArray pass;
passcode(password->text(), pass);
password->setText(pass);
qInfo() << "password row" << row << "changed";
}
void udpServerSetup::addUserLine(const QString& user, const QString& pass, const int& type)
{
ui->usersTable->insertRow(ui->usersTable->rowCount());
ui->usersTable->setItem(ui->usersTable->rowCount() - 1, 0, new QTableWidgetItem(user));
ui->usersTable->setItem(ui->usersTable->rowCount() - 1, 1, new QTableWidgetItem());
ui->usersTable->setItem(ui->usersTable->rowCount() - 1, 2, new QTableWidgetItem());
QLineEdit* password = new QLineEdit();
password->setProperty("row", (int)ui->usersTable->rowCount() - 1);
password->setEchoMode(QLineEdit::PasswordEchoOnEdit);
password->setText(pass);
connect(password, SIGNAL(editingFinished()), this, SLOT(onPasswordChanged()));
ui->usersTable->setCellWidget(ui->usersTable->rowCount() - 1, 1, password);
QComboBox* comboBox = new QComboBox();
comboBox->insertItems(0, { "Full User","Full with no TX","Monitor only" });
comboBox->setCurrentIndex(type);
ui->usersTable->setCellWidget(ui->usersTable->rowCount() - 1, 2, comboBox);
}

Wyświetl plik

@ -42,6 +42,7 @@ public:
private slots:
void on_usersTable_cellClicked(int row, int col);
void onPasswordChanged();
public slots:
void receiveServerConfig(SERVERCONFIG conf);
@ -53,6 +54,7 @@ private:
Ui::udpServerSetup* ui;
void accept();
QList<QComboBox*> userTypes;
void addUserLine(const QString &user, const QString &pass, const int &type);
};
#endif // UDPSERVER_H

Wyświetl plik

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>440</width>
<height>351</height>
<height>361</height>
</rect>
</property>
<property name="sizePolicy">

Plik diff jest za duży Load Diff

Wyświetl plik

@ -31,6 +31,8 @@
#include <qserialportinfo.h>
#include "shuttle.h"
#include <deque>
namespace Ui {
class wfmain;
}
@ -147,6 +149,7 @@ signals:
void openShuttle();
private slots:
void updateSizes(int tabIndex);
void shortcutF1();
void shortcutF2();
void shortcutF3();
@ -240,8 +243,7 @@ private slots:
void handleWFDoubleClick(QMouseEvent *);
void handleWFScroll(QWheelEvent *);
void handlePlotScroll(QWheelEvent *);
void runDelayedCommand();
void runPeriodicCommands();
void sendRadioCommandLoop();
void showStatusBarText(QString text);
void serverConfigRequested(SERVERCONFIG conf, bool store);
void receiveBaudRate(quint32 baudrate);
@ -458,6 +460,8 @@ private slots:
void on_wfLengthSlider_valueChanged(int value);
void on_pollingBtn_clicked();
private:
Ui::wfmain *ui;
void closeEvent(QCloseEvent *event);
@ -472,6 +476,7 @@ private:
void setPlotTheme(QCustomPlot *plot, bool isDark);
void prepareWf();
void prepareWf(unsigned int wfLength);
void showHideSpectrum(bool show);
void getInitialRigState();
void setBandButtons();
void showButton(QPushButton *btn);
@ -519,6 +524,8 @@ private:
QShortcut *keyF;
QShortcut *keyM;
QShortcut *keyDebug;
rigCommander * rig=Q_NULLPTR;
QThread* rigThread = Q_NULLPTR;
@ -526,8 +533,9 @@ private:
QCPColorMapData * colorMapData;
QCPColorScale * colorScale;
QTimer * delayedCommand;
QTimer * periodicPollingTimer;
QTimer * pttTimer;
uint16_t loopTickCounter;
uint16_t slowCmdNum;
void setupPlots();
void makeRig();
@ -568,6 +576,7 @@ private:
int smeterPos=0;
QVector <QByteArray> wfimage;
unsigned int wfLengthMax;
bool onFullscreen;
bool drawPeaks;
@ -588,16 +597,18 @@ private:
cmdGetSql, cmdGetATUStatus, cmdGetSpectrumMode, cmdGetSpectrumSpan, cmdScopeCenterMode, cmdScopeFixedMode, cmdGetPTT,
cmdGetTxPower, cmdGetMicGain, cmdGetSpectrumRefLevel, cmdGetDuplexMode, cmdGetModInput, cmdGetModDataInput,
cmdGetCurrentModLevel, cmdStartRegularPolling, cmdStopRegularPolling, cmdQueNormalSpeed,
cmdGetVdMeter, cmdGetIdMeter, cmdGetSMeter, cmdGetPowerMeter, cmdGetALCMeter, cmdGetCompMeter,
cmdGetVdMeter, cmdGetIdMeter, cmdGetSMeter, cmdGetPowerMeter, cmdGetALCMeter, cmdGetCompMeter, cmdGetTxRxMeter,
cmdGetTone, cmdGetTSQL, cmdGetDTCS, cmdGetRptAccessMode, cmdGetPreamp, cmdGetAttenuator, cmdGetAntenna};
cmds cmdOut;
QVector <cmds> cmdOutQue;
QVector <cmds> periodicCmdQueue;
std::deque <cmds> delayedCmdQue;
std::deque <cmds> periodicCmdQueue;
std::deque <cmds> slowPollCmdQueue;
void doCmd(cmds cmd);
int pCmdNum = 0;
int delayedCmdIntervalLAN_ms = 100;
int delayedCmdIntervalSerial_ms = 100;
int delayedCmdStartupInterval_ms = 100;
bool runPeriodicCommands;
bool usingLAN = false;
freqMemory mem;
@ -671,6 +682,8 @@ private:
void issueDelayedCommandPriority(cmds cmd);
void issueDelayedCommandUnique(cmds cmd);
void changeSliderQuietly(QSlider *slider, int value);
void statusFromSliderPercent(QString name, int percentValue);
void statusFromSliderRaw(QString name, int rawValue);
void processModLevel(rigInput source, unsigned char level);
@ -683,6 +696,7 @@ private:
void initPeriodicCommands();
void insertPeriodicCommand(cmds cmd, unsigned char priority);
void insertSlowPeriodicCommand(cmds cmd, unsigned char priority);
void calculateTimingParameters();
void changeMode(mode_kind mode);

Wyświetl plik

@ -18,7 +18,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>3</number>
</property>
<widget class="QWidget" name="mainTab">
<attribute name="title">
@ -26,7 +26,7 @@
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<widget class="QGroupBox" name="spectrumGroupBox">
<property name="title">
<string>Spectrum</string>
</property>
@ -44,12 +44,12 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<layout class="QHBoxLayout" name="specControlsHorizLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_26">
<widget class="QLabel" name="specModeLabel">
<property name="text">
<string>Spectrum Mode: </string>
</property>
@ -66,7 +66,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<widget class="QLabel" name="specSpanLabel">
<property name="text">
<string>Span:</string>
</property>
@ -86,7 +86,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<widget class="QLabel" name="specEdgeLabel">
<property name="text">
<string>Edge</string>
</property>
@ -133,7 +133,7 @@
</widget>
</item>
<item>
<widget class="QLabel" name="label_31">
<widget class="QLabel" name="specThemeLabel">
<property name="text">
<string>Theme:</string>
</property>
@ -150,7 +150,7 @@
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<spacer name="specHorizSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -2612,6 +2612,22 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pollingBtn">
<property name="toolTip">
<string>Set up radio polling. The radio's meter is polled every-other interval.</string>
</property>
<property name="accessibleName">
<string>Polling</string>
</property>
<property name="accessibleDescription">
<string/>
</property>
<property name="text">
<string>Polling</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">

Wyświetl plik

@ -31,7 +31,10 @@ linux:QMAKE_LFLAGS += -O2 -s
DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += QCUSTOMPLOT_COMPILE_LIBRARY
# These defines are used for the resampler
equals(QT_ARCH, i386): DEFINES += USE_SSE
equals(QT_ARCH, arm): DEFINES += USE_NEON
DEFINES += OUTSIDE_SPEEX
DEFINES += RANDOM_PREFIX=wf
@ -107,7 +110,7 @@ win32:INCLUDEPATH += ../hidapi/hidapi
!linux:INCLUDEPATH += ../qcustomplot
INCLUDEPATH += opus-tools/src
INCLUDEPATH += resampler
!linux:INCLUDEPATH += rtaudio
SOURCES += main.cpp\
@ -126,7 +129,7 @@ SOURCES += main.cpp\
meter.cpp \
qledlabel.cpp \
pttyhandler.cpp \
opus-tools/src/resample.c \
resampler/resample.c \
repeatersetup.cpp \
rigctld.cpp \
ring/ring.cpp \
@ -148,9 +151,9 @@ HEADERS += wfmain.h \
meter.h \
qledlabel.h \
pttyhandler.h \
opus-tools/src/speex_resampler.h \
opus-tools/src/arch.h \
opus-tools/src/resample_sse.h \
resampler/speex_resampler.h \
resampler/arch.h \
resampler/resample_sse.h \
repeatersetup.h \
repeaterattributes.h \
rigctld.h \