/*! * * Copyright (c) 2019-2020 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 * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. \n * * \file caninterface.cpp * \date 2019/09/30 * \author Behrouz NematiPour * */ #include "caninterface.h" // Qt #include // Project #include "messagehandler.h" // namespace using namespace Can; // Singleton SINGLETON_INIT(CanInterface) /*! * \brief Caninterface Constructor * \param parent object */ CanInterface::CanInterface(QObject *parent) : QObject(parent) {} bool CanInterface::init() { QString mError; _canDevice = QCanBus::instance()->createDevice(_canType, _canInterface, &mError); if (!_canDevice) { status(tr("Error: Device Creation"),mError); return false; } _numberFramesWritten = 0; connection(); if (!_canDevice->connectDevice()) { status(tr("Error: Connection")); delete _canDevice; _canDevice = nullptr; return false; } status(tr("Connected")); return true; } QString CanInterface::status() const { return _canStatus; } void CanInterface::connection() { if (_canDevice) { connect(_canDevice, SIGNAL(framesReceived()), this , SLOT ( onRead())); connect(_canDevice, SIGNAL(errorOccurred(QCanBusDevice::CanBusError)), this , SLOT ( onError(QCanBusDevice::CanBusError))); } connect(_MessageHandler, SIGNAL(didActionPerform(QCanBusFrame)), this , SLOT( onActionPerform(QCanBusFrame))); connect(_MessageHandler, SIGNAL(didActionRequest(QCanBusFrame)), this , SLOT( onActionRequest(QCanBusFrame))); } 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; } void CanInterface::send(const QCanBusFrame &vFrame) { if( !_canDevice ) return; _canDevice->writeFrame(vFrame); } void CanInterface::quit() { if (!_canDevice) return; _canDevice->disconnectDevice(); delete _canDevice; _canDevice = nullptr; status(tr("Disconnected")); } static QString frameFlags(const QCanBusFrame &frame) { QString result = QLatin1String(" --- "); if (frame.hasBitrateSwitch()) result[1] = QLatin1Char('B'); if (frame.hasErrorStateIndicator()) result[2] = QLatin1Char('E'); if (frame.hasLocalEcho()) result[3] = QLatin1Char('L'); return result; } void CanInterface::onError(QCanBusDevice::CanBusError vError) { switch (vError) { case QCanBusDevice::ReadError: case QCanBusDevice::WriteError: case QCanBusDevice::ConnectionError: case QCanBusDevice::ConfigurationError: case QCanBusDevice::UnknownError: _canStatus = _canDevice->errorString(); break; default: break; } emit didError(_canStatus); } void CanInterface::onRead() { if (!_canDevice) return; while (_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); } } void CanInterface::onActionPerform(const QCanBusFrame &vFrame) { // TODO : Process Frame send(vFrame); } void CanInterface::onActionRequest(const QCanBusFrame &vFrame) { // TODO : Process Frame send(vFrame); }