Index: sources/canbus/caninterface.cpp =================================================================== diff -u -rd2035a8728794afeefaa244bf8d1597926d945f5 -red5d989264015440d9da6d0830679394a323cf55 --- sources/canbus/caninterface.cpp (.../caninterface.cpp) (revision d2035a8728794afeefaa244bf8d1597926d945f5) +++ sources/canbus/caninterface.cpp (.../caninterface.cpp) (revision ed5d989264015440d9da6d0830679394a323cf55) @@ -1,432 +1,432 @@ /*! - * + * * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * \copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. - * + * * \file caninterface.cpp * \author (last) Behrouz NematiPour * \date (last) 07-May-2020 * \author (original) Behrouz NematiPour * \date (original) 28-Oct-2019 - * + * */ -#include "caninterface.h" - -// Qt -#include -#include - -// stl -#include - -// Project -#include "logger.h" -#include "messageglobals.h" -#include "frameinterface.h" - -// namespace -using namespace Can; - -/*! - * \brief CanInterface::CanInterface - * \details Constructor - * \param parent - QObject parent owner object. - * Qt handles the children destruction by their parent objects life-cycle. - */ -CanInterface::CanInterface(QObject *parent) : QObject(parent) { } - -/*! - * \brief CanInterface Initialization - * \details Initializes the CANBUS and checks if can be connected - * \return true if connected, false otherwise - */ -bool CanInterface::init() -{ - if ( _init ) return false; - _init = true; - - // coco begin validated: Manually tested since required to disable and enable the canbus - if ( ! initDevice() ) return false; - // coco end - if ( ! testDevice() ) return false; - - initConnections(); - - status(tr("Connected")); - QString logMessage = QString("UI,%1,%2") - .arg(tr("%1 Initialized").arg(metaObject()->className())) - .arg(status()); - LOG_EVENT(logMessage); - - return true; -} - -/*! - * \brief CanInterface::init - * \details Initialized the Class by calling the init() method first - * And initializes the thread vThread by calling initThread - * on success init(). - * \param vThread - the thread - * \return returns the return value of the init() method - */ -bool CanInterface::init(QThread &vThread) -{ - // coco begin validated: Manually tested since required to disable and enable the canbus - if ( ! init() ) return false; - // coco end - initThread(vThread); - return true; -} - -/*! - * \brief CanInterface quit - * \details quits the class - * Calls quitThread - */ -void CanInterface::quit() -{ - // coco begin validated: Application termination is not correctly done in coco!!! - // it has been tested and works perfectly fine in normal run. - quitThread(); // verified -} -// coco end - -/*! - * \brief CanInterface status - * \details CanInterface status description - * \return The current stores status - */ -QString CanInterface::status() const -{ - return _canStatus; -} - -/*! - * \brief CanInterface::enableConsoleOut - * \details Enable or Disables the console output and logs the status - * \param vEnabled - Enalbe console output if true - */ -void CanInterface::enableConsoleOut(bool vEnabled) { - // coco begin validated: This code meant to be used only for debugging and tested manually - if (_enableConsoleOut == vEnabled) return; - _enableConsoleOut = vEnabled; - if (_enableConsoleOut) { - LOG_DEBUG("Console out CanInterface enabled"); - } else { - LOG_DEBUG("Console out CanInterface disabled"); - } -} -// coco end - -/*! - * \brief CanInterface connections definition - * \details Initializes the required signal/slot connection between this class and other objects - * to be able to communicate. - */ -void CanInterface::initConnections() -{ - // coco begin validated: Manually tested since required to disable and enable the canbus - if (_canDevice) { - // coco end - connect(_canDevice, SIGNAL( framesReceived()), - this , SLOT (onFrameReceive ())); - - connect(_canDevice, SIGNAL( errorOccurred(QCanBusDevice::CanBusError)), - this , SLOT (onFrameError (QCanBusDevice::CanBusError))); - - connect(_canDevice, SIGNAL( framesWritten(qint64)), - this , SLOT (onFrameWritten (qint64))); - } - connect(&_FrameInterface, SIGNAL(didFrameTransmit(QCanBusFrame)), - this , SLOT( onFrameTransmit(QCanBusFrame))); -} - -/*! - * \brief CanInterface::initThread - * \details Moves this object into the thread vThread. - * And checks that this method is called from main thread. - * Also connects quitThread to application aboutToQuit. - * \param vThread - the thread - */ -void CanInterface::initThread(QThread &vThread) -{ - // runs in main thread - Q_ASSERT_X(QThread::currentThread() == qApp->thread() , __func__, "The Class initialization must be done in Main Thread" ); - _thread = &vThread; - _thread->setObjectName(QString("%1_Thread").arg(metaObject()->className())); - connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(quit())); - _thread->start(); - moveToThread(_thread); -} - -/*! - * \brief CanInterface::quitThread - * \details Moves this object to main thread to be handled by QApplicaiton - * And to be destroyed there. - */ -void CanInterface::quitThread() -{ - // coco begin validated: Application termination is not correctly done in coco!!! - // it has been tested and works perfectly fine in normal run. - - if (! _thread) return; - - // runs in thread - moveToThread(qApp->thread()); // verified -} -// coco end - -/*! - * \brief CanInterface::createDevice - * \details Creates the CANBus device - * \return false if can't create the device - */ -bool CanInterface::initDevice() -{ - QString mError; - _canDevice = QCanBus::instance()->createDevice(_canType, _canInterface, &mError); - // coco begin validated: Manually tested since required to disable and enable the canbus - if (!_canDevice) { - status(tr("Device Creation"), mError); - LOG_DEBUG(status()); - return false; - } - // coco end - return true; -} - -/*! - * \brief CanInterface::checkDevice - * \details Checks if the device has been connected. - * \return - */ -bool CanInterface::testDevice() -{ - if (!_canDevice->connectDevice()) { - status(tr("Connection")); - LOG_DEBUG(status()); - delete _canDevice; - _canDevice = nullptr; - return false; - } - return true; -} - -/*! - * \brief CanInterface::deleteDevice - * \details Disconnect the CANBus device and deletes the pointer - */ -void CanInterface::quitDevice() -{ - // coco begin validated: Manually tested since required to disable and enable the canbus - if (!_canDevice) return; - // coco end - _canDevice->disconnectDevice(); - delete _canDevice; - _canDevice = nullptr; - status(tr("Disconnected")); -} - -/*! - * \brief CanInterface status - * \details Sets the Can interface status description - * \param vDescription - Description about the CANBUS Interface errors - * \param vError - Qt CANBUS Interface Error - */ -void CanInterface::status(const QString &vDescription, QString vError) -{ - QString mError=""; - if (_canDevice) { - mError = _canDevice->errorString() + vError; - } - else { - mError = vError; - } - _canStatus = tr("%1 '%2[%3]', %4") - .arg(vDescription) - .arg(_canType) - .arg(_canInterface) - .arg(mError) - ; - qDebug() << _canStatus; -} - -/*! - * \brief CanInterface send - * \details send a frame over the CANBUS - * \param vFrame - CANBUS message frame - */ -bool CanInterface::transmit(const QCanBusFrame &vFrame) -{ - // coco begin validated: Manually tested since required to disable and enable the canbus - if( !_canDevice ) return false; - //coco end - return _canDevice->writeFrame(vFrame); -} - -/*! - * \brief CanInterface console Output messaging - * \details Sends out formatted CANBUS message to the console - * for debugging purposes. - * \param vFrame - The CANBUS frame to be sent out - */ -void CanInterface::consoleOut(const QCanBusFrame &vFrame, const QString &vFrameCount) -{ - // coco begin validated: This code is only for debugging purposes and had been tested manually. - if ( ! _enableConsoleOut ) return; - - const QString time = QString::fromLatin1("%1.%2 ") - .arg(vFrame.timeStamp().seconds(), 10, 10, QLatin1Char(' ')) - .arg(vFrame.timeStamp().microSeconds() / 100, 4, 10, QLatin1Char('0')); - const QString flags = frameFlags(vFrame); - QString view; - if (vFrame.frameType() == QCanBusFrame::ErrorFrame) { - view = _canDevice->interpretErrorFrame(vFrame); - } - else { - view = vFrame.payload().toHex('.').replace(QByteArray("a5"),QByteArray("\033[1;33mA5\033[0m")); - } - fprintf(stderr, "%s %s %s %i %s\n", vFrameCount.toLatin1().constData(), time.toLatin1().constData(), flags.toLatin1().constData(), vFrame.frameId(), view.toLatin1().constData()); -} -// coco end - -/*! - * \brief CanInterface::rxCount - * \details count received frames up the size of the FrameCount type size - * \return frame count - */ -FrameCount CanInterface::rxCount() -{ - Types::safeIncrement(_rxFrameCount); - return _rxFrameCount; -} - -/*! - * \brief CanInterface::txCount - * \details count transmitted frames up the size of the FrameCount type size - * \return frame count - */ -FrameCount CanInterface::txCount() -{ - Types::safeIncrement(_txFrameCount); - return _txFrameCount; -} - -/*! - * \brief CanInterface::erCount - * \details count errors happened - * \return error count - */ -FrameCount CanInterface::erCount() -{ - // coco begin validated: CANBus error handling has been tested manually. - // since it requires massive can messages sent/received to catch the error - Types::safeIncrement(_erFrameCount); - return _erFrameCount; - // coco end -} - -/*! - * \brief frameFlags - * \details CANBUS message frame type as flags - * \param vFrame - CANBUS message frame - * \return Frame flag as QString - */ -QString CanInterface::frameFlags(const QCanBusFrame &vFrame) -{ - // coco begin validated: CANBus error handling has been tested manually. - // since it requires massive can messages sent/received to catch the error - QString result = QLatin1String(" --- "); - - if (vFrame.hasBitrateSwitch()) - result[1] = QLatin1Char('B'); - if (vFrame.hasErrorStateIndicator()) - result[2] = QLatin1Char('E'); - if (vFrame.hasLocalEcho()) - result[3] = QLatin1Char('L'); - - return result; - // coco end -} - -/*! - * \brief CanInterface onError - * \details Can Bus error handler which sets the can status description - * \param vError - CANBUS error - */ -void CanInterface::onFrameError(QCanBusDevice::CanBusError vError) -{ - // coco begin validated: CANBus error handling has been tested manually. - // since it requires massive can messages sent/received to catch the error - erCount(); - switch (vError) { - case QCanBusDevice::ReadError: - case QCanBusDevice::WriteError: - case QCanBusDevice::ConnectionError: - case QCanBusDevice::ConfigurationError: - case QCanBusDevice::UnknownError: - _canStatus = _canDevice->errorString(); - LOG_DEBUG(QString("%1 - %2").arg(_erFrameCount).arg(_canStatus)); - break; - - default: - break; - - } - emit didFrameError(_canStatus); -} -// coco end - -/*! - * \brief CanInterface::onFrameWritten - * \details This is the slot connected to the signal - * which is emitted every time a payload of frames - * has been written to the CANBUS bus. - * \param vFramesCount - The framesCount argument is set to the number of frames - * that were written in this payload. - */ -void CanInterface::onFrameWritten(qint64 vFramesCount) -{ - static FrameCount mFrameCount = 0; - Types::safeIncrement(mFrameCount, vFramesCount); - emit didFrameWritten(vFramesCount); -} - -/*! - * \brief CanInterface onFrameReceived - * \details CANBUS message read handler - */ -void CanInterface::onFrameReceive () -{ - // coco begin validated: Manually tested since required to disable and enable the canbus - if (!_canDevice) return; - // coco end - while (_canDevice->framesAvailable()) { - const QCanBusFrame frame = _canDevice->readFrame(); - rxCount(); - // coco begin validated: This code is only for debugging purposes and had been tested manually. - if ( _enableConsoleOut ) - consoleOut(frame, QString("Rx:%1").arg(_rxFrameCount)); - // coco end - emit didFrameReceive(frame); - } -} - -/*! - * \brief CanInterface onActionPerform - * \details sends a CANBUS message frame of the CANBUS message of the performed action - * This is a response from application UI to HD device - * \param vFrame - CANBUS message frame - */ -void CanInterface::onFrameTransmit(const QCanBusFrame &vFrame) -{ - bool ok = transmit(vFrame); - txCount(); - // coco begin validated: This code is only for debugging purposes and had been tested manually. - if ( _enableConsoleOut ) - consoleOut(vFrame, QString("Tx:%1").arg(_txFrameCount)); - // coco end - emit didFrameTransmit(ok); -} +#include "caninterface.h" + +// Qt +#include +#include + +// stl +#include + +// Project +#include "logger.h" +#include "messageglobals.h" +#include "frameinterface.h" + +// namespace +using namespace Can; + +/*! + * \brief CanInterface::CanInterface + * \details Constructor + * \param parent - QObject parent owner object. + * Qt handles the children destruction by their parent objects life-cycle. + */ +CanInterface::CanInterface(QObject *parent) : QObject(parent) { } + +/*! + * \brief CanInterface Initialization + * \details Initializes the CANBUS and checks if can be connected + * \return true if connected, false otherwise + */ +bool CanInterface::init() +{ + if ( _init ) return false; + _init = true; + + // coco begin validated: Manually tested since required to disable and enable the canbus + if ( ! initDevice() ) return false; + // coco end + if ( ! testDevice() ) return false; + + initConnections(); + + status(tr("Connected")); + QString logMessage = QString("UI,%1,%2") + .arg(tr("%1 Initialized").arg(metaObject()->className())) + .arg(status()); + LOG_EVENT(logMessage); + + return true; +} + +/*! + * \brief CanInterface::init + * \details Initialized the Class by calling the init() method first + * And initializes the thread vThread by calling initThread + * on success init(). + * \param vThread - the thread + * \return returns the return value of the init() method + */ +bool CanInterface::init(QThread &vThread) +{ + // coco begin validated: Manually tested since required to disable and enable the canbus + if ( ! init() ) return false; + // coco end + initThread(vThread); + return true; +} + +/*! + * \brief CanInterface quit + * \details quits the class + * Calls quitThread + */ +void CanInterface::quit() +{ + // coco begin validated: Application termination is not correctly done in coco!!! + // it has been tested and works perfectly fine in normal run. + quitThread(); // verified +} +// coco end + +/*! + * \brief CanInterface status + * \details CanInterface status description + * \return The current stores status + */ +QString CanInterface::status() const +{ + return _canStatus; +} + +/*! + * \brief CanInterface::enableConsoleOut + * \details Enable or Disables the console output and logs the status + * \param vEnabled - Enalbe console output if true + */ +void CanInterface::enableConsoleOut(bool vEnabled) { + // coco begin validated: This code meant to be used only for debugging and tested manually + if (_enableConsoleOut == vEnabled) return; + _enableConsoleOut = vEnabled; + if (_enableConsoleOut) { + LOG_DEBUG("Console out CanInterface enabled"); + } else { + LOG_DEBUG("Console out CanInterface disabled"); + } +} +// coco end + +/*! + * \brief CanInterface connections definition + * \details Initializes the required signal/slot connection between this class and other objects + * to be able to communicate. + */ +void CanInterface::initConnections() +{ + // coco begin validated: Manually tested since required to disable and enable the canbus + if (_canDevice) { + // coco end + connect(_canDevice, SIGNAL( framesReceived()), + this , SLOT (onFrameReceive ())); + + connect(_canDevice, SIGNAL( errorOccurred(QCanBusDevice::CanBusError)), + this , SLOT (onFrameError (QCanBusDevice::CanBusError))); + + connect(_canDevice, SIGNAL( framesWritten(qint64)), + this , SLOT (onFrameWritten (qint64))); + } + connect(&_FrameInterface, SIGNAL(didFrameTransmit(QCanBusFrame)), + this , SLOT( onFrameTransmit(QCanBusFrame))); +} + +/*! + * \brief CanInterface::initThread + * \details Moves this object into the thread vThread. + * And checks that this method is called from main thread. + * Also connects quitThread to application aboutToQuit. + * \param vThread - the thread + */ +void CanInterface::initThread(QThread &vThread) +{ + // runs in main thread + Q_ASSERT_X(QThread::currentThread() == qApp->thread() , __func__, "The Class initialization must be done in Main Thread" ); + _thread = &vThread; + _thread->setObjectName(QString("%1_Thread").arg(metaObject()->className())); + connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(quit())); + _thread->start(); + moveToThread(_thread); +} + +/*! + * \brief CanInterface::quitThread + * \details Moves this object to main thread to be handled by QApplicaiton + * And to be destroyed there. + */ +void CanInterface::quitThread() +{ + // coco begin validated: Application termination is not correctly done in coco!!! + // it has been tested and works perfectly fine in normal run. + + if (! _thread) return; + + // runs in thread + moveToThread(qApp->thread()); // verified +} +// coco end + +/*! + * \brief CanInterface::createDevice + * \details Creates the CANBus device + * \return false if can't create the device + */ +bool CanInterface::initDevice() +{ + QString mError; + _canDevice = QCanBus::instance()->createDevice(_canType, _canInterface, &mError); + // coco begin validated: Manually tested since required to disable and enable the canbus + if (!_canDevice) { + status(tr("Device Creation"), mError); + LOG_DEBUG(status()); + return false; + } + // coco end + return true; +} + +/*! + * \brief CanInterface::checkDevice + * \details Checks if the device has been connected. + * \return + */ +bool CanInterface::testDevice() +{ + if (!_canDevice->connectDevice()) { + status(tr("Connection")); + LOG_DEBUG(status()); + delete _canDevice; + _canDevice = nullptr; + return false; + } + return true; +} + +/*! + * \brief CanInterface::deleteDevice + * \details Disconnect the CANBus device and deletes the pointer + */ +void CanInterface::quitDevice() +{ + // coco begin validated: Manually tested since required to disable and enable the canbus + if (!_canDevice) return; + // coco end + _canDevice->disconnectDevice(); + delete _canDevice; + _canDevice = nullptr; + status(tr("Disconnected")); +} + +/*! + * \brief CanInterface status + * \details Sets the Can interface status description + * \param vDescription - Description about the CANBUS Interface errors + * \param vError - Qt CANBUS Interface Error + */ +void CanInterface::status(const QString &vDescription, QString vError) +{ + QString mError=""; + if (_canDevice) { + mError = _canDevice->errorString() + vError; + } + else { + mError = vError; + } + _canStatus = tr("%1 '%2[%3]', %4") + .arg(vDescription) + .arg(_canType) + .arg(_canInterface) + .arg(mError) + ; + qDebug() << _canStatus; +} + +/*! + * \brief CanInterface send + * \details send a frame over the CANBUS + * \param vFrame - CANBUS message frame + */ +bool CanInterface::transmit(const QCanBusFrame &vFrame) +{ + // coco begin validated: Manually tested since required to disable and enable the canbus + if( !_canDevice ) return false; + //coco end + return _canDevice->writeFrame(vFrame); +} + +/*! + * \brief CanInterface console Output messaging + * \details Sends out formatted CANBUS message to the console + * for debugging purposes. + * \param vFrame - The CANBUS frame to be sent out + */ +void CanInterface::consoleOut(const QCanBusFrame &vFrame, const QString &vFrameCount) +{ + // coco begin validated: This code is only for debugging purposes and had been tested manually. + if ( ! _enableConsoleOut ) return; + + const QString time = QString::fromLatin1("%1.%2 ") + .arg(vFrame.timeStamp().seconds(), 10, 10, QLatin1Char(' ')) + .arg(vFrame.timeStamp().microSeconds() / 100, 4, 10, QLatin1Char('0')); + const QString flags = frameFlags(vFrame); + QString view; + if (vFrame.frameType() == QCanBusFrame::ErrorFrame) { + view = _canDevice->interpretErrorFrame(vFrame); + } + else { + view = vFrame.payload().toHex('.').replace(QByteArray("a5"),QByteArray("\033[1;33mA5\033[0m")); + } + fprintf(stderr, "%s %s %s %i %s\n", vFrameCount.toLatin1().constData(), time.toLatin1().constData(), flags.toLatin1().constData(), vFrame.frameId(), view.toLatin1().constData()); +} +// coco end + +/*! + * \brief CanInterface::rxCount + * \details count received frames up the size of the FrameCount type size + * \return frame count + */ +FrameCount CanInterface::rxCount() +{ + Types::safeIncrement(_rxFrameCount); + return _rxFrameCount; +} + +/*! + * \brief CanInterface::txCount + * \details count transmitted frames up the size of the FrameCount type size + * \return frame count + */ +FrameCount CanInterface::txCount() +{ + Types::safeIncrement(_txFrameCount); + return _txFrameCount; +} + +/*! + * \brief CanInterface::erCount + * \details count errors happened + * \return error count + */ +FrameCount CanInterface::erCount() +{ + // coco begin validated: CANBus error handling has been tested manually. + // since it requires massive can messages sent/received to catch the error + Types::safeIncrement(_erFrameCount); + return _erFrameCount; + // coco end +} + +/*! + * \brief frameFlags + * \details CANBUS message frame type as flags + * \param vFrame - CANBUS message frame + * \return Frame flag as QString + */ +QString CanInterface::frameFlags(const QCanBusFrame &vFrame) +{ + // coco begin validated: CANBus error handling has been tested manually. + // since it requires massive can messages sent/received to catch the error + QString result = QLatin1String(" --- "); + + if (vFrame.hasBitrateSwitch()) + result[1] = QLatin1Char('B'); + if (vFrame.hasErrorStateIndicator()) + result[2] = QLatin1Char('E'); + if (vFrame.hasLocalEcho()) + result[3] = QLatin1Char('L'); + + return result; + // coco end +} + +/*! + * \brief CanInterface onError + * \details Can Bus error handler which sets the can status description + * \param vError - CANBUS error + */ +void CanInterface::onFrameError(QCanBusDevice::CanBusError vError) +{ + // coco begin validated: CANBus error handling has been tested manually. + // since it requires massive can messages sent/received to catch the error + erCount(); + switch (vError) { + case QCanBusDevice::ReadError: + case QCanBusDevice::WriteError: + case QCanBusDevice::ConnectionError: + case QCanBusDevice::ConfigurationError: + case QCanBusDevice::UnknownError: + _canStatus = _canDevice->errorString(); + LOG_DEBUG(QString("%1 - %2").arg(_erFrameCount).arg(_canStatus)); + break; + + default: + break; + + } + emit didFrameError(_canStatus); +} +// coco end + +/*! + * \brief CanInterface::onFrameWritten + * \details This is the slot connected to the signal + * which is emitted every time a payload of frames + * has been written to the CANBUS bus. + * \param vFramesCount - The framesCount argument is set to the number of frames + * that were written in this payload. + */ +void CanInterface::onFrameWritten(qint64 vFramesCount) +{ + static FrameCount mFrameCount = 0; + Types::safeIncrement(mFrameCount, vFramesCount); + emit didFrameWritten(vFramesCount); +} + +/*! + * \brief CanInterface onFrameReceived + * \details CANBUS message read handler + */ +void CanInterface::onFrameReceive () +{ + // coco begin validated: Manually tested since required to disable and enable the canbus + if (!_canDevice) return; + // coco end + while (_canDevice->framesAvailable()) { + const QCanBusFrame frame = _canDevice->readFrame(); + rxCount(); + // coco begin validated: This code is only for debugging purposes and had been tested manually. + if ( _enableConsoleOut ) + consoleOut(frame, QString("Rx:%1").arg(_rxFrameCount)); + // coco end + emit didFrameReceive(frame); + } +} + +/*! + * \brief CanInterface onActionPerform + * \details sends a CANBUS message frame of the CANBUS message of the performed action + * This is a response from application UI to HD device + * \param vFrame - CANBUS message frame + */ +void CanInterface::onFrameTransmit(const QCanBusFrame &vFrame) +{ + bool ok = transmit(vFrame); + txCount(); + // coco begin validated: This code is only for debugging purposes and had been tested manually. + if ( _enableConsoleOut ) + consoleOut(vFrame, QString("Tx:%1").arg(_txFrameCount)); + // coco end + emit didFrameTransmit(ok); +}