Use the low confidence decode quality marker to elide spots and pass info via UDP

The UDP  decode and reply message  have been augmented with  a boolean
flag denoting a  low confidence decode when set.  Existing clients can
safely use the  reply message without passing the flag  as the default
value will  still action  messages that have  high confidence.  If low
confidence decodes  are to be passed  back via the reply  message then
the low  confidence flag must be  included and correctly set  to match
the original decode.

See NetworkMessage.hpp for message fields and meanings.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7957 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Bill Somerville 2017-07-26 21:18:59 +00:00
parent 8fe7d5c5de
commit ee2badb86f
14 changed files with 72 additions and 40 deletions

View File

@ -151,11 +151,13 @@ void MessageClient::impl::parse_message (QByteArray const& msg)
quint32 delta_frequency; quint32 delta_frequency;
QByteArray mode; QByteArray mode;
QByteArray message; QByteArray message;
in >> time >> snr >> delta_time >> delta_frequency >> mode >> message; bool low_confidence {false};
in >> time >> snr >> delta_time >> delta_frequency >> mode >> message >> low_confidence;
if (check_status (in) != Fail) if (check_status (in) != Fail)
{ {
Q_EMIT self_->reply (time, snr, delta_time, delta_frequency Q_EMIT self_->reply (time, snr, delta_time, delta_frequency
, QString::fromUtf8 (mode), QString::fromUtf8 (message)); , QString::fromUtf8 (mode), QString::fromUtf8 (message)
, low_confidence);
} }
} }
break; break;
@ -366,13 +368,14 @@ void MessageClient::status_update (Frequency f, QString const& mode, QString con
} }
void MessageClient::decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency void MessageClient::decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
, QString const& mode, QString const& message_text) , QString const& mode, QString const& message_text, bool low_confidence)
{ {
if (m_->server_port_ && !m_->server_string_.isEmpty ()) if (m_->server_port_ && !m_->server_string_.isEmpty ())
{ {
QByteArray message; QByteArray message;
NetworkMessage::Builder out {&message, NetworkMessage::Decode, m_->id_, m_->schema_}; NetworkMessage::Builder out {&message, NetworkMessage::Decode, m_->id_, m_->schema_};
out << is_new << time << snr << delta_time << delta_frequency << mode.toUtf8 () << message_text.toUtf8 (); out << is_new << time << snr << delta_time << delta_frequency << mode.toUtf8 ()
<< message_text.toUtf8 () << low_confidence;
m_->send_message (out, message); m_->send_message (out, message);
} }
} }

View File

@ -53,7 +53,7 @@ public:
, QString const& dx_grid, bool watchdog_timeout, QString const& sub_mode , QString const& dx_grid, bool watchdog_timeout, QString const& sub_mode
, bool fast_mode); , bool fast_mode);
Q_SLOT void decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency Q_SLOT void decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
, QString const& mode, QString const& message); , QString const& mode, QString const& message, bool low_confidence);
Q_SLOT void WSPR_decode (bool is_new, QTime time, qint32 snr, float delta_time, Frequency Q_SLOT void WSPR_decode (bool is_new, QTime time, qint32 snr, float delta_time, Frequency
, qint32 drift, QString const& callsign, QString const& grid, qint32 power); , qint32 drift, QString const& callsign, QString const& grid, qint32 power);
Q_SLOT void clear_decodes (); Q_SLOT void clear_decodes ();
@ -70,7 +70,7 @@ public:
// this signal is emitted if the server sends us a reply, the only // this signal is emitted if the server sends us a reply, the only
// reply supported is reply to a prior CQ or QRZ message // reply supported is reply to a prior CQ or QRZ message
Q_SIGNAL void reply (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode Q_SIGNAL void reply (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode
, QString const& message_text); , QString const& message_text, bool low_confidence);
// this signal is emitted if the server has requested a replay of // this signal is emitted if the server has requested a replay of
// all decodes // all decodes

View File

