Files
pilotclient/src/blackmisc/com_handler.cpp

127 lines
3.7 KiB
C++

//! Copyright (C) 2013 Roland Winklmeier
//! This Source Code Form is subject to the terms of the Mozilla Public
//! License, v. 2.0. If a copy of the MPL was not distributed with this
//! file, You can obtain one at http://mozilla.org/MPL/2.0/
#include "blackmisc/com_handler.h"
#include "blackmisc/debug.h"
#include <QTcpSocket>
#include <QDataStream>
namespace BlackMisc
{
IComHandler::IComHandler(IContext &context, QObject *parent) :
QObject(parent),
m_context(context)
{
}
void IComHandler::createFrame(const QString& messageID, const QByteArray &data)
{
m_sender_buffer.clear();
QDataStream stream(&m_sender_buffer, QIODevice::WriteOnly);
qint32 message_size = data.size();
quint16 crc = qChecksum(data.constData(), message_size);
stream << (qint32)Sync_Marker
<< (qint32)message_size
<< (QString)messageID;
stream.writeRawData(data.constData(), message_size);
stream << (quint16)crc;
}
bool IComHandler::parseFrame(QString &messageID, QByteArray &data)
{
if (m_receive_buffer.isEmpty())
return false;
qint32 total_length = 0;
qint32 min_size = 3 * (int)sizeof(qint32);
if (m_receive_buffer.size() < min_size)
{
bDebug(m_context) << "Received data is to small to read SYNC and frame length!";
return false;
}
bool found_sync = false;
QDataStream stream (m_receive_buffer);
/////////////////////////////////////////////////
// Read the Sync
/////////////////////////////////////////////////
do
{
qint32 sync = 0;
stream >> sync;
if (sync == Sync_Marker)
found_sync = true;
}
while (!found_sync && !stream.atEnd());
if (!found_sync)
{
bWarning(m_context) << "Could not find sync pattern in the stream. Discarding all data!";
m_receive_buffer.clear();
return false;
}
total_length += (int)sizeof(qint32); // Sync
/////////////////////////////////////////////////
// Read size of the message itself
/////////////////////////////////////////////////
qint32 message_length = 0;
stream >> message_length;
total_length += (int)sizeof(qint32); // Length
total_length += message_length; // Data
/////////////////////////////////////////////////
// Read the message id
/////////////////////////////////////////////////
stream >> messageID;
total_length += sizeof(QChar) * messageID.length() + (int)sizeof(quint32); // ID
if (m_receive_buffer.size() < (total_length + (int)sizeof (quint16)))
{
bDebug(m_context) << "Received data is to small to read data block!";
return false;
}
/////////////////////////////////////////////////
// Read the data
/////////////////////////////////////////////////
data.resize(message_length);
// creates warning when compiled as RELEASE
qint32 bytes = stream.readRawData(data.data(), message_length);
Q_ASSERT (bytes == message_length);
Q_ASSERT (data.size() == message_length);
quint16 crc_calc = qChecksum (data.constData(), data.size());
quint16 crc_recv = 0;
stream >> crc_recv;
total_length += (int)sizeof(quint16);
m_receive_buffer.remove(0, total_length);
if (crc_calc != crc_recv)
{
bWarning(m_context) << "Message CRC error!";
data.clear();
return false;
}
return true;
}
} // namespace BlackMisc