Index: sources/canbus/caninterface.cpp =================================================================== diff -u -rde2f87e15fa05b1c45581cfedd8f1af0c47c2b48 -r56d00a82669a7a2c00ab90109a89dbec8db27527 --- sources/canbus/caninterface.cpp (.../caninterface.cpp) (revision de2f87e15fa05b1c45581cfedd8f1af0c47c2b48) +++ sources/canbus/caninterface.cpp (.../caninterface.cpp) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) @@ -1,6 +1,6 @@ /*! * - * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. + * Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. * \copyright \n * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, \n * IN PART OR IN WHOLE, \n @@ -14,66 +14,187 @@ #include "caninterface.h" // Qt -#include +#include +#include // Project -#include "messagehandler.h" +#include "logger.h" +#include "messageglobals.h" +#include "frameinterface.h" // namespace using namespace Can; -// Singleton -SINGLETON_INIT(CanInterface) - /*! * \brief Caninterface Constructor * \param parent object */ -CanInterface::CanInterface(QObject *parent) : QObject(parent) {} +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() { - QString mError; - _canDevice = QCanBus::instance()->createDevice(_canType, _canInterface, &mError); - if (!_canDevice) { - status(tr("Error: Device Creation"),mError); - return false; - } + if ( _init ) return false; + _init = true; + if ( ! initDevice() ) return false; + if ( ! testDevice() ) return false; + _numberFramesWritten = 0; + initConnections(); - connection(); - - if (!_canDevice->connectDevice()) { - status(tr("Error: Connection")); - delete _canDevice; - _canDevice = nullptr; - return false; - } status(tr("Connected")); + LOG_EVENT(status()); + LOG_EVENT(QObject::tr("%1 Initialized").arg(metaObject()->className())); + 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) +{ + if ( ! init() ) return false; + initThread(vThread); + return true; +} + +/*! + * \brief CanInterface quit + * \details quits the class + * Calls quitThread + */ +void CanInterface::quit() +{ + quitThread(); +} + +/*! + * \brief CanInterface status + * \details CanInterface status description + * \return The current stores status + */ QString CanInterface::status() const { return _canStatus; } -void CanInterface::connection() +/*! + * \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() { - if (_canDevice) { - connect(_canDevice, SIGNAL(framesReceived()), - this , SLOT ( onRead())); - connect(_canDevice, SIGNAL(errorOccurred(QCanBusDevice::CanBusError)), - this , SLOT ( onError(QCanBusDevice::CanBusError))); + 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 (onFrameWrittern(qint64))); } - connect(_MessageHandler, SIGNAL(didActionPerform(QCanBusFrame)), - this , SLOT( onActionPerform(QCanBusFrame))); - connect(_MessageHandler, SIGNAL(didActionRequest(QCanBusFrame)), - this , SLOT( onActionRequest(QCanBusFrame))); + 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() +{ + if (! _thread) return; + + // runs in thread + moveToThread(qApp->thread()); +} + +/*! + * \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); + if (!_canDevice) { + status(tr("Device Creation"), mError); + LOG_ERROR(status()); + return false; + } + return true; +} + +/*! + * \brief CanInterface::checkDevice + * \details Checks if the device has been connected. + * \return + */ +bool CanInterface::testDevice() +{ + if (!_canDevice->connectDevice()) { + status(tr("Connection")); + LOG_ERROR(status()); + delete _canDevice; + _canDevice = nullptr; + return false; + } + return true; +} + +/*! + * \brief CanInterface::deleteDevice + * \details Disconnect the CANBus device and deletes the pointer + */ +void CanInterface::quitDevice() +{ + if (!_canDevice) + return; + _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=""; @@ -89,43 +210,73 @@ .arg(_canInterface) .arg(mError) ; - // qDebug() << _canStatus; + qDebug() << _canStatus; } -void CanInterface::send(const QCanBusFrame &vFrame) +/*! + * \brief CanInterface send + * \details send a frame over the CANBUS + * \param vFrame - CANBUS message frame + */ +bool CanInterface::transmit(const QCanBusFrame &vFrame) { if( !_canDevice ) - return; - _canDevice->writeFrame(vFrame); + return false; + return _canDevice->writeFrame(vFrame); } -void CanInterface::quit() +/*! + * \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) { - if (!_canDevice) - return; + if ( ! _enableConsoleOut ) return; - _canDevice->disconnectDevice(); - delete _canDevice; - _canDevice = nullptr; + LOG_EVENT(QObject::tr("console out CanInterface Enabled")); - status(tr("Disconnected")); + 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 %i %s\n", time.toLatin1().constData(), flags.toLatin1().constData(), vFrame.frameId(), view.toLatin1().constData()); } -static QString frameFlags(const QCanBusFrame &frame) +/*! + * \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) { QString result = QLatin1String(" --- "); - if (frame.hasBitrateSwitch()) + if (vFrame.hasBitrateSwitch()) result[1] = QLatin1Char('B'); - if (frame.hasErrorStateIndicator()) + if (vFrame.hasErrorStateIndicator()) result[2] = QLatin1Char('E'); - if (frame.hasLocalEcho()) + if (vFrame.hasLocalEcho()) result[3] = QLatin1Char('L'); return result; } -void CanInterface::onError(QCanBusDevice::CanBusError vError) +/*! + * \brief CanInterface onError + * \details Can Bus error handler which sets the can status description + * \param vError - CANBUS error + */ +void CanInterface::onFrameError(QCanBusDevice::CanBusError vError) { switch (vError) { case QCanBusDevice::ReadError: @@ -138,47 +289,49 @@ default: break; } - emit didError(_canStatus); + emit didFrameError(_canStatus); } -void CanInterface::onRead() +/*! + * \brief CanInterface::onFrameWrittern + * \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::onFrameWrittern(qint64 /*vFramesCount*/) { + //_numberFramesWritten = vFramesCount; + //qDebug() << "onFrameWrittern::FramesCount : " << vFramesCount; +} + +/*! + * \brief CanInterface onFrameReceived + * \details CANBUS message read handler + */ +void CanInterface::onFrameReceive () +{ if (!_canDevice) return; - while (_canDevice->framesAvailable()) { + //int i = _canDevice->framesAvailable(); const QCanBusFrame frame = _canDevice->readFrame(); - - QString view; - if (frame.frameType() == QCanBusFrame::ErrorFrame) { - view = _canDevice->interpretErrorFrame(frame); - } - else { - view = frame.toString(); - } - - const QString time = QString::fromLatin1("%1.%2 ") - .arg(frame.timeStamp().seconds(), 10, 10, QLatin1Char(' ')) - .arg(frame.timeStamp().microSeconds() / 100, 4, 10, QLatin1Char('0')); - - const QString flags = frameFlags(frame); - - // qDebug() << time + flags + view; - // TODO : Needs to be investigated on how the messages on canBus will be received. - // may require to be moved at the end of the function, to not to be called for each message. - emit didRead(frame); + //qDebug() << "frame: #" << i << frame.toString(); + consoleOut(frame); + emit didFrameReceive(frame); } } -void CanInterface::onActionPerform(const QCanBusFrame &vFrame) +/*! + * \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) { - // TODO : Process Frame - send(vFrame); + bool ok = transmit(vFrame); + consoleOut(vFrame); + emit didFrameTransmit(ok); } - -void CanInterface::onActionRequest(const QCanBusFrame &vFrame) -{ - // TODO : Process Frame - send(vFrame); -} -