Allow for HRD to fragment command replies

Also cleaned up some debugging messages.

Merged from wsjtx-1.4 branch.



git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5141 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Bill Somerville 2015-04-02 10:28:10 +00:00
parent a7a60412c5
commit aa7e6b7a86
2 changed files with 60 additions and 42 deletions

View File

@ -52,7 +52,7 @@ struct HRDMessage
delete [] reinterpret_cast<char *> (p); // Mirror allocation in operator new above.
}
qint32 size_;
quint32 size_;
qint32 magic_1_;
qint32 magic_2_;
qint32 checksum_; // Apparently not used.
@ -931,7 +931,7 @@ QString HRDTransceiver::send_command (QString const& cmd, bool no_debug, bool pr
if (QTcpSocket::ConnectedState != hrd_->state ())
{
#if WSJT_TRACE_CAT
qDebug () << "HRDTransceiver::send_command \"" << cmd << "\" failed" << hrd_->errorString ();
qDebug () << "HRDTransceiver::send_command" << cmd << "failed" << hrd_->errorString ();
#endif
throw error {
@ -947,7 +947,7 @@ QString HRDTransceiver::send_command (QString const& cmd, bool no_debug, bool pr
if (!write_to_port (message.constData (), message.size ()))
{
#if WSJT_TRACE_CAT
qDebug () << "HRDTransceiver::send_command failed to write command \"" << cmd << "\" to HRD";
qDebug () << "HRDTransceiver::send_command failed to write command" << cmd << "to HRD";
#endif
throw error {
@ -959,11 +959,11 @@ QString HRDTransceiver::send_command (QString const& cmd, bool no_debug, bool pr
else
{
auto string = prepend_context ? context + cmd : cmd;
QScopedPointer<HRDMessage> message (new (string) HRDMessage);
QScopedPointer<HRDMessage> message {new (string) HRDMessage};
if (!write_to_port (reinterpret_cast<char const *> (message.data ()), message->size_))
{
#if WSJT_TRACE_CAT
qDebug () << "HRDTransceiver::send_command failed to write command \"" << cmd << "\" to HRD";
qDebug () << "HRDTransceiver::send_command failed to write command" << cmd << "to HRD";
#endif
throw error {
@ -973,40 +973,7 @@ QString HRDTransceiver::send_command (QString const& cmd, bool no_debug, bool pr
}
}
// waitForReadReady appears to be occasionally unreliable on Windows
// timing out when data is waiting so retry a few times
unsigned retries {3};
bool replied {false};
while (!replied && retries--)
{
replied = hrd_->waitForReadyRead ();
if (!replied && hrd_->error () != hrd_->SocketTimeoutError)
{
#if WSJT_TRACE_CAT
qDebug () << "HRDTransceiver::send_command \"" << cmd << "\" failed to reply" << hrd_->errorString ();
#endif
throw error {
tr ("Ham Radio Deluxe failed to reply to command \"%1\" %2\n")
.arg (cmd)
.arg (hrd_->errorString ())
};
}
}
if (!replied)
{
#if WSJT_TRACE_CAT
qDebug () << "HRDTransceiver::send_command \"" << cmd << "\" retries exhausted";
#endif
throw error {
tr ("Ham Radio Deluxe retries exhausted sending command \"%1\"")
.arg (cmd)
};
}
QByteArray buffer (hrd_->readAll ());
auto buffer = read_reply (cmd);
if (v4 == protocol_)
{
@ -1014,12 +981,12 @@ QString HRDTransceiver::send_command (QString const& cmd, bool no_debug, bool pr
}
else
{
HRDMessage const * reply (new (buffer) HRDMessage);
HRDMessage const * reply {new (buffer) HRDMessage};
if (reply->magic_1_value_ != reply->magic_1_ && reply->magic_2_value_ != reply->magic_2_)
{
#if WSJT_TRACE_CAT
qDebug () << "HRDTransceiver::send_command \"" << cmd << "\" invalid reply";
qDebug () << "HRDTransceiver::send_command" << cmd << "invalid reply";
#endif
throw error {
@ -1028,6 +995,17 @@ QString HRDTransceiver::send_command (QString const& cmd, bool no_debug, bool pr
};
}
// keep reading until expected size arrives
while (buffer.size () - offsetof (HRDMessage, size_) < reply->size_)
{
#if WSJT_TRACE_CAT
qDebug () << "HRDTransceiver::send_command" << cmd << "reading more reply data";
#endif
buffer += read_reply (cmd);
reply = new (buffer) HRDMessage;
}
result = QString {reply->payload_}; // this is not a memory leak (honest!)
}
@ -1057,12 +1035,50 @@ bool HRDTransceiver::write_to_port (char const * data, qint64 length)
return true;
}
QByteArray HRDTransceiver::read_reply (QString const& cmd)
{
// waitForReadReady appears to be occasionally unreliable on Windows
// timing out when data is waiting so retry a few times
unsigned retries {3};
bool replied {false};
while (!replied && retries--)
{
replied = hrd_->waitForReadyRead ();
if (!replied && hrd_->error () != hrd_->SocketTimeoutError)
{
#if WSJT_TRACE_CAT
qDebug () << "HRDTransceiver::send_command" << cmd << "failed to reply" << hrd_->errorString ();
#endif
throw error {
tr ("Ham Radio Deluxe failed to reply to command \"%1\" %2\n")
.arg (cmd)
.arg (hrd_->errorString ())
};
}
}
if (!replied)
{
#if WSJT_TRACE_CAT
qDebug () << "HRDTransceiver::send_command" << cmd << "retries exhausted";
#endif
throw error {
tr ("Ham Radio Deluxe retries exhausted sending command \"%1\"")
.arg (cmd)
};
}
return hrd_->readAll ();
}
void HRDTransceiver::send_simple_command (QString const& command, bool no_debug)
{
if ("OK" != send_command (command, no_debug))
{
#if WSJT_TRACE_CAT
qDebug () << "HRDTransceiver::send_simple_command \"" << command << "\" unexpected response";
qDebug () << "HRDTransceiver::send_simple_command" << command << "unexpected response";
#endif
throw error {

View File

@ -14,6 +14,7 @@
class QRegExp;
class QTcpSocket;
class QByteArray;
//
// Ham Radio Deluxe Transceiver Interface
@ -50,6 +51,7 @@ protected:
private:
QString send_command (QString const&, bool no_debug = false, bool prepend_context = true, bool recurse = false);
QByteArray read_reply (QString const& command);
void send_simple_command (QString const&, bool no_debug = false);
bool write_to_port (char const *, qint64 length);
int find_button (QRegExp const&) const;