Index: sources/canbus/messagebuilder.cpp =================================================================== diff -u -r1732e83d2a0308b9c706f37d6d7724a364bbff2a -r460df093c4475816fc25d6b4c3ebfc50424ccca3 --- sources/canbus/messagebuilder.cpp (.../messagebuilder.cpp) (revision 1732e83d2a0308b9c706f37d6d7724a364bbff2a) +++ sources/canbus/messagebuilder.cpp (.../messagebuilder.cpp) (revision 460df093c4475816fc25d6b4c3ebfc50424ccca3) @@ -17,6 +17,8 @@ #include // Project +#include "crc.h" + // namespace using namespace Can; @@ -62,8 +64,7 @@ void MessageBuilder::addData(QByteArray &vPayload, GuiActionType vAction, const QByteArray &vData) { - quint16 i = static_cast(vAction); - quint8 len = payloadLen[i]; + quint8 len = payloadLen[vAction]; // if len has been set to max(255) // it means it has no limit and can be as long as 255 bytes if (len == eLenMaxData) { @@ -79,63 +80,73 @@ void MessageBuilder::addCRC(QByteArray &vPayload) { - vPayload += calcCRC(vPayload); + // sync byte should not be passed for crc calculation + vPayload += calcCRC(vPayload.mid(1)); } void MessageBuilder::addPadding(QByteArray &vPayload) { vPayload = vPayload.leftJustified(eLenCanFrame, '\0'); } +// TODO : This section better to be in the MessageModel quint8 MessageBuilder::calcCRC(const QByteArray &vData) { - // TODO : calcCRC has not been used yet - Q_UNUSED(vData) -#ifdef QT_DEBUG - return ePayload_Sync; -#else - return '\0'; -#endif + quint8 crc = crc8(vData); + return crc; } // CRC is always next byte after Data +// TODO : This section better to be in the MessageModel bool MessageBuilder::checkCRC(const QByteArray &vData) { -#ifdef QT_DEBUG - //qDebug() << "qChecksum(\"0\",1) : " << qChecksum("\0",1); - // TODO : If a Message ID has not data does it still have CRC ? - if ( ! vData.length()) return false; +#ifndef DISABLE_CRC + int len = vData.length(); + if ( ! len ) return false; quint8 crc = vData.back(); - bool ok = calcCRC(vData) == crc; + quint8 got = calcCRC(vData.mid(0, len - 1)); + bool ok = got == crc; + // it's very good but I'm not sure if it's correct. + //bool ok = calcCRC(vData) == 0; + if ( ! ok ) { + qDebug() << "ch crc :" << hex << got << crc << vData.toHex('.'); + } return ok; #else - Q_UNUSED(vData) return true; #endif - - } -bool MessageBuilder::buildMessage(const QByteArray &vPayload, Message &vMessage) +bool MessageBuilder::buildMessage(const QByteArray &vPayload, Message &vMessage, Can_Id vCan_Id) { QByteArray mPayload = vPayload; - if (vMessage.data.isEmpty()) { // message is empty so expected a header + if (vMessage.data.isEmpty()) { // message is empty so expected a header if (hasSyncByte(mPayload)) { // Got header - vMessage.actionId = getActionId(mPayload); - vMessage.length = getLength (mPayload); - vMessage.data = getData (mPayload, vMessage.length); + consoleOut(vPayload, true, vCan_Id); + vMessage.can_id = vCan_Id; + vMessage.head = getHeader (mPayload); // keep header before taking it out of the payload. doesn't affect payload + vMessage.actionId = getActionId (mPayload); + vMessage.length = getLength (mPayload); + vMessage.data = getData (mPayload, vMessage.length); vMessage.initialized = true; } else { // Expected Header but got pure data - qDebug() << "ERROR :" << "Expected Header, got frame without Sync byte"; + printPayload(vPayload, false ,vCan_Id); + qDebug() << "ERROR :" << tr("Expected Header, got frame without Sync byte"); return false; } } else { + consoleOut(vPayload, false ,vCan_Id); vMessage.data += vPayload.mid(0, vMessage.length - vMessage.data.length()); } + // TODO : This section better to be in the MessageModel + // and when Message model identifies the message is complete + // will SIGNAL builder to check for crc. if (vMessage.isComplete()) { - if ( ! checkCRC(vMessage.data) ) { // CRC is always next byte after Data - qDebug() << "ERROR :" << "CRC error"; + consoleOut("", false, Can_Id::eChlid_NONE); + QByteArray crcData = vMessage.head + vMessage.data; + if ( ! checkCRC(crcData) ) { // CRC is always next byte after Data + qDebug() << "ERROR :" << tr("CRC error"); return false; } } @@ -153,6 +164,15 @@ return false; } +QByteArray MessageBuilder::getHeader(const QByteArray &vPayload) +{ + QByteArray headInfo; + for (int i = 0; i < eLenHeaderInfo; i++) { + headInfo += vPayload[i]; + } + return headInfo; +} + GuiActionType MessageBuilder::getActionId(QByteArray &vPayload) { quint16 mActionId; @@ -184,3 +204,42 @@ return mData; } +void MessageBuilder::printPayload(const QByteArray &vPayload, bool vIsHeader, Can_Id vCan_Id, bool vUseColor) +{ + if (vCan_Id == Can_Id::eChlid_NONE) { + qDebug() << " "; + return; + } + QByteArray view; + if (vUseColor) { + QList byteList; + byteList = vPayload.toHex('.').split('.'); + for (int i = 0; i < byteList.length(); i++) { + if (vIsHeader) { + if(i == 0) { + byteList[i] = QByteArray("\033[32m") + byteList[i].constData(); + } + if (i == 1 || i == 2) { + byteList[i] = QByteArray("\033[33m") + byteList[i].constData(); + } + if (i > 2) { + byteList[i] = QByteArray("\033[36m") + byteList[i].constData() + QByteArray("\033[0m"); + } + } else { + byteList[i] = QByteArray("\033[36m") + byteList[i].constData() + QByteArray("\033[0m"); + } + } + view = GuiActions::toHexString(vCan_Id, false, 3).toLatin1() + " " + byteList.join('.'); + fprintf(stderr, "%s\n", view.constData()); + } else { + view = GuiActions::toHexString(vCan_Id, false, 3).toLatin1() + " " + vPayload.toHex('.'); + fprintf(stderr, "%s\n", view.constData()); + } +} + +void MessageBuilder::consoleOut(const QByteArray &vPayload, bool vIsHeader, Can_Id vCan_Id, bool vUseColor) +{ + if ( ! _enableConsoleOut) return; + printPayload(vPayload, vIsHeader, vCan_Id, vUseColor); + +}