Files
VkuMonitor/cpp/core/Backend.cpp
2024-07-03 19:11:29 +09:00

301 lines
7.0 KiB
C++

/*
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);
}