@ -241,11 +241,14 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s
quint32 delta_frequency; quint32 delta_frequency;
QByteArray mode; QByteArray mode;
QByteArray message; QByteArray message;
in >> is_new >> time >> snr >> delta_time >> delta_frequency >> mode >> message; bool low_confidence;
in >> is_new >> time >> snr >> delta_time >> delta_frequency >> mode
>> message >> low_confidence;
if (check_status (in) != Fail) if (check_status (in) != Fail)
{ {
Q_EMIT self_->decode (is_new, id, time, snr, delta_time, delta_frequency Q_EMIT self_->decode (is_new, id, time, snr, delta_time, delta_frequency
, QString::fromUtf8 (mode), QString::fromUtf8 (message)); , QString::fromUtf8 (mode), QString::fromUtf8 (message)
, low_confidence);
} }
} }
break; break;
@ -396,14 +399,15 @@ void MessageServer::start (port_type port, QHostAddress const& multicast_group_a
} }
} }
void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text) void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text, bool low_confidence)
{ {
auto iter = m_->clients_.find (id); auto iter = m_->clients_.find (id);
if (iter != std::end (m_->clients_)) if (iter != std::end (m_->clients_))
{ {
QByteArray message; QByteArray message;
NetworkMessage::Builder out {&message, NetworkMessage::Reply, id, (*iter).negotiated_schema_number_}; NetworkMessage::Builder out {&message, NetworkMessage::Reply, id, (*iter).negotiated_schema_number_};
out << time << snr << delta_time << delta_frequency << mode.toUtf8 () << message_text.toUtf8 (); out << time << snr << delta_time << delta_frequency << mode.toUtf8 ()
<< message_text.toUtf8 () << low_confidence;
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_); m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
} }
} }

View File

