diff --git a/USER_MANUAL.html b/USER_MANUAL.html
index ca1d840e..18eff2b4 100644
--- a/USER_MANUAL.html
+++ b/USER_MANUAL.html
@@ -560,7 +560,17 @@ FMA - Supports FMA extensions using YMM state
Release Notes
- V1.7.0 February 2022
+ TBD April 2022
+
+- Enhancements:
+
+- PSK Reporter: Encodes callsign regardless of whether the internet is working. (PR #214)
+- PSK Reporter: Sends report upon pushing Stop (vs. simply clearing the report list). (PR #214)
+- PSK Reporter: Performs reporting in background instead of hanging the caller of the PskReporter class. (PR #214)
+- PSK Reporter: Suppress reporting if we’re playing back a radio file (to avoid false reports). (PR #214)
+
+
+ V1.7.0 February 2022
- Bugfixes:
@@ -594,7 +604,7 @@ FMA - Supports FMA extensions using YMM state
- Windows installer now installs sample .wav files. (PR #182)
- V1.6.1 September 2021
+ V1.6.1 September 2021
- Bugfixes:
@@ -612,7 +622,7 @@ FMA - Supports FMA extensions using YMM state
Note: The PSK Reporter feature beginning in this release is incompatible with versions older than 1.6.1 due to a change in how callsigns are encoded.
- V1.6.0 August 2021
+ V1.6.0 August 2021
- Bugfixes:
@@ -647,43 +657,43 @@ FMA - Supports FMA extensions using YMM state
- Created “make dist” target for easy tarball generation. (PR #152)
- V1.5.3 April 2021
+ V1.5.3 April 2021
- Simultaneous decode of 2020, 1600 and 700C/D/E (without needing to push Stop first, change the mode and push Start again).
- Dynamic switching of the current Tx mode between the aforementioned modes, again without needing to restart the session.
- A Tx level slider on the right hand side of the main screen to fine-tune transmit output (to more easily avoid clipping ALC and conflicting with other soundcard ham radio applications).
- V1.5.2 January 2021
+ V1.5.2 January 2021
- Updates storage for sound card configuration to use device names instead of IDs.
- Detects changes to computer sound card configuration and notifies user when devices go away.
- V1.5.1 January 2021
+ V1.5.1 January 2021
- Experimental support for reporting to PSK Reporter added.
- Bug fixes with audio configuration to allow mono devices to be used along with stereo ones.
- Tweaks to user interface and record/playback functionality to improve usability.
- Bug fixes and tweaks to improve voice keyer support.
- V1.5.0 December 2020
+ V1.5.0 December 2020
- FreeDV 700E, better performance than 700D on fast fading channels
- FreeDV 700D/700E clipper to increase average transmit power by 6dB
- V1.4.3 August 2020
+ V1.4.3 August 2020
- Maintenance Release (no major new features)
- Changes to support wxWidgets 3.1 (but Windows versions built against wxWidgets 3.0)
- Under the hood - OFDM modem has been refactored, shouldn’t affect freedv-gui operation
- V1.4.2 July 2020
+ V1.4.2 July 2020
- Maintenance Release (no major new features)
- Improved squelch/audio pass through on 700D/2020/2400B
- Under the hood - Codec2 library has been refactored, shouldn’t affect freedv-gui operation
- Removed Project Horus support (now being maintained outside of Codec2/FreeDV)
- V1.4 June-October 2019
+ V1.4 June-October 2019
- FreeDV 2020, Project Horus Binary Modes.
- Improved OFDM Modem Acquisition, this will improve sync time on FreeDV 700D and 2020 on HF fading channels, and can also handle +/- 60 Hz frequency offsets when tuning.
@@ -691,7 +701,7 @@ FMA - Supports FMA extensions using YMM state
- Wide bandwidth phase estimation and DPSK for OFDM modes (700D/2020) for fast fading/QO-100 channels (Tools-Options)
- Better speech quality on FreeDV 700C/700D with Auto equaliser (Tools-Filter)
- V1.3 May 2018
+ V1.3 May 2018
diff --git a/USER_MANUAL.md b/USER_MANUAL.md
index 44bada7c..02b8c172 100644
--- a/USER_MANUAL.md
+++ b/USER_MANUAL.md
@@ -765,6 +765,14 @@ LDPC | Low Density Parity Check Codes - a family of powerful FEC codes
# Release Notes
+## TBD April 2022
+
+1. Enhancements:
+ * PSK Reporter: Encodes callsign regardless of whether the internet is working. (PR #214)
+ * PSK Reporter: Sends report upon pushing Stop (vs. simply clearing the report list). (PR #214)
+ * PSK Reporter: Performs reporting in background instead of hanging the caller of the PskReporter class. (PR #214)
+ * PSK Reporter: Suppress reporting if we're playing back a radio file (to avoid false reports). (PR #214)
+
## V1.7.0 February 2022
1. Bugfixes:
diff --git a/USER_MANUAL.pdf b/USER_MANUAL.pdf
index 4b96df45..9fe8a365 100644
Binary files a/USER_MANUAL.pdf and b/USER_MANUAL.pdf differ
diff --git a/src/main.cpp b/src/main.cpp
index d5a57ec0..ec8cc502 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1169,7 +1169,10 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
}
unsigned int freq = wxGetApp().m_psk_freq;
- if (freq > 0)
+
+ // Only report if there's a valid reporting frequency and if we're not playing
+ // a recording through ourselves (to avoid false reports).
+ if (freq > 0 && !g_playFileFromRadio)
{
fprintf(
stderr,
@@ -1702,22 +1705,13 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
wxGetApp().m_psk_callsign.ToStdString(),
wxGetApp().m_psk_grid_square.ToStdString(),
std::string("FreeDV ") + FREEDV_VERSION);
+ assert(wxGetApp().m_pskReporter != nullptr);
+
wxGetApp().m_pskPendingCallsign = "";
wxGetApp().m_pskPendingSnr = 0;
- // Send empty packet to verify network connectivity.
- bool success = wxGetApp().m_pskReporter->send();
- if (success)
- {
- // Enable PSK Reporter timer (every 5 minutes).
- m_pskReporterTimer.Start(5 * 60 * 1000);
- }
- else
- {
- wxMessageBox("Couldn't connect to PSK Reporter server. Reporting functionality will be disabled.", wxT("Error"), wxOK | wxICON_ERROR, this);
- delete wxGetApp().m_pskReporter;
- wxGetApp().m_pskReporter = NULL;
- }
+ // Enable PSK Reporter timer (every 5 minutes).
+ m_pskReporterTimer.Start(5 * 60 * 1000);
}
}
else
diff --git a/src/pskreporter.cpp b/src/pskreporter.cpp
index 89170c42..5fda0024 100644
--- a/src/pskreporter.cpp
+++ b/src/pskreporter.cpp
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -112,7 +113,10 @@ PskReporter::PskReporter(std::string callsign, std::string gridSquare, std::stri
PskReporter::~PskReporter()
{
- recordList_.clear();
+ if (recordList_.size() > 0)
+ {
+ reportCommon_();
+ }
}
void PskReporter::addReceiveRecord(std::string callsign, unsigned int frequency, char snr)
@@ -120,89 +124,12 @@ void PskReporter::addReceiveRecord(std::string callsign, unsigned int frequency,
recordList_.push_back(SenderRecord(callsign, frequency, snr));
}
-bool PskReporter::send()
+void PskReporter::send()
{
- // Header (2) + length (2) + time (4) + sequence # (4) + random identifier (4) +
- // RX format block + TX format block + RX data + TX data
- int dgSize = 16 + sizeof(rxFormatHeader) + sizeof(txFormatHeader) + getRxDataSize_() + getTxDataSize_();
- if (getTxDataSize_() == 0) dgSize -= sizeof(txFormatHeader);
+ auto task = std::thread([&]() { reportCommon_(); });
- char* packet = new char[dgSize];
- memset(packet, 0, dgSize);
-
- // Encode packet header.
- packet[0] = 0x00;
- packet[1] = 0x0A;
-
- // Encode datagram size.
- char* fieldLoc = &packet[2];
- *((unsigned short*)fieldLoc) = htons(dgSize);
-
- // Encode send time.
- fieldLoc += sizeof(unsigned short);
- *((unsigned int*)fieldLoc) = htonl(time(0));
-
- // Encode sequence number.
- fieldLoc += sizeof(unsigned int);
- *((unsigned int*)fieldLoc) = htonl(currentSequenceNumber_++);
-
- // Encode random identifier.
- fieldLoc += sizeof(unsigned int);
- *((unsigned int*)fieldLoc) = htonl(randomIdentifier_);
-
- // Copy RX and TX format headers.
- fieldLoc += sizeof(unsigned int);
- memcpy(fieldLoc, rxFormatHeader, sizeof(rxFormatHeader));
- fieldLoc += sizeof(rxFormatHeader);
-
- if (getTxDataSize_() > 0)
- {
- memcpy(fieldLoc, txFormatHeader, sizeof(txFormatHeader));
- fieldLoc += sizeof(txFormatHeader);
- }
-
- // Encode receiver and sender records.
- encodeReceiverRecord_(fieldLoc);
- fieldLoc += getRxDataSize_();
- encodeSenderRecords_(fieldLoc);
-
- recordList_.clear();
-
- // Send to PSKReporter.
- struct addrinfo hints;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_protocol = 0;
-#ifdef WIN32
- hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
-#else
- hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED | AI_NUMERICSERV;
-#endif // WIN32
- struct addrinfo* res = NULL;
- int err = getaddrinfo(PSK_REPORTER_HOSTNAME, PSK_REPORTER_PORT, &hints, &res);
- if (err != 0) {
- if (g_verbose) fprintf(stderr, "cannot resolve %s (err=%d)", PSK_REPORTER_HOSTNAME, err);
- return false;
- }
-
- int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if(fd < 0){
- if (g_verbose) fprintf(stderr, "cannot open PSK Reporter socket (err=%d)\n", errno);
- return false;
- }
-
- if (sendto(fd, packet, dgSize, 0, res->ai_addr, res->ai_addrlen) < 0){
- delete[] packet;
- if (g_verbose) fprintf(stderr, "cannot send message to PSK Reporter (err=%d)\n", errno);
- close(fd);
- return false;
- }
- delete[] packet;
- close(fd);
-
- freeaddrinfo(res);
- return true;
+ // Allow the reporting to run without needing to wait for it.
+ task.detach();
}
int PskReporter::getRxDataSize_()
@@ -283,6 +210,91 @@ void PskReporter::encodeSenderRecords_(char* buf)
}
}
+bool PskReporter::reportCommon_()
+{
+ // Header (2) + length (2) + time (4) + sequence # (4) + random identifier (4) +
+ // RX format block + TX format block + RX data + TX data
+ int dgSize = 16 + sizeof(rxFormatHeader) + sizeof(txFormatHeader) + getRxDataSize_() + getTxDataSize_();
+ if (getTxDataSize_() == 0) dgSize -= sizeof(txFormatHeader);
+
+ char* packet = new char[dgSize];
+ memset(packet, 0, dgSize);
+
+ // Encode packet header.
+ packet[0] = 0x00;
+ packet[1] = 0x0A;
+
+ // Encode datagram size.
+ char* fieldLoc = &packet[2];
+ *((unsigned short*)fieldLoc) = htons(dgSize);
+
+ // Encode send time.
+ fieldLoc += sizeof(unsigned short);
+ *((unsigned int*)fieldLoc) = htonl(time(0));
+
+ // Encode sequence number.
+ fieldLoc += sizeof(unsigned int);
+ *((unsigned int*)fieldLoc) = htonl(currentSequenceNumber_++);
+
+ // Encode random identifier.
+ fieldLoc += sizeof(unsigned int);
+ *((unsigned int*)fieldLoc) = htonl(randomIdentifier_);
+
+ // Copy RX and TX format headers.
+ fieldLoc += sizeof(unsigned int);
+ memcpy(fieldLoc, rxFormatHeader, sizeof(rxFormatHeader));
+ fieldLoc += sizeof(rxFormatHeader);
+
+ if (getTxDataSize_() > 0)
+ {
+ memcpy(fieldLoc, txFormatHeader, sizeof(txFormatHeader));
+ fieldLoc += sizeof(txFormatHeader);
+ }
+
+ // Encode receiver and sender records.
+ encodeReceiverRecord_(fieldLoc);
+ fieldLoc += getRxDataSize_();
+ encodeSenderRecords_(fieldLoc);
+
+ recordList_.clear();
+
+ // Send to PSKReporter.
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = 0;
+#ifdef WIN32
+ hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED;
+#else
+ hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED | AI_NUMERICSERV;
+#endif // WIN32
+ struct addrinfo* res = NULL;
+ int err = getaddrinfo(PSK_REPORTER_HOSTNAME, PSK_REPORTER_PORT, &hints, &res);
+ if (err != 0) {
+ if (g_verbose) fprintf(stderr, "cannot resolve %s (err=%d)", PSK_REPORTER_HOSTNAME, err);
+ return false;
+ }
+
+ int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if(fd < 0){
+ if (g_verbose) fprintf(stderr, "cannot open PSK Reporter socket (err=%d)\n", errno);
+ return false;
+ }
+
+ if (sendto(fd, packet, dgSize, 0, res->ai_addr, res->ai_addrlen) < 0){
+ delete[] packet;
+ if (g_verbose) fprintf(stderr, "cannot send message to PSK Reporter (err=%d)\n", errno);
+ close(fd);
+ return false;
+ }
+ delete[] packet;
+ close(fd);
+
+ freeaddrinfo(res);
+ return true;
+}
+
#if 0
int main()
{
diff --git a/src/pskreporter.h b/src/pskreporter.h
index 057c80dc..88ff97de 100644
--- a/src/pskreporter.h
+++ b/src/pskreporter.h
@@ -23,7 +23,7 @@ public:
virtual ~PskReporter();
void addReceiveRecord(std::string callsign, unsigned int frequency, char snr);
- bool send();
+ void send();
private:
unsigned int currentSequenceNumber_;
@@ -38,6 +38,8 @@ private:
int getTxDataSize_();
void encodeReceiverRecord_(char* buf);
void encodeSenderRecords_(char* buf);
+
+ bool reportCommon_();
};