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

16 Release Notes

-

16.1 V1.7.0 February 2022

+

16.1 TBD April 2022

+
    +
  1. Enhancements: +
  2. +
+

16.2 V1.7.0 February 2022

  1. Bugfixes:
-

16.2 V1.6.1 September 2021

+

16.3 V1.6.1 September 2021

  1. Bugfixes:

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.

-

16.3 V1.6.0 August 2021

+

16.4 V1.6.0 August 2021

  1. Bugfixes:
-

16.4 V1.5.3 April 2021

+

16.5 V1.5.3 April 2021

  1. Simultaneous decode of 2020, 1600 and 700C/D/E (without needing to push Stop first, change the mode and push Start again).
  2. Dynamic switching of the current Tx mode between the aforementioned modes, again without needing to restart the session.
  3. 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).
-

16.5 V1.5.2 January 2021

+

16.6 V1.5.2 January 2021

  1. Updates storage for sound card configuration to use device names instead of IDs.
  2. Detects changes to computer sound card configuration and notifies user when devices go away.
-

16.6 V1.5.1 January 2021

+

16.7 V1.5.1 January 2021

  1. Experimental support for reporting to PSK Reporter added.
  2. Bug fixes with audio configuration to allow mono devices to be used along with stereo ones.
  3. Tweaks to user interface and record/playback functionality to improve usability.
  4. Bug fixes and tweaks to improve voice keyer support.
-

16.7 V1.5.0 December 2020

+

16.8 V1.5.0 December 2020

  1. FreeDV 700E, better performance than 700D on fast fading channels
  2. FreeDV 700D/700E clipper to increase average transmit power by 6dB
-

16.8 V1.4.3 August 2020

+

16.9 V1.4.3 August 2020

  1. Maintenance Release (no major new features)
  2. Changes to support wxWidgets 3.1 (but Windows versions built against wxWidgets 3.0)
  3. Under the hood - OFDM modem has been refactored, shouldn’t affect freedv-gui operation
-

16.9 V1.4.2 July 2020

+

16.10 V1.4.2 July 2020

  1. Maintenance Release (no major new features)
  2. Improved squelch/audio pass through on 700D/2020/2400B
  3. Under the hood - Codec2 library has been refactored, shouldn’t affect freedv-gui operation
  4. Removed Project Horus support (now being maintained outside of Codec2/FreeDV)
-

16.10 V1.4 June-October 2019

+

16.11 V1.4 June-October 2019

  1. FreeDV 2020, Project Horus Binary Modes.
  2. 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.
  3. @@ -691,7 +701,7 @@ FMA - Supports FMA extensions using YMM state
  4. Wide bandwidth phase estimation and DPSK for OFDM modes (700D/2020) for fast fading/QO-100 channels (Tools-Options)
  5. Better speech quality on FreeDV 700C/700D with Auto equaliser (Tools-Filter)
-

16.11 V1.3 May 2018

+

16.12 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_(); };