Added APRSIS spotting back into the app, but this time under the APJ8CL aprs registered callsign

This commit is contained in:
Jordan Sherer 2020-03-30 23:07:40 -04:00
parent 79acdfccd3
commit ab339e9728
8 changed files with 167 additions and 118 deletions

View File

@ -206,28 +206,31 @@ QString APRSISClient::replaceCallsignSuffixWithSSID(QString call, QString base){
return call;
}
void APRSISClient::enqueueSpot(QString theircall, QString grid, QString comment){
if(m_localCall.isEmpty()) return;
auto geo = APRSISClient::grid2aprs(grid);
auto spotFrame = QString("%1>APRS,%2,TCPIP*:=%3/%4nJS8 %5\n");
spotFrame = spotFrame.arg(theircall);
spotFrame = spotFrame.arg(stripSSID(m_localCall));
spotFrame = spotFrame.arg(geo.first);
spotFrame = spotFrame.arg(geo.second);
spotFrame = spotFrame.arg(comment.left(43));
enqueueRaw(spotFrame);
}
void APRSISClient::enqueueThirdParty(QString theircall, QString payload){
void APRSISClient::enqueueSpot(QString by_call, QString from_call, QString grid, QString comment){
if(!isPasscodeValid()){
return;
}
auto frame = QString("%1>APRS,%2,TCPIP*:%3\n");
frame = frame.arg(theircall);
frame = frame.arg(stripSSID(m_localCall));
frame = frame.arg(payload);
auto geo = APRSISClient::grid2aprs(grid);
auto spotFrame = QString("%1>APJ8CL,qAS,%2:=%3/%4G#JS8 %5\n");
spotFrame = spotFrame.arg(from_call);
spotFrame = spotFrame.arg(by_call);
spotFrame = spotFrame.arg(geo.first);
spotFrame = spotFrame.arg(geo.second);
spotFrame = spotFrame.arg(comment.left(42));
enqueueRaw(spotFrame);
}
void APRSISClient::enqueueThirdParty(QString by_call, QString from_call, QString text){
if(!isPasscodeValid()){
return;
}
auto frame = QString("%1>APJ8CL,qAS,%2:%3\n");
frame = frame.arg(from_call);
frame = frame.arg(by_call);
frame = frame.arg(text);
enqueueRaw(frame);
}

View File

@ -35,16 +35,15 @@ public:
m_paused = paused;
}
void setLocalStation(QString mycall, QString mygrid, QString passcode){
void setLocalStation(QString mycall, QString passcode){
m_localCall = mycall;
m_localGrid = mygrid;
m_localPasscode = passcode;
}
bool isPasscodeValid(){ return m_localPasscode == QString::number(hashCallsign(m_localCall)); }
void enqueueSpot(QString theircall, QString grid, QString comment);
void enqueueThirdParty(QString theircall, QString payload);
void enqueueSpot(QString by_call, QString from_call, QString grid, QString comment);
void enqueueThirdParty(QString by_call, QString from_call, QString text);
void enqueueRaw(QString aprsFrame);
void processQueue(bool disconnect=true);
@ -58,7 +57,6 @@ public slots:
private:
QString m_localCall;
QString m_localGrid;
QString m_localPasscode;
QQueue<QPair<QString, QDateTime>> m_frameQueue;

View File

@ -678,7 +678,6 @@ private:
QString opCall_;
QString ptt_command_;
QString aprs_server_name_;
QString aprs_passcode_;
port_type aprs_server_port_;
QString udp_server_name_;
@ -859,7 +858,6 @@ QString Configuration::opCall() const {return m_->opCall_;}
QString Configuration::ptt_command() const { return m_->ptt_command_.trimmed();}
QString Configuration::aprs_server_name () const {return m_->aprs_server_name_;}
auto Configuration::aprs_server_port () const -> port_type {return m_->aprs_server_port_;}
QString Configuration::aprs_passcode() const { return m_->aprs_passcode_; }
QString Configuration::udp_server_name () const {return m_->udp_server_name_;}
auto Configuration::udp_server_port () const -> port_type {return m_->udp_server_port_;}
bool Configuration::accept_udp_requests () const {return m_->accept_udp_requests_;}
@ -1609,7 +1607,6 @@ void Configuration::impl::initialize_models ()
ui_->ptt_command_line_edit->setText(ptt_command_);
ui_->aprs_server_line_edit->setText (aprs_server_name_);
ui_->aprs_server_port_spin_box->setValue (aprs_server_port_);
ui_->aprs_passcode_line_edit->setText(aprs_passcode_);
ui_->udp_server_line_edit->setText (udp_server_name_);
ui_->udp_server_port_spin_box->setValue (udp_server_port_);
ui_->accept_udp_requests_check_box->setChecked (accept_udp_requests_);
@ -2060,7 +2057,6 @@ void Configuration::impl::read_settings ()
ptt_command_ = settings_->value("PTTCommand", "").toString();
aprs_server_name_ = settings_->value ("aprsServer", "rotate.aprs2.net").toString ();
aprs_server_port_ = settings_->value ("aprsServerPort", 14580).toUInt ();
aprs_passcode_ = settings_->value ("aprsPasscode", "").toString();
udp_server_name_ = settings_->value ("UDPServer", "127.0.0.1").toString ();
udp_server_port_ = settings_->value ("UDPServerPort", 2242).toUInt ();
n3fjp_server_name_ = settings_->value ("N3FJPServer", "127.0.0.1").toString ();
@ -2246,7 +2242,6 @@ void Configuration::impl::write_settings ()
settings_->setValue ("PTTCommand", ptt_command_);
settings_->setValue ("aprsServer", aprs_server_name_);
settings_->setValue ("aprsServerPort", aprs_server_port_);
settings_->setValue ("aprsPasscode", aprs_passcode_);
settings_->setValue ("UDPServer", udp_server_name_);
settings_->setValue ("UDPServerPort", udp_server_port_);
settings_->setValue ("N3FJPServer", n3fjp_server_name_);
@ -2861,7 +2856,6 @@ void Configuration::impl::accept ()
ptt_command_ = ui_->ptt_command_line_edit->text();
aprs_server_name_ = ui_->aprs_server_line_edit->text();
aprs_server_port_ = ui_->aprs_server_port_spin_box->value();
aprs_passcode_ = ui_->aprs_passcode_line_edit->text();
auto newUdpEnabled = ui_->udpEnable->isChecked();
auto new_server = ui_->udp_server_line_edit->text ();

View File

@ -185,7 +185,6 @@ public:
QString ptt_command() const;
QString aprs_server_name () const;
port_type aprs_server_port () const;
QString aprs_passcode () const;
QString udp_server_name () const;
port_type udp_server_port () const;
QString n1mm_server_name () const;

View File

@ -315,7 +315,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>724</width>
<width>615</width>
<height>537</height>
</rect>
</property>
@ -837,8 +837,8 @@ text message.</string>
<rect>
<x>0</x>
<y>0</y>
<width>738</width>
<height>461</height>
<width>674</width>
<height>360</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_16">
@ -876,7 +876,9 @@ text message.</string>
</item>
<item>
<widget class="QCheckBox" name="heartbeat_ack_snr_check_box">
<property name="visible"><bool>false</bool></property>
<property name="visible">
<bool>false</bool>
</property>
<property name="text">
<string>Send SNR report when acknowledging heartbeats</string>
</property>
@ -2366,9 +2368,9 @@ both here.</string>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<y>-60</y>
<width>746</width>
<height>567</height>
<height>682</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_30">
@ -2616,7 +2618,7 @@ This is used for reverse ping analysis which is very useful
for assessing propagation and system performance.</string>
</property>
<property name="text">
<string>Enable spotting to reporting networks (JS8NET, PSKReporter, etc)</string>
<string>Enable spotting to reporting networks (JS8NET, APRSIS, PSKReporter, etc)</string>
</property>
<property name="checked">
<bool>true</bool>
@ -2626,6 +2628,77 @@ for assessing propagation and system performance.</string>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_8">
<property name="title">
<string>APRSIS Spotting</string>
</property>
<layout class="QFormLayout" name="formLayout_18">
<item row="0" column="0">
<layout class="QFormLayout" name="formLayout_17">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="udp_server_label_2">
<property name="text">
<string>APRS Server:</string>
</property>
<property name="buddy">
<cstring>udp_server_line_edit</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="aprs_server_line_edit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Optional hostname of APRS server to send spots to.&lt;/p&gt;&lt;p&gt;Formats:&lt;/p&gt;&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;hostname&lt;/li&gt;&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;IPv4 address&lt;/li&gt;&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;IPv6 address&lt;/li&gt;&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;IPv4 multicast group address&lt;/li&gt;&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;IPv6 multicast group address&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Clearing this field will disable the spotting to APRS.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="inputMethodHints">
<set>Qt::ImhDigitsOnly</set>
</property>
<property name="text">
<string>rotate.aprs2.net</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>APRS Server Port:</string>
</property>
<property name="buddy">
<cstring>udp_server_port_spin_box</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="aprs_server_port_spin_box">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enter the service port number of the APRS server that should receive updates. If this is zero no updates will be broadcast.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>65534</number>
</property>
<property name="value">
<number>14580</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_11">
<property name="title">
@ -2736,9 +2809,6 @@ for assessing propagation and system performance.</string>
<height>0</height>
</size>
</property>
<property name="visible">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_36">
<property name="spacing">
<number>0</number>
@ -2755,81 +2825,6 @@ for assessing propagation and system performance.</string>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QFormLayout" name="formLayout_17">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="udp_server_label_2">
<property name="text">
<string>APRS Server:</string>
</property>
<property name="buddy">
<cstring>udp_server_line_edit</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="aprs_server_line_edit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Optional hostname of APRS server to send spots to.&lt;/p&gt;&lt;p&gt;Formats:&lt;/p&gt;&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;hostname&lt;/li&gt;&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;IPv4 address&lt;/li&gt;&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;IPv6 address&lt;/li&gt;&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;IPv4 multicast group address&lt;/li&gt;&lt;li style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;IPv6 multicast group address&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Clearing this field will disable the spotting to APRS.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="inputMethodHints">
<set>Qt::ImhDigitsOnly</set>
</property>
<property name="text">
<string>rotate.aprs2.net</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>APRS Server Port:</string>
</property>
<property name="buddy">
<cstring>udp_server_port_spin_box</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="aprs_server_port_spin_box">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enter the service port number of the APRS server that should receive updates. If this is zero no updates will be broadcast.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>65534</number>
</property>
<property name="value">
<number>14580</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_16">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;APRS Server Passcode for Sending APRS Packets&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>APRS Passcode:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="aprs_passcode_line_edit"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
@ -4516,7 +4511,6 @@ soundcard changes</string>
<tabstop>psk_reporter_check_box</tabstop>
<tabstop>aprs_server_line_edit</tabstop>
<tabstop>aprs_server_port_spin_box</tabstop>
<tabstop>aprs_passcode_line_edit</tabstop>
<tabstop>enable_n3fjp_broadcast_check_box</tabstop>
<tabstop>n3fjp_server_name_line_edit</tabstop>
<tabstop>n3fjp_server_port_spin_box</tabstop>

View File

@ -91,7 +91,8 @@ SOURCES += \
WaveUtils.cpp \
ProcessThread.cpp \
DecoderThread.cpp \
Decoder.cpp
Decoder.cpp \
APRSISClient.cpp
HEADERS += qt_helpers.hpp \
pimpl_h.hpp pimpl_impl.hpp \
@ -133,7 +134,8 @@ HEADERS += qt_helpers.hpp \
WaveUtils.h \
ProcessThread.h \
DecoderThread.h \
Decoder.h
Decoder.h \
APRSISClient.h
INCLUDEPATH += qmake_only

View File

@ -437,6 +437,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
this}},
m_n3fjpClient { new TCPClient{this}},
m_spotClient { new SpotClient{m_messageClient, this}},
m_aprsClient {new APRSISClient{"rotate.aprs2.net", 14580, this}},
psk_Reporter {new PSK_Reporter {m_messageClient, this}},
m_i3bit {0},
m_manual {&m_network_manager},
@ -3154,8 +3155,12 @@ void MainWindow::prepareSpotting(){
if(m_config.spot_to_reporting_networks ()){
spotSetLocal();
pskSetLocal();
aprsSetLocal();
m_aprsClient->setServer(m_config.aprs_server_name(), m_config.aprs_server_port());
m_aprsClient->setPaused(false);
ui->spotButton->setChecked(true);
} else {
m_aprsClient->setPaused(true);
ui->spotButton->setChecked(false);
}
}
@ -5224,6 +5229,37 @@ void MainWindow::spotCmd(CommandDetail cmd){
m_spotClient->enqueueCmd(cmdStr, cmd.from, cmd.to, cmd.relayPath, cmd.text, cmd.grid, cmd.extra, cmd.submode, m_freqNominal + cmd.freq, cmd.snr);
}
// KN4CRD: @APRSIS CMD :EMAIL-2 :email@domain.com booya{1
void MainWindow::spotAprsCmd(CommandDetail cmd){
if(!m_config.spot_to_reporting_networks()) return;
if(cmd.cmd != " CMD") return;
qDebug() << "APRSISClient Enqueueing Third Party Text" << cmd.from << cmd.text;
auto by_call = Radio::base_callsign(m_config.my_callsign());
auto from_call = Radio::base_callsign(cmd.from);
m_aprsClient->enqueueThirdParty(by_call, from_call, cmd.text);
}
void MainWindow::spotAprsGrid(int offset, int snr, QString callsign, QString grid){
if(!m_config.spot_to_reporting_networks()) return;
if(grid.length() < 4) return;
Frequency frequency = m_freqNominal + offset;
auto comment = QString("%1MHz %2dB").arg(Radio::frequency_MHz_string(frequency)).arg(Varicode::formatSNR(snr));
if(callsign.contains("/")){
comment = QString("%1 %2").arg(callsign).arg(comment);
}
auto by_call = Radio::base_callsign(m_config.my_callsign());
auto from_call = Radio::base_callsign(callsign);
m_aprsClient->enqueueSpot(by_call, from_call, grid, comment);
}
void MainWindow::pskLogReport(QString mode, int offset, int snr, QString callsign, QString grid){
if(!m_config.spot_to_reporting_networks()) return;
@ -7851,6 +7887,8 @@ void MainWindow::band_changed (Frequency f)
m_bandEdited = false;
psk_Reporter->sendReport(); // Upload any queued spots before changing band
m_aprsClient->sendReports();
if (!m_transmitting) monitor (true);
if ("FreqCal" == m_mode)
{
@ -9526,6 +9564,7 @@ void MainWindow::handle_transceiver_update (Transceiver::TransceiverState const&
if (m_config.spot_to_reporting_networks ()) {
spotSetLocal();
pskSetLocal();
aprsSetLocal();
}
statusChanged();
m_wideGraph->setDialFreq(m_freqNominal / 1.e6);
@ -9690,6 +9729,11 @@ void MainWindow::pskSetLocal ()
psk_Reporter->setLocalStation(m_config.my_callsign (), m_config.my_grid (), info, QString {"JS8Call v" + version() }.simplified ());
}
void MainWindow::aprsSetLocal ()
{
m_aprsClient->setLocalStation("APJ8CL", QString::number(APRSISClient::hashCallsign("APJ8CL")));
}
void MainWindow::transmitDisplay (bool transmitting)
{
ui->monitorTxButton->setChecked(transmitting);
@ -10839,6 +10883,11 @@ void MainWindow::processCommandActivity() {
cd.tdrift = d.tdrift;
cd.submode = d.submode;
// PROCESS GRID SPOTS TO APRSIS FOR EVERYONE
if(d.to == "@APRSIS"){
spotAprsGrid(cd.freq, cd.snr, cd.call, cd.grid);
}
logCallActivity(cd, true);
}
}
@ -10848,6 +10897,11 @@ void MainWindow::processCommandActivity() {
spotCmd(d);
}
// PROCESS @APRSIS CMD SPOTS FOR EVERYONE
if (d.to == "@APRSIS"){
spotAprsCmd(d);
}
// PREPARE CMD TEXT STRING
QStringList textList = {
QString("%1: %2%3").arg(d.from).arg(d.to).arg(d.cmd)

View File

@ -46,6 +46,7 @@
#include "MessageClient.hpp"
#include "TCPClient.h"
#include "SpotClient.h"
#include "APRSISClient.h"
#include "keyeater.h"
#include "NotificationAudio.h"
#include "ProcessThread.h"
@ -922,6 +923,7 @@ private:
TCPClient * m_n3fjpClient;
PSK_Reporter *psk_Reporter;
SpotClient *m_spotClient;
APRSISClient *m_aprsClient;
DisplayManual m_manual;
QHash<QString, QVariant> m_pwrBandTxMemory; // Remembers power level by band
QHash<QString, QVariant> m_pwrBandTuneMemory; // Remembers power level by band for tuning
@ -955,9 +957,12 @@ private:
void rigFailure (QString const& reason);
void spotSetLocal();
void pskSetLocal ();
void aprsSetLocal ();
void spotReport(int submode, int offset, int snr, QString callsign, QString grid);
void spotCmd(CommandDetail cmd);
void spotAprsCmd(CommandDetail cmd);
void pskLogReport(QString mode, int offset, int snr, QString callsign, QString grid);
void spotAprsGrid(int offset, int snr, QString callsign, QString grid);
Radio::Frequency dialFrequency();
void setSubmode(int submode);
int submodeNameToSubmode(QString speed);