Added active/inactive flag and restructuring heartbeat
This commit is contained in:
parent
09cea086c7
commit
d9d3e6fba3
@ -140,7 +140,7 @@ bool DecodedText::tryUnpackHeartbeat(){
|
||||
cmp.append(parts.at(1));
|
||||
}
|
||||
compound_ = cmp.join("/");
|
||||
message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? Varicode::cqString(bits3) : "HEARTBEAT").arg(extra_);
|
||||
message_ = QString("%1: %2 %3 ").arg(compound_).arg(isAlt ? Varicode::cqString(bits3) : Varicode::hbString(bits3)).arg(extra_);
|
||||
frameType_ = type;
|
||||
return true;
|
||||
}
|
||||
|
153
mainwindow.cpp
153
mainwindow.cpp
@ -1405,21 +1405,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple,
|
||||
// Don't block heartbeat's first run...
|
||||
m_lastTxTime = DriftingDateTime::currentDateTimeUtc().addSecs(-300);
|
||||
|
||||
|
||||
auto heartbeatNow = new QAction(QString("Send Heartbeat Now"), ui->heartbeatButton);
|
||||
connect(heartbeatNow, &QAction::triggered, this, [this](){
|
||||
if(m_transmitting){
|
||||
return;
|
||||
}
|
||||
if(!ui->heartbeatButton->isChecked()){
|
||||
ui->heartbeatButton->setChecked(true);
|
||||
}
|
||||
scheduleHeartbeat(true);
|
||||
});
|
||||
ui->heartbeatButton->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
ui->heartbeatButton->addAction(heartbeatNow);
|
||||
|
||||
|
||||
int width = 75;
|
||||
/*
|
||||
QList<QPushButton*> btns;
|
||||
@ -1564,12 +1549,6 @@ void MainWindow::initializeDummyData(){
|
||||
displayTextForFreq("HELLO BRAVE NEW WORLD \u2301 ", 42, DriftingDateTime::currentDateTimeUtc().addSecs(-300), false, true, true);
|
||||
|
||||
displayActivity(true);
|
||||
|
||||
ui->heartbeatButton->click();
|
||||
QTimer::singleShot(10000, this, [this](){
|
||||
m_idleMinutes = 61;
|
||||
scheduleHeartbeat(true);
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::initialize_fonts ()
|
||||
@ -2361,8 +2340,8 @@ void rebuildMacQAction(QMenu *menu, QAction *existingAction){
|
||||
|
||||
void MainWindow::on_menuControl_aboutToShow(){
|
||||
ui->actionEnable_Spotting->setChecked(ui->spotButton->isChecked());
|
||||
ui->actionEnable_Active->setChecked(ui->activeButton->isChecked());
|
||||
ui->actionEnable_Auto_Reply->setChecked(ui->autoReplyButton->isChecked());
|
||||
ui->actionEnable_Heartbeat->setChecked(ui->heartbeatButton->isChecked());
|
||||
ui->actionEnable_Selcall->setChecked(ui->selcalButton->isChecked());
|
||||
}
|
||||
|
||||
@ -2374,8 +2353,8 @@ void MainWindow::on_actionEnable_Auto_Reply_toggled(bool checked){
|
||||
ui->autoReplyButton->setChecked(checked);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionEnable_Heartbeat_toggled(bool checked){
|
||||
ui->heartbeatButton->setChecked(checked);
|
||||
void MainWindow::on_actionEnable_Active_toggled(bool checked){
|
||||
ui->activeButton->setChecked(checked);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionEnable_Selcall_toggled(bool checked){
|
||||
@ -2715,6 +2694,27 @@ void MainWindow::on_spotButton_toggled(bool checked){
|
||||
resetPushButtonToggleText(ui->spotButton);
|
||||
}
|
||||
|
||||
void MainWindow::on_activeButton_toggled(bool checked){
|
||||
#if 0
|
||||
// clear the ping queue when you toggle the button
|
||||
m_txHeartbeatQueue.clear();
|
||||
displayBandActivity();
|
||||
|
||||
// then process the action
|
||||
if(checked){
|
||||
scheduleHeartbeat(false);
|
||||
} else {
|
||||
pauseHeartbeat();
|
||||
}
|
||||
#endif
|
||||
|
||||
// we call this so hb button disabled state is updated
|
||||
updateButtonDisplay();
|
||||
|
||||
resetPushButtonToggleText(ui->activeButton);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void MainWindow::on_heartbeatButton_toggled(bool checked){
|
||||
// clear the ping queue when you toggle the button
|
||||
m_txHeartbeatQueue.clear();
|
||||
@ -2729,6 +2729,7 @@ void MainWindow::on_heartbeatButton_toggled(bool checked){
|
||||
|
||||
resetPushButtonToggleText(ui->heartbeatButton);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MainWindow::auto_tx_mode (bool state)
|
||||
{
|
||||
@ -3852,7 +3853,7 @@ void MainWindow::readFromStdout() //readFromStdout
|
||||
// convert HEARTBEAT to a directed command and process...
|
||||
cmd.from = cd.call;
|
||||
cmd.to = "@ALLCALL";
|
||||
cmd.cmd = " HEARTBEAT";
|
||||
cmd.cmd = " ACTIVE";
|
||||
cmd.snr = cd.snr;
|
||||
cmd.bits = cd.bits;
|
||||
cmd.grid = cd.grid;
|
||||
@ -4569,7 +4570,7 @@ void MainWindow::guiUpdate()
|
||||
} else if(m_monitoring) {
|
||||
if (m_tx_watchdog) {
|
||||
tx_status_label.setStyleSheet ("QLabel{background-color: #ff0000}");
|
||||
tx_status_label.setText ("Idle watchdog");
|
||||
tx_status_label.setText ("Inactive watchdog");
|
||||
} else {
|
||||
tx_status_label.setStyleSheet("QLabel{background-color: #00ff00}");
|
||||
QString t;
|
||||
@ -4594,24 +4595,22 @@ void MainWindow::guiUpdate()
|
||||
parts << t.date().toString("yyyy MMM dd");
|
||||
ui->labUTC->setText(parts.join("\n"));
|
||||
|
||||
#if 0
|
||||
auto delta = t.secsTo(m_nextHeartbeat);
|
||||
QString ping;
|
||||
if(ui->heartbeatButton->isChecked()){
|
||||
if(heartbeatTimer.isActive()){
|
||||
if(delta > 0){
|
||||
ping = QString("%1 s").arg(delta);
|
||||
} else {
|
||||
ping = "queued!";
|
||||
}
|
||||
if(heartbeatTimer.isActive()){
|
||||
if(delta > 0){
|
||||
ping = QString("%1 s").arg(delta);
|
||||
} else {
|
||||
ping = "on demand";
|
||||
ping = "queued!";
|
||||
}
|
||||
} else if (m_nextHeartPaused) {
|
||||
ping = "paused";
|
||||
} else {
|
||||
ping = "disabled";
|
||||
ping = "on demand";
|
||||
}
|
||||
ui->labHeartbeat->setText(QString("Next Heartbeat: %1").arg(ping));
|
||||
#endif
|
||||
|
||||
auto callLabel = m_config.my_callsign();
|
||||
if(m_config.use_dynamic_grid() && !m_config.my_grid().isEmpty()){
|
||||
@ -5446,7 +5445,6 @@ void MainWindow::enqueueMessage(int priority, QString message, int freq, Callbac
|
||||
|
||||
void MainWindow::enqueueHeartbeat(QString message){
|
||||
m_txHeartbeatQueue.enqueue(message);
|
||||
scheduleHeartbeat(true);
|
||||
}
|
||||
|
||||
void MainWindow::resetMessage(){
|
||||
@ -5664,10 +5662,7 @@ bool MainWindow::prepareNextMessageFrame()
|
||||
|
||||
updateTxButtonDisplay();
|
||||
|
||||
if(ui->heartbeatButton->isChecked()){
|
||||
// bump ping
|
||||
scheduleHeartbeat(false);
|
||||
}
|
||||
// TODO: bump heartbeat
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -5726,10 +5721,10 @@ int MainWindow::findFreeFreqOffset(int fmin, int fmax, int bw){
|
||||
return fmin;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// schedulePing
|
||||
void MainWindow::scheduleHeartbeat(bool first){
|
||||
auto timestamp = DriftingDateTime::currentDateTimeUtc();
|
||||
auto orig = timestamp;
|
||||
|
||||
// if we have the heartbeat interval disabled, return early, unless this is a "heartbeat now"
|
||||
if(!m_config.heartbeat() && !first){
|
||||
@ -5765,7 +5760,6 @@ void MainWindow::scheduleHeartbeat(bool first){
|
||||
|
||||
// pausePing
|
||||
void MainWindow::pauseHeartbeat(){
|
||||
ui->heartbeatButton->setChecked(false);
|
||||
m_nextHeartPaused = true;
|
||||
|
||||
if(heartbeatTimer.isActive()){
|
||||
@ -5775,13 +5769,12 @@ void MainWindow::pauseHeartbeat(){
|
||||
|
||||
// unpausePing
|
||||
void MainWindow::unpauseHeartbeat(){
|
||||
ui->heartbeatButton->setChecked(true);
|
||||
scheduleHeartbeat(false);
|
||||
}
|
||||
|
||||
// checkPing
|
||||
void MainWindow::checkHeartbeat(){
|
||||
if(!ui->heartbeatButton->isChecked()){
|
||||
if(m_config.heartbeat() <= 0){
|
||||
return;
|
||||
}
|
||||
auto secondsUntilHeartbeat = DriftingDateTime::currentDateTimeUtc().secsTo(m_nextHeartbeat);
|
||||
@ -5835,8 +5828,11 @@ void MainWindow::prepareHeartbeat(){
|
||||
|
||||
m_nextHeartbeatQueued = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void MainWindow::checkHeartbeat(){
|
||||
|
||||
}
|
||||
|
||||
QString MainWindow::calculateDistance(QString const& value, int *pDistance, int *pAzimuth)
|
||||
{
|
||||
@ -6496,6 +6492,16 @@ void MainWindow::on_clearAction_triggered(QObject * sender){
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_hbMacroButton_clicked(){
|
||||
QString mycall = m_config.my_callsign();
|
||||
QString mygrid = m_config.my_grid().left(4);
|
||||
QString message = QString("%1: ACTIVE %2").arg(mycall).arg(mygrid).trimmed();
|
||||
|
||||
addMessageText(message);
|
||||
|
||||
if(m_config.transmit_directed()) toggleTx(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_cqMacroButton_clicked(){
|
||||
auto message = m_config.cq_message();
|
||||
if(message.isEmpty()){
|
||||
@ -6911,7 +6917,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
|
||||
addMessageText(QString("%1>[MESSAGE]").arg(selectedCall), true, true);
|
||||
});
|
||||
|
||||
auto qsoQueryAction = menu->addAction(QString("%1 HEARTBEAT REQ [CALLSIGN]? - Please acknowledge you can communicate directly with [CALLSIGN]").arg(call).trimmed());
|
||||
auto qsoQueryAction = menu->addAction(QString("%1 QUERY [CALLSIGN]? - Please acknowledge you can communicate directly with [CALLSIGN]").arg(call).trimmed());
|
||||
connect(qsoQueryAction, &QAction::triggered, this, [this](){
|
||||
|
||||
QString selectedCall = callsignSelected();
|
||||
@ -6919,7 +6925,7 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){
|
||||
return;
|
||||
}
|
||||
|
||||
addMessageText(QString("%1 HEARTBEAT REQ [CALLSIGN]?").arg(selectedCall), true, true);
|
||||
addMessageText(QString("%1 QUERY [CALLSIGN]?").arg(selectedCall), true, true);
|
||||
});
|
||||
|
||||
menu->addSeparator();
|
||||
@ -7135,6 +7141,7 @@ QMap<QString, QString> MainWindow::buildMacroValues(){
|
||||
{"<MYQTH>", m_config.my_qth()},
|
||||
{"<MYCQ>", m_config.cq_message()},
|
||||
{"<MYREPLY>", m_config.reply_message()},
|
||||
{"<MYSTATUS>", (ui->activeButton->isChecked() ? "ACTIVE" : "INACTIVE")},
|
||||
};
|
||||
|
||||
auto selectedCall = callsignSelected();
|
||||
@ -8260,7 +8267,9 @@ void MainWindow::updateButtonDisplay(){
|
||||
|
||||
auto selectedCallsign = callsignSelected(true);
|
||||
bool emptyCallsign = selectedCallsign.isEmpty();
|
||||
bool isActive = ui->activeButton->isChecked();
|
||||
|
||||
ui->hbMacroButton->setDisabled(isTransmitting || !isActive);
|
||||
ui->cqMacroButton->setDisabled(isTransmitting);
|
||||
ui->replyMacroButton->setDisabled(isTransmitting || emptyCallsign);
|
||||
ui->snrMacroButton->setDisabled(isTransmitting || emptyCallsign);
|
||||
@ -8603,7 +8612,7 @@ void MainWindow::processRxActivity() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(d.isDirected && d.text.contains(": HEARTBEAT")){
|
||||
if(d.isDirected && d.text.contains(": ACTIVE")){ // TODO: HEARTBEAT
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -8885,7 +8894,7 @@ void MainWindow::processCommandActivity() {
|
||||
cd.snr = d.snr;
|
||||
cd.freq = d.freq;
|
||||
cd.bits = d.bits;
|
||||
cd.ackTimestamp = d.text.contains("HEARTBEAT ACK") || toMe ? d.utcTimestamp : QDateTime{};
|
||||
cd.ackTimestamp = d.text.contains(": ACK") || toMe ? d.utcTimestamp : QDateTime{};
|
||||
cd.utcTimestamp = d.utcTimestamp;
|
||||
cd.tdrift = d.tdrift;
|
||||
logCallActivity(cd, true);
|
||||
@ -8927,7 +8936,7 @@ void MainWindow::processCommandActivity() {
|
||||
bool shouldDisplay = true;
|
||||
|
||||
// don't display ping allcalls
|
||||
if(isAllCall && (d.cmd != " " || ad.text.contains(": HEARTBEAT"))){ // || d.cmd == " HEARTBEAT")){
|
||||
if(isAllCall && (d.cmd != " " || ad.text.contains(": ACTIVE"))){ // || d.cmd == " HEARTBEAT")){
|
||||
shouldDisplay = false;
|
||||
}
|
||||
|
||||
@ -8938,7 +8947,7 @@ void MainWindow::processCommandActivity() {
|
||||
|
||||
// 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("HEARTBEAT ACK")); /* && isRecentOffset(d.freq);*/
|
||||
bool shouldOverwrite = (!d.cmd.contains(" 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...
|
||||
@ -9006,10 +9015,10 @@ void MainWindow::processCommandActivity() {
|
||||
|
||||
// QUERIED ACTIVE
|
||||
else if (d.cmd == " STATUS?" && !isAllCall) {
|
||||
if(m_idleMinutes < 10){
|
||||
if(ui->activeButton->isChecked()){
|
||||
reply = QString("%1 ACTIVE").arg(d.from);
|
||||
} else {
|
||||
reply = QString("%1 IDLE").arg(d.from);
|
||||
reply = QString("%1 INACTIVE").arg(d.from);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9142,22 +9151,18 @@ void MainWindow::processCommandActivity() {
|
||||
reply = m_lastTxMessage;
|
||||
}
|
||||
|
||||
// PROCESS HEARTBEAT
|
||||
else if (d.cmd == " HEARTBEAT" && ui->heartbeatButton->isChecked() && ui->autoReplyButton->isChecked() && !ui->selcalButton->isChecked()){
|
||||
reply = QString("%1 HEARTBEAT ACK %2").arg(d.from).arg(Varicode::formatSNR(d.snr));
|
||||
|
||||
enqueueHeartbeat(reply);
|
||||
// PROCESS ACTIVE HEARTBEAT
|
||||
else if (d.cmd == " ACTIVE" && ui->autoReplyButton->isChecked() && !ui->selcalButton->isChecked()){
|
||||
reply = QString("%1 ACK %2").arg(d.from).arg(Varicode::formatSNR(d.snr));
|
||||
|
||||
if(isAllCall){
|
||||
// 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 HEARTBEAT REQ QUERY
|
||||
else if (d.cmd == " HEARTBEAT REQ" && ui->heartbeatButton->isChecked()){
|
||||
// PROCESS BUFFERED QUERY
|
||||
else if (d.cmd == " QUERY" && ui->autoReplyButton->isChecked() && !ui->selcalButton->isChecked()){
|
||||
auto who = d.text;
|
||||
if(who.isEmpty()){
|
||||
continue;
|
||||
@ -9184,15 +9189,11 @@ void MainWindow::processCommandActivity() {
|
||||
reply = replies.join("\n");
|
||||
|
||||
if(!reply.isEmpty()){
|
||||
enqueueHeartbeat(reply);
|
||||
|
||||
if(isAllCall){
|
||||
// since all pings are technically @ALLCALL, let's bump the allcall cache here...
|
||||
m_txAllcallCommandCache.insert(d.from, new QDateTime(now), 25);
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// PROCESS BUFFERED APRS:
|
||||
@ -9246,7 +9247,7 @@ void MainWindow::processCommandActivity() {
|
||||
}
|
||||
|
||||
// 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("HEARTBEAT")){
|
||||
if(!ui->autoReplyButton->isChecked() && isAllCall && !d.cmd.contains("ACTIVE")){
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -9428,8 +9429,7 @@ void MainWindow::processTxQueue(){
|
||||
|
||||
// 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->heartbeatButton->isChecked() && message.message.contains("HEARTBEAT"))
|
||||
(ui->autoReplyButton->isChecked())
|
||||
){
|
||||
// then try to set the frequency...
|
||||
setFreqOffsetForRestore(f, true);
|
||||
@ -9470,7 +9470,9 @@ void MainWindow::displayBandActivity() {
|
||||
selectedOffset = selectedItems.first()->text().toInt();
|
||||
}
|
||||
|
||||
bool pingEnabled = ui->heartbeatButton->isChecked();
|
||||
#if 0
|
||||
bool pingEnabled = m_config.heartbeat() > 0;
|
||||
#endif
|
||||
|
||||
ui->tableWidgetRXAll->setUpdatesEnabled(false);
|
||||
{
|
||||
@ -9562,10 +9564,12 @@ void MainWindow::displayBandActivity() {
|
||||
if (!isOffsetSelected && activityAging && item.utcTimestamp.secsTo(now) / 60 >= activityAging) {
|
||||
continue;
|
||||
}
|
||||
#if 0
|
||||
if (!pingEnabled && (item.text.contains(": HEARTBEAT") || item.text.contains("HEARTBEAT ACK"))){
|
||||
// hide pings if we're not pinging.
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (item.text.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
@ -9933,7 +9937,7 @@ void MainWindow::networkMessage(Message const &message)
|
||||
|
||||
auto type = message.type();
|
||||
|
||||
if(type == "HEARTBEAT"){
|
||||
if(type == "PING"){
|
||||
return;
|
||||
}
|
||||
|
||||
@ -10611,11 +10615,12 @@ void MainWindow::tx_watchdog (bool triggered)
|
||||
if (m_auto) auto_tx_mode (false);
|
||||
stopTx();
|
||||
tx_status_label.setStyleSheet ("QLabel{background-color: #ff0000}");
|
||||
tx_status_label.setText ("Idle watchdog");
|
||||
tx_status_label.setText ("Inactive watchdog");
|
||||
|
||||
pauseHeartbeat();
|
||||
MessageBox::warning_message(this, QString("Attempting to transmit heartbeat, but you have been idle for more than %1 minutes.").arg(m_config.watchdog()));
|
||||
unpauseHeartbeat();
|
||||
// if the watchdog is triggered...we're no longer active
|
||||
ui->activeButton->setChecked(false);
|
||||
|
||||
MessageBox::warning_message(this, QString("Attempting to transmit, but you have been inactive for more than %1 minutes.").arg(m_config.watchdog()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -173,8 +173,8 @@ private slots:
|
||||
void on_tx6_editingFinished();
|
||||
void on_menuControl_aboutToShow();
|
||||
void on_actionEnable_Spotting_toggled(bool checked);
|
||||
void on_actionEnable_Active_toggled(bool checked);
|
||||
void on_actionEnable_Auto_Reply_toggled(bool checked);
|
||||
void on_actionEnable_Heartbeat_toggled(bool checked);
|
||||
void on_actionEnable_Selcall_toggled(bool checked);
|
||||
void on_menuWindow_aboutToShow();
|
||||
void on_actionShow_Fullscreen_triggered(bool checked);
|
||||
@ -274,6 +274,7 @@ private slots:
|
||||
void on_rbGenMsg_clicked(bool checked);
|
||||
void on_rbFreeText_clicked(bool checked);
|
||||
void on_clearAction_triggered(QObject * sender);
|
||||
void on_hbMacroButton_clicked();
|
||||
void on_cqMacroButton_clicked();
|
||||
void on_replyMacroButton_clicked();
|
||||
void on_snrMacroButton_clicked();
|
||||
@ -311,11 +312,7 @@ private slots:
|
||||
bool prepareNextMessageFrame();
|
||||
bool isFreqOffsetFree(int f, int bw);
|
||||
int findFreeFreqOffset(int fmin, int fmax, int bw);
|
||||
void scheduleHeartbeat(bool first=false);
|
||||
void pauseHeartbeat();
|
||||
void unpauseHeartbeat();
|
||||
void checkHeartbeat();
|
||||
void prepareHeartbeat();
|
||||
QString calculateDistance(QString const& grid, int *pDistance=nullptr, int *pAzimuth=nullptr);
|
||||
void on_driftSpinBox_valueChanged(int n);
|
||||
void on_driftSyncButton_clicked();
|
||||
@ -355,7 +352,7 @@ private slots:
|
||||
void on_selcalButton_toggled(bool checked);
|
||||
void on_tuneButton_toggled(bool checked);
|
||||
void on_spotButton_toggled(bool checked);
|
||||
void on_heartbeatButton_toggled(bool checked);
|
||||
void on_activeButton_toggled(bool checked);
|
||||
|
||||
void on_actionMessage_averaging_triggered();
|
||||
void on_actionFox_Log_triggered();
|
||||
|
462
mainwindow.ui
462
mainwindow.ui
@ -359,7 +359,7 @@ QPushButton[oob="true"] {
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
<string>Callsign</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
@ -411,29 +411,6 @@ color : white;
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labHeartbeat">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QLabel {
|
||||
font-family: MS Shell Dlg 2;
|
||||
font-size: 11pt;
|
||||
color : white;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Next Heartbeat: disabled</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
@ -499,7 +476,7 @@ QPushButton:checked {
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_8" columnstretch="1,1,1,1,0" columnminimumwidth="75,75,75,75,0">
|
||||
<layout class="QGridLayout" name="gridLayout_8" columnstretch="1,1,1,1" columnminimumwidth="75,75,75,75">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
@ -573,43 +550,6 @@ QPushButton:checked {
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QPushButton" name="activeButton">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable or disable automatic station replies to directed queries</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ACTIVE</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="monitorButton">
|
||||
<property name="enabled">
|
||||
@ -776,7 +716,7 @@ QPushButton:checked {
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="heartbeatButton">
|
||||
<widget class="QPushButton" name="activeButton">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -804,7 +744,7 @@ QPushButton:checked {
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enable or disable the automatic heartbeat transmission</p></body></html></string>
|
||||
<string><html><head/><body><p>Register your station as active or idle</p></body></html></string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
@ -820,7 +760,7 @@ QPushButton:checked {
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>HB</string>
|
||||
<string>ACTIVE</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
@ -1361,192 +1301,7 @@ QTextEdit[transmitting="true"] {
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="11">
|
||||
<widget class="QPushButton" name="queryButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send a directed message to another station</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Directed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="16">
|
||||
<widget class="QPushButton" name="stopTxButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Stop transmitting</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Halt</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="14">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QPushButton" name="qtcMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send your station message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>QTC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="snrMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send an SNR message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>SNR</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="replyMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Reply to a CQ</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QPushButton" name="macrosMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send a saved message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Saved</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="12">
|
||||
<widget class="QPushButton" name="deselectButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Deselect the current callsign for directed messaging</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Deselect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QPushButton" name="qthMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send your station location message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>QTH</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="cqMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send a CQ message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CQ</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="15">
|
||||
<widget class="QPushButton" name="startTxButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
@ -1578,6 +1333,207 @@ color:#555;
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="17">
|
||||
<widget class="QPushButton" name="stopTxButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>75</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Stop transmitting</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Halt</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="15">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QPushButton" name="qthMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send your station location message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>QTH</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="13">
|
||||
<widget class="QPushButton" name="deselectButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Deselect the current callsign for directed messaging</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Deselect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QPushButton" name="snrMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send an SNR message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>SNR</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="replyMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Reply to a CQ</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="cqMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send a CQ message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>CQ</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<widget class="QPushButton" name="qtcMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send your station message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>QTC</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<widget class="QPushButton" name="macrosMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send a saved message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Saved</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="12">
|
||||
<widget class="QPushButton" name="queryButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Send a directed message to another station</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Directed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="hbMacroButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p align="justify">Send a Heartbeat message</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>HB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="frame_5">
|
||||
@ -4757,7 +4713,7 @@ list. The list can be maintained in Settings (F2).</string>
|
||||
<string>C&ontrol</string>
|
||||
</property>
|
||||
<addaction name="actionEnable_Spotting"/>
|
||||
<addaction name="actionEnable_Heartbeat"/>
|
||||
<addaction name="actionEnable_Active"/>
|
||||
<addaction name="actionEnable_Auto_Reply"/>
|
||||
<addaction name="actionEnable_Selcall"/>
|
||||
</widget>
|
||||
@ -5578,12 +5534,12 @@ list. The list can be maintained in Settings (F2).</string>
|
||||
<string>Enable Spotting</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnable_Heartbeat">
|
||||
<action name="actionEnable_Active">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Heartbeat</string>
|
||||
<string>Enable Active</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnable_Auto_Reply">
|
||||
|
58
varicode.cpp
58
varicode.cpp
@ -71,11 +71,12 @@ QMap<QString, int> directed_cmds = {
|
||||
{" TU", 9 }, // thank you
|
||||
|
||||
{" ACTIVE", 10 }, // i have been active in the past 10 minutes
|
||||
{" IDLE", 11 }, // i have not been active in the past 10 minutes
|
||||
{" INACTIVE", 11 }, // i have not been active in the past 10 minutes
|
||||
|
||||
{" HEARTBEAT", -1 }, // this is my ping (unused except for faux processing of pings as directed commands)
|
||||
{" HEARTBEAT ACK", 12 }, // i acknowledge your ping at this SNR
|
||||
{" HEARTBEAT REQ", 13 }, // can you transmit a ping to callsign?
|
||||
//{" HEARTBEAT", -1 }, // this is my ping (unused except for faux processing of pings as directed commands)
|
||||
//{" HEARTBEAT ACK", 12 }, // i acknowledge your ping at this SNR
|
||||
|
||||
{" QUERY", 13 }, // can you transmit a ping to callsign?
|
||||
|
||||
{" APRS:", 14 }, // send an aprs packet
|
||||
|
||||
@ -103,7 +104,7 @@ QSet<int> allowed_cmds = {-1, 0, 1, 2, 3, 4, 5, 6, /*7,*/ 8, 9, 10, 11, 12, 13,
|
||||
|
||||
QSet<int> buffered_cmds = {3, 5, /*6,*/ /*7,*/ 8, 13, 14, 15};
|
||||
|
||||
QSet<int> snr_cmds = {12, 25};
|
||||
QSet<int> snr_cmds = {25, 29};
|
||||
|
||||
QMap<int, int> checksum_cmds = {
|
||||
{ 5, 16 },
|
||||
@ -114,17 +115,17 @@ QMap<int, int> checksum_cmds = {
|
||||
};
|
||||
|
||||
QString callsign_pattern = QString("(?<callsign>[@]?[A-Z0-9/]+)");
|
||||
QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:HEARTBEAT (ACK|REQ)|AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|QRZ[?]|SNR[?]|QTC[?]|QTH[?]|GRID[?]|STATUS[?]|(?:(?:ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|QTC|GRID|ACTIVE|IDLE|TU)(?=[ ]|$))|[?*^&@#> ]))?");
|
||||
QString optional_cmd_pattern = QString("(?<cmd>\\s?(?:AGN[?]|QSL[?]|HW CPY[?]|APRS[:]|QRZ[?]|SNR[?]|QTC[?]|QTH[?]|GRID[?]|STATUS[?]|(?:(?:QUERY|ACK|73|YES|NO|SNR|QSL|RR|SK|FB|QTH|QTC|GRID|INACTIVE|ACTIVE|TU)(?=[ ]|$))|[?*^&@#> ]))?");
|
||||
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|HEARTBEAT 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 heartbeat_re(R"(^\s*(?<type>CQCQCQ|CQ QRPP?|CQ DX|CQ TEST|CQ( CQ){0,2}|HEARTBEAT)(?:\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}|ACTIVE)(?:\s(?<grid>[A-R]{2}[0-9]{2}))?\b)");
|
||||
|
||||
QRegularExpression compound_re("^\\s*[`]" +
|
||||
callsign_pattern +
|
||||
@ -206,6 +207,12 @@ QMap<quint32, QString> cqs = {
|
||||
{ 7, "CQ CQ CQ"},
|
||||
};
|
||||
|
||||
QMap<quint32, QString> hbs = {
|
||||
{ 0, "ACTIVE" },
|
||||
{ 1, "INACTIVE" },
|
||||
};
|
||||
|
||||
|
||||
QMap<int, int> dbm2mw = {
|
||||
{0 , 1}, // 1mW
|
||||
{3 , 2}, // 2mW
|
||||
@ -292,6 +299,13 @@ QString Varicode::cqString(int number){
|
||||
return cqs[number];
|
||||
}
|
||||
|
||||
QString Varicode::hbString(int number){
|
||||
if(!hbs.contains(number)){
|
||||
return QString{};
|
||||
}
|
||||
return hbs[number];
|
||||
}
|
||||
|
||||
bool Varicode::startsWithCQ(QString text){
|
||||
foreach(auto cq, cqs.values()){
|
||||
if(text.startsWith(cq)){
|
||||
@ -301,6 +315,15 @@ bool Varicode::startsWithCQ(QString text){
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Varicode::startsWithHB(QString text){
|
||||
foreach(auto cq, hbs.values()){
|
||||
if(text.startsWith(cq)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString Varicode::formatSNR(int snr){
|
||||
if(snr < -60 || snr > 60){
|
||||
return QString();
|
||||
@ -994,7 +1017,7 @@ quint8 Varicode::packCmd(quint8 cmd, quint8 num, bool *pPackedNum){
|
||||
// [1][X][6]
|
||||
// X = 0 == SNR
|
||||
// X = 1 == ACK
|
||||
value = ((1 << 1) | (int)(cmdStr == " HEARTBEAT ACK")) << 6;
|
||||
value = ((1 << 1) | (int)(cmdStr == " ACK")) << 6;
|
||||
value = value + (num & ((1<<6)-1));
|
||||
if(pPackedNum) *pPackedNum = true;
|
||||
} else {
|
||||
@ -1012,7 +1035,7 @@ quint8 Varicode::unpackCmd(quint8 value, quint8 *pNum){
|
||||
|
||||
auto cmd = directed_cmds[" SNR"];
|
||||
if(value & (1<<6)){
|
||||
cmd = directed_cmds[" HEARTBEAT ACK"];
|
||||
cmd = directed_cmds[" ACK"];
|
||||
}
|
||||
return cmd;
|
||||
} else {
|
||||
@ -1121,7 +1144,7 @@ bool Varicode::isCompoundCallsign(const QString &callsign){
|
||||
// CQCQCQ EM73
|
||||
// CQ DX EM73
|
||||
// CQ QRP EM73
|
||||
// HEARTBEAT EM73
|
||||
// ACTIVE EM73
|
||||
QString Varicode::packHeartbeatMessage(QString const &text, const QString &callsign, int *n){
|
||||
QString frame;
|
||||
|
||||
@ -1135,7 +1158,7 @@ QString Varicode::packHeartbeatMessage(QString const &text, const QString &calls
|
||||
|
||||
// Heartbeat Alt Type
|
||||
// ---------------
|
||||
// 1 0 HEARTBEAT
|
||||
// 1 0 ACTIVE
|
||||
// 1 1 CQCQCQ
|
||||
|
||||
auto type = parsedText.captured("type");
|
||||
@ -1151,12 +1174,13 @@ QString Varicode::packHeartbeatMessage(QString const &text, const QString &calls
|
||||
packed_extra = Varicode::packGrid(extra);
|
||||
}
|
||||
|
||||
quint8 cqNumber = cqs.key(type, 0);
|
||||
|
||||
if(isAlt){
|
||||
packed_extra |= (1<<15);
|
||||
cqNumber = hbs.key(type, 0);
|
||||
}
|
||||
|
||||
quint8 cqNumber = cqs.key(type, 0);
|
||||
|
||||
frame = packCompoundFrame(callsign, FrameHeartbeat, packed_extra, cqNumber);
|
||||
if(frame.isEmpty()){
|
||||
if(n) *n = 0;
|
||||
@ -1657,9 +1681,9 @@ QList<QPair<QString, int>> Varicode::buildMessageFrames(
|
||||
// and if this isn't a raw message (starting with "`")... then...
|
||||
if(!selectedCall.isEmpty() && !line.startsWith(selectedCall) && !line.startsWith("`")){
|
||||
bool lineStartsWithBaseCall = (
|
||||
line.startsWith("@ALLCALL") ||
|
||||
line.contains("HEARTBEAT") ||
|
||||
Varicode::startsWithCQ(line)
|
||||
line.startsWith("@ALLCALL") ||
|
||||
Varicode::startsWithCQ(line) ||
|
||||
Varicode::startsWithHB(line)
|
||||
);
|
||||
|
||||
#if AUTO_PREPEND_DIRECTED_ALLOW_TEXT_CALLSIGNS
|
||||
|
@ -63,7 +63,9 @@ public:
|
||||
|
||||
static QMap<QString, QString> defaultHuffTable();
|
||||
static QString cqString(int number);
|
||||
static QString hbString(int number);
|
||||
static bool startsWithCQ(QString text);
|
||||
static bool startsWithHB(QString text);
|
||||
static QString formatSNR(int snr);
|
||||
static QString formatPWR(int dbm);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user