First implementation
This commit is contained in:
300
core/Backend.cpp
Normal file
300
core/Backend.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "Backend.h"
|
||||
#include "LogModel.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
|
||||
#include <core/CanTrace.h>
|
||||
#include <core/MeasurementSetup.h>
|
||||
#include <core/MeasurementNetwork.h>
|
||||
#include <core/MeasurementInterface.h>
|
||||
#include <driver/CanDriver.h>
|
||||
#include <driver/CanInterface.h>
|
||||
#include <driver/CanListener.h>
|
||||
#include <parser/dbc/DbcParser.h>
|
||||
|
||||
Backend *Backend::_instance = 0;
|
||||
|
||||
Backend::Backend()
|
||||
: QObject(0),
|
||||
_measurementRunning(false),
|
||||
_measurementStartTime(0),
|
||||
_setup(this)
|
||||
{
|
||||
_logModel = new LogModel(*this);
|
||||
|
||||
setDefaultSetup();
|
||||
_trace = new CanTrace(*this, this, 100);
|
||||
|
||||
connect(&_setup, SIGNAL(onSetupChanged()), this, SIGNAL(onSetupChanged()));
|
||||
}
|
||||
|
||||
Backend &Backend::instance()
|
||||
{
|
||||
if (!_instance) {
|
||||
_instance = new Backend;
|
||||
}
|
||||
return *_instance;
|
||||
}
|
||||
|
||||
Backend::~Backend()
|
||||
{
|
||||
delete _trace;
|
||||
}
|
||||
|
||||
void Backend::addCanDriver(CanDriver &driver)
|
||||
{
|
||||
driver.init(_drivers.size());
|
||||
_drivers.append(&driver);
|
||||
}
|
||||
|
||||
bool Backend::startMeasurement()
|
||||
{
|
||||
log_info("Starting measurement");
|
||||
|
||||
_measurementStartTime = QDateTime::currentMSecsSinceEpoch();
|
||||
_timerSinceStart.start();
|
||||
|
||||
int i=0;
|
||||
foreach (MeasurementNetwork *network, _setup.getNetworks()) {
|
||||
i++;
|
||||
foreach (MeasurementInterface *mi, network->interfaces()) {
|
||||
|
||||
CanInterface *intf = getInterfaceById(mi->canInterface());
|
||||
if (intf) {
|
||||
intf->applyConfig(*mi);
|
||||
|
||||
log_info(QString("Listening on interface: %1").arg(intf->getName()));
|
||||
CanListener *listener = new CanListener(0, *this, *intf);
|
||||
listener->startThread();
|
||||
_listeners.append(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_measurementRunning = true;
|
||||
emit beginMeasurement();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Backend::stopMeasurement()
|
||||
{
|
||||
if (_measurementRunning) {
|
||||
foreach (CanListener *listener, _listeners) {
|
||||
listener->requestStop();
|
||||
}
|
||||
|
||||
foreach (CanListener *listener, _listeners) {
|
||||
log_info(QString("Closing interface: %1").arg(getInterfaceName(listener->getInterfaceId())));
|
||||
listener->waitFinish();
|
||||
}
|
||||
|
||||
qDeleteAll(_listeners);
|
||||
_listeners.clear();
|
||||
|
||||
log_info("Measurement stopped");
|
||||
|
||||
_measurementRunning = false;
|
||||
|
||||
emit endMeasurement();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Backend::isMeasurementRunning() const
|
||||
{
|
||||
return _measurementRunning;
|
||||
}
|
||||
|
||||
void Backend::loadDefaultSetup(MeasurementSetup &setup)
|
||||
{
|
||||
setup.clear();
|
||||
int i = 1;
|
||||
|
||||
foreach (CanDriver *driver, _drivers) {
|
||||
driver->update();
|
||||
foreach (CanInterfaceId intf, driver->getInterfaceIds()) {
|
||||
MeasurementNetwork *network = setup.createNetwork();
|
||||
network->setName(QString().sprintf("Network %d", i++));
|
||||
|
||||
MeasurementInterface *mi = new MeasurementInterface();
|
||||
mi->setCanInterface(intf);
|
||||
mi->setBitrate(500000);
|
||||
network->addInterface(mi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Backend::setDefaultSetup()
|
||||
{
|
||||
loadDefaultSetup(_setup);
|
||||
}
|
||||
|
||||
MeasurementSetup &Backend::getSetup()
|
||||
{
|
||||
return _setup;
|
||||
}
|
||||
|
||||
void Backend::setSetup(MeasurementSetup &new_setup)
|
||||
{
|
||||
_setup.cloneFrom(new_setup);
|
||||
}
|
||||
|
||||
double Backend::currentTimeStamp() const
|
||||
{
|
||||
return ((double)QDateTime::currentMSecsSinceEpoch()) / 1000;
|
||||
}
|
||||
|
||||
CanTrace *Backend::getTrace()
|
||||
{
|
||||
return _trace;
|
||||
}
|
||||
|
||||
void Backend::clearTrace()
|
||||
{
|
||||
_trace->clear();
|
||||
}
|
||||
|
||||
CanDbMessage *Backend::findDbMessage(const CanMessage &msg) const
|
||||
{
|
||||
return _setup.findDbMessage(msg);
|
||||
}
|
||||
|
||||
CanInterfaceIdList Backend::getInterfaceList()
|
||||
{
|
||||
CanInterfaceIdList result;
|
||||
foreach (CanDriver *driver, _drivers) {
|
||||
foreach (CanInterfaceId id, driver->getInterfaceIds()) {
|
||||
result.append(id);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CanDriver *Backend::getDriverById(CanInterfaceId id)
|
||||
{
|
||||
CanDriver *driver = _drivers.value((id>>8) & 0xFF);
|
||||
if (!driver) {
|
||||
log_critical(QString("Unable to get driver for interface id: %1. This should never happen.").arg(QString().number(id)));
|
||||
}
|
||||
return driver;
|
||||
}
|
||||
|
||||
CanInterface *Backend::getInterfaceById(CanInterfaceId id)
|
||||
{
|
||||
CanDriver *driver = getDriverById(id);
|
||||
return driver ? driver->getInterfaceById(id) : 0;
|
||||
}
|
||||
|
||||
QString Backend::getInterfaceName(CanInterfaceId id)
|
||||
{
|
||||
CanInterface *intf = getInterfaceById(id);
|
||||
if (intf) {
|
||||
return intf->getName();
|
||||
} else {
|
||||
log_critical(QString("Trying to get name from unknown interface id: %1. This should never happen.").arg(QString().number(id)));
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
QString Backend::getDriverName(CanInterfaceId id)
|
||||
{
|
||||
CanDriver *driver = getDriverById(id);
|
||||
return driver ? driver->getName() : "";
|
||||
}
|
||||
|
||||
CanDriver *Backend::getDriverByName(QString driverName)
|
||||
{
|
||||
foreach (CanDriver *driver, _drivers) {
|
||||
if (driver->getName()==driverName) {
|
||||
return driver;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CanInterface *Backend::getInterfaceByDriverAndName(QString driverName, QString deviceName)
|
||||
{
|
||||
CanDriver *driver = getDriverByName(driverName);
|
||||
if (driver) {
|
||||
return driver->getInterfaceByName(deviceName);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pCanDb Backend::loadDbc(QString filename)
|
||||
{
|
||||
DbcParser parser;
|
||||
|
||||
QFile *dbc = new QFile(filename);
|
||||
pCanDb candb(new CanDb());
|
||||
parser.parseFile(dbc, *candb);
|
||||
delete dbc;
|
||||
|
||||
return candb;
|
||||
}
|
||||
|
||||
void Backend::clearLog()
|
||||
{
|
||||
_logModel->clear();
|
||||
}
|
||||
|
||||
LogModel &Backend::getLogModel() const
|
||||
{
|
||||
return *_logModel;
|
||||
}
|
||||
|
||||
double Backend::getTimestampAtMeasurementStart() const
|
||||
{
|
||||
return (double)_measurementStartTime / 1000.0;
|
||||
}
|
||||
|
||||
uint64_t Backend::getUsecsAtMeasurementStart() const
|
||||
{
|
||||
return _measurementStartTime * 1000;
|
||||
}
|
||||
|
||||
uint64_t Backend::getNsecsSinceMeasurementStart() const
|
||||
{
|
||||
return _timerSinceStart.nsecsElapsed();
|
||||
}
|
||||
|
||||
uint64_t Backend::getUsecsSinceMeasurementStart() const
|
||||
{
|
||||
return getNsecsSinceMeasurementStart() / 1000;
|
||||
}
|
||||
|
||||
void Backend::logMessage(const QDateTime dt, const log_level_t level, const QString msg)
|
||||
{
|
||||
// QFile logfile("tkr.log");
|
||||
// logfile.open(QIODevice::WriteOnly | QIODevice::Append);
|
||||
// logfile.write(QString("%1 %2 %3\n").arg(dt.toString("yyyy-MM-dd hh:mm:ss.zzz")).arg(level).arg(msg).toUtf8());
|
||||
// logfile.close();
|
||||
|
||||
qDebug() << "logMessage" << dt << level << msg;
|
||||
emit onLogMessage(dt, level, msg);
|
||||
}
|
||||
114
core/Backend.h
Normal file
114
core/Backend.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QMutex>
|
||||
#include <QDateTime>
|
||||
#include <QElapsedTimer>
|
||||
#include <driver/CanDriver.h>
|
||||
#include <core/CanDb.h>
|
||||
#include <core/MeasurementSetup.h>
|
||||
#include <core/Log.h>
|
||||
|
||||
class MeasurementNetwork;
|
||||
class CanTrace;
|
||||
class CanListener;
|
||||
class CanDbMessage;
|
||||
class SetupDialog;
|
||||
class LogModel;
|
||||
|
||||
class Backend : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static Backend &instance();
|
||||
|
||||
explicit Backend();
|
||||
virtual ~Backend();
|
||||
|
||||
void addCanDriver(CanDriver &driver);
|
||||
|
||||
bool startMeasurement();
|
||||
bool stopMeasurement();
|
||||
bool isMeasurementRunning() const;
|
||||
double getTimestampAtMeasurementStart() const;
|
||||
uint64_t getUsecsAtMeasurementStart() const;
|
||||
uint64_t getNsecsSinceMeasurementStart() const;
|
||||
uint64_t getUsecsSinceMeasurementStart() const;
|
||||
|
||||
|
||||
void logMessage(const QDateTime dt, const log_level_t level, const QString msg);
|
||||
|
||||
MeasurementSetup &getSetup();
|
||||
void loadDefaultSetup(MeasurementSetup &setup);
|
||||
void setDefaultSetup();
|
||||
void setSetup(MeasurementSetup &new_setup);
|
||||
|
||||
double currentTimeStamp() const;
|
||||
|
||||
CanTrace *getTrace();
|
||||
void clearTrace();
|
||||
|
||||
CanDbMessage *findDbMessage(const CanMessage &msg) const;
|
||||
|
||||
CanInterfaceIdList getInterfaceList();
|
||||
CanDriver *getDriverById(CanInterfaceId id);
|
||||
CanInterface *getInterfaceById(CanInterfaceId id);
|
||||
QString getInterfaceName(CanInterfaceId id);
|
||||
QString getDriverName(CanInterfaceId id);
|
||||
|
||||
CanDriver *getDriverByName(QString driverName);
|
||||
CanInterface *getInterfaceByDriverAndName(QString driverName, QString deviceName);
|
||||
|
||||
pCanDb loadDbc(QString filename);
|
||||
|
||||
void clearLog();
|
||||
LogModel &getLogModel() const;
|
||||
|
||||
signals:
|
||||
void beginMeasurement();
|
||||
void endMeasurement();
|
||||
|
||||
void onSetupChanged();
|
||||
|
||||
void onLogMessage(const QDateTime dt, const log_level_t level, const QString msg);
|
||||
|
||||
void onSetupDialogCreated(SetupDialog &dlg);
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
static Backend *_instance;
|
||||
|
||||
bool _measurementRunning;
|
||||
uint64_t _measurementStartTime;
|
||||
QElapsedTimer _timerSinceStart;
|
||||
QList<CanDriver*> _drivers;
|
||||
MeasurementSetup _setup;
|
||||
CanTrace *_trace;
|
||||
QList<CanListener*> _listeners;
|
||||
|
||||
LogModel *_logModel;
|
||||
};
|
||||
89
core/CanDb.cpp
Normal file
89
core/CanDb.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "CanDb.h"
|
||||
#include <QFileInfo>
|
||||
#include <QDomDocument>
|
||||
|
||||
#include <core/Backend.h>
|
||||
|
||||
CanDb::CanDb()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString CanDb::getFileName()
|
||||
{
|
||||
QFileInfo fi(getPath());
|
||||
return fi.fileName();
|
||||
}
|
||||
|
||||
QString CanDb::getDirectory()
|
||||
{
|
||||
QFileInfo fi(getPath());
|
||||
return fi.absolutePath();
|
||||
}
|
||||
|
||||
CanDbNode *CanDb::getOrCreateNode(QString node_name)
|
||||
{
|
||||
if (!_nodes.contains(node_name)) {
|
||||
CanDbNode *node = new CanDbNode(this);
|
||||
node->setName(node_name);
|
||||
_nodes[node_name] = node;
|
||||
return node;
|
||||
} else {
|
||||
return _nodes[node_name];
|
||||
}
|
||||
}
|
||||
|
||||
CanDbMessage *CanDb::getMessageById(uint32_t raw_id)
|
||||
{
|
||||
if (_messages.contains(raw_id)) {
|
||||
return _messages[raw_id];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CanDb::addMessage(CanDbMessage *msg)
|
||||
{
|
||||
_messages[msg->getRaw_id()] = msg;
|
||||
}
|
||||
|
||||
QString CanDb::getComment() const
|
||||
{
|
||||
return _comment;
|
||||
}
|
||||
|
||||
void CanDb::setComment(const QString &comment)
|
||||
{
|
||||
_comment = comment;
|
||||
}
|
||||
|
||||
bool CanDb::saveXML(Backend &backend, QDomDocument &xml, QDomElement &root)
|
||||
{
|
||||
(void) backend;
|
||||
(void) xml;
|
||||
root.setAttribute("type", "dbc");
|
||||
root.setAttribute("filename", _path);
|
||||
return true;
|
||||
}
|
||||
|
||||
73
core/CanDb.h
Normal file
73
core/CanDb.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include "CanDbNode.h"
|
||||
#include "CanDbMessage.h"
|
||||
|
||||
class QDomDocument;
|
||||
class QDomElement;
|
||||
|
||||
class Backend;
|
||||
class CanDb;
|
||||
class CanDbMessage;
|
||||
|
||||
typedef QMap<QString,CanDbNode*> CanDbNodeMap;
|
||||
typedef QMap<uint32_t, CanDbMessage*> CanDbMessageList;
|
||||
typedef QSharedPointer<CanDb> pCanDb;
|
||||
|
||||
class CanDb
|
||||
{
|
||||
public:
|
||||
CanDb();
|
||||
|
||||
void setPath(QString path) { _path = path; }
|
||||
QString getPath() { return _path; }
|
||||
QString getFileName();
|
||||
QString getDirectory();
|
||||
|
||||
void setVersion(QString version) { _version = version; }
|
||||
QString getVersion() { return _version; }
|
||||
|
||||
CanDbNode *getOrCreateNode(QString node_name);
|
||||
|
||||
CanDbMessage *getMessageById(uint32_t raw_id);
|
||||
void addMessage(CanDbMessage *msg);
|
||||
|
||||
QString getComment() const;
|
||||
void setComment(const QString &comment);
|
||||
|
||||
bool saveXML(Backend &backend, QDomDocument &xml, QDomElement &root);
|
||||
|
||||
private:
|
||||
QString _path;
|
||||
QString _version;
|
||||
QString _comment;
|
||||
CanDbNodeMap _nodes;
|
||||
CanDbMessageList _messages;
|
||||
|
||||
};
|
||||
112
core/CanDbMessage.cpp
Normal file
112
core/CanDbMessage.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "CanDbMessage.h"
|
||||
|
||||
CanDbMessage::CanDbMessage(CanDb *parent)
|
||||
: _parent(parent), _raw_id(0), _dlc(0), _sender(0), _muxer(0)
|
||||
{
|
||||
}
|
||||
|
||||
QString CanDbMessage::getName() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
void CanDbMessage::setName(const QString &name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
uint32_t CanDbMessage::getRaw_id() const
|
||||
{
|
||||
return _raw_id;
|
||||
}
|
||||
|
||||
void CanDbMessage::setRaw_id(const uint32_t &raw_id)
|
||||
{
|
||||
_raw_id = raw_id;
|
||||
}
|
||||
|
||||
uint8_t CanDbMessage::getDlc() const
|
||||
{
|
||||
return _dlc;
|
||||
}
|
||||
|
||||
void CanDbMessage::setDlc(const uint8_t &dlc)
|
||||
{
|
||||
_dlc = dlc;
|
||||
}
|
||||
|
||||
CanDbNode *CanDbMessage::getSender() const
|
||||
{
|
||||
return _sender;
|
||||
}
|
||||
|
||||
void CanDbMessage::setSender(CanDbNode *sender)
|
||||
{
|
||||
_sender = sender;
|
||||
}
|
||||
|
||||
void CanDbMessage::addSignal(CanDbSignal *signal)
|
||||
{
|
||||
_signals.append(signal);
|
||||
}
|
||||
|
||||
CanDbSignal *CanDbMessage::getSignal(int num)
|
||||
{
|
||||
if (_signals.size()>num) {
|
||||
return _signals[num];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
CanDbSignal *CanDbMessage::getSignalByName(QString signal_name)
|
||||
{
|
||||
CanDbSignal *signal;
|
||||
foreach (signal, _signals) {
|
||||
if (signal->name() == signal_name) {
|
||||
return signal;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString CanDbMessage::getComment() const
|
||||
{
|
||||
return _comment;
|
||||
}
|
||||
|
||||
void CanDbMessage::setComment(const QString &comment)
|
||||
{
|
||||
_comment = comment;
|
||||
}
|
||||
|
||||
CanDbSignal *CanDbMessage::getMuxer() const
|
||||
{
|
||||
return _muxer;
|
||||
}
|
||||
|
||||
void CanDbMessage::setMuxer(CanDbSignal *muxer)
|
||||
{
|
||||
_muxer = muxer;
|
||||
}
|
||||
73
core/CanDbMessage.h
Normal file
73
core/CanDbMessage.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <QString>
|
||||
#include "CanDb.h"
|
||||
#include "CanDbSignal.h"
|
||||
|
||||
class CanDbNode;
|
||||
class CanDbSignal;
|
||||
|
||||
typedef QList<CanDbSignal*> CanDbSignalList;
|
||||
|
||||
class CanDbMessage
|
||||
{
|
||||
public:
|
||||
CanDbMessage(CanDb *parent);
|
||||
|
||||
QString getName() const;
|
||||
void setName(const QString &name);
|
||||
|
||||
uint32_t getRaw_id() const;
|
||||
void setRaw_id(const uint32_t &raw_id);
|
||||
|
||||
uint8_t getDlc() const;
|
||||
void setDlc(const uint8_t &dlc);
|
||||
|
||||
CanDbNode *getSender() const;
|
||||
void setSender(CanDbNode *sender);
|
||||
|
||||
void addSignal(CanDbSignal *signal);
|
||||
CanDbSignal *getSignal(int num);
|
||||
CanDbSignal *getSignalByName(QString signal_name);
|
||||
|
||||
CanDbSignalList getSignals() { return _signals; }
|
||||
|
||||
QString getComment() const;
|
||||
void setComment(const QString &comment);
|
||||
|
||||
CanDbSignal *getMuxer() const;
|
||||
void setMuxer(CanDbSignal *muxer);
|
||||
|
||||
private:
|
||||
CanDb *_parent;
|
||||
QString _name;
|
||||
uint32_t _raw_id;
|
||||
uint8_t _dlc;
|
||||
CanDbNode *_sender;
|
||||
CanDbSignalList _signals;
|
||||
QString _comment;
|
||||
CanDbSignal *_muxer;
|
||||
|
||||
};
|
||||
49
core/CanDbNode.cpp
Normal file
49
core/CanDbNode.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "CanDbNode.h"
|
||||
|
||||
CanDbNode::CanDbNode(CanDb *parent)
|
||||
: _parent(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString CanDbNode::name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
void CanDbNode::setName(const QString &name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
QString CanDbNode::comment() const
|
||||
{
|
||||
return _comment;
|
||||
}
|
||||
|
||||
void CanDbNode::setComment(const QString &comment)
|
||||
{
|
||||
_comment = comment;
|
||||
}
|
||||
|
||||
43
core/CanDbNode.h
Normal file
43
core/CanDbNode.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
class CanDb;
|
||||
|
||||
class CanDbNode
|
||||
{
|
||||
public:
|
||||
CanDbNode(CanDb *parent);
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
|
||||
QString comment() const;
|
||||
void setComment(const QString &comment);
|
||||
|
||||
private:
|
||||
CanDb *_parent;
|
||||
QString _name;
|
||||
QString _comment;
|
||||
};
|
||||
229
core/CanDbSignal.cpp
Normal file
229
core/CanDbSignal.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "CanDbSignal.h"
|
||||
|
||||
CanDbSignal::CanDbSignal(CanDbMessage *parent)
|
||||
: _parent(parent),
|
||||
_isUnsigned(false),
|
||||
_isBigEndian(false),
|
||||
_factor(1),
|
||||
_offset(0),
|
||||
_min(0),
|
||||
_max(0),
|
||||
_isMuxer(false),
|
||||
_isMuxed(false),
|
||||
_muxValue(0)
|
||||
{
|
||||
}
|
||||
|
||||
QString CanDbSignal::name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
void CanDbSignal::setName(const QString &name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
uint8_t CanDbSignal::startBit() const
|
||||
{
|
||||
return _startBit;
|
||||
}
|
||||
|
||||
void CanDbSignal::setStartBit(uint8_t startBit)
|
||||
{
|
||||
_startBit = startBit;
|
||||
}
|
||||
|
||||
uint8_t CanDbSignal::length() const
|
||||
{
|
||||
return _length;
|
||||
}
|
||||
|
||||
void CanDbSignal::setLength(uint8_t length)
|
||||
{
|
||||
_length = length;
|
||||
}
|
||||
|
||||
QString CanDbSignal::comment() const
|
||||
{
|
||||
return _comment;
|
||||
}
|
||||
|
||||
void CanDbSignal::setComment(const QString &comment)
|
||||
{
|
||||
_comment = comment;
|
||||
}
|
||||
|
||||
QString CanDbSignal::getValueName(const uint64_t value) const
|
||||
{
|
||||
if (_valueTable.contains(value)) {
|
||||
return _valueTable[value];
|
||||
} else {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
void CanDbSignal::setValueName(const uint64_t value, const QString &name)
|
||||
{
|
||||
_valueTable[value] = name;
|
||||
}
|
||||
|
||||
double CanDbSignal::convertRawValueToPhysical(const uint64_t rawValue)
|
||||
{
|
||||
if (isUnsigned()) {
|
||||
uint64_t v = rawValue;
|
||||
return v * _factor + _offset;
|
||||
} else {
|
||||
// TODO check with DBC that actually contains signed values?!
|
||||
int64_t v = (int64_t)(rawValue<<(64-_length));
|
||||
v>>=(64-_length);
|
||||
return v * _factor + _offset;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
double CanDbSignal::extractPhysicalFromMessage(const CanMessage &msg)
|
||||
{
|
||||
return convertRawValueToPhysical(extractRawDataFromMessage(msg));
|
||||
}
|
||||
|
||||
double CanDbSignal::getFactor() const
|
||||
{
|
||||
return _factor;
|
||||
}
|
||||
|
||||
void CanDbSignal::setFactor(double factor)
|
||||
{
|
||||
_factor = factor;
|
||||
}
|
||||
|
||||
double CanDbSignal::getOffset() const
|
||||
{
|
||||
return _offset;
|
||||
}
|
||||
|
||||
void CanDbSignal::setOffset(double offset)
|
||||
{
|
||||
_offset = offset;
|
||||
}
|
||||
|
||||
double CanDbSignal::getMinimumValue() const
|
||||
{
|
||||
return _min;
|
||||
}
|
||||
|
||||
void CanDbSignal::setMinimumValue(double min)
|
||||
{
|
||||
_min = min;
|
||||
}
|
||||
|
||||
double CanDbSignal::getMaximumValue() const
|
||||
{
|
||||
return _max;
|
||||
}
|
||||
|
||||
void CanDbSignal::setMaximumValue(double max)
|
||||
{
|
||||
_max = max;
|
||||
}
|
||||
|
||||
QString CanDbSignal::getUnit() const
|
||||
{
|
||||
return _unit;
|
||||
}
|
||||
|
||||
void CanDbSignal::setUnit(const QString &unit)
|
||||
{
|
||||
_unit = unit;
|
||||
}
|
||||
|
||||
bool CanDbSignal::isUnsigned() const
|
||||
{
|
||||
return _isUnsigned;
|
||||
}
|
||||
|
||||
void CanDbSignal::setUnsigned(bool isUnsigned)
|
||||
{
|
||||
_isUnsigned = isUnsigned;
|
||||
}
|
||||
bool CanDbSignal::isBigEndian() const
|
||||
{
|
||||
return _isBigEndian;
|
||||
}
|
||||
|
||||
void CanDbSignal::setIsBigEndian(bool isBigEndian)
|
||||
{
|
||||
_isBigEndian = isBigEndian;
|
||||
}
|
||||
|
||||
bool CanDbSignal::isMuxer() const
|
||||
{
|
||||
return _isMuxer;
|
||||
}
|
||||
|
||||
void CanDbSignal::setIsMuxer(bool isMuxer)
|
||||
{
|
||||
_isMuxer = isMuxer;
|
||||
}
|
||||
|
||||
bool CanDbSignal::isMuxed() const
|
||||
{
|
||||
return _isMuxed;
|
||||
}
|
||||
|
||||
void CanDbSignal::setIsMuxed(bool isMuxed)
|
||||
{
|
||||
_isMuxed = isMuxed;
|
||||
}
|
||||
|
||||
uint32_t CanDbSignal::getMuxValue() const
|
||||
{
|
||||
return _muxValue;
|
||||
}
|
||||
|
||||
void CanDbSignal::setMuxValue(const uint32_t &muxValue)
|
||||
{
|
||||
_muxValue = muxValue;
|
||||
}
|
||||
|
||||
bool CanDbSignal::isPresentInMessage(const CanMessage &msg)
|
||||
{
|
||||
if ((_startBit + _length)>(8*msg.getLength())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_isMuxed) { return true; }
|
||||
|
||||
CanDbSignal *muxer = _parent->getMuxer();
|
||||
if (!muxer) { return false; }
|
||||
|
||||
return _muxValue == muxer->extractRawDataFromMessage(msg);
|
||||
}
|
||||
|
||||
uint64_t CanDbSignal::extractRawDataFromMessage(const CanMessage &msg)
|
||||
{
|
||||
return msg.extractRawSignal(startBit(), length(), isBigEndian());
|
||||
}
|
||||
|
||||
|
||||
106
core/CanDbSignal.h
Normal file
106
core/CanDbSignal.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CanMessage.h"
|
||||
#include "CanDbMessage.h"
|
||||
#include <QString>
|
||||
#include <QMap>
|
||||
|
||||
class CanDbMessage;
|
||||
|
||||
typedef QMap<uint64_t,QString> CanDbValueTable;
|
||||
|
||||
class CanDbSignal
|
||||
{
|
||||
public:
|
||||
CanDbSignal(CanDbMessage *parent);
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
|
||||
uint8_t startBit() const;
|
||||
void setStartBit(uint8_t startBit);
|
||||
|
||||
uint8_t length() const;
|
||||
void setLength(uint8_t length);
|
||||
|
||||
QString comment() const;
|
||||
void setComment(const QString &comment);
|
||||
|
||||
QString getValueName(const uint64_t value) const;
|
||||
void setValueName(const uint64_t value, const QString &name);
|
||||
|
||||
double getFactor() const;
|
||||
void setFactor(double factor);
|
||||
|
||||
double getOffset() const;
|
||||
void setOffset(double offset);
|
||||
|
||||
double getMinimumValue() const;
|
||||
void setMinimumValue(double min);
|
||||
|
||||
double getMaximumValue() const;
|
||||
void setMaximumValue(double max);
|
||||
|
||||
QString getUnit() const;
|
||||
void setUnit(const QString &unit);
|
||||
|
||||
bool isUnsigned() const;
|
||||
void setUnsigned(bool isUnsigned);
|
||||
|
||||
bool isBigEndian() const;
|
||||
void setIsBigEndian(bool isBigEndian);
|
||||
|
||||
bool isMuxer() const;
|
||||
void setIsMuxer(bool isMuxer);
|
||||
|
||||
bool isMuxed() const;
|
||||
void setIsMuxed(bool isMuxed);
|
||||
|
||||
uint32_t getMuxValue() const;
|
||||
void setMuxValue(const uint32_t &muxValue);
|
||||
|
||||
bool isPresentInMessage(const CanMessage &msg);
|
||||
uint64_t extractRawDataFromMessage(const CanMessage &msg);
|
||||
|
||||
double convertRawValueToPhysical(const uint64_t rawValue);
|
||||
double extractPhysicalFromMessage(const CanMessage &msg);
|
||||
|
||||
|
||||
private:
|
||||
CanDbMessage *_parent;
|
||||
QString _name;
|
||||
uint8_t _startBit;
|
||||
uint8_t _length;
|
||||
bool _isUnsigned;
|
||||
bool _isBigEndian;
|
||||
double _factor;
|
||||
double _offset;
|
||||
double _min;
|
||||
double _max;
|
||||
QString _unit;
|
||||
bool _isMuxer;
|
||||
bool _isMuxed;
|
||||
uint32_t _muxValue;
|
||||
QString _comment;
|
||||
CanDbValueTable _valueTable;
|
||||
};
|
||||
346
core/CanMessage.cpp
Normal file
346
core/CanMessage.cpp
Normal file
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "CanMessage.h"
|
||||
#include <core/portable_endian.h>
|
||||
|
||||
enum {
|
||||
id_flag_extended = 0x80000000,
|
||||
id_flag_rtr = 0x40000000,
|
||||
id_flag_error = 0x20000000,
|
||||
id_mask_extended = 0x1FFFFFFF,
|
||||
id_mask_standard = 0x7FF
|
||||
};
|
||||
|
||||
CanMessage::CanMessage()
|
||||
: _raw_id(0), _dlc(0), _isFD(false), _interface(0), _u8()
|
||||
{
|
||||
_timestamp.tv_sec = 0;
|
||||
_timestamp.tv_usec = 0;
|
||||
|
||||
}
|
||||
|
||||
CanMessage::CanMessage(uint32_t can_id)
|
||||
: _dlc(0), _interface(0), _u8()
|
||||
{
|
||||
_timestamp.tv_sec = 0;
|
||||
_timestamp.tv_usec = 0;
|
||||
setId(can_id);
|
||||
}
|
||||
|
||||
CanMessage::CanMessage(const CanMessage &msg)
|
||||
{
|
||||
cloneFrom(msg);
|
||||
}
|
||||
|
||||
void CanMessage::cloneFrom(const CanMessage &msg)
|
||||
{
|
||||
_raw_id = msg._raw_id;
|
||||
_dlc = msg._dlc;
|
||||
|
||||
// Copy data
|
||||
for(int i=0; i<64; i++)
|
||||
{
|
||||
_u8[i] = msg._u8[i];
|
||||
}
|
||||
|
||||
_interface = msg._interface;
|
||||
_timestamp = msg._timestamp;
|
||||
}
|
||||
|
||||
|
||||
uint32_t CanMessage::getRawId() const {
|
||||
return _raw_id;
|
||||
}
|
||||
|
||||
void CanMessage::setRawId(const uint32_t raw_id) {
|
||||
_raw_id = raw_id;
|
||||
}
|
||||
|
||||
uint32_t CanMessage::getId() const {
|
||||
if (isExtended()) {
|
||||
return _raw_id & id_mask_extended;
|
||||
} else {
|
||||
return _raw_id & id_mask_standard;
|
||||
}
|
||||
}
|
||||
|
||||
void CanMessage::setId(const uint32_t id) {
|
||||
_raw_id &= ~ id_mask_extended;
|
||||
_raw_id = id;
|
||||
if (id>0x7FF) {
|
||||
setExtended(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool CanMessage::isExtended() const {
|
||||
return (_raw_id & id_flag_extended) != 0;
|
||||
}
|
||||
|
||||
void CanMessage::setExtended(const bool isExtended) {
|
||||
if (isExtended) {
|
||||
_raw_id |= id_flag_extended;
|
||||
} else {
|
||||
_raw_id &= ~id_flag_extended;
|
||||
}
|
||||
}
|
||||
|
||||
bool CanMessage::isRTR() const {
|
||||
return (_raw_id & id_flag_rtr) != 0;
|
||||
}
|
||||
|
||||
void CanMessage::setRTR(const bool isRTR) {
|
||||
if (isRTR) {
|
||||
_raw_id |= id_flag_rtr;
|
||||
} else {
|
||||
_raw_id &= ~id_flag_rtr;
|
||||
}
|
||||
}
|
||||
|
||||
bool CanMessage::isFD() const {
|
||||
return _isFD;
|
||||
}
|
||||
|
||||
void CanMessage::setFD(const bool isFD) {
|
||||
_isFD = isFD;
|
||||
}
|
||||
|
||||
bool CanMessage::isBRS() const {
|
||||
return _isBRS;
|
||||
}
|
||||
|
||||
void CanMessage::setBRS(const bool isBRS) {
|
||||
_isBRS = isBRS;
|
||||
}
|
||||
|
||||
bool CanMessage::isErrorFrame() const {
|
||||
return (_raw_id & id_flag_error) != 0;
|
||||
}
|
||||
|
||||
void CanMessage::setErrorFrame(const bool isErrorFrame) {
|
||||
if (isErrorFrame) {
|
||||
_raw_id |= id_flag_error;
|
||||
} else {
|
||||
_raw_id &= ~id_flag_error;
|
||||
}
|
||||
}
|
||||
|
||||
CanInterfaceId CanMessage::getInterfaceId() const
|
||||
{
|
||||
return _interface;
|
||||
}
|
||||
|
||||
void CanMessage::setInterfaceId(CanInterfaceId interface)
|
||||
{
|
||||
_interface = interface;
|
||||
}
|
||||
|
||||
uint8_t CanMessage::getLength() const {
|
||||
return _dlc;
|
||||
}
|
||||
|
||||
void CanMessage::setLength(const uint8_t dlc) {
|
||||
// Limit to CANFD max length
|
||||
if (dlc<=64) {
|
||||
_dlc = dlc;
|
||||
} else {
|
||||
_dlc = 8;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t CanMessage::getByte(const uint8_t index) const {
|
||||
if (index<sizeof(_u8)) {
|
||||
return _u8[index];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CanMessage::setByte(const uint8_t index, const uint8_t value) {
|
||||
if (index<sizeof(_u8)) {
|
||||
_u8[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t CanMessage::extractRawSignal(uint8_t start_bit, const uint8_t length, const bool isBigEndian) const
|
||||
{
|
||||
// if ((start_bit+length) > (getLength()*8)) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// FIXME: This only gives access to data bytes 0-8. Need to rework for CANFD.
|
||||
uint64_t data = le64toh(_u64[0]);
|
||||
|
||||
data >>= start_bit;
|
||||
|
||||
uint64_t mask = 0xFFFFFFFFFFFFFFFF;
|
||||
mask <<= length;
|
||||
mask = ~mask;
|
||||
|
||||
data &= mask;
|
||||
|
||||
// If the length is greater than 8, we need to byteswap to preserve endianness
|
||||
if (isBigEndian && (length > 8))
|
||||
{
|
||||
|
||||
// Swap bytes
|
||||
data = __builtin_bswap64(data);
|
||||
|
||||
// Shift out unused bits
|
||||
data >>= 64 - length;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void CanMessage::setDataAt(uint8_t position, uint8_t data)
|
||||
{
|
||||
if(position < 64)
|
||||
_u8[position] = data;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
void CanMessage::setData(const uint8_t d0) {
|
||||
_dlc = 1;
|
||||
_u8[0] = d0;
|
||||
}
|
||||
|
||||
void CanMessage::setData(const uint8_t d0, const uint8_t d1) {
|
||||
_dlc = 2;
|
||||
_u8[0] = d0;
|
||||
_u8[1] = d1;
|
||||
}
|
||||
|
||||
void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2) {
|
||||
_dlc = 3;
|
||||
_u8[0] = d0;
|
||||
_u8[1] = d1;
|
||||
_u8[2] = d2;
|
||||
}
|
||||
|
||||
void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2,
|
||||
const uint8_t d3) {
|
||||
_dlc = 4;
|
||||
_u8[0] = d0;
|
||||
_u8[1] = d1;
|
||||
_u8[2] = d2;
|
||||
_u8[3] = d3;
|
||||
}
|
||||
|
||||
void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2,
|
||||
const uint8_t d3, const uint8_t d4) {
|
||||
_dlc = 5;
|
||||
_u8[0] = d0;
|
||||
_u8[1] = d1;
|
||||
_u8[2] = d2;
|
||||
_u8[3] = d3;
|
||||
_u8[4] = d4;
|
||||
}
|
||||
|
||||
void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2,
|
||||
const uint8_t d3, const uint8_t d4, const uint8_t d5) {
|
||||
_dlc = 6;
|
||||
_u8[0] = d0;
|
||||
_u8[1] = d1;
|
||||
_u8[2] = d2;
|
||||
_u8[3] = d3;
|
||||
_u8[4] = d4;
|
||||
_u8[5] = d5;
|
||||
}
|
||||
|
||||
void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2,
|
||||
const uint8_t d3, const uint8_t d4, const uint8_t d5,
|
||||
const uint8_t d6) {
|
||||
_dlc = 7;
|
||||
_u8[0] = d0;
|
||||
_u8[1] = d1;
|
||||
_u8[2] = d2;
|
||||
_u8[3] = d3;
|
||||
_u8[4] = d4;
|
||||
_u8[5] = d5;
|
||||
_u8[6] = d6;
|
||||
}
|
||||
|
||||
void CanMessage::setData(const uint8_t d0, const uint8_t d1, const uint8_t d2,
|
||||
const uint8_t d3, const uint8_t d4, const uint8_t d5, const uint8_t d6,
|
||||
const uint8_t d7) {
|
||||
_dlc = 8;
|
||||
_u8[0] = d0;
|
||||
_u8[1] = d1;
|
||||
_u8[2] = d2;
|
||||
_u8[3] = d3;
|
||||
_u8[4] = d4;
|
||||
_u8[5] = d5;
|
||||
_u8[6] = d6;
|
||||
_u8[7] = d7;
|
||||
}
|
||||
|
||||
timeval CanMessage::getTimestamp() const
|
||||
{
|
||||
return _timestamp;
|
||||
}
|
||||
|
||||
void CanMessage::setTimestamp(const timeval timestamp)
|
||||
{
|
||||
_timestamp = timestamp;
|
||||
}
|
||||
|
||||
void CanMessage::setTimestamp(const uint64_t seconds, const uint32_t micro_seconds)
|
||||
{
|
||||
_timestamp.tv_sec = seconds;
|
||||
_timestamp.tv_usec = micro_seconds;
|
||||
}
|
||||
|
||||
double CanMessage::getFloatTimestamp() const
|
||||
{
|
||||
return (double)_timestamp.tv_sec + ((double)_timestamp.tv_usec/1000000);
|
||||
}
|
||||
|
||||
QDateTime CanMessage::getDateTime() const
|
||||
{
|
||||
return QDateTime::fromMSecsSinceEpoch((qint64)(1000*getFloatTimestamp()));
|
||||
}
|
||||
|
||||
QString CanMessage::getIdString() const
|
||||
{
|
||||
if (isExtended()) {
|
||||
return QString().sprintf("0x%08X", getId());
|
||||
} else {
|
||||
return QString().sprintf("0x%03X", getId());
|
||||
}
|
||||
}
|
||||
|
||||
QString CanMessage::getDataHexString() const
|
||||
{
|
||||
if(getLength() == 0)
|
||||
return "";
|
||||
|
||||
QString outstr = "";
|
||||
for(int i=0; i<getLength(); i++)
|
||||
{
|
||||
outstr += QString().sprintf("%02X ", getByte(i));
|
||||
}
|
||||
|
||||
return outstr;
|
||||
}
|
||||
104
core/CanMessage.h
Normal file
104
core/CanMessage.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
#include <driver/CanDriver.h>
|
||||
|
||||
class CanMessage {
|
||||
public:
|
||||
CanMessage();
|
||||
CanMessage(uint32_t can_id);
|
||||
CanMessage(const CanMessage &msg);
|
||||
void cloneFrom(const CanMessage &msg);
|
||||
|
||||
uint32_t getRawId() const;
|
||||
void setRawId(const uint32_t raw_id);
|
||||
|
||||
uint32_t getId() const;
|
||||
void setId(const uint32_t id);
|
||||
|
||||
bool isExtended() const;
|
||||
void setExtended(const bool isExtended);
|
||||
|
||||
bool isRTR() const;
|
||||
void setRTR(const bool isRTR);
|
||||
|
||||
bool isFD() const;
|
||||
void setFD(const bool isFD);
|
||||
|
||||
bool isBRS() const;
|
||||
void setBRS(const bool isFD);
|
||||
|
||||
bool isErrorFrame() const;
|
||||
void setErrorFrame(const bool isErrorFrame);
|
||||
|
||||
CanInterfaceId getInterfaceId() const;
|
||||
void setInterfaceId(CanInterfaceId interface);
|
||||
|
||||
uint8_t getLength() const;
|
||||
void setLength(const uint8_t dlc);
|
||||
|
||||
uint8_t getByte(const uint8_t index) const;
|
||||
void setByte(const uint8_t index, const uint8_t value);
|
||||
|
||||
uint64_t extractRawSignal(uint8_t start_bit, const uint8_t length, const bool isBigEndian) const;
|
||||
|
||||
void setDataAt(uint8_t position, uint8_t data);
|
||||
void setData(const uint8_t d0);
|
||||
void setData(const uint8_t d0, const uint8_t d1);
|
||||
void setData(const uint8_t d0, const uint8_t d1, const uint8_t d2);
|
||||
void setData(const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3);
|
||||
void setData(const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3, const uint8_t d4);
|
||||
void setData(const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3, const uint8_t d4, const uint8_t d5);
|
||||
void setData(const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3, const uint8_t d4, const uint8_t d5, const uint8_t d6);
|
||||
void setData(const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3, const uint8_t d4, const uint8_t d5, const uint8_t d6, const uint8_t d7);
|
||||
|
||||
struct timeval getTimestamp() const;
|
||||
void setTimestamp(const struct timeval timestamp);
|
||||
void setTimestamp(const uint64_t seconds, const uint32_t micro_seconds);
|
||||
|
||||
double getFloatTimestamp() const;
|
||||
QDateTime getDateTime() const;
|
||||
|
||||
QString getIdString() const;
|
||||
QString getDataHexString() const;
|
||||
|
||||
private:
|
||||
uint32_t _raw_id;
|
||||
uint8_t _dlc;
|
||||
bool _isFD;
|
||||
bool _isBRS;
|
||||
CanInterfaceId _interface;
|
||||
union {
|
||||
uint8_t _u8[8*8];
|
||||
uint16_t _u16[4*8];
|
||||
uint32_t _u32[2*8];
|
||||
uint64_t _u64[8];
|
||||
};
|
||||
struct timeval _timestamp;
|
||||
|
||||
};
|
||||
215
core/CanTrace.cpp
Normal file
215
core/CanTrace.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "CanTrace.h"
|
||||
#include <QMutexLocker>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
#include <core/Backend.h>
|
||||
#include <core/CanMessage.h>
|
||||
#include <core/CanDbMessage.h>
|
||||
#include <core/CanDbSignal.h>
|
||||
#include <driver/CanInterface.h>
|
||||
|
||||
CanTrace::CanTrace(Backend &backend, QObject *parent, int flushInterval)
|
||||
: QObject(parent),
|
||||
_backend(backend),
|
||||
_isTimerRunning(false),
|
||||
_mutex(QMutex::Recursive),
|
||||
_timerMutex(),
|
||||
_flushTimer(this)
|
||||
{
|
||||
clear();
|
||||
_flushTimer.setSingleShot(true);
|
||||
_flushTimer.setInterval(flushInterval);
|
||||
connect(&_flushTimer, SIGNAL(timeout()), this, SLOT(flushQueue()));
|
||||
}
|
||||
|
||||
unsigned long CanTrace::size()
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
return _dataRowsUsed;
|
||||
}
|
||||
|
||||
void CanTrace::clear()
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
emit beforeClear();
|
||||
_data.resize(pool_chunk_size);
|
||||
_dataRowsUsed = 0;
|
||||
_newRows = 0;
|
||||
emit afterClear();
|
||||
}
|
||||
|
||||
const CanMessage *CanTrace::getMessage(int idx)
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
if (idx >= (_dataRowsUsed + _newRows)) {
|
||||
return 0;
|
||||
} else {
|
||||
return &_data[idx];
|
||||
}
|
||||
}
|
||||
|
||||
void CanTrace::enqueueMessage(const CanMessage &msg, bool more_to_follow)
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
|
||||
int idx = size() + _newRows;
|
||||
if (idx>=_data.size()) {
|
||||
_data.resize(_data.size() + pool_chunk_size);
|
||||
}
|
||||
|
||||
_data[idx].cloneFrom(msg);
|
||||
_newRows++;
|
||||
|
||||
if (!more_to_follow) {
|
||||
startTimer();
|
||||
}
|
||||
|
||||
emit messageEnqueued(idx);
|
||||
}
|
||||
|
||||
void CanTrace::flushQueue()
|
||||
{
|
||||
{
|
||||
QMutexLocker locker(&_timerMutex);
|
||||
_isTimerRunning = false;
|
||||
}
|
||||
|
||||
QMutexLocker locker(&_mutex);
|
||||
if (_newRows) {
|
||||
emit beforeAppend(_newRows);
|
||||
|
||||
// see if we have muxed messages. cache muxed values, if any.
|
||||
MeasurementSetup &setup = _backend.getSetup();
|
||||
for (int i=_dataRowsUsed; i<_dataRowsUsed + _newRows; i++) {
|
||||
CanMessage &msg = _data[i];
|
||||
CanDbMessage *dbmsg = setup.findDbMessage(msg);
|
||||
if (dbmsg && dbmsg->getMuxer()) {
|
||||
foreach (CanDbSignal *signal, dbmsg->getSignals()) {
|
||||
if (signal->isMuxed() && signal->isPresentInMessage(msg)) {
|
||||
_muxCache[signal] = signal->extractRawDataFromMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_dataRowsUsed += _newRows;
|
||||
_newRows = 0;
|
||||
emit afterAppend();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CanTrace::startTimer()
|
||||
{
|
||||
QMutexLocker locker(&_timerMutex);
|
||||
if (!_isTimerRunning) {
|
||||
_isTimerRunning = true;
|
||||
QMetaObject::invokeMethod(&_flushTimer, "start", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
void CanTrace::saveCanDump(QFile &file)
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
QTextStream stream(&file);
|
||||
for (unsigned int i=0; i<size(); i++) {
|
||||
CanMessage *msg = &_data[i];
|
||||
QString line;
|
||||
line.append(QString().sprintf("(%.6f) ", msg->getFloatTimestamp()));
|
||||
line.append(_backend.getInterfaceName(msg->getInterfaceId()));
|
||||
if (msg->isExtended()) {
|
||||
line.append(QString().sprintf(" %08X#", msg->getId()));
|
||||
} else {
|
||||
line.append(QString().sprintf(" %03X#", msg->getId()));
|
||||
}
|
||||
for (int i=0; i<msg->getLength(); i++) {
|
||||
line.append(QString().sprintf("%02X", msg->getByte(i)));
|
||||
}
|
||||
stream << line << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void CanTrace::saveVectorAsc(QFile &file)
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
QTextStream stream(&file);
|
||||
|
||||
if (_data.length()<1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto firstMessage = _data.first();
|
||||
double t_start = firstMessage.getFloatTimestamp();
|
||||
|
||||
QLocale locale_c(QLocale::C);
|
||||
QString dt_start = locale_c.toString(firstMessage.getDateTime(), "ddd MMM dd hh:mm:ss.zzz ap yyyy");
|
||||
|
||||
stream << "date " << dt_start << endl;
|
||||
stream << "base hex timestamps absolute" << endl;
|
||||
stream << "internal events logged" << endl;
|
||||
stream << "// version 8.5.0" << endl;
|
||||
stream << "Begin Triggerblock " << dt_start << endl;
|
||||
stream << " 0.000000 Start of measurement" << endl;
|
||||
|
||||
for (unsigned int i=0; i<size(); i++) {
|
||||
CanMessage &msg = _data[i];
|
||||
|
||||
double t_current = msg.getFloatTimestamp();
|
||||
QString id_hex_str = QString().sprintf("%x", msg.getId());
|
||||
QString id_dec_str = QString().sprintf("%d", msg.getId());
|
||||
if (msg.isExtended()) {
|
||||
id_hex_str.append("x");
|
||||
id_dec_str.append("x");
|
||||
}
|
||||
|
||||
// TODO how to handle RTR flag?
|
||||
QString line = QString().sprintf(
|
||||
"%11.6lf 1 %-15s %s d %d %s Length = %d BitCount = %d ID = %s",
|
||||
t_current-t_start,
|
||||
id_hex_str.toStdString().c_str(),
|
||||
"Rx", // TODO handle Rx/Tx
|
||||
msg.getLength(),
|
||||
msg.getDataHexString().toStdString().c_str(),
|
||||
0, // TODO Length (transfer time in ns)
|
||||
0, // TODO BitCount (overall frame length, including stuff bits)
|
||||
id_dec_str.toStdString().c_str()
|
||||
);
|
||||
|
||||
stream << line << endl;
|
||||
}
|
||||
|
||||
stream << "End TriggerBlock" << endl;
|
||||
}
|
||||
|
||||
bool CanTrace::getMuxedSignalFromCache(const CanDbSignal *signal, uint64_t *raw_value)
|
||||
{
|
||||
if (_muxCache.contains(signal)) {
|
||||
*raw_value = _muxCache[signal];
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
87
core/CanTrace.h
Normal file
87
core/CanTrace.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
#include <QTimer>
|
||||
#include <QVector>
|
||||
#include <QMap>
|
||||
#include <QFile>
|
||||
|
||||
#include "CanMessage.h"
|
||||
|
||||
class CanInterface;
|
||||
class CanDbMessage;
|
||||
class CanDbSignal;
|
||||
class MeasurementSetup;
|
||||
class Backend;
|
||||
|
||||
class CanTrace : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CanTrace(Backend &backend, QObject *parent, int flushInterval);
|
||||
|
||||
unsigned long size();
|
||||
void clear();
|
||||
const CanMessage *getMessage(int idx);
|
||||
void enqueueMessage(const CanMessage &msg, bool more_to_follow=false);
|
||||
|
||||
void saveCanDump(QFile &file);
|
||||
void saveVectorAsc(QFile &file);
|
||||
|
||||
bool getMuxedSignalFromCache(const CanDbSignal *signal, uint64_t *raw_value);
|
||||
|
||||
signals:
|
||||
void messageEnqueued(int idx);
|
||||
void beforeAppend(int num_messages);
|
||||
void afterAppend();
|
||||
void beforeClear();
|
||||
void afterClear();
|
||||
|
||||
private slots:
|
||||
void flushQueue();
|
||||
|
||||
private:
|
||||
enum {
|
||||
pool_chunk_size = 1024
|
||||
};
|
||||
|
||||
Backend &_backend;
|
||||
|
||||
QVector<CanMessage> _data;
|
||||
int _dataRowsUsed;
|
||||
int _newRows;
|
||||
bool _isTimerRunning;
|
||||
|
||||
QMap<const CanDbSignal*,uint64_t> _muxCache;
|
||||
|
||||
QMutex _mutex;
|
||||
QMutex _timerMutex;
|
||||
QTimer _flushTimer;
|
||||
|
||||
void startTimer();
|
||||
|
||||
|
||||
};
|
||||
44
core/ConfigurableWidget.cpp
Normal file
44
core/ConfigurableWidget.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "ConfigurableWidget.h"
|
||||
#include <QDomDocument>
|
||||
#include <core/Backend.h>
|
||||
|
||||
ConfigurableWidget::ConfigurableWidget(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ConfigurableWidget::saveXML(Backend &backend, QDomDocument &xml, QDomElement &root)
|
||||
{
|
||||
(void) backend;
|
||||
(void) xml;
|
||||
(void) root;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigurableWidget::loadXML(Backend &backend, QDomElement &el)
|
||||
{
|
||||
(void) backend;
|
||||
(void) el;
|
||||
return true;
|
||||
}
|
||||
43
core/ConfigurableWidget.h
Normal file
43
core/ConfigurableWidget.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
|
||||
class Backend;
|
||||
class QDomDocument;
|
||||
class QDomElement;
|
||||
|
||||
class ConfigurableWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ConfigurableWidget(QWidget *parent = 0);
|
||||
virtual bool saveXML(Backend &backend, QDomDocument &xml, QDomElement &root);
|
||||
virtual bool loadXML(Backend &backend, QDomElement &el);
|
||||
|
||||
signals:
|
||||
void settingsChanged(ConfigurableWidget *sender);
|
||||
|
||||
public slots:
|
||||
};
|
||||
63
core/Log.cpp
Normal file
63
core/Log.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "Log.h"
|
||||
#include <core/Backend.h>
|
||||
|
||||
void log_msg(const QDateTime dt, const log_level_t level, const QString msg)
|
||||
{
|
||||
Backend::instance().logMessage(dt, level, msg);
|
||||
}
|
||||
|
||||
void log_msg(const log_level_t level, const QString msg)
|
||||
{
|
||||
Backend::instance().logMessage(QDateTime::currentDateTime(), level, msg);
|
||||
}
|
||||
|
||||
void log_debug(const QString msg)
|
||||
{
|
||||
log_msg(log_level_debug, msg);
|
||||
}
|
||||
|
||||
void log_info(const QString msg)
|
||||
{
|
||||
log_msg(log_level_info, msg);
|
||||
}
|
||||
|
||||
void log_warning(const QString msg)
|
||||
{
|
||||
log_msg(log_level_warning, msg);
|
||||
}
|
||||
|
||||
void log_error(const QString msg)
|
||||
{
|
||||
log_msg(log_level_error, msg);
|
||||
}
|
||||
|
||||
void log_critical(const QString msg)
|
||||
{
|
||||
log_msg(log_level_critical, msg);
|
||||
}
|
||||
|
||||
void log_fatal(const QString msg)
|
||||
{
|
||||
log_msg(log_level_fatal, msg);
|
||||
}
|
||||
43
core/Log.h
Normal file
43
core/Log.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
typedef enum log_level {
|
||||
log_level_debug,
|
||||
log_level_info,
|
||||
log_level_warning,
|
||||
log_level_error,
|
||||
log_level_critical,
|
||||
log_level_fatal
|
||||
} log_level_t;
|
||||
|
||||
void log_msg(const QDateTime dt, const log_level_t level, const QString msg);
|
||||
void log_msg(const log_level_t level, const QString msg);
|
||||
|
||||
void log_debug(const QString msg);
|
||||
void log_info(const QString msg);
|
||||
void log_warning(const QString msg);
|
||||
void log_error(const QString msg);
|
||||
void log_critical(const QString msg);
|
||||
void log_fatal(const QString msg);
|
||||
160
core/LogModel.cpp
Normal file
160
core/LogModel.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "LogModel.h"
|
||||
|
||||
LogModel::LogModel(Backend &backend)
|
||||
{
|
||||
connect(&backend, SIGNAL(onLogMessage(QDateTime,log_level_t,QString)), this, SLOT(onLogMessage(QDateTime,log_level_t,QString)));
|
||||
}
|
||||
|
||||
LogModel::~LogModel()
|
||||
{
|
||||
qDeleteAll(_items);
|
||||
_items.clear();
|
||||
}
|
||||
|
||||
void LogModel::clear()
|
||||
{
|
||||
beginResetModel();
|
||||
_items.clear();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QModelIndex LogModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
return QModelIndex();
|
||||
} else {
|
||||
return createIndex(row, column, (quintptr)0);
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex LogModel::parent(const QModelIndex &child) const
|
||||
{
|
||||
(void) child;
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int LogModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
(void) parent;
|
||||
return _items.size();
|
||||
}
|
||||
|
||||
int LogModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
(void) parent;
|
||||
return column_count;
|
||||
}
|
||||
|
||||
bool LogModel::hasChildren(const QModelIndex &parent) const
|
||||
{
|
||||
return !parent.isValid();
|
||||
}
|
||||
|
||||
QVariant LogModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole) {
|
||||
|
||||
if (orientation == Qt::Horizontal) {
|
||||
switch (section) {
|
||||
case column_time:
|
||||
return QString("Time");
|
||||
case column_level:
|
||||
return QString("Level");
|
||||
case column_text:
|
||||
return QString("Message");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant LogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
|
||||
if (role == Qt::TextAlignmentRole) {
|
||||
switch (index.column()) {
|
||||
case column_time:
|
||||
return Qt::AlignRight + Qt::AlignVCenter;
|
||||
case column_level:
|
||||
return Qt::AlignCenter + Qt::AlignVCenter;
|
||||
case column_text:
|
||||
return Qt::AlignLeft + Qt::AlignVCenter;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
if (role != Qt::DisplayRole) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (!index.isValid()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
LogItem *item = _items.value(index.row(), 0);
|
||||
if (item) {
|
||||
|
||||
switch (index.column()) {
|
||||
case column_time:
|
||||
return item->dt.toString("hh:mm:ss");
|
||||
case column_level:
|
||||
return logLevelText(item->level);
|
||||
case column_text:
|
||||
return item->text;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void LogModel::onLogMessage(const QDateTime dt, const log_level_t level, const QString msg)
|
||||
{
|
||||
LogItem *item = new LogItem();
|
||||
item->dt = dt;
|
||||
item->level = level;
|
||||
item->text = msg;
|
||||
|
||||
beginInsertRows(QModelIndex(), _items.size(), _items.size());
|
||||
_items.append(item);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
QString LogModel::logLevelText(log_level_t level)
|
||||
{
|
||||
switch (level) {
|
||||
case log_level_debug: return "debug";
|
||||
case log_level_info: return "info";
|
||||
case log_level_warning: return "warning";
|
||||
case log_level_error: return "error";
|
||||
case log_level_critical: return "critical";
|
||||
case log_level_fatal: return "fatal";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
71
core/LogModel.h
Normal file
71
core/LogModel.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QDateTime>
|
||||
#include <QList>
|
||||
#include <core/Backend.h>
|
||||
|
||||
class LogItem {
|
||||
public:
|
||||
QDateTime dt;
|
||||
log_level_t level;
|
||||
QString text;
|
||||
};
|
||||
|
||||
class LogModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum {
|
||||
column_time,
|
||||
column_level,
|
||||
column_text,
|
||||
column_count
|
||||
};
|
||||
|
||||
public:
|
||||
LogModel(Backend &backend);
|
||||
virtual ~LogModel();
|
||||
|
||||
void clear();
|
||||
|
||||
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const;
|
||||
virtual QModelIndex parent(const QModelIndex &child) const;
|
||||
|
||||
virtual int rowCount(const QModelIndex &parent) const;
|
||||
virtual int columnCount(const QModelIndex &parent) const;
|
||||
virtual bool hasChildren(const QModelIndex &parent) const;
|
||||
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
virtual QVariant data(const QModelIndex &index, int role) const;
|
||||
|
||||
public slots:
|
||||
void onLogMessage(const QDateTime dt, const log_level_t level, const QString msg);
|
||||
|
||||
private:
|
||||
QList<LogItem*> _items;
|
||||
|
||||
static QString logLevelText(log_level_t level);
|
||||
};
|
||||
215
core/MeasurementInterface.cpp
Normal file
215
core/MeasurementInterface.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "MeasurementInterface.h"
|
||||
|
||||
#include <core/Backend.h>
|
||||
#include <driver/CanDriver.h>
|
||||
#include <driver/CanInterface.h>
|
||||
|
||||
|
||||
MeasurementInterface::MeasurementInterface()
|
||||
: _doConfigure(true),
|
||||
_bitrate(500000),
|
||||
_samplePoint(875),
|
||||
_isCanFD(false),
|
||||
_fdBitrate(4000000),
|
||||
_fdSamplePoint(875),
|
||||
|
||||
_isListenOnlyMode(false),
|
||||
_isOneShotMode(false),
|
||||
_isTripleSampling(false),
|
||||
_doAutoRestart(false),
|
||||
_autoRestartMs(100)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool MeasurementInterface::loadXML(Backend &backend, QDomElement &el)
|
||||
{
|
||||
(void) backend;
|
||||
|
||||
_doConfigure = el.attribute("configure", "0").toInt() != 0;
|
||||
|
||||
_bitrate = el.attribute("bitrate", "500000").toInt();
|
||||
_samplePoint = el.attribute("sample-point", "875").toInt();
|
||||
_isCanFD = el.attribute("can-fd", "0").toInt() != 0;
|
||||
_fdBitrate = el.attribute("bitrate-fd", "500000").toInt();
|
||||
_fdSamplePoint = el.attribute("sample-point-fd", "875").toInt();
|
||||
|
||||
_isListenOnlyMode = el.attribute("listen-only", "0").toInt() != 0;
|
||||
_isOneShotMode = el.attribute("one-shot", "0").toInt() != 0;
|
||||
_isTripleSampling = el.attribute("triple-sampling", "0").toInt() != 0;
|
||||
_doAutoRestart = el.attribute("auto-restart", "0").toInt() != 0;
|
||||
_autoRestartMs = el.attribute("auto-restart-time", "100").toInt();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MeasurementInterface::saveXML(Backend &backend, QDomDocument &xml, QDomElement &root)
|
||||
{
|
||||
(void) xml;
|
||||
|
||||
root.setAttribute("type", "can");
|
||||
root.setAttribute("driver", backend.getDriverName(_canif));
|
||||
root.setAttribute("name", backend.getInterfaceName(_canif));
|
||||
|
||||
root.setAttribute("configure", _doConfigure ? 1 : 0);
|
||||
|
||||
root.setAttribute("bitrate", _bitrate);
|
||||
root.setAttribute("sample-point", _samplePoint);
|
||||
root.setAttribute("can-fd", _isCanFD ? 1 : 0);
|
||||
root.setAttribute("bitrate-fd", _fdBitrate);
|
||||
root.setAttribute("sample-point-fd", _fdSamplePoint);
|
||||
|
||||
root.setAttribute("listen-only", _isListenOnlyMode ? 1 : 0);
|
||||
root.setAttribute("one-shot", _isOneShotMode ? 1 : 0);
|
||||
root.setAttribute("triple-sampling", _isTripleSampling ? 1 : 0);
|
||||
root.setAttribute("auto-restart", _doAutoRestart ? 1 : 0);
|
||||
root.setAttribute("auto-restart-time", _autoRestartMs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned MeasurementInterface::bitrate() const
|
||||
{
|
||||
return _bitrate;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setBitrate(unsigned bitrate)
|
||||
{
|
||||
_bitrate = bitrate;
|
||||
}
|
||||
|
||||
CanInterfaceId MeasurementInterface::canInterface() const
|
||||
{
|
||||
return _canif;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setCanInterface(CanInterfaceId canif)
|
||||
{
|
||||
_canif = canif;
|
||||
}
|
||||
|
||||
void MeasurementInterface::cloneFrom(MeasurementInterface &origin)
|
||||
{
|
||||
*this = origin;
|
||||
}
|
||||
|
||||
bool MeasurementInterface::doConfigure() const
|
||||
{
|
||||
return _doConfigure;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setDoConfigure(bool doConfigure)
|
||||
{
|
||||
_doConfigure = doConfigure;
|
||||
}
|
||||
|
||||
bool MeasurementInterface::isListenOnlyMode() const
|
||||
{
|
||||
return _isListenOnlyMode;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setListenOnlyMode(bool isListenOnlyMode)
|
||||
{
|
||||
_isListenOnlyMode = isListenOnlyMode;
|
||||
}
|
||||
|
||||
bool MeasurementInterface::isOneShotMode() const
|
||||
{
|
||||
return _isOneShotMode;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setOneShotMode(bool isOneShotMode)
|
||||
{
|
||||
_isOneShotMode = isOneShotMode;
|
||||
}
|
||||
|
||||
bool MeasurementInterface::isTripleSampling() const
|
||||
{
|
||||
return _isTripleSampling;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setTripleSampling(bool isTripleSampling)
|
||||
{
|
||||
_isTripleSampling = isTripleSampling;
|
||||
}
|
||||
|
||||
bool MeasurementInterface::isCanFD() const
|
||||
{
|
||||
return _isCanFD;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setCanFD(bool isCanFD)
|
||||
{
|
||||
_isCanFD = isCanFD;
|
||||
}
|
||||
|
||||
int MeasurementInterface::samplePoint() const
|
||||
{
|
||||
return _samplePoint;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setSamplePoint(int samplePoint)
|
||||
{
|
||||
_samplePoint = samplePoint;
|
||||
}
|
||||
|
||||
unsigned MeasurementInterface::fdBitrate() const
|
||||
{
|
||||
return _fdBitrate;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setFdBitrate(unsigned fdBitrate)
|
||||
{
|
||||
_fdBitrate = fdBitrate;
|
||||
}
|
||||
|
||||
unsigned MeasurementInterface::fdSamplePoint() const
|
||||
{
|
||||
return _fdSamplePoint;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setFdSamplePoint(unsigned fdSamplePoint)
|
||||
{
|
||||
_fdSamplePoint = fdSamplePoint;
|
||||
}
|
||||
|
||||
bool MeasurementInterface::doAutoRestart() const
|
||||
{
|
||||
return _doAutoRestart;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setAutoRestart(bool doAutoRestart)
|
||||
{
|
||||
_doAutoRestart = doAutoRestart;
|
||||
}
|
||||
|
||||
int MeasurementInterface::autoRestartMs() const
|
||||
{
|
||||
return _autoRestartMs;
|
||||
}
|
||||
|
||||
void MeasurementInterface::setAutoRestartMs(int autoRestartMs)
|
||||
{
|
||||
_autoRestartMs = autoRestartMs;
|
||||
}
|
||||
92
core/MeasurementInterface.h
Normal file
92
core/MeasurementInterface.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <driver/CanDriver.h>
|
||||
#include <driver/CanInterface.h>
|
||||
|
||||
class Backend;
|
||||
|
||||
class MeasurementInterface
|
||||
{
|
||||
public:
|
||||
MeasurementInterface();
|
||||
|
||||
CanInterfaceId canInterface() const;
|
||||
void setCanInterface(CanInterfaceId canif);
|
||||
|
||||
void cloneFrom(MeasurementInterface &origin);
|
||||
bool loadXML(Backend &backend, QDomElement &el);
|
||||
bool saveXML(Backend &backend, QDomDocument &xml, QDomElement &root);
|
||||
|
||||
bool doConfigure() const;
|
||||
void setDoConfigure(bool doConfigure);
|
||||
|
||||
bool isListenOnlyMode() const;
|
||||
void setListenOnlyMode(bool isListenOnlyMode);
|
||||
|
||||
bool isOneShotMode() const;
|
||||
void setOneShotMode(bool isOneShotMode);
|
||||
|
||||
bool isTripleSampling() const;
|
||||
void setTripleSampling(bool isTripleSampling);
|
||||
|
||||
bool isCanFD() const;
|
||||
void setCanFD(bool isCanFD);
|
||||
|
||||
unsigned bitrate() const;
|
||||
void setBitrate(unsigned bitrate);
|
||||
|
||||
int samplePoint() const;
|
||||
void setSamplePoint(int samplePoint);
|
||||
|
||||
unsigned fdBitrate() const;
|
||||
void setFdBitrate(unsigned fdBitrate);
|
||||
|
||||
unsigned fdSamplePoint() const;
|
||||
void setFdSamplePoint(unsigned fdSamplePoint);
|
||||
|
||||
bool doAutoRestart() const;
|
||||
void setAutoRestart(bool doAutoRestart);
|
||||
|
||||
int autoRestartMs() const;
|
||||
void setAutoRestartMs(int autoRestartMs);
|
||||
|
||||
private:
|
||||
CanInterfaceId _canif;
|
||||
|
||||
bool _doConfigure;
|
||||
|
||||
unsigned _bitrate;
|
||||
unsigned _samplePoint;
|
||||
|
||||
bool _isCanFD;
|
||||
unsigned _fdBitrate;
|
||||
unsigned _fdSamplePoint;
|
||||
|
||||
bool _isListenOnlyMode;
|
||||
bool _isOneShotMode;
|
||||
bool _isTripleSampling;
|
||||
bool _doAutoRestart;
|
||||
int _autoRestartMs;
|
||||
};
|
||||
159
core/MeasurementNetwork.cpp
Normal file
159
core/MeasurementNetwork.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "MeasurementNetwork.h"
|
||||
#include "MeasurementInterface.h"
|
||||
|
||||
#include <core/Backend.h>
|
||||
|
||||
|
||||
MeasurementNetwork::MeasurementNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
void MeasurementNetwork::cloneFrom(MeasurementNetwork &origin)
|
||||
{
|
||||
_name = origin._name;
|
||||
foreach (MeasurementInterface *omi, origin._interfaces) {
|
||||
MeasurementInterface *mi = new MeasurementInterface();
|
||||
mi->cloneFrom(*omi);
|
||||
_interfaces.append(mi);
|
||||
}
|
||||
_canDbs = origin._canDbs;
|
||||
}
|
||||
|
||||
void MeasurementNetwork::addInterface(MeasurementInterface *intf)
|
||||
{
|
||||
_interfaces.append(intf);
|
||||
}
|
||||
|
||||
void MeasurementNetwork::removeInterface(MeasurementInterface *intf)
|
||||
{
|
||||
_interfaces.removeAll(intf);
|
||||
}
|
||||
|
||||
QList<MeasurementInterface *> MeasurementNetwork::interfaces()
|
||||
{
|
||||
return _interfaces;
|
||||
}
|
||||
|
||||
MeasurementInterface *MeasurementNetwork::addCanInterface(CanInterfaceId canif)
|
||||
{
|
||||
MeasurementInterface *mi = new MeasurementInterface();
|
||||
mi->setCanInterface(canif);
|
||||
addInterface(mi);
|
||||
return mi;
|
||||
}
|
||||
|
||||
CanInterfaceIdList MeasurementNetwork::getReferencedCanInterfaces()
|
||||
{
|
||||
CanInterfaceIdList list;
|
||||
foreach (MeasurementInterface *mi, _interfaces) {
|
||||
list << mi->canInterface();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void MeasurementNetwork::addCanDb(QSharedPointer<CanDb> candb)
|
||||
{
|
||||
_canDbs.append(candb);
|
||||
}
|
||||
|
||||
void MeasurementNetwork::reloadCanDbs(Backend *backend)
|
||||
{
|
||||
foreach(pCanDb db, _canDbs)
|
||||
{
|
||||
db = backend->loadDbc(db->getPath());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString MeasurementNetwork::name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
void MeasurementNetwork::setName(const QString &name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
bool MeasurementNetwork::saveXML(Backend &backend, QDomDocument &xml, QDomElement &root)
|
||||
{
|
||||
root.setAttribute("name", _name);
|
||||
|
||||
QDomElement interfacesNode = xml.createElement("interfaces");
|
||||
foreach (MeasurementInterface *intf, _interfaces) {
|
||||
QDomElement intfNode = xml.createElement("interface");
|
||||
if (!intf->saveXML(backend, xml, intfNode)) {
|
||||
return false;
|
||||
}
|
||||
interfacesNode.appendChild(intfNode);
|
||||
}
|
||||
root.appendChild(interfacesNode);
|
||||
|
||||
QDomElement candbsNode = xml.createElement("databases");
|
||||
foreach (pCanDb candb, _canDbs) {
|
||||
QDomElement dbNode = xml.createElement("database");
|
||||
if (!candb->saveXML(backend, xml, dbNode)) {
|
||||
return false;
|
||||
}
|
||||
candbsNode.appendChild(dbNode);
|
||||
}
|
||||
root.appendChild(candbsNode);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MeasurementNetwork::loadXML(Backend &backend, QDomElement el)
|
||||
{
|
||||
setName(el.attribute("name", "unnamed network"));
|
||||
|
||||
QDomNodeList ifList = el.firstChildElement("interfaces").elementsByTagName("interface");
|
||||
for (int i=0; i<ifList.length(); i++) {
|
||||
QDomElement elIntf = ifList.item(i).toElement();
|
||||
QString driverName = elIntf.attribute("driver");
|
||||
QString deviceName = elIntf.attribute("name");
|
||||
CanInterface *intf = backend.getInterfaceByDriverAndName(driverName, deviceName);
|
||||
if (intf) {
|
||||
MeasurementInterface *mi = addCanInterface(intf->getId());
|
||||
mi->loadXML(backend, elIntf);
|
||||
} else {
|
||||
log_error(QString("Could not find interface %1/%2, which is referenced in the workspace config file.").arg(driverName, deviceName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QDomNodeList dbList = el.firstChildElement("databases").elementsByTagName("database");
|
||||
for (int i=0; i<dbList.length(); i++) {
|
||||
QDomElement elDb = dbList.item(i).toElement();
|
||||
QString filename = elDb.attribute("filename", QString());
|
||||
if (!filename.isEmpty()) {
|
||||
addCanDb(backend.loadDbc(filename));
|
||||
} else {
|
||||
log_error(QString("Unable to load CanDB: %1").arg(filename));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
61
core/MeasurementNetwork.h
Normal file
61
core/MeasurementNetwork.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QDomDocument>
|
||||
|
||||
#include <driver/CanDriver.h>
|
||||
#include <driver/CanInterface.h>
|
||||
#include <core/CanDb.h>
|
||||
|
||||
class Backend;
|
||||
class MeasurementInterface;
|
||||
|
||||
class MeasurementNetwork
|
||||
{
|
||||
public:
|
||||
MeasurementNetwork();
|
||||
void cloneFrom(MeasurementNetwork &origin);
|
||||
|
||||
void addInterface(MeasurementInterface *intf);
|
||||
void removeInterface(MeasurementInterface *intf);
|
||||
QList<MeasurementInterface*> interfaces();
|
||||
|
||||
MeasurementInterface *addCanInterface(CanInterfaceId canif);
|
||||
CanInterfaceIdList getReferencedCanInterfaces();
|
||||
|
||||
void addCanDb(pCanDb candb);
|
||||
void reloadCanDbs(Backend *backend);
|
||||
QList<pCanDb> _canDbs;
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
|
||||
bool saveXML(Backend &backend, QDomDocument &xml, QDomElement &root);
|
||||
bool loadXML(Backend &backend, QDomElement el);
|
||||
|
||||
private:
|
||||
QString _name;
|
||||
QList<MeasurementInterface*> _interfaces;
|
||||
};
|
||||
145
core/MeasurementSetup.cpp
Normal file
145
core/MeasurementSetup.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "MeasurementSetup.h"
|
||||
|
||||
#include <QThread>
|
||||
#include <QMetaType>
|
||||
|
||||
#include <core/CanTrace.h>
|
||||
#include <core/CanMessage.h>
|
||||
#include <core/MeasurementNetwork.h>
|
||||
|
||||
MeasurementSetup::MeasurementSetup(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
MeasurementSetup::~MeasurementSetup()
|
||||
{
|
||||
qDeleteAll(_networks);
|
||||
}
|
||||
|
||||
void MeasurementSetup::clear()
|
||||
{
|
||||
qDeleteAll(_networks);
|
||||
_networks.clear();
|
||||
emit onSetupChanged();
|
||||
}
|
||||
|
||||
void MeasurementSetup::cloneFrom(MeasurementSetup &origin)
|
||||
{
|
||||
clear();
|
||||
foreach (MeasurementNetwork *network, origin._networks) {
|
||||
MeasurementNetwork *network_copy = new MeasurementNetwork();
|
||||
network_copy->cloneFrom(*network);
|
||||
_networks.append(network_copy);
|
||||
}
|
||||
emit onSetupChanged();
|
||||
}
|
||||
|
||||
bool MeasurementSetup::saveXML(Backend &backend, QDomDocument &xml, QDomElement &root)
|
||||
{
|
||||
foreach (MeasurementNetwork *network, _networks) {
|
||||
QDomElement networkNode = xml.createElement("network");
|
||||
if (!network->saveXML(backend, xml, networkNode)) {
|
||||
return false;
|
||||
}
|
||||
root.appendChild(networkNode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MeasurementSetup::loadXML(Backend &backend, QDomElement &el)
|
||||
{
|
||||
clear();
|
||||
|
||||
QDomNodeList networks = el.elementsByTagName("network");
|
||||
for (int i=0; i<networks.length(); i++) {
|
||||
MeasurementNetwork *network = createNetwork();
|
||||
if (!network->loadXML(backend, networks.item(i).toElement())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
emit onSetupChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
MeasurementNetwork *MeasurementSetup::createNetwork()
|
||||
{
|
||||
MeasurementNetwork *network = new MeasurementNetwork();
|
||||
_networks.append(network);
|
||||
return network;
|
||||
}
|
||||
|
||||
void MeasurementSetup::removeNetwork(MeasurementNetwork *network)
|
||||
{
|
||||
_networks.removeAll(network);
|
||||
}
|
||||
|
||||
|
||||
CanDbMessage *MeasurementSetup::findDbMessage(const CanMessage &msg) const
|
||||
{
|
||||
CanDbMessage *result = 0;
|
||||
|
||||
foreach (MeasurementNetwork *network, _networks) {
|
||||
foreach (pCanDb db, network->_canDbs) {
|
||||
result = db->getMessageById(msg.getRawId());
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString MeasurementSetup::getInterfaceName(const CanInterface &interface) const
|
||||
{
|
||||
return interface.getName();
|
||||
}
|
||||
|
||||
int MeasurementSetup::countNetworks() const
|
||||
{
|
||||
return _networks.length();
|
||||
}
|
||||
|
||||
MeasurementNetwork *MeasurementSetup::getNetwork(int index) const
|
||||
{
|
||||
return _networks.value(index);
|
||||
}
|
||||
|
||||
MeasurementNetwork *MeasurementSetup::getNetworkByName(QString name) const
|
||||
{
|
||||
foreach (MeasurementNetwork *network, _networks) {
|
||||
if (network->name() == name) {
|
||||
return network;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QList<MeasurementNetwork *> MeasurementSetup::getNetworks()
|
||||
{
|
||||
return _networks;
|
||||
}
|
||||
|
||||
63
core/MeasurementSetup.h
Normal file
63
core/MeasurementSetup.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, 2016 Hubert Denkmair <hubert@denkmair.de>
|
||||
|
||||
This file is part of cangaroo.
|
||||
|
||||
cangaroo is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cangaroo is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cangaroo. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QDomDocument>
|
||||
|
||||
class Backend;
|
||||
class MeasurementNetwork;
|
||||
class CanTrace;
|
||||
class CanMessage;
|
||||
class CanInterface;
|
||||
class CanDbMessage;
|
||||
|
||||
class MeasurementSetup : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MeasurementSetup(QObject *parent);
|
||||
virtual ~MeasurementSetup();
|
||||
void clear();
|
||||
|
||||
CanDbMessage *findDbMessage(const CanMessage &msg) const;
|
||||
QString getInterfaceName(const CanInterface &interface) const;
|
||||
|
||||
int countNetworks() const;
|
||||
MeasurementNetwork *getNetwork(int index) const;
|
||||
MeasurementNetwork *getNetworkByName(QString name) const;
|
||||
QList<MeasurementNetwork*> getNetworks();
|
||||
MeasurementNetwork *createNetwork();
|
||||
void removeNetwork(MeasurementNetwork *network);
|
||||
|
||||
void cloneFrom(MeasurementSetup &origin);
|
||||
bool saveXML(Backend &backend, QDomDocument &xml, QDomElement &root);
|
||||
bool loadXML(Backend &backend, QDomElement &el);
|
||||
|
||||
signals:
|
||||
void onSetupChanged();
|
||||
|
||||
private:
|
||||
QList<MeasurementNetwork*> _networks;
|
||||
};
|
||||
30
core/core.pri
Normal file
30
core/core.pri
Normal file
@@ -0,0 +1,30 @@
|
||||
SOURCES += \
|
||||
$$PWD/Backend.cpp \
|
||||
$$PWD/CanMessage.cpp \
|
||||
$$PWD/CanTrace.cpp \
|
||||
$$PWD/CanDbMessage.cpp \
|
||||
$$PWD/CanDb.cpp \
|
||||
$$PWD/CanDbNode.cpp \
|
||||
$$PWD/CanDbSignal.cpp \
|
||||
$$PWD/MeasurementSetup.cpp \
|
||||
$$PWD/MeasurementNetwork.cpp \
|
||||
$$PWD/MeasurementInterface.cpp \
|
||||
$$PWD/LogModel.cpp \
|
||||
$$PWD/ConfigurableWidget.cpp \
|
||||
$$PWD/Log.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/portable_endian.h \
|
||||
$$PWD/Backend.h \
|
||||
$$PWD/CanMessage.h \
|
||||
$$PWD/CanTrace.h \
|
||||
$$PWD/CanDbMessage.h \
|
||||
$$PWD/CanDb.h \
|
||||
$$PWD/CanDbNode.h \
|
||||
$$PWD/CanDbSignal.h \
|
||||
$$PWD/MeasurementSetup.h \
|
||||
$$PWD/MeasurementNetwork.h \
|
||||
$$PWD/MeasurementInterface.h \
|
||||
$$PWD/LogModel.h \
|
||||
$$PWD/ConfigurableWidget.h \
|
||||
$$PWD/Log.h
|
||||
73
core/portable_endian.h
Normal file
73
core/portable_endian.h
Normal file
@@ -0,0 +1,73 @@
|
||||
// "License": Public Domain
|
||||
// I, Mathias Panzenböck, place this file hereby into the public domain. Use it at your own risk for whatever you like.
|
||||
// In case there are jurisdictions that don't support putting things in the public domain you can also consider it to
|
||||
// be "dual licensed" under the BSD, MIT and Apache licenses, if you want to. This code is trivial anyway. Consider it
|
||||
// an example on how to get the endian conversion functions on different platforms.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__)
|
||||
|
||||
# define __WINDOWS__
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__CYGWIN__)
|
||||
|
||||
# include <endian.h>
|
||||
|
||||
#elif defined(__WINDOWS__)
|
||||
|
||||
# include <sys/param.h>
|
||||
|
||||
# if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
# define htobe16(x) htons(x)
|
||||
# define htole16(x) (x)
|
||||
# define be16toh(x) ntohs(x)
|
||||
# define le16toh(x) (x)
|
||||
|
||||
# define htobe32(x) htonl(x)
|
||||
# define htole32(x) (x)
|
||||
# define be32toh(x) ntohl(x)
|
||||
# define le32toh(x) (x)
|
||||
|
||||
# define htobe64(x) htonll(x)
|
||||
# define htole64(x) (x)
|
||||
# define be64toh(x) ntohll(x)
|
||||
# define le64toh(x) (x)
|
||||
|
||||
# elif BYTE_ORDER == BIG_ENDIAN
|
||||
|
||||
/* that would be xbox 360 */
|
||||
# define htobe16(x) (x)
|
||||
# define htole16(x) __builtin_bswap16(x)
|
||||
# define be16toh(x) (x)
|
||||
# define le16toh(x) __builtin_bswap16(x)
|
||||
|
||||
# define htobe32(x) (x)
|
||||
# define htole32(x) __builtin_bswap32(x)
|
||||
# define be32toh(x) (x)
|
||||
# define le32toh(x) __builtin_bswap32(x)
|
||||
|
||||
# define htobe64(x) (x)
|
||||
# define htole64(x) __builtin_bswap64(x)
|
||||
# define be64toh(x) (x)
|
||||
# define le64toh(x) __builtin_bswap64(x)
|
||||
|
||||
# else
|
||||
|
||||
# error byte order not supported
|
||||
|
||||
# endif
|
||||
|
||||
# define __BYTE_ORDER BYTE_ORDER
|
||||
# define __BIG_ENDIAN BIG_ENDIAN
|
||||
# define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||
# define __PDP_ENDIAN PDP_ENDIAN
|
||||
|
||||
#else
|
||||
|
||||
# error platform not supported
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user