diff --git a/Configuration.cpp b/Configuration.cpp index 65bd7c1..aaf7da4 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -555,7 +555,7 @@ private: QString my_callsign_; QString my_grid_; QString my_station_; - int my_dBm_; + QString aprs_ssid_; QString my_qth_; QString reply_; int callsign_aging_; @@ -865,8 +865,8 @@ QString Configuration::my_station() const return station; } -int Configuration::my_dBm() const { - return m_->my_dBm_; +QString Configuration::aprs_ssid() const { + return m_->aprs_ssid_; } QString Configuration::my_qth() const @@ -1221,40 +1221,6 @@ void Configuration::impl::initialize_models () pal.setColor (QPalette::Base, Qt::white); } - QMap dbm2mw = { - {0 , 1}, - {3 , 2}, - {7 , 5}, - {10 , 10}, - {13 , 20}, - {17 , 50}, - {20 , 100}, - {23 , 200}, - {27 , 500}, - {30 , 1000}, // 1W - {33 , 2000}, // 2W - {37 , 5000}, // 5W - {40 , 10000}, // 10W - {43 , 20000}, // 20W - {47 , 50000}, // 50W - {50 , 100000}, // 100W - {53 , 200000}, // 200W - {57 , 500000}, // 500W - {60 , 1000000}, // 1000W - }; - - ui_->station_power_combo_box->clear(); - ui_->station_power_combo_box->addItem(QString(""), -1); - - foreach(auto dbm, dbm2mw.keys()){ - ui_->station_power_combo_box->addItem(QString("%1 (%2 dBm)").arg(Varicode::formatPWR(dbm)).arg(dbm), dbm); - - if(dbm == my_dBm_){ - ui_->station_power_combo_box->setCurrentIndex(ui_->station_power_combo_box->count()-1); - } - } - - ui_->callsign_line_edit->setPalette (pal); ui_->grid_line_edit->setPalette (pal); ui_->auto_switch_bands_check_box->setChecked(auto_switch_bands_); @@ -1390,7 +1356,7 @@ void Configuration::impl::read_settings () my_callsign_ = settings_->value ("MyCall", QString {}).toString (); my_grid_ = settings_->value ("MyGrid", QString {}).toString (); my_station_ = settings_->value("MyStation", QString {}).toString(); - my_dBm_ = settings_->value("MyPower", -1).toInt(); + aprs_ssid_ = settings_->value("APRSSSID", "-0").toString(); callsign_aging_ = settings_->value ("CallsignAging", 0).toInt (); activity_aging_ = settings_->value ("ActivityAging", 2).toInt (); my_qth_ = settings_->value("MyQTH", QString {}).toString(); @@ -1586,7 +1552,7 @@ void Configuration::impl::write_settings () settings_->setValue ("MyCall", my_callsign_); settings_->setValue ("MyGrid", my_grid_); settings_->setValue ("MyStation", my_station_); - settings_->setValue ("MyPower", my_dBm_); + settings_->setValue ("APRSSSID", aprs_ssid_); settings_->setValue ("MyQTH", my_qth_); settings_->setValue ("Reply", reply_); settings_->setValue ("CallsignAging", callsign_aging_); @@ -2050,7 +2016,7 @@ void Configuration::impl::accept () my_grid_ = ui_->grid_line_edit->text (); my_station_ = ui_->station_message_line_edit->text().toUpper(); reply_ = ui_->reply_message_line_edit->text().toUpper(); - my_dBm_ = ui_->station_power_combo_box->currentData().toInt(); + aprs_ssid_ = ui_->aprs_ssid_line_edit->text().toUpper(); my_qth_ = ui_->qth_message_line_edit->text().toUpper(); callsign_aging_ = ui_->callsign_aging_spin_box->value(); activity_aging_ = ui_->activity_aging_spin_box->value(); diff --git a/Configuration.hpp b/Configuration.hpp index 41aa76a..0db5b51 100644 --- a/Configuration.hpp +++ b/Configuration.hpp @@ -98,7 +98,7 @@ public: QString my_callsign () const; QString my_grid () const; QString my_station () const; - int my_dBm() const; + QString aprs_ssid() const; int activity_aging() const; int callsign_aging() const; QString my_qth () const; diff --git a/Configuration.ui b/Configuration.ui index f199a50..e176f96 100644 --- a/Configuration.ui +++ b/Configuration.ui @@ -175,6 +175,20 @@ 0 + + + + Reply Message: + + + + + + + HW CPY? + + + @@ -209,34 +223,6 @@ - - - - Station Power: - - - - - - - <html><head/><body><p>Approximate or average station transmit power to be sent in response to &quot;%&quot; directed queries. </p></body></html> - - - - - - - Reply Message: - - - - - - - HW CPY? - - - @@ -2042,21 +2028,70 @@ comments field. Network Services - - - - The program can send your station details and all + + + + 20 + + + + + The program can send your station details and all decoded signals as spots to the http://pskreporter.info web site. This is used for reverse beacon analysis which is very useful for assessing propagation and system performance. - - - Enable spotting to reporting networks (PSKReporter, APRS-IS, etc) - - - true - - + + + Enable spotting to reporting networks (PSKReporter && APRS-IS) + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + The SSID to be used for local APRS spots + + + APRS SSID: + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + -0 + + + + @@ -3100,7 +3135,6 @@ soundcard changes delete_macro_push_button macros_list_view prompt_to_log_check_box - psk_reporter_check_box udp_server_line_edit udp_server_port_spin_box accept_udp_requests_check_box @@ -3192,12 +3226,12 @@ soundcard changes - - - + + + diff --git a/mainwindow.cpp b/mainwindow.cpp index 040d052..d431fdc 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -7400,20 +7400,6 @@ void MainWindow::buildQueryMenu(QMenu * menu, QString call){ if(m_config.transmit_directed()) toggleTx(true); }); - auto sendPWRAction = menu->addAction(QString("%1 PWR - Send station power level to the selected callsign").arg(call).trimmed()); - sendPWRAction->setDisabled(isAllCall || m_config.my_dBm() < 0); - connect(sendPWRAction, &QAction::triggered, this, [this](){ - - QString selectedCall = callsignSelected(); - if(selectedCall.isEmpty()){ - return; - } - - addMessageText(QString("%1 PWR %2").arg(selectedCall).arg(Varicode::formatPWR(m_config.my_dBm())), true); - - if(m_config.transmit_directed()) toggleTx(true); - }); - menu->addSeparator(); auto snrQueryAction = menu->addAction(QString("%1? - What is my signal report?").arg(call)); @@ -8411,7 +8397,15 @@ void MainWindow::pskSetLocal () void MainWindow::aprsSetLocal () { - m_aprsClient->setLocalStation(Radio::base_callsign(m_config.my_callsign()), m_config.my_grid()); + auto ssid = m_config.aprs_ssid(); + auto call = Radio::base_callsign(m_config.my_callsign()); + if(!ssid.isEmpty()){ + if(!ssid.startsWith("-")){ + ssid = "-" + ssid; + } + call = call + ssid; + } + m_aprsClient->setLocalStation(call, m_config.my_grid()); } void MainWindow::transmitDisplay (bool transmitting) @@ -9239,10 +9233,6 @@ void MainWindow::processCommandActivity() { if (d.cmd == "?") { reply = QString("%1 SNR %2").arg(d.from).arg(Varicode::formatSNR(d.snr)); } - // QUERIED PWR - else if (d.cmd == "%" && !isAllCall && m_config.my_dBm() >= 0) { - reply = QString("%1 PWR %2").arg(d.from).arg(Varicode::formatPWR(m_config.my_dBm())); - } // QUERIED QTH else if (d.cmd == "@" && !isAllCall) { QString qth = m_config.my_qth(); diff --git a/varicode.cpp b/varicode.cpp index 180a4f2..10a2749 100644 --- a/varicode.cpp +++ b/varicode.cpp @@ -45,7 +45,7 @@ QMap directed_cmds = { {"&", 2 }, // query station message {"$", 3 }, // query station(s) heard {"^", 4 }, // query grid - {"%", 5 }, // query pwr + // {"%" 5 }, // unused {"|", 6 }, // retransmit message {"!", 7 }, // alert message {"#", 8 }, // all or nothing message @@ -68,7 +68,7 @@ QMap directed_cmds = { {" RR", 21 }, // roger roger {" QSL?", 22 }, // do you copy? {" QSL", 23 }, // i copy - {" PWR", 24 }, // power level + // {"", 24 }, // unused {" SNR", 25 }, // seen a station at the provided snr {" NO", 26 }, // negative confirm {" YES", 27 }, // confirm @@ -78,7 +78,7 @@ QMap directed_cmds = { {" ", 31 }, // send freetext }; -QSet allowed_cmds = {0, 1, 2, 3, 4, 5, 6, 7, 8, /*...*/ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; +QSet allowed_cmds = {0, 1, 2, 3, 4, /*5,*/ 6, 7, 8, /*...*/ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, /*24,*/ 25, 26, 27, 28, 29, 30, 31}; QSet buffered_cmds = {6, 7, 8, 13, 14, 15}; @@ -92,16 +92,14 @@ QMap checksum_cmds = { }; QString callsign_pattern = QString("(?[A-Z0-9/]+)"); -QString optional_cmd_pattern = QString("(?\\s?(?:AGN[?]|ACK|73|YES|NO|SNR|PWR|QSL[?]?|RR|HEARING|HW CPY[?]|FB|QTH|QTC|GRID|APRS[:]|QSO|[?@&$%|!#^ ]))?"); +QString optional_cmd_pattern = QString("(?\\s?(?:AGN[?]|ACK|73|YES|NO|SNR|QSL[?]?|RR|HEARING|HW CPY[?]|FB|QTH|QTC|GRID|APRS[:]|QSO|[?@&$%|!#^ ]))?"); QString optional_grid_pattern = QString("(?\\s?[A-R]{2}[0-9]{2})?"); QString optional_extended_grid_pattern = QString("^(?\\s?(?:[A-R]{2}[0-9]{2}(?:[A-X]{2}(?:[0-9]{2})?)*))?"); -QString optional_pwr_pattern = QString("(?(?<=PWR)\\s?\\d+\\s?[KM]?W)?"); QString optional_num_pattern = QString("(?(?<=SNR|HEARING)\\s?[-+]?(?:3[01]|[0-2]?[0-9]))?"); QRegularExpression directed_re("^" + callsign_pattern + optional_cmd_pattern + - optional_pwr_pattern + optional_num_pattern); QRegularExpression beacon_re(R"(^\s*(?CQCQCQ|BEACON)(?:\s(?[A-R]{2}[0-9]{2}))?\b)"); @@ -111,7 +109,6 @@ QRegularExpression compound_re("^\\s*[<]" + "(?" + optional_grid_pattern + optional_cmd_pattern + - optional_pwr_pattern + optional_num_pattern + ")[>]"); @@ -440,19 +437,6 @@ QString Varicode::formatSNR(int snr){ return QString("%1%2").arg(snr >= 0 ? "+" : "").arg(snr, snr < 0 ? 3 : 2, 10, QChar('0')); } -QString Varicode::formatPWR(int dbm){ - if(dbm < 0 || dbm > 60){ - return QString(); - } - - int mwatts = dbmTomwatts(dbm); - if(mwatts < 1000){ - return QString("%1mW").arg(mwatts); - } - - return QString("%1W").arg(mwatts/1000); -} - QString Varicode::checksum16(QString const &input){ auto fromBytes = input.toLocal8Bit(); auto crc = CRC::Calculate(fromBytes.data(), fromBytes.length(), CRC::CRC_16_KERMIT()); @@ -1061,43 +1045,18 @@ quint8 Varicode::packNum(QString const &num, bool *ok){ return inum + 30 + 1; } -// pack pwr string into a dbm between 0 and 62 -quint8 Varicode::packPwr(QString const &pwr, bool *ok){ - int ipwr = 0; - if(pwr.isEmpty()){ - if(ok) *ok = false; - return ipwr; - } - - int factor = 1000; - if(pwr.endsWith("KW")){ - factor = 1000000; - } - else if(pwr.endsWith("MW")){ - factor = 1; - } - - ipwr = QString(pwr).replace(QRegExp("[KM]?W", Qt::CaseInsensitive), "").toInt() * factor; - ipwr = mwattsToDbm(ipwr); - - if(ok) *ok = true; - return ipwr + 1; -} - // pack a reduced fidelity command and a number into the extra bits provided between nbasegrid and nmaxgrid quint8 Varicode::packCmd(quint8 cmd, quint8 num, bool *pPackedNum){ //quint8 allowed = nmaxgrid - nbasegrid - 1; - // if cmd == pwr || cmd == snr + // if cmd == snr quint8 value = 0; - if(cmd == directed_cmds[" PWR"] || cmd == directed_cmds[" SNR"]){ + if(cmd == directed_cmds[" SNR"]){ // 8 bits - 1 bit flag + 1 bit type + 6 bit number // [1][X][6] // X = 0 == SNR - // X = 1 == PWR - - value = ((1 << 1) + ((int)cmd == directed_cmds[" PWR"])) << 6; - value = value + num; + value = (1 << 1) << 6; + value = value + (num & ((1<<6)-1)); if(pPackedNum) *pPackedNum = true; } else { value = cmd & ((1<<7)-1); @@ -1108,18 +1067,10 @@ quint8 Varicode::packCmd(quint8 cmd, quint8 num, bool *pPackedNum){ } quint8 Varicode::unpackCmd(quint8 value, quint8 *pNum){ - // if the first bit is 1, the second bit will indicate if its pwr or snr... + // if the first bit is 1, this is an SNR with a number encoded in the lower 6 bits if(value & (1<<7)){ - // either pwr or snr... - bool pwr = value & (1<<6); - if(pNum) *pNum = value & ((1<<6)-1); - - if(pwr){ - return directed_cmds[" PWR"]; - } else { - return directed_cmds[" SNR"]; - } + return directed_cmds[" SNR"]; } else { if(pNum) *pNum = 0; return value & ((1<<7)-1); @@ -1238,7 +1189,6 @@ QString Varicode::packCompoundMessage(QString const &text, int *n){ QString grid = parsedText.captured("grid"); QString cmd = parsedText.captured("cmd"); QString num = parsedText.captured("num").trimmed(); - QString pwr = parsedText.captured("pwr").trimmed().toUpper(); QString base; QString fix; @@ -1272,9 +1222,6 @@ QString Varicode::packCompoundMessage(QString const &text, int *n){ if (!cmd.isEmpty() && directed_cmds.contains(cmd) && Varicode::isCommandAllowed(cmd)){ bool packedNum = false; qint8 inum = Varicode::packNum(num, nullptr); - if(cmd == " PWR"){ - inum = Varicode::packPwr(pwr, nullptr); - } extra = nusergrid + Varicode::packCmd(directed_cmds[cmd], inum, &packedNum); type = FrameCompoundDirected; @@ -1305,9 +1252,7 @@ QStringList Varicode::unpackCompoundMessage(const QString &text, quint8 *pType){ unpacked.append(directed_cmds.key(cmd)); - if(cmd == directed_cmds[" PWR"]){ - unpacked.append(Varicode::formatPWR(num - 1)); - } else if(cmd == directed_cmds[" SNR"]){ + if(cmd == directed_cmds[" SNR"]){ unpacked.append(Varicode::formatSNR(num - 31)); } } @@ -1412,7 +1357,6 @@ QString Varicode::packDirectedMessage(const QString &text, const QString &callsi QString to = match.captured("callsign"); QString cmd = match.captured("cmd"); QString num = match.captured("num").trimmed(); - QString pwr = match.captured("pwr").trimmed().toUpper(); // ensure we have a directed command if(cmd.isEmpty()){ @@ -1446,15 +1390,8 @@ QString Varicode::packDirectedMessage(const QString &text, const QString &callsi } // packing general number... - quint8 inum = 0; - - if(cmd.trimmed() == "PWR"){ - inum = Varicode::packPwr(pwr, nullptr); - if(pNum) *pNum = pwr; - } else { - inum = Varicode::packNum(num, nullptr); - if(pNum) *pNum = num; - } + quint8 inum = Varicode::packNum(num, nullptr); + if(pNum) *pNum = num; quint32 packed_from = Varicode::packCallsign(from); quint32 packed_to = Varicode::packCallsign(to); @@ -1517,9 +1454,7 @@ QStringList Varicode::unpackDirectedMessage(const QString &text, quint8 *pType){ if(extra != 0){ // TODO: jsherer - should we decide which format to use on the command, or something else? - if(packed_cmd == directed_cmds[" PWR"]){ - unpacked.append(Varicode::formatPWR(extra-1)); - } else if(packed_cmd == directed_cmds[" SNR"]) { + if(packed_cmd == directed_cmds[" SNR"]) { unpacked.append(Varicode::formatSNR((int)extra-31)); } else { unpacked.append(QString("%1").arg(extra-31));