Rename beacon to heartbean with pings and ping acks

This commit is contained in:
Jordan Sherer 2018-10-28 09:47:30 -04:00
parent 41fb7481ed
commit cac5f798a3
11 changed files with 792 additions and 778 deletions

View File

@ -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 ();

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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_;

View File

@ -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;
}

View File

@ -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;

View File

@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable or disable the automatic beacon&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable or disable the automatic heartbeat transmission&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>

View File

@ -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);
}

View File

@ -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;

View File

@ -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);