Rename beacon to heartbean with pings and ping acks
This commit is contained in:
parent
41fb7481ed
commit
cac5f798a3
@ -628,7 +628,7 @@ private:
|
||||
bool spot_to_reporting_networks_;
|
||||
bool transmit_directed_;
|
||||
bool autoreply_off_at_startup_;
|
||||
bool beacon_anywhere_;
|
||||
bool ping_anywhere_;
|
||||
bool relay_disabled_;
|
||||
bool monitor_off_at_startup_;
|
||||
bool monitor_last_used_;
|
||||
@ -642,7 +642,7 @@ private:
|
||||
bool miles_;
|
||||
bool quick_call_;
|
||||
bool disable_TX_on_73_;
|
||||
int beacon_;
|
||||
int ping_;
|
||||
int watchdog_;
|
||||
bool TX_messages_;
|
||||
bool enable_VHF_features_;
|
||||
@ -759,7 +759,7 @@ void Configuration::set_spot_to_reporting_networks (bool spot)
|
||||
|
||||
bool Configuration::transmit_directed() const { return m_->transmit_directed_; }
|
||||
bool Configuration::autoreply_off_at_startup () const {return m_->autoreply_off_at_startup_;}
|
||||
bool Configuration::beacon_anywhere() const { return m_->beacon_anywhere_;}
|
||||
bool Configuration::ping_anywhere() const { return m_->ping_anywhere_;}
|
||||
bool Configuration::relay_off() const { return m_->relay_disabled_; }
|
||||
bool Configuration::monitor_off_at_startup () const {return m_->monitor_off_at_startup_;}
|
||||
bool Configuration::monitor_last_used () const {return m_->rig_is_dummy_ || m_->monitor_last_used_;}
|
||||
@ -773,7 +773,7 @@ bool Configuration::clear_DX () const {return m_->clear_DX_;}
|
||||
bool Configuration::miles () const {return m_->miles_;}
|
||||
bool Configuration::quick_call () const {return m_->quick_call_;}
|
||||
bool Configuration::disable_TX_on_73 () const {return m_->disable_TX_on_73_;}
|
||||
int Configuration::beacon () const {return m_->beacon_;}
|
||||
int Configuration::ping () const {return m_->ping_;}
|
||||
int Configuration::watchdog () const {return m_->watchdog_;}
|
||||
bool Configuration::TX_messages () const {return m_->TX_messages_;}
|
||||
bool Configuration::enable_VHF_features () const {return m_->enable_VHF_features_;}
|
||||
@ -1338,7 +1338,7 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->psk_reporter_check_box->setChecked (spot_to_reporting_networks_);
|
||||
ui_->transmit_directed_check_box->setChecked(transmit_directed_);
|
||||
ui_->autoreply_off_check_box->setChecked (autoreply_off_at_startup_);
|
||||
ui_->beacon_anywhere_check_box->setChecked(beacon_anywhere_);
|
||||
ui_->ping_anywhere_check_box->setChecked(ping_anywhere_);
|
||||
ui_->relay_disabled_check_box->setChecked(relay_disabled_);
|
||||
ui_->monitor_off_check_box->setChecked (monitor_off_at_startup_);
|
||||
ui_->monitor_last_used_check_box->setChecked (monitor_last_used_);
|
||||
@ -1350,7 +1350,7 @@ void Configuration::impl::initialize_models ()
|
||||
ui_->miles_check_box->setChecked (miles_);
|
||||
ui_->quick_call_check_box->setChecked (quick_call_);
|
||||
ui_->disable_TX_on_73_check_box->setChecked (disable_TX_on_73_);
|
||||
ui_->beacon_spin_box->setValue (beacon_);
|
||||
ui_->ping_spin_box->setValue (ping_);
|
||||
ui_->tx_watchdog_spin_box->setValue (watchdog_);
|
||||
ui_->enable_VHF_features_check_box->setChecked(enable_VHF_features_);
|
||||
ui_->decode_at_52s_check_box->setChecked(decode_at_52s_);
|
||||
@ -1596,7 +1596,7 @@ void Configuration::impl::read_settings ()
|
||||
|
||||
transmit_directed_ = settings_->value ("TransmitDirected", true).toBool();
|
||||
autoreply_off_at_startup_ = settings_->value ("AutoreplyOFF", false).toBool ();
|
||||
beacon_anywhere_ = settings_->value("BeaconAnywhere", false).toBool();
|
||||
ping_anywhere_ = settings_->value("BeaconAnywhere", false).toBool();
|
||||
relay_disabled_ = settings_->value ("RelayOFF", false).toBool ();
|
||||
monitor_off_at_startup_ = settings_->value ("MonitorOFF", false).toBool ();
|
||||
monitor_last_used_ = settings_->value ("MonitorLastUsed", false).toBool ();
|
||||
@ -1657,7 +1657,7 @@ void Configuration::impl::read_settings ()
|
||||
miles_ = settings_->value ("Miles", false).toBool ();
|
||||
quick_call_ = settings_->value ("QuickCall", false).toBool ();
|
||||
disable_TX_on_73_ = settings_->value ("73TxDisable", false).toBool ();
|
||||
beacon_ = settings_->value ("TxBeacon", 30).toInt ();
|
||||
ping_ = settings_->value ("TxBeacon", 30).toInt ();
|
||||
watchdog_ = settings_->value ("TxIdleWatchdog", 60).toInt ();
|
||||
if(watchdog_){
|
||||
watchdog_ = qMax(5, watchdog_);
|
||||
@ -1762,7 +1762,7 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("Type2MsgGen", QVariant::fromValue (type_2_msg_gen_));
|
||||
settings_->setValue ("TransmitDirected", transmit_directed_);
|
||||
settings_->setValue ("AutoreplyOFF", autoreply_off_at_startup_);
|
||||
settings_->setValue ("BeaconAnywhere", beacon_anywhere_);
|
||||
settings_->setValue ("BeaconAnywhere", ping_anywhere_);
|
||||
settings_->setValue ("RelayOFF", relay_disabled_);
|
||||
settings_->setValue ("MonitorOFF", monitor_off_at_startup_);
|
||||
settings_->setValue ("MonitorLastUsed", monitor_last_used_);
|
||||
@ -1791,7 +1791,7 @@ void Configuration::impl::write_settings ()
|
||||
settings_->setValue ("Miles", miles_);
|
||||
settings_->setValue ("QuickCall", quick_call_);
|
||||
settings_->setValue ("73TxDisable", disable_TX_on_73_);
|
||||
settings_->setValue ("TxBeacon", beacon_);
|
||||
settings_->setValue ("TxBeacon", ping_);
|
||||
settings_->setValue ("TxIdleWatchdog", watchdog_);
|
||||
settings_->setValue ("Tx2QSO", TX_messages_);
|
||||
settings_->setValue ("CATForceDTR", rig_params_.force_dtr);
|
||||
@ -2260,7 +2260,7 @@ void Configuration::impl::accept ()
|
||||
tx_qsy_allowed_ = ui_->tx_qsy_check_box->isChecked ();
|
||||
transmit_directed_ = ui_->transmit_directed_check_box->isChecked();
|
||||
autoreply_off_at_startup_ = ui_->autoreply_off_check_box->isChecked ();
|
||||
beacon_anywhere_ = ui_->beacon_anywhere_check_box->isChecked();
|
||||
ping_anywhere_ = ui_->ping_anywhere_check_box->isChecked();
|
||||
relay_disabled_ = ui_->relay_disabled_check_box->isChecked();
|
||||
monitor_off_at_startup_ = ui_->monitor_off_check_box->isChecked ();
|
||||
monitor_last_used_ = ui_->monitor_last_used_check_box->isChecked ();
|
||||
@ -2272,7 +2272,7 @@ void Configuration::impl::accept ()
|
||||
miles_ = ui_->miles_check_box->isChecked ();
|
||||
quick_call_ = ui_->quick_call_check_box->isChecked ();
|
||||
disable_TX_on_73_ = ui_->disable_TX_on_73_check_box->isChecked ();
|
||||
beacon_ = ui_->beacon_spin_box->value ();
|
||||
ping_ = ui_->ping_spin_box->value ();
|
||||
watchdog_ = ui_->tx_watchdog_spin_box->value ();
|
||||
data_mode_ = static_cast<DataMode> (ui_->TX_mode_button_group->checkedId ());
|
||||
save_directory_ = ui_->save_path_display_label->text ();
|
||||
|
@ -121,7 +121,7 @@ public:
|
||||
void set_spot_to_reporting_networks (bool);
|
||||
bool transmit_directed() const;
|
||||
bool autoreply_off_at_startup () const;
|
||||
bool beacon_anywhere() const;
|
||||
bool ping_anywhere() const;
|
||||
bool relay_off() const;
|
||||
bool monitor_off_at_startup () const;
|
||||
bool monitor_last_used () const;
|
||||
@ -135,7 +135,7 @@ public:
|
||||
bool miles () const;
|
||||
bool quick_call () const;
|
||||
bool disable_TX_on_73 () const;
|
||||
int beacon () const;
|
||||
int ping () const;
|
||||
int watchdog () const;
|
||||
bool TX_messages () const;
|
||||
bool split_mode () const;
|
||||
|
1236
Configuration.ui
1236
Configuration.ui
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
|
||||
, message_ {string_.mid (column_qsoText + padding_).trimmed ()}
|
||||
, is_standard_ {false}
|
||||
, frameType_(Varicode::FrameUnknown)
|
||||
, isBeacon_(false)
|
||||
, isHeartbeat_(false)
|
||||
, isAlt_(false)
|
||||
{
|
||||
if(message_.length() >= 1) {
|
||||
@ -51,7 +51,7 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
|
||||
grid_c_string += QByteArray {6 - grid_c_string.size (), ' '};
|
||||
is_standard_ = stdmsg_ (message_c_string.constData (), contest_mode_, grid_c_string.constData (), 22, 6);
|
||||
|
||||
// We're only going to unpack standard messages for CQs && beacons...
|
||||
// We're only going to unpack standard messages for CQs && pings...
|
||||
// TODO: jsherer - this is a hack for now...
|
||||
if(is_standard_){
|
||||
is_standard_ = QRegularExpression("^(CQ|DE|QRZ)\\s").match(message_).hasMatch();
|
||||
@ -64,7 +64,7 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
|
||||
DecodedText::DecodedText (QString const& js8callmessage):
|
||||
frameType_(Varicode::FrameUnknown),
|
||||
message_(js8callmessage),
|
||||
isBeacon_(false),
|
||||
isHeartbeat_(false),
|
||||
isAlt_(false)
|
||||
{
|
||||
is_standard_ = QRegularExpression("^(CQ|DE|QRZ)\\s").match(message_).hasMatch();
|
||||
@ -80,7 +80,7 @@ bool DecodedText::tryUnpack(){
|
||||
|
||||
bool unpacked = false;
|
||||
if(!unpacked){
|
||||
unpacked = tryUnpackBeacon();
|
||||
unpacked = tryUnpackHeartbeat();
|
||||
}
|
||||
|
||||
if(!unpacked){
|
||||
@ -98,7 +98,7 @@ bool DecodedText::tryUnpack(){
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
bool DecodedText::tryUnpackBeacon(){
|
||||
bool DecodedText::tryUnpackHeartbeat(){
|
||||
QString m = message().trimmed();
|
||||
|
||||
// directed calls will always be 12+ chars and contain no spaces.
|
||||
@ -109,17 +109,17 @@ bool DecodedText::tryUnpackBeacon(){
|
||||
bool isAlt = false;
|
||||
quint8 type = Varicode::FrameUnknown;
|
||||
quint8 bits3 = 0;
|
||||
QStringList parts = Varicode::unpackBeaconMessage(m, &type, &isAlt, &bits3);
|
||||
QStringList parts = Varicode::unpackHeartbeatMessage(m, &type, &isAlt, &bits3);
|
||||
|
||||
if(parts.isEmpty() || parts.length() < 2){
|
||||
return false;
|
||||
}
|
||||
|
||||
// Beacon Alt Type
|
||||
// Heartbeat Alt Type
|
||||
// ---------------
|
||||
// 1 0 BCN
|
||||
// 1 1 CQ
|
||||
isBeacon_ = true;
|
||||
isHeartbeat_ = true;
|
||||
isAlt_ = isAlt;
|
||||
extra_ = parts.length() < 3 ? "" : parts.at(2);
|
||||
|
||||
@ -131,7 +131,7 @@ bool DecodedText::tryUnpackBeacon(){
|
||||
cmp.append(parts.at(1));
|
||||
}
|
||||
compound_ = cmp.join("/");
|
||||
message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? Varicode::cqString(bits3) : "BEACON").arg(extra_);
|
||||
message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? Varicode::cqString(bits3) : "PING").arg(extra_);
|
||||
frameType_ = type;
|
||||
return true;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
explicit DecodedText (QString const& js8callmessage);
|
||||
|
||||
bool tryUnpack();
|
||||
bool tryUnpackBeacon();
|
||||
bool tryUnpackHeartbeat();
|
||||
bool tryUnpackCompound();
|
||||
bool tryUnpackDirected();
|
||||
bool tryUnpackData();
|
||||
@ -45,7 +45,7 @@ public:
|
||||
QString compoundCall() const { return compound_; }
|
||||
bool isCompound() const { return !compound_.isEmpty(); }
|
||||
|
||||
bool isBeacon() const { return isBeacon_; }
|
||||
bool isHeartbeat() const { return isHeartbeat_; }
|
||||
bool isAlt() const { return isAlt_; }
|
||||
|
||||
QStringList directedMessage() const { return directed_; }
|
||||
@ -99,7 +99,7 @@ private:
|
||||
column_qsoText = 22 };
|
||||
|
||||
quint8 frameType_;
|
||||
bool isBeacon_;
|
||||
bool isHeartbeat_;
|
||||
bool isAlt_;
|
||||
QString compound_;
|
||||
QString extra_;
|
||||
|
194
mainwindow.cpp
194
mainwindow.cpp
@ -872,8 +872,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
TxAgainTimer.setSingleShot(true);
|
||||
connect(&TxAgainTimer, SIGNAL(timeout()), this, SLOT(TxAgain()));
|
||||
|
||||
beaconTimer.setSingleShot(false);
|
||||
connect(&beaconTimer, &QTimer::timeout, this, &MainWindow::checkBeacon);
|
||||
heartbeatTimer.setSingleShot(false);
|
||||
connect(&heartbeatTimer, &QTimer::timeout, this, &MainWindow::checkHeartbeat);
|
||||
|
||||
connect(m_wideGraph.data (), SIGNAL(setFreq3(int,int)),this,
|
||||
SLOT(setFreq4(int,int)));
|
||||
@ -1372,22 +1372,22 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
p.setColor(QPalette::Inactive, QPalette::Highlight, p.color(QPalette::Active, QPalette::Highlight));
|
||||
ui->tableWidgetCalls->setPalette(p);
|
||||
|
||||
// Don't block beacon's first run...
|
||||
// Don't block ping's first run...
|
||||
m_lastTxTime = DriftingDateTime::currentDateTimeUtc().addSecs(-300);
|
||||
|
||||
|
||||
auto beaconNow = new QAction(QString("Beacon Now"), ui->beaconButton);
|
||||
connect(beaconNow, &QAction::triggered, this, [this](){
|
||||
auto heartbeatNow = new QAction(QString("Send Heartbeat Now"), ui->heartbeatButton);
|
||||
connect(heartbeatNow, &QAction::triggered, this, [this](){
|
||||
if(m_transmitting){
|
||||
return;
|
||||
}
|
||||
if(!ui->beaconButton->isChecked()){
|
||||
ui->beaconButton->setChecked(true);
|
||||
if(!ui->heartbeatButton->isChecked()){
|
||||
ui->heartbeatButton->setChecked(true);
|
||||
}
|
||||
scheduleBeacon(true);
|
||||
scheduleHeartbeat(true);
|
||||
});
|
||||
ui->beaconButton->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
ui->beaconButton->addAction(beaconNow);
|
||||
ui->heartbeatButton->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
ui->heartbeatButton->addAction(heartbeatNow);
|
||||
|
||||
pskSetLocal();
|
||||
aprsSetLocal();
|
||||
@ -3634,18 +3634,18 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
|
||||
// Process compound callsign commands (put them in cache)"
|
||||
#if 1
|
||||
qDebug() << "decoded" << decodedtext.frameType() << decodedtext.isCompound() << decodedtext.isDirectedMessage() << decodedtext.isBeacon();
|
||||
qDebug() << "decoded" << decodedtext.frameType() << decodedtext.isCompound() << decodedtext.isDirectedMessage() << decodedtext.isHeartbeat();
|
||||
bool shouldProcessCompound = true;
|
||||
if(shouldProcessCompound && decodedtext.isCompound() && !decodedtext.isDirectedMessage()){
|
||||
cd.call = decodedtext.compoundCall();
|
||||
cd.grid = decodedtext.extra(); // compound calls via beacons may contain grid...
|
||||
cd.grid = decodedtext.extra(); // compound calls via pings may contain grid...
|
||||
cd.snr = decodedtext.snr();
|
||||
cd.freq = decodedtext.frequencyOffset();
|
||||
cd.utcTimestamp = DriftingDateTime::currentDateTimeUtc();
|
||||
cd.bits = decodedtext.bits();
|
||||
|
||||
// Only respond to BEACONS...remember that CQ messages are "Alt" beacons
|
||||
if(decodedtext.isBeacon()){
|
||||
// Only respond to PINGS...remember that CQ messages are "Alt" pings
|
||||
if(decodedtext.isHeartbeat()){
|
||||
if(decodedtext.isAlt()){
|
||||
|
||||
// this is a cq with a compound call, ala "KN4CRD/P: CQCQCQ"
|
||||
@ -3653,10 +3653,10 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
logCallActivity(cd, true);
|
||||
|
||||
} else {
|
||||
// convert BEACON to a directed command and process...
|
||||
// convert PING to a directed command and process...
|
||||
cmd.from = cd.call;
|
||||
cmd.to = "@ALLCALL";
|
||||
cmd.cmd = " BEACON";
|
||||
cmd.cmd = " PING";
|
||||
cmd.snr = cd.snr;
|
||||
cmd.bits = cd.bits;
|
||||
cmd.grid = cd.grid;
|
||||
@ -4357,9 +4357,9 @@ void MainWindow::guiUpdate()
|
||||
t.time().toString() + (!drift ? " " : QString(" (%1%2ms)").arg(drift > 0 ? "+" : "").arg(drift));
|
||||
ui->labUTC->setText(utc);
|
||||
|
||||
auto delta = t.secsTo(m_nextBeacon);
|
||||
auto beacon = ui->beaconButton->isChecked() ? delta > 0 ? QString("%1 s").arg(delta) : "queued!" : m_nextBeaconPaused ? "paused" : "disabled";
|
||||
ui->labBeacon->setText(QString("Next Beacon: %1").arg(beacon));
|
||||
auto delta = t.secsTo(m_nextHeartbeat);
|
||||
auto ping = ui->heartbeatButton->isChecked() ? delta > 0 ? QString("%1 s").arg(delta) : "queued!" : m_nextHeartPaused ? "paused" : "disabled";
|
||||
ui->labHeartbeat->setText(QString("Next Heartbeat: %1").arg(ping));
|
||||
|
||||
auto callLabel = m_config.my_callsign();
|
||||
if(m_config.use_dynamic_grid() && !m_config.my_grid().isEmpty()){
|
||||
@ -4946,7 +4946,7 @@ void MainWindow::restoreActivity(QString key){
|
||||
void MainWindow::clearActivity(){
|
||||
m_bandActivity.clear();
|
||||
m_callActivity.clear();
|
||||
m_callSeenBeacon.clear();
|
||||
m_callSeenHeartbeat.clear();
|
||||
m_compoundCallCache.clear();
|
||||
m_rxCallCache.clear();
|
||||
m_rxCallQueue.clear();
|
||||
@ -5180,9 +5180,9 @@ void MainWindow::enqueueMessage(int priority, QString message, int freq, Callbac
|
||||
);
|
||||
}
|
||||
|
||||
void MainWindow::enqueueBeacon(QString message){
|
||||
m_txBeaconQueue.enqueue(message);
|
||||
scheduleBeacon(true);
|
||||
void MainWindow::enqueueHeartbeat(QString message){
|
||||
m_txHeartbeatQueue.enqueue(message);
|
||||
scheduleHeartbeat(true);
|
||||
}
|
||||
|
||||
void MainWindow::resetMessage(){
|
||||
@ -5406,9 +5406,9 @@ bool MainWindow::prepareNextMessageFrame()
|
||||
|
||||
updateTxButtonDisplay();
|
||||
|
||||
if(ui->beaconButton->isChecked()){
|
||||
// bump beacon
|
||||
scheduleBeacon(false);
|
||||
if(ui->heartbeatButton->isChecked()){
|
||||
// bump ping
|
||||
scheduleHeartbeat(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -5468,8 +5468,8 @@ int MainWindow::findFreeFreqOffset(int fmin, int fmax, int bw){
|
||||
return fmin;
|
||||
}
|
||||
|
||||
// scheduleBeacon
|
||||
void MainWindow::scheduleBeacon(bool first){
|
||||
// schedulePing
|
||||
void MainWindow::scheduleHeartbeat(bool first){
|
||||
auto timestamp = DriftingDateTime::currentDateTimeUtc();
|
||||
auto orig = timestamp;
|
||||
|
||||
@ -5480,7 +5480,7 @@ void MainWindow::scheduleBeacon(bool first){
|
||||
|
||||
// round to 15 second increment
|
||||
int secondsSinceEpoch = (timestamp.toMSecsSinceEpoch()/1000);
|
||||
int delta = roundUp(secondsSinceEpoch, 15) + 1 + (first ? 0 : qMax(1, m_config.beacon()) * 60) - secondsSinceEpoch;
|
||||
int delta = roundUp(secondsSinceEpoch, 15) + 1 + (first ? 0 : qMax(1, m_config.ping()) * 60) - secondsSinceEpoch;
|
||||
timestamp = timestamp.addSecs(delta);
|
||||
|
||||
// 25% of the time, switch intervals
|
||||
@ -5489,75 +5489,75 @@ void MainWindow::scheduleBeacon(bool first){
|
||||
timestamp = timestamp.addSecs(15);
|
||||
}
|
||||
|
||||
m_nextBeacon = timestamp;
|
||||
m_nextBeaconQueued = false;
|
||||
m_nextBeaconPaused = false;
|
||||
m_nextHeartbeat = timestamp;
|
||||
m_nextHeartbeatQueued = false;
|
||||
m_nextHeartPaused = false;
|
||||
|
||||
if(!beaconTimer.isActive()){
|
||||
beaconTimer.setInterval(1000);
|
||||
beaconTimer.start();
|
||||
if(!heartbeatTimer.isActive()){
|
||||
heartbeatTimer.setInterval(1000);
|
||||
heartbeatTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
// pauseBeacon
|
||||
void MainWindow::pauseBeacon(){
|
||||
ui->beaconButton->setChecked(false);
|
||||
m_nextBeaconPaused = true;
|
||||
// pausePing
|
||||
void MainWindow::pauseHeartbeat(){
|
||||
ui->heartbeatButton->setChecked(false);
|
||||
m_nextHeartPaused = true;
|
||||
|
||||
if(beaconTimer.isActive()){
|
||||
beaconTimer.stop();
|
||||
if(heartbeatTimer.isActive()){
|
||||
heartbeatTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
// checkBeacon
|
||||
void MainWindow::checkBeacon(){
|
||||
if(!ui->beaconButton->isChecked()){
|
||||
// checkPing
|
||||
void MainWindow::checkHeartbeat(){
|
||||
if(!ui->heartbeatButton->isChecked()){
|
||||
return;
|
||||
}
|
||||
auto secondsUntilBeacon = DriftingDateTime::currentDateTimeUtc().secsTo(m_nextBeacon);
|
||||
if(secondsUntilBeacon > 5 && m_txBeaconQueue.isEmpty()){
|
||||
auto secondsUntilHeartbeat = DriftingDateTime::currentDateTimeUtc().secsTo(m_nextHeartbeat);
|
||||
if(secondsUntilHeartbeat > 5 && m_txHeartbeatQueue.isEmpty()){
|
||||
return;
|
||||
}
|
||||
if(m_nextBeaconQueued){
|
||||
if(m_nextHeartbeatQueued){
|
||||
return;
|
||||
}
|
||||
if(m_tx_watchdog){
|
||||
return;
|
||||
}
|
||||
|
||||
prepareBeacon();
|
||||
prepareHeartbeat();
|
||||
}
|
||||
|
||||
// prepareBeacon
|
||||
void MainWindow::prepareBeacon(){
|
||||
// preparePing
|
||||
void MainWindow::prepareHeartbeat(){
|
||||
QStringList lines;
|
||||
|
||||
QString mycall = m_config.my_callsign();
|
||||
QString mygrid = m_config.my_grid().left(4);
|
||||
|
||||
// JS8Call Style
|
||||
if(m_txBeaconQueue.isEmpty()){
|
||||
lines.append(QString("%1: BEACON %2").arg(mycall).arg(mygrid));
|
||||
if(m_txHeartbeatQueue.isEmpty()){
|
||||
lines.append(QString("%1: PING %2").arg(mycall).arg(mygrid));
|
||||
} else {
|
||||
while(!m_txBeaconQueue.isEmpty() && lines.length() < 1){
|
||||
lines.append(m_txBeaconQueue.dequeue());
|
||||
while(!m_txHeartbeatQueue.isEmpty() && lines.length() < 1){
|
||||
lines.append(m_txHeartbeatQueue.dequeue());
|
||||
}
|
||||
}
|
||||
|
||||
// Choose a beacon frequency
|
||||
auto f = m_config.beacon_anywhere() ? -1 : findFreeFreqOffset(500, 1000, 50);
|
||||
// Choose a ping frequency
|
||||
auto f = m_config.ping_anywhere() ? -1 : findFreeFreqOffset(500, 1000, 50);
|
||||
|
||||
auto text = lines.join(QChar('\n'));
|
||||
if(text.isEmpty()){
|
||||
return;
|
||||
}
|
||||
|
||||
// Queue the beacon
|
||||
// Queue the ping
|
||||
enqueueMessage(PriorityLow, text, f, [this](){
|
||||
m_nextBeaconQueued = false;
|
||||
m_nextHeartbeatQueued = false;
|
||||
});
|
||||
|
||||
m_nextBeaconQueued = true;
|
||||
m_nextHeartbeatQueued = true;
|
||||
}
|
||||
|
||||
|
||||
@ -5642,7 +5642,7 @@ void MainWindow::on_logQSOButton_clicked() //Log QSO button
|
||||
auto dateTimeQSOOff = DriftingDateTime::currentDateTimeUtc();
|
||||
if (dateTimeQSOOff < m_dateTimeQSOOn) dateTimeQSOOff = m_dateTimeQSOOn;
|
||||
QString call=callsignSelected();
|
||||
if(call == "@ALLCALL"){
|
||||
if(call.startsWith("@")){
|
||||
call = "";
|
||||
}
|
||||
QString grid="";
|
||||
@ -6538,7 +6538,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
|
||||
addMessageText(QString("%1>[MESSAGE]").arg(selectedCall), true, true);
|
||||
});
|
||||
|
||||
auto qsoQueryAction = menu->addAction(QString("%1 BEACON REQ [CALLSIGN]? - Please acknowledge you can communicate directly with [CALLSIGN]").arg(call).trimmed());
|
||||
auto qsoQueryAction = menu->addAction(QString("%1 PING REQ [CALLSIGN]? - Please acknowledge you can communicate directly with [CALLSIGN]").arg(call).trimmed());
|
||||
connect(qsoQueryAction, &QAction::triggered, this, [this](){
|
||||
|
||||
QString selectedCall = callsignSelected();
|
||||
@ -6546,7 +6546,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
|
||||
return;
|
||||
}
|
||||
|
||||
addMessageText(QString("%1 BEACON REQ [CALLSIGN]?").arg(selectedCall), true, true);
|
||||
addMessageText(QString("%1 PING REQ [CALLSIGN]?").arg(selectedCall), true, true);
|
||||
});
|
||||
|
||||
menu->addSeparator();
|
||||
@ -7136,17 +7136,17 @@ void MainWindow::on_pbT2R_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_beaconButton_clicked()
|
||||
void MainWindow::on_heartbeatButton_clicked()
|
||||
{
|
||||
// clear the beacon queue when you toggle the button
|
||||
m_txBeaconQueue.clear();
|
||||
// clear the ping queue when you toggle the button
|
||||
m_txHeartbeatQueue.clear();
|
||||
displayBandActivity();
|
||||
|
||||
// then process the action
|
||||
if(ui->beaconButton->isChecked()){
|
||||
scheduleBeacon(false);
|
||||
if(ui->heartbeatButton->isChecked()){
|
||||
scheduleHeartbeat(false);
|
||||
} else {
|
||||
pauseBeacon();
|
||||
pauseHeartbeat();
|
||||
}
|
||||
}
|
||||
|
||||
@ -8212,7 +8212,7 @@ void MainWindow::processRxActivity() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(d.isDirected && d.text.contains("BEACON")){
|
||||
if(d.isDirected && d.text.contains(": PING")){
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -8466,15 +8466,13 @@ void MainWindow::processCommandActivity() {
|
||||
|
||||
auto now = DriftingDateTime::currentDateTimeUtc();
|
||||
|
||||
int freqOffset = currentFreqOffset();
|
||||
|
||||
while (!m_rxCommandQueue.isEmpty()) {
|
||||
auto d = m_rxCommandQueue.dequeue();
|
||||
|
||||
bool isAllCall = isAllCallIncluded(d.to);
|
||||
bool isGroupCall = isGroupCallIncluded(d.to);
|
||||
|
||||
qDebug() << "try processing command" << d.from << d.to << d.cmd << d.freq << d.grid << d.extra;
|
||||
qDebug() << "try processing command" << d.from << d.to << d.cmd << d.freq << d.grid << d.extra << isAllCall << isGroupCall;
|
||||
|
||||
// if we need a compound callsign but never got one...skip
|
||||
if (d.from == "<....>" || d.to == "<....>") {
|
||||
@ -8496,7 +8494,7 @@ void MainWindow::processCommandActivity() {
|
||||
cd.snr = d.snr;
|
||||
cd.freq = d.freq;
|
||||
cd.bits = d.bits;
|
||||
cd.ackTimestamp = d.text.contains("BEACON ACK") || toMe ? d.utcTimestamp : QDateTime{};
|
||||
cd.ackTimestamp = d.text.contains("PING ACK") || toMe ? d.utcTimestamp : QDateTime{};
|
||||
cd.utcTimestamp = d.utcTimestamp;
|
||||
logCallActivity(cd, true);
|
||||
|
||||
@ -8536,8 +8534,8 @@ void MainWindow::processCommandActivity() {
|
||||
// we'd be double printing here if were on frequency, so let's be "smart" about this...
|
||||
bool shouldDisplay = true;
|
||||
|
||||
// don't display beacon allcalls
|
||||
if(isAllCall && ad.text.contains("BEACON")){
|
||||
// don't display ping allcalls
|
||||
if(isAllCall && (ad.text.contains(": PING") || d.cmd == " PING")){
|
||||
shouldDisplay = false;
|
||||
}
|
||||
|
||||
@ -8546,9 +8544,9 @@ void MainWindow::processCommandActivity() {
|
||||
c.movePosition(QTextCursor::End);
|
||||
ui->textEditRX->setTextCursor(c);
|
||||
|
||||
// BEACON ACKs are the most likely source of items to be overwritten (multiple responses at once)...
|
||||
// ACKs are the most likely source of items to be overwritten (multiple responses at once)...
|
||||
// so don't overwrite those (i.e., print each on a new line)
|
||||
bool shouldOverwrite = (!d.cmd.contains("BEACON ACK")); /* && isRecentOffset(d.freq);*/
|
||||
bool shouldOverwrite = (!d.cmd.contains("PING ACK")); /* && isRecentOffset(d.freq);*/
|
||||
|
||||
if(shouldOverwrite && ui->textEditRX->find(d.utcTimestamp.time().toString(), QTextDocument::FindBackward)){
|
||||
// ... maybe we could delete the last line that had this message on this frequency...
|
||||
@ -8588,9 +8586,9 @@ void MainWindow::processCommandActivity() {
|
||||
writeDirectedCommandToFile(d);
|
||||
}
|
||||
|
||||
// if this is an allcall, check to make sure we haven't replied to their allcall recently (in the past beacon interval)
|
||||
// that way we never get spammed by allcalls at a higher frequency than what we would normally beacon
|
||||
if (isAllCall && m_txAllcallCommandCache.contains(d.from) && m_txAllcallCommandCache[d.from]->secsTo(now) / 60 < m_config.beacon()) {
|
||||
// if this is an allcall, check to make sure we haven't replied to their allcall recently (in the past ping interval)
|
||||
// that way we never get spammed by allcalls at a higher frequency than what we would normally ping
|
||||
if (isAllCall && m_txAllcallCommandCache.contains(d.from) && m_txAllcallCommandCache[d.from]->secsTo(now) / 60 < m_config.ping()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -8750,22 +8748,22 @@ void MainWindow::processCommandActivity() {
|
||||
reply = m_lastTxMessage;
|
||||
}
|
||||
|
||||
// PROCESS BEACON
|
||||
else if (d.cmd == " BEACON" && ui->beaconButton->isChecked()){
|
||||
reply = QString("%1 BEACON ACK %2").arg(d.from).arg(Varicode::formatSNR(d.snr));
|
||||
// PROCESS PING
|
||||
else if (d.cmd == " PING" && ui->heartbeatButton->isChecked()){
|
||||
reply = QString("%1 PING ACK %2").arg(d.from).arg(Varicode::formatSNR(d.snr));
|
||||
|
||||
enqueueBeacon(reply);
|
||||
enqueueHeartbeat(reply);
|
||||
|
||||
if(isAllCall){
|
||||
// since all beacons are technically @ALLCALL, let's bump the allcall cache here...
|
||||
// since all pings are technically @ALLCALL, let's bump the allcall cache here...
|
||||
m_txAllcallCommandCache.insert(d.from, new QDateTime(now), 5);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// PROCESS BUFFERED BEACON REQ QUERY
|
||||
else if (d.cmd == " BEACON REQ" && ui->beaconButton->isChecked()){
|
||||
// PROCESS BUFFERED PING REQ QUERY
|
||||
else if (d.cmd == " PING REQ" && ui->heartbeatButton->isChecked()){
|
||||
auto who = d.text;
|
||||
if(who.isEmpty()){
|
||||
continue;
|
||||
@ -8785,17 +8783,17 @@ void MainWindow::processCommandActivity() {
|
||||
}
|
||||
|
||||
if(baseCall == cd.call || baseCall == Radio::base_callsign(cd.call)){
|
||||
auto r = QString("%1 BEACON ACK %2").arg(cd.call).arg(Varicode::formatSNR(cd.snr));
|
||||
auto r = QString("%1 ACK %2").arg(cd.call).arg(Varicode::formatSNR(cd.snr));
|
||||
replies.append(r);
|
||||
}
|
||||
}
|
||||
reply = replies.join("\n");
|
||||
|
||||
if(!reply.isEmpty()){
|
||||
enqueueBeacon(reply);
|
||||
enqueueHeartbeat(reply);
|
||||
|
||||
if(isAllCall){
|
||||
// since all beacons are technically @ALLCALL, let's bump the allcall cache here...
|
||||
// since all pings are technically @ALLCALL, let's bump the allcall cache here...
|
||||
m_txAllcallCommandCache.insert(d.from, new QDateTime(now), 25);
|
||||
}
|
||||
}
|
||||
@ -8851,8 +8849,8 @@ void MainWindow::processCommandActivity() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// do not queue @ALLCALL replies if auto-reply is not checked or it's a beacon reply
|
||||
if(!ui->autoReplyButton->isChecked() && isAllCall && !d.cmd.contains("BEACON")){
|
||||
// do not queue @ALLCALL replies if auto-reply is not checked or it's a ping reply
|
||||
if(!ui->autoReplyButton->isChecked() && isAllCall && !d.cmd.contains("PING")){
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -9028,10 +9026,10 @@ void MainWindow::processTxQueue(){
|
||||
// add the message to the outgoing message text box
|
||||
addMessageText(message.message, true);
|
||||
|
||||
// check to see if this is a high priority message, or if we have autoreply enabled, or if this is a beacon and the beacon button is enabled
|
||||
// check to see if this is a high priority message, or if we have autoreply enabled, or if this is a ping and the ping button is enabled
|
||||
if(message.priority >= PriorityHigh ||
|
||||
(ui->autoReplyButton->isChecked()) ||
|
||||
(ui->beaconButton->isChecked() && message.message.contains("BEACON"))
|
||||
(ui->heartbeatButton->isChecked() && message.message.contains("PING"))
|
||||
){
|
||||
// then try to set the frequency...
|
||||
setFreqOffsetForRestore(f, true);
|
||||
@ -9072,7 +9070,7 @@ void MainWindow::displayBandActivity() {
|
||||
selectedOffset = selectedItems.first()->text().toInt();
|
||||
}
|
||||
|
||||
bool beaconEnabled = ui->beaconButton->isChecked();
|
||||
bool pingEnabled = ui->heartbeatButton->isChecked();
|
||||
|
||||
ui->tableWidgetRXAll->setUpdatesEnabled(false);
|
||||
{
|
||||
@ -9163,8 +9161,8 @@ void MainWindow::displayBandActivity() {
|
||||
if (!isOffsetSelected && activityAging && item.utcTimestamp.secsTo(now) / 60 >= activityAging) {
|
||||
continue;
|
||||
}
|
||||
if (!beaconEnabled && (item.text.contains(": BEACON") || item.text.contains("BEACON ACK"))){
|
||||
// hide beacons if we're not beaconing.
|
||||
if (!pingEnabled && (item.text.contains(": PING") || item.text.contains("PING ACK"))){
|
||||
// hide pings if we're not pinging.
|
||||
continue;
|
||||
}
|
||||
if (item.text.isEmpty()) {
|
||||
@ -9482,7 +9480,7 @@ void MainWindow::networkMessage(Message const &message)
|
||||
|
||||
auto type = message.type();
|
||||
|
||||
if(type == "PONG"){
|
||||
if(type == "PING"){
|
||||
return;
|
||||
}
|
||||
|
||||
|
24
mainwindow.h
24
mainwindow.h
@ -144,7 +144,7 @@ public slots:
|
||||
void prependMessageText(QString text);
|
||||
void addMessageText(QString text, bool clear=false, bool selectFirstPlaceholder=false);
|
||||
void enqueueMessage(int priority, QString message, int freq, Callback c);
|
||||
void enqueueBeacon(QString message);
|
||||
void enqueueHeartbeat(QString message);
|
||||
void resetMessage();
|
||||
void resetMessageUI();
|
||||
void restoreMessage();
|
||||
@ -301,10 +301,10 @@ private slots:
|
||||
bool prepareNextMessageFrame();
|
||||
bool isFreqOffsetFree(int f, int bw);
|
||||
int findFreeFreqOffset(int fmin, int fmax, int bw);
|
||||
void scheduleBeacon(bool first=false);
|
||||
void pauseBeacon();
|
||||
void checkBeacon();
|
||||
void prepareBeacon();
|
||||
void scheduleHeartbeat(bool first=false);
|
||||
void pauseHeartbeat();
|
||||
void checkHeartbeat();
|
||||
void prepareHeartbeat();
|
||||
QString calculateDistance(QString const& grid, int *pDistance=nullptr);
|
||||
void on_driftSpinBox_valueChanged(int n);
|
||||
void on_driftSyncButton_clicked();
|
||||
@ -316,7 +316,7 @@ private slots:
|
||||
void on_tuneButton_clicked (bool);
|
||||
void on_pbR2T_clicked();
|
||||
void on_pbT2R_clicked();
|
||||
void on_beaconButton_clicked();
|
||||
void on_heartbeatButton_clicked();
|
||||
void on_selcalButton_clicked();
|
||||
void acceptQSO (QDateTime const&, QString const& call, QString const& grid
|
||||
, Frequency dial_freq, QString const& mode
|
||||
@ -645,7 +645,7 @@ private:
|
||||
QTimer minuteTimer;
|
||||
QTimer splashTimer;
|
||||
QTimer p1Timer;
|
||||
QTimer beaconTimer;
|
||||
QTimer heartbeatTimer;
|
||||
|
||||
QString m_path;
|
||||
QString m_baseCall;
|
||||
@ -780,14 +780,14 @@ private:
|
||||
QMap<int, QList<ActivityDetail>> m_bandActivity; // freq -> [(text, last timestamp), ...]
|
||||
QMap<int, MessageBuffer> m_messageBuffer; // freq -> (cmd, [frames, ...])
|
||||
QMap<QString, CallDetail> m_callActivity; // call -> (last freq, last timestamp)
|
||||
QQueue<QString> m_txBeaconQueue; // beacon frames to be sent
|
||||
QQueue<QString> m_txHeartbeatQueue; // ping frames to be sent
|
||||
QMap<QString, QDateTime> m_aprsCallCache;
|
||||
|
||||
QMap<QString, QMap<QString, CallDetail>> m_callActivityCache; // band -> call activity
|
||||
QMap<QString, QMap<int, QList<ActivityDetail>>> m_bandActivityCache; // band -> band activity
|
||||
QMap<QString, QString> m_rxTextCache; // band -> rx text
|
||||
|
||||
QSet<QString> m_callSeenBeacon; // call
|
||||
QSet<QString> m_callSeenHeartbeat; // call
|
||||
int m_previousFreq;
|
||||
bool m_shouldRestoreFreq;
|
||||
bool m_bandHopped;
|
||||
@ -811,9 +811,9 @@ private:
|
||||
QQueue<QString> m_foxQSOinProgress; //QSOs in progress: Fox has sent a report
|
||||
QQueue<qint64> m_foxRateQueue;
|
||||
|
||||
bool m_nextBeaconQueued = false;
|
||||
bool m_nextBeaconPaused = false;
|
||||
QDateTime m_nextBeacon;
|
||||
bool m_nextHeartbeatQueued = false;
|
||||
bool m_nextHeartPaused = false;
|
||||
QDateTime m_nextHeartbeat;
|
||||
QDateTime m_dateTimeQSOOn;
|
||||
QDateTime m_dateTimeLastTX;
|
||||
|
||||
|
@ -406,7 +406,7 @@ color : white;
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labBeacon">
|
||||
<widget class="QLabel" name="labHeartbeat">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel {
|
||||
font-family: MS Shell Dlg 2;
|
||||
@ -415,7 +415,7 @@ color : white;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Next Beacon: disabled</string>
|
||||
<string>Next Heartbeat: disabled</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
@ -988,7 +988,7 @@ background-color: #00ff00;
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QPushButton" name="beaconButton">
|
||||
<widget class="QPushButton" name="heartbeatButton">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -1011,7 +1011,7 @@ background-color: #00ff00;
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable or disable the automatic beacon</p></body></html></string>
|
||||
<string><html><head/><body><p>Enable or disable the automatic heartbeat transmission</p></body></html></string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
@ -1043,7 +1043,7 @@ background-color: #6699ff;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>BEACON</string>
|
||||
<string>HB</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
@ -578,7 +578,7 @@ void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
x1=XfromFreq(500);
|
||||
x2=XfromFreq(1000);
|
||||
if(x1<=m_w and x2>0) {
|
||||
painter0.setPen(penBlue); //Mark beacon range
|
||||
painter0.setPen(penBlue); //Mark ping range
|
||||
painter0.drawLine(x1+1,26,x2-2,26);
|
||||
painter0.drawLine(x1+1,28,x2-2,28);
|
||||
}
|
||||
|
44
varicode.cpp
44
varicode.cpp
@ -47,7 +47,7 @@ QMap<QString, int> directed_cmds = {
|
||||
{"?", 0 }, // query snr
|
||||
{"@", 1 }, // query qth
|
||||
{"&", 2 }, // query station message
|
||||
{"$", 3 }, // query station(s) heard
|
||||
//{"$", 3 }, // query station(s) heard
|
||||
{"^", 4 }, // query grid
|
||||
{">", 5 }, // relay message
|
||||
{"*", 6 }, // query idle message
|
||||
@ -59,9 +59,9 @@ QMap<QString, int> directed_cmds = {
|
||||
{" ACTIVE", 10 }, // i have been active in the past 10 minutes
|
||||
{" IDLE", 11 }, // i have not been active in the past 10 minutes
|
||||
|
||||
{" BEACON", -1 }, // this is my beacon (unused except for faux processing of beacons as directed commands)
|
||||
{" BEACON ACK", 12 }, // i received your beacon at this snr
|
||||
{" BEACON REQ", 13 }, // can you transmit a beacon to callsign?
|
||||
{" PING", -1 }, // this is my ping (unused except for faux processing of pings as directed commands)
|
||||
{" PING ACK", 12 }, // i acknowledge your ping at this SNR
|
||||
{" PING REQ", 13 }, // can you transmit a ping to callsign?
|
||||
|
||||
{" APRS:", 14 }, // send an aprs packet
|
||||
|
||||
@ -100,17 +100,17 @@ QMap<int, int> checksum_cmds = {
|
||||
};
|
||||
|
||||
QString callsign_pattern = QString("(?<callsign>[@]?[A-Z0-9/]+)");
|
||||
QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:BEACON (ACK|REQ)|AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|QRZ[?]|(?:(?:ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|QTC|GRID|ACTIVE|IDLE)(?=[ ]|$))|[?@&$%#^>* ]))?");
|
||||
QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:PING (ACK|REQ)|AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|QRZ[?]|(?:(?:ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|QTC|GRID|ACTIVE|IDLE)(?=[ ]|$))|[?@&$%#^>* ]))?");
|
||||
QString optional_grid_pattern = QString("(?<grid>\\s?[A-R]{2}[0-9]{2})?");
|
||||
QString optional_extended_grid_pattern = QString("^(?<grid>\\s?(?:[A-R]{2}[0-9]{2}(?:[A-X]{2}(?:[0-9]{2})?)*))?");
|
||||
QString optional_num_pattern = QString("(?<num>(?<=SNR|BEACON ACK)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?");
|
||||
QString optional_num_pattern = QString("(?<num>(?<=SNR|ACK)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?");
|
||||
|
||||
QRegularExpression directed_re("^" +
|
||||
callsign_pattern +
|
||||
optional_cmd_pattern +
|
||||
optional_num_pattern);
|
||||
|
||||
QRegularExpression beacon_re(R"(^\s*(?<type>CQCQCQ|CQ QRPP?|CQ DX|CQ TEST|CQ( CQ){0,2}|BEACON)(?:\s(?<grid>[A-R]{2}[0-9]{2}))?\b)");
|
||||
QRegularExpression heartbeat_re(R"(^\s*(?<type>CQCQCQ|CQ QRPP?|CQ DX|CQ TEST|CQ( CQ){0,2}|PING)(?:\s(?<grid>[A-R]{2}[0-9]{2}))?\b)");
|
||||
|
||||
QRegularExpression compound_re("^\\s*[`]" +
|
||||
callsign_pattern +
|
||||
@ -979,8 +979,8 @@ quint8 Varicode::packCmd(quint8 cmd, quint8 num, bool *pPackedNum){
|
||||
// 8 bits - 1 bit flag + 1 bit type + 6 bit number
|
||||
// [1][X][6]
|
||||
// X = 0 == SNR
|
||||
// X = 1 == BEACON ACK
|
||||
value = ((1 << 1) | (int)(cmdStr == " BEACON ACK")) << 6;
|
||||
// X = 1 == ACK
|
||||
value = ((1 << 1) | (int)(cmdStr == " ACK")) << 6;
|
||||
value = value + (num & ((1<<6)-1));
|
||||
if(pPackedNum) *pPackedNum = true;
|
||||
} else {
|
||||
@ -998,7 +998,7 @@ quint8 Varicode::unpackCmd(quint8 value, quint8 *pNum){
|
||||
|
||||
auto cmd = directed_cmds[" SNR"];
|
||||
if(value & (1<<6)){
|
||||
cmd = directed_cmds[" BEACON ACK"];
|
||||
cmd = directed_cmds[" ACK"];
|
||||
}
|
||||
return cmd;
|
||||
} else {
|
||||
@ -1107,11 +1107,11 @@ bool Varicode::isCompoundCallsign(const QString &callsign){
|
||||
// CQCQCQ EM73
|
||||
// CQ DX EM73
|
||||
// CQ QRP EM73
|
||||
// BEACON EM73
|
||||
QString Varicode::packBeaconMessage(QString const &text, const QString &callsign, int *n){
|
||||
// PING EM73
|
||||
QString Varicode::packHeartbeatMessage(QString const &text, const QString &callsign, int *n){
|
||||
QString frame;
|
||||
|
||||
auto parsedText = beacon_re.match(text);
|
||||
auto parsedText = heartbeat_re.match(text);
|
||||
if(!parsedText.hasMatch()){
|
||||
if(n) *n = 0;
|
||||
return frame;
|
||||
@ -1119,9 +1119,9 @@ QString Varicode::packBeaconMessage(QString const &text, const QString &callsign
|
||||
|
||||
auto extra = parsedText.captured("grid");
|
||||
|
||||
// Beacon Alt Type
|
||||
// Heartbeat Alt Type
|
||||
// ---------------
|
||||
// 1 0 BEACON
|
||||
// 1 0 PING
|
||||
// 1 1 CQCQCQ
|
||||
|
||||
auto type = parsedText.captured("type");
|
||||
@ -1143,7 +1143,7 @@ QString Varicode::packBeaconMessage(QString const &text, const QString &callsign
|
||||
|
||||
quint8 cqNumber = cqs.key(type, 0);
|
||||
|
||||
frame = packCompoundFrame(callsign, FrameBeacon, packed_extra, cqNumber);
|
||||
frame = packCompoundFrame(callsign, FrameHeartbeat, packed_extra, cqNumber);
|
||||
if(frame.isEmpty()){
|
||||
if(n) *n = 0;
|
||||
return frame;
|
||||
@ -1153,13 +1153,13 @@ QString Varicode::packBeaconMessage(QString const &text, const QString &callsign
|
||||
return frame;
|
||||
}
|
||||
|
||||
QStringList Varicode::unpackBeaconMessage(const QString &text, quint8 *pType, bool * isAlt, quint8 * pBits3){
|
||||
quint8 type = FrameBeacon;
|
||||
QStringList Varicode::unpackHeartbeatMessage(const QString &text, quint8 *pType, bool * isAlt, quint8 * pBits3){
|
||||
quint8 type = FrameHeartbeat;
|
||||
quint16 num = nmaxgrid;
|
||||
quint8 bits3 = 0;
|
||||
|
||||
QStringList unpacked = unpackCompoundFrame(text, &type, &num, &bits3);
|
||||
if(unpacked.isEmpty() || type != FrameBeacon){
|
||||
if(unpacked.isEmpty() || type != FrameHeartbeat){
|
||||
return QStringList{};
|
||||
}
|
||||
|
||||
@ -1297,7 +1297,7 @@ QStringList Varicode::unpackCompoundFrame(const QString &text, quint8 *pType, qu
|
||||
|
||||
quint8 packed_flag = Varicode::bitsToInt(bits.mid(0, 3));
|
||||
|
||||
// needs to be a beacon type...
|
||||
// needs to be a ping type...
|
||||
if(packed_flag == FrameDataCompressed || packed_flag == FrameDataUncompressed || packed_flag == FrameDirected){
|
||||
return unpacked;
|
||||
}
|
||||
@ -1649,7 +1649,7 @@ QStringList Varicode::buildMessageFrames(
|
||||
if(!selectedCall.isEmpty() && !line.startsWith(selectedCall) && !line.startsWith("`")){
|
||||
bool lineStartsWithBaseCall = (
|
||||
line.startsWith("@ALLCALL") ||
|
||||
line.startsWith("BEACON") ||
|
||||
line.startsWith("PING") ||
|
||||
Varicode::startsWithCQ(line)
|
||||
);
|
||||
|
||||
@ -1684,7 +1684,7 @@ QStringList Varicode::buildMessageFrames(
|
||||
bool useDat = false;
|
||||
|
||||
int l = 0;
|
||||
QString bcnFrame = Varicode::packBeaconMessage(line, mycall, &l);
|
||||
QString bcnFrame = Varicode::packHeartbeatMessage(line, mycall, &l);
|
||||
|
||||
#if ALLOW_SEND_COMPOUND
|
||||
int o = 0;
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
|
||||
enum FrameType {
|
||||
FrameUnknown = 255, // [11111111] <- only used as a sentinel
|
||||
FrameBeacon = 0, // [000]
|
||||
FrameHeartbeat = 0, // [000]
|
||||
FrameCompound = 1, // [001]
|
||||
FrameCompoundDirected = 2, // [010]
|
||||
FrameDirected = 3, // [011]
|
||||
@ -39,7 +39,7 @@ public:
|
||||
|
||||
static QString frameTypeString(quint8 type) {
|
||||
const char* FrameTypeStrings[] = {
|
||||
"FrameBeacon",
|
||||
"FrameHeartbeat",
|
||||
"FrameCompound",
|
||||
"FrameCompoundDirected",
|
||||
"FrameDirected",
|
||||
@ -132,8 +132,8 @@ public:
|
||||
static bool isValidCallsign(const QString &callsign, bool *pIsCompound);
|
||||
static bool isCompoundCallsign(const QString &callsign);
|
||||
|
||||
static QString packBeaconMessage(QString const &text, QString const&callsign, int *n);
|
||||
static QStringList unpackBeaconMessage(const QString &text, quint8 *pType, bool *isAlt, quint8 *pBits3);
|
||||
static QString packHeartbeatMessage(QString const &text, QString const&callsign, int *n);
|
||||
static QStringList unpackHeartbeatMessage(const QString &text, quint8 *pType, bool *isAlt, quint8 *pBits3);
|
||||
|
||||
static QString packCompoundMessage(QString const &text, int *n);
|
||||
static QStringList unpackCompoundMessage(const QString &text, quint8 *pType, quint8 *pBits3);
|
||||
|
Loading…
Reference in New Issue
Block a user