@ -46,7 +46,7 @@ public:
// note that the client is not obliged to take any action and only // note that the client is not obliged to take any action and only
// takes any action if the decode is present and is a CQ or QRZ message // takes any action if the decode is present and is a CQ or QRZ message
Q_SLOT void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency Q_SLOT void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
, QString const& mode, QString const& message); , QString const& mode, QString const& message, bool low_confidence);
// ask the client with identification 'id' to replay all decodes // ask the client with identification 'id' to replay all decodes
Q_SLOT void replay (QString const& id); Q_SLOT void replay (QString const& id);
@ -69,7 +69,8 @@ public:
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode); , bool watchdog_timeout, QString const& sub_mode, bool fast_mode);
Q_SIGNAL void client_closed (QString const& id); Q_SIGNAL void client_closed (QString const& id);
Q_SIGNAL void decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time Q_SIGNAL void decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time
, quint32 delta_frequency, QString const& mode, QString const& message); , quint32 delta_frequency, QString const& mode, QString const& message
, bool low_confidence);
Q_SIGNAL void WSPR_decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time, Frequency Q_SIGNAL void WSPR_decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time, Frequency
, qint32 drift, QString const& callsign, QString const& grid, qint32 power); , qint32 drift, QString const& callsign, QString const& grid, qint32 power);
Q_SIGNAL void qso_logged (QString const& id, QDateTime timeOff, QString const& dx_call, QString const& dx_grid Q_SIGNAL void qso_logged (QString const& id, QDateTime timeOff, QString const& dx_call, QString const& dx_grid

View File

@ -156,13 +156,19 @@
* Delta frequency (Hz) quint32 * Delta frequency (Hz) quint32
* Mode utf8 * Mode utf8
* Message utf8 * Message utf8
* Low confidence bool
* *
* The decode message is sent when a new decode is completed, in * The decode message is sent when a new decode is completed, in
* this case the 'New' field is true. It is also used in response * this case the 'New' field is true. It is also used in response
* to a "Replay" message where each old decode in the "Band * to a "Replay" message where each old decode in the "Band
* activity" window, that has not been erased, is sent in order * activity" window, that has not been erased, is sent in order
* as a one of these messages with the 'New' field set to * as a one of these messages with the 'New' field set to false.
* false. See the "Replay" message below for details of usage. * See the "Replay" message below for details of usage. Low
* confidence decodes are flagged in protocols where the decoder
* has knows that a decode has a higher than normal probability
* of being false, they should not be reported on publicly
* accessible services without some attached warning or further
* validation.
* *
* *
* Clear Out 3 quint32 * Clear Out 3 quint32
@ -184,6 +190,7 @@
* Delta frequency (Hz) quint32 * Delta frequency (Hz) quint32
* Mode utf8 * Mode utf8
* Message utf8 * Message utf8
* Low confidence bool
* *
* In order for a server to provide a useful cooperative service * In order for a server to provide a useful cooperative service
* to WSJT-X it is possible for it to initiate a QSO by sending * to WSJT-X it is possible for it to initiate a QSO by sending

View File

@ -244,7 +244,7 @@ void ClientWidget::update_status (QString const& id, Frequency f, QString const&
void ClientWidget::decode_added (bool /*is_new*/, QString const& client_id, QTime /*time*/, qint32 /*snr*/ void ClientWidget::decode_added (bool /*is_new*/, QString const& client_id, QTime /*time*/, qint32 /*snr*/
, float /*delta_time*/, quint32 /*delta_frequency*/, QString const& /*mode*/ , float /*delta_time*/, quint32 /*delta_frequency*/, QString const& /*mode*/
, QString const& /*message*/) , QString const& /*message*/, bool /*low_confidence*/)
{ {
if (client_id == id_) if (client_id == id_)
{ {

View File

@ -33,7 +33,7 @@ public:
, bool watchdog_timeout, QString const& sub_mode, bool fast_mode); , bool watchdog_timeout, QString const& sub_mode, bool fast_mode);
Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime, qint32 snr Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime, qint32 snr
, float delta_time, quint32 delta_frequency, QString const& mode , float delta_time, quint32 delta_frequency, QString const& mode
, QString const& message); , QString const& message, bool low_confidence);
Q_SLOT void beacon_spot_added (bool is_new, QString const& client_id, QTime, qint32 snr Q_SLOT void beacon_spot_added (bool is_new, QString const& client_id, QTime, qint32 snr
, float delta_time, Frequency delta_frequency, qint32 drift , float delta_time, Frequency delta_frequency, qint32 drift
, QString const& callsign, QString const& grid, qint32 power); , QString const& callsign, QString const& grid, qint32 power);

View File

@ -17,13 +17,19 @@ namespace
QT_TRANSLATE_NOOP ("DecodesModel", "DF"), QT_TRANSLATE_NOOP ("DecodesModel", "DF"),
QT_TRANSLATE_NOOP ("DecodesModel", "Md"), QT_TRANSLATE_NOOP ("DecodesModel", "Md"),
QT_TRANSLATE_NOOP ("DecodesModel", "Message"), QT_TRANSLATE_NOOP ("DecodesModel", "Message"),
QT_TRANSLATE_NOOP ("DecodesModel", "Confidence"),
}; };
QString confidence_string (bool low_confidence)
{
return low_confidence ? QT_TRANSLATE_NOOP ("DecodesModel", "low") : QT_TRANSLATE_NOOP ("DecodesModel", "high");
}
QFont text_font {"Courier", 10}; QFont text_font {"Courier", 10};
QList<QStandardItem *> make_row (QString const& client_id, QTime time, qint32 snr, float delta_time QList<QStandardItem *> make_row (QString const& client_id, QTime time, qint32 snr, float delta_time
, quint32 delta_frequency, QString const& mode, QString const& message , quint32 delta_frequency, QString const& mode, QString const& message
, bool is_fast) , bool low_confidence, bool is_fast)
{ {
auto time_item = new QStandardItem {time.toString (is_fast || "~" == mode ? "hh:mm:ss" : "hh:mm")}; auto time_item = new QStandardItem {time.toString (is_fast || "~" == mode ? "hh:mm:ss" : "hh:mm")};
time_item->setData (time); time_item->setData (time);
@ -44,8 +50,11 @@ namespace
auto md = new QStandardItem {mode}; auto md = new QStandardItem {mode};
md->setTextAlignment (Qt::AlignHCenter); md->setTextAlignment (Qt::AlignHCenter);
auto confidence = new QStandardItem {confidence_string (low_confidence)};
confidence->setTextAlignment (Qt::AlignHCenter);
QList<QStandardItem *> row { QList<QStandardItem *> row {
new QStandardItem {client_id}, time_item, snr_item, dt, df, md, new QStandardItem {message}}; new QStandardItem {client_id}, time_item, snr_item, dt, df, md, new QStandardItem {message}, confidence};
Q_FOREACH (auto& item, row) Q_FOREACH (auto& item, row)
{ {
item->setEditable (false); item->setEditable (false);
@ -57,7 +66,7 @@ namespace
} }
DecodesModel::DecodesModel (QObject * parent) DecodesModel::DecodesModel (QObject * parent)
: QStandardItemModel {0, 7, parent} : QStandardItemModel {0, sizeof (headings) / sizeof (headings[0]), parent}
{ {
int column {0}; int column {0};
for (auto const& heading : headings) for (auto const& heading : headings)
@ -68,7 +77,7 @@ DecodesModel::DecodesModel (QObject * parent)
void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
, quint32 delta_frequency, QString const& mode, QString const& message , quint32 delta_frequency, QString const& mode, QString const& message
, bool is_fast) , bool low_confidence, bool is_fast)
{ {
if (!is_new) if (!is_new)
{ {
@ -83,7 +92,8 @@ void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time
&& item (row, 3)->data ().toFloat () == delta_time && item (row, 3)->data ().toFloat () == delta_time
&& item (row, 4)->data ().toUInt () == delta_frequency && item (row, 4)->data ().toUInt () == delta_frequency
&& data (index (row, 5)).toString () == mode && data (index (row, 5)).toString () == mode
&& data (index (row, 6)).toString () == message) && data (index (row, 6)).toString () == message
&& data (index (row, 7)).toString () == confidence_string (low_confidence))
{ {
return; return;
} }
@ -96,12 +106,12 @@ void DecodesModel::add_decode (bool is_new, QString const& client_id, QTime time
if (target_row >= 0) if (target_row >= 0)
{ {
insertRow (target_row + 1, make_row (client_id, time, snr, delta_time, delta_frequency, mode insertRow (target_row + 1, make_row (client_id, time, snr, delta_time, delta_frequency, mode
, message, is_fast)); , message, low_confidence, is_fast));
return; return;
} }
} }
appendRow (make_row (client_id, time, snr, delta_time, delta_frequency, mode, message, is_fast)); appendRow (make_row (client_id, time, snr, delta_time, delta_frequency, mode, message, low_confidence, is_fast));
} }
void DecodesModel::clear_decodes (QString const& client_id) void DecodesModel::clear_decodes (QString const& client_id)
@ -124,7 +134,8 @@ void DecodesModel::do_reply (QModelIndex const& source)
, item (row, 3)->data ().toFloat () , item (row, 3)->data ().toFloat ()
, item (row, 4)->data ().toInt () , item (row, 4)->data ().toInt ()
, data (index (row, 5)).toString () , data (index (row, 5)).toString ()
, data (index (row, 6)).toString ()); , data (index (row, 6)).toString ()
, confidence_string (true) == data (index (row, 7)).toString ());
} }
#include "moc_DecodesModel.cpp" #include "moc_DecodesModel.cpp"

View File

@ -32,12 +32,13 @@ public:
explicit DecodesModel (QObject * parent = nullptr); explicit DecodesModel (QObject * parent = nullptr);
Q_SLOT void add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time Q_SLOT void add_decode (bool is_new, QString const& client_id, QTime time, qint32 snr, float delta_time
, quint32 delta_frequency, QString const& mode, QString const& message, bool is_fast); , quint32 delta_frequency, QString const& mode, QString const& message
, bool low_confidence, bool is_fast);
Q_SLOT void clear_decodes (QString const& client_id); Q_SLOT void clear_decodes (QString const& client_id);
Q_SLOT void do_reply (QModelIndex const& source); Q_SLOT void do_reply (QModelIndex const& source);
Q_SIGNAL void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency Q_SIGNAL void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency
, QString const& mode, QString const& message); , QString const& mode, QString const& message, bool low_confidence);
}; };
#endif #endif

View File

@ -91,9 +91,9 @@ MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
connect (server_, &MessageServer::decode, [this] (bool is_new, QString const& id, QTime time connect (server_, &MessageServer::decode, [this] (bool is_new, QString const& id, QTime time
, qint32 snr, float delta_time , qint32 snr, float delta_time
, quint32 delta_frequency, QString const& mode , quint32 delta_frequency, QString const& mode
, QString const& message) { , QString const& message, bool low_confidence) {
decodes_model_->add_decode (is_new, id, time, snr, delta_time, delta_frequency, mode, message decodes_model_->add_decode (is_new, id, time, snr, delta_time, delta_frequency, mode, message
, dock_widgets_[id]->fast_mode ());}); , low_confidence, dock_widgets_[id]->fast_mode ());});
connect (server_, &MessageServer::WSPR_decode, beacons_model_, &BeaconsModel::add_beacon_spot); connect (server_, &MessageServer::WSPR_decode, beacons_model_, &BeaconsModel::add_beacon_spot);
connect (server_, &MessageServer::clear_decodes, decodes_model_, &DecodesModel::clear_decodes); connect (server_, &MessageServer::clear_decodes, decodes_model_, &DecodesModel::clear_decodes);
connect (server_, &MessageServer::clear_decodes, beacons_model_, &BeaconsModel::clear_decodes); connect (server_, &MessageServer::clear_decodes, beacons_model_, &BeaconsModel::clear_decodes);

View File

@ -69,13 +69,13 @@ public:
Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime time, qint32 snr Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime time, qint32 snr
, float delta_time, quint32 delta_frequency, QString const& mode , float delta_time, quint32 delta_frequency, QString const& mode
, QString const& message) , QString const& message, bool low_confidence)
{ {
if (client_id == id_) if (client_id == id_)
{ {
qDebug () << "new:" << is_new << "t:" << time << "snr:" << snr qDebug () << "new:" << is_new << "t:" << time << "snr:" << snr
<< "Dt:" << delta_time << "Df:" << delta_frequency << "Dt:" << delta_time << "Df:" << delta_frequency
<< "mode:" << mode; << "mode:" << mode << "Confidence:" << (low_confidence ? "low" : "high");
std::cout << tr ("%1: Decoded %2").arg (id_).arg (message).toStdString () << std::endl; std::cout << tr ("%1: Decoded %2").arg (id_).arg (message).toStdString () << std::endl;
} }
} }

View File

@ -56,6 +56,11 @@ bool DecodedText::isTX()
return (i >= 0 && i < 15); // TODO guessing those numbers. Does Tx ever move? return (i >= 0 && i < 15); // TODO guessing those numbers. Does Tx ever move?
} }
bool DecodedText::isLowConfidence ()
{
return QChar {'?'} == _string.mid (padding_ + column_qsoText + 21, 1);
}
int DecodedText::frequencyOffset() int DecodedText::frequencyOffset()
{ {
return _string.mid(column_freq + padding_,4).toInt(); return _string.mid(column_freq + padding_,4).toInt();

View File

@ -57,6 +57,7 @@ public:
bool isJT65(); bool isJT65();
bool isJT9(); bool isJT9();
bool isTX(); bool isTX();
bool isLowConfidence ();
int frequencyOffset(); // hertz offset from the tuned dial or rx frequency, aka audio frequency int frequencyOffset(); // hertz offset from the tuned dial or rx frequency, aka audio frequency
int snr(); int snr();
float dt(); float dt();

View File

@ -1440,7 +1440,7 @@ void MainWindow::fastSink(qint64 frames)
bool stdMsg = decodedtext.report(m_baseCall, bool stdMsg = decodedtext.report(m_baseCall,
Radio::base_callsign(ui->dxCallEntry->text()),m_rptRcvd); Radio::base_callsign(ui->dxCallEntry->text()),m_rptRcvd);
decodedtext=message.mid(0,4) + message.mid(6,-1); decodedtext=message.mid(0,4) + message.mid(6,-1);
if(m_config.spot_to_psk_reporter() and stdMsg and !m_diskData) pskPost(decodedtext); if (stdMsg) pskPost (decodedtext);
} }
float fracTR=float(k)/(12000.0*m_TRperiod); float fracTR=float(k)/(12000.0*m_TRperiod);
@ -2593,9 +2593,7 @@ void::MainWindow::fast_decode_done()
Radio::base_callsign(ui->dxCallEntry->text()), m_rptRcvd); Radio::base_callsign(ui->dxCallEntry->text()), m_rptRcvd);
// extract details and send to PSKreporter // extract details and send to PSKreporter
if(m_config.spot_to_psk_reporter() and stdMsg and !m_diskData) { if (stdMsg) pskPost(decodedtext);
pskPost(decodedtext);
}
} }
} }
m_startAnother=m_loopall; m_startAnother=m_loopall;
@ -2774,9 +2772,7 @@ void MainWindow::readFromStdout() //readFromStdout
// extract details and send to PSKreporter // extract details and send to PSKreporter
int nsec=QDateTime::currentMSecsSinceEpoch()/1000-m_secBandChanged; int nsec=QDateTime::currentMSecsSinceEpoch()/1000-m_secBandChanged;
bool okToPost=(nsec>(4*m_TRperiod)/5); bool okToPost=(nsec>(4*m_TRperiod)/5);
if(m_config.spot_to_psk_reporter () and stdMsg and !m_diskData and okToPost) { if (stdMsg && okToPost) pskPost(decodedtext);
pskPost(decodedtext);
}
if((m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64") and m_msgAvgWidget!=NULL) { if((m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64") and m_msgAvgWidget!=NULL) {
if(m_msgAvgWidget->isVisible()) { if(m_msgAvgWidget->isVisible()) {
@ -2830,8 +2826,10 @@ void MainWindow::auto_sequence (QString const& message, unsigned tolerance)
} }
} }
void MainWindow::pskPost(DecodedText decodedtext) void MainWindow::pskPost (DecodedText decodedtext)
{ {
if (m_diskData || !m_config.spot_to_psk_reporter() || decodedtext.isLowConfidence ()) return;
QString msgmode=m_mode; QString msgmode=m_mode;
if(m_mode=="JT9+JT65") { if(m_mode=="JT9+JT65") {
msgmode="JT9"; msgmode="JT9";
@ -6157,14 +6155,15 @@ void MainWindow::postDecode (bool is_new, QString const& message)
{ {
auto const& decode = message.trimmed (); auto const& decode = message.trimmed ();
auto const& parts = decode.left (22).split (' ', QString::SkipEmptyParts); auto const& parts = decode.left (22).split (' ', QString::SkipEmptyParts);
if (parts.size () >= 5) if (!m_diskData && parts.size () >= 5)
{ {
auto has_seconds = parts[0].size () > 4; auto has_seconds = parts[0].size () > 4;
m_messageClient->decode (is_new m_messageClient->decode (is_new
, QTime::fromString (parts[0], has_seconds ? "hhmmss" : "hhmm") , QTime::fromString (parts[0], has_seconds ? "hhmmss" : "hhmm")
, parts[1].toInt () , parts[1].toInt ()
, parts[2].toFloat (), parts[3].toUInt (), parts[4][0] , parts[2].toFloat (), parts[3].toUInt (), parts[4][0]
, decode.mid (has_seconds ? 24 : 22)); , decode.mid (has_seconds ? 24 : 22, 21)
, QChar {'?'} == decode.mid (has_seconds ? 24 + 21 : 22 + 21, 1));
} }
} }