Merge pull request #67 from collin80/WIP2

Merge WIP2 changes into Master
This commit is contained in:
Collin Kidder
2017-01-02 17:55:45 -05:00
committed by GitHub
115 changed files with 5475 additions and 1412 deletions
+14 -8
View File
@@ -1,6 +1,6 @@
# SavvyCAN # SavvyCAN
QT based cross platform canbus tool QT based cross platform canbus tool
(C) 2015-2016 EVTV and Collin Kidder (C) 2015-2017 EVTV and Collin Kidder
A QT5 based cross platform tool which can be used to load, save, and capture canbus frames. A QT5 based cross platform tool which can be used to load, save, and capture canbus frames.
This tool is designed to help with visualization, reverse engineering, debugging, and This tool is designed to help with visualization, reverse engineering, debugging, and
@@ -14,7 +14,7 @@ You are highly recommended to use the CANDue board from EVTV:
The CANDue board must be running the GVRET firmware which can also be found The CANDue board must be running the GVRET firmware which can also be found
within the collin80 repos. within the collin80 repos.
It is very soon to be possible to use any SocketCAN compatible device It is now possible to use any SocketCAN compatible device
under LINUX. There may, however, be some loss of some functionality as under LINUX. There may, however, be some loss of some functionality as
some functions of SavvyCAN are designed for use directly with the some functions of SavvyCAN are designed for use directly with the
EVTVDue and CANDue 2.0 boards. EVTVDue and CANDue 2.0 boards.
@@ -40,6 +40,10 @@ of this program. It can load and save in several formats:
9. Vehicle Spy log files 9. Vehicle Spy log files
10. CANDump / Kayak (Read only)
11. PCAN Viewer (Read Only)
Requires QScintilla library available at: Requires QScintilla library available at:
https://www.riverbankcomputing.com/software/qscintilla/download https://www.riverbankcomputing.com/software/qscintilla/download
@@ -50,18 +54,20 @@ http://www.qcustomplot.com/
However, this source code is integrated into the source for SavvyCAN and one isn't required to download it separately. However, this source code is integrated into the source for SavvyCAN and one isn't required to download it separately.
This project will soon require 5.6.0 or higher because of an upcoming dependency on QSerialBus but currently This project requires 5.6.0 or higher because of a dependency on QSerialBus which is an optional download
should compile with QT 5.5 with QT 5.6 (so, be sure to select it)
Instructions for compiling with Ubuntu: Instructions for compiling:
sudo apt-get install qt5-default qtdeclarative5-dev libqt5serialport5-dev libudev-dev Download the newest stable version of Qt directly from qt.io (You need 5.6.x or newer)
download and extract QScintilla (see above for link), assume it is extracted in QScintilla-gpl-2.9.1 download and extract QScintilla (see above for link), assume it is extracted in QScintilla-gpl-2.9.1
cd ~/QScintilla-gpl-2.9.1/Qt4Qt5 cd ~/QScintilla-gpl-2.9.1/Qt4Qt5
qmake qscintilla.pro You will need to either put your copy of QT into your path or specify the path to qmake directly
~/Qt/5.7/gcc_64/bin/qmake qscintilla.pro
make make
@@ -75,7 +81,7 @@ git clone https://github.com/collin80/SavvyCAN.git
cd SavvyCAN cd SavvyCAN
qmake ~/Qt/5.7/gcc_64/bin/qmake
make make
+85 -62
View File
@@ -4,7 +4,7 @@
# #
#------------------------------------------------- #-------------------------------------------------
QT += core gui QT += core gui serialbus
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets serialport printsupport qml greaterThan(QT_MAJOR_VERSION, 4): QT += widgets serialport printsupport qml
@@ -21,95 +21,118 @@ SOURCES += main.cpp\
canframemodel.cpp \ canframemodel.cpp \
utility.cpp \ utility.cpp \
qcustomplot.cpp \ qcustomplot.cpp \
graphingwindow.cpp \
frameinfowindow.cpp \
newgraphdialog.cpp \
frameplaybackwindow.cpp \ frameplaybackwindow.cpp \
serialworker.cpp \
candatagrid.cpp \ candatagrid.cpp \
flowviewwindow.cpp \
framesenderwindow.cpp \ framesenderwindow.cpp \
dbchandler.cpp \
dbcmaineditor.cpp \
dbcsignaleditor.cpp \
framefileio.cpp \ framefileio.cpp \
filecomparatorwindow.cpp \
mainsettingsdialog.cpp \ mainsettingsdialog.cpp \
firmwareuploaderwindow.cpp \ firmwareuploaderwindow.cpp \
discretestatewindow.cpp \
connectionwindow.cpp \
scriptingwindow.cpp \ scriptingwindow.cpp \
scriptcontainer.cpp \ scriptcontainer.cpp \
canfilter.cpp \ canfilter.cpp \
rangestatewindow.cpp \
dbc_classes.cpp \
dbcloadsavewindow.cpp \
fuzzingwindow.cpp \
udsscanwindow.cpp \
can_structs.cpp \ can_structs.cpp \
isotp_interpreterwindow.cpp \ motorcontrollerconfigwindow.cpp \
isotp_handler.cpp \ connections/canconnection.cpp \
motorcontrollerconfigwindow.cpp connections/socketcan.cpp \
connections/canconfactory.cpp \
connections/gvretserial.cpp \
connections/canconmanager.cpp \
re/sniffer/snifferitem.cpp \
re/sniffer/sniffermodel.cpp \
re/sniffer/snifferwindow.cpp \
dbc/dbc_classes.cpp \
dbc/dbchandler.cpp \
dbc/dbcloadsavewindow.cpp \
dbc/dbcmaineditor.cpp \
dbc/dbcsignaleditor.cpp \
re/discretestatewindow.cpp \
re/filecomparatorwindow.cpp \
re/flowviewwindow.cpp \
re/frameinfowindow.cpp \
re/fuzzingwindow.cpp \
re/isotp_handler.cpp \
re/isotp_interpreterwindow.cpp \
re/rangestatewindow.cpp \
re/udsscanwindow.cpp \
connections/canbus.cpp \
connections/canconnectionmodel.cpp \
connections/connectionwindow.cpp \
re/graphingwindow.cpp \
re/newgraphdialog.cpp \
bisectwindow.cpp
HEADERS += mainwindow.h \ HEADERS += mainwindow.h \
can_structs.h \ can_structs.h \
canframemodel.h \ canframemodel.h \
utility.h \ utility.h \
qcustomplot.h \ qcustomplot.h \
graphingwindow.h \
frameinfowindow.h \
newgraphdialog.h \
frameplaybackwindow.h \ frameplaybackwindow.h \
serialworker.h \
candatagrid.h \ candatagrid.h \
flowviewwindow.h \
framesenderwindow.h \ framesenderwindow.h \
can_trigger_structs.h \ can_trigger_structs.h \
dbc_classes.h \
dbchandler.h \
dbcmaineditor.h \
dbcsignaleditor.h \
framefileio.h \ framefileio.h \
config.h \ config.h \
filecomparatorwindow.h \
mainsettingsdialog.h \ mainsettingsdialog.h \
firmwareuploaderwindow.h \ firmwareuploaderwindow.h \
discretestatewindow.h \
connectionwindow.h \
scriptingwindow.h \ scriptingwindow.h \
scriptcontainer.h \ scriptcontainer.h \
canfilter.h \ canfilter.h \
rangestatewindow.h \ utils/lfqueue.h \
dbcloadsavewindow.h \ motorcontrollerconfigwindow.h \
fuzzingwindow.h \ connections/canconnection.h \
udsscanwindow.h \ connections/socketcan.h \
isotp_interpreterwindow.h \ connections/canconconst.h \
isotp_handler.h \ connections/canconfactory.h \
motorcontrollerconfigwindow.h connections/gvretserial.h \
connections/canconmanager.h \
re/sniffer/snifferitem.h \
re/sniffer/sniffermodel.h \
re/sniffer/snifferwindow.h \
dbc/dbc_classes.h \
dbc/dbchandler.h \
dbc/dbcloadsavewindow.h \
dbc/dbcmaineditor.h \
dbc/dbcsignaleditor.h \
re/discretestatewindow.h \
re/filecomparatorwindow.h \
re/flowviewwindow.h \
re/frameinfowindow.h \
re/fuzzingwindow.h \
re/isotp_handler.h \
re/isotp_interpreterwindow.h \
re/rangestatewindow.h \
re/udsscanwindow.h \
connections/canbus.h \
connections/canconnectionmodel.h \
connections/connectionwindow.h \
re/graphingwindow.h \
re/newgraphdialog.h \
bisectwindow.h
FORMS += mainwindow.ui \ FORMS += ui/candatagrid.ui \
graphingwindow.ui \ ui/connectionwindow.ui \
frameinfowindow.ui \ ui/dbcloadsavewindow.ui \
newgraphdialog.ui \ ui/dbcmaineditor.ui \
frameplaybackwindow.ui \ ui/dbcsignaleditor.ui \
candatagrid.ui \ ui/discretestatewindow.ui \
flowviewwindow.ui \ ui/filecomparatorwindow.ui \
framesenderwindow.ui \ ui/firmwareuploaderwindow.ui \
dbcmaineditor.ui \ ui/flowviewwindow.ui \
dbcsignaleditor.ui \ ui/frameinfowindow.ui \
filecomparatorwindow.ui \ ui/frameplaybackwindow.ui \
mainsettingsdialog.ui \ ui/framesenderwindow.ui \
firmwareuploaderwindow.ui \ ui/fuzzingwindow.ui \
discretestatewindow.ui \ ui/graphingwindow.ui \
connectionwindow.ui \ ui/isotp_interpreterwindow.ui \
scriptingwindow.ui \ ui/mainsettingsdialog.ui \
rangestatewindow.ui \ ui/mainwindow.ui \
dbcloadsavewindow.ui \ ui/motorcontrollerconfigwindow.ui \
fuzzingwindow.ui \ ui/newgraphdialog.ui \
udsscanwindow.ui \ ui/rangestatewindow.ui \
isotp_interpreterwindow.ui \ ui/scriptingwindow.ui \
deltawindow.ui \ ui/snifferwindow.ui \
motorcontrollerconfigwindow.ui ui/udsscanwindow.ui \
ui/bisectwindow.ui
DISTFILES += DISTFILES +=
+154
View File
@@ -0,0 +1,154 @@
#include "bisectwindow.h"
#include "ui_bisectwindow.h"
#include "mainwindow.h"
#include "framefileio.h"
#include <QDebug>
#include <algorithm>
BisectWindow::BisectWindow(const QVector<CANFrame> *frames, QWidget *parent) :
QDialog(parent),
ui(new Ui::BisectWindow)
{
ui->setupUi(this);
modelFrames = frames;
connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int)));
connect(ui->btnCalculate, &QAbstractButton::clicked, this, &BisectWindow::handleCalculateButton);
connect(ui->btnReplaceFrames, &QAbstractButton::clicked, this, &BisectWindow::handleReplaceButton);
connect(ui->btnSaveFrames, &QAbstractButton::clicked, this, &BisectWindow::handleSaveButton);
connect(ui->slideFrameNumber, &QSlider::sliderReleased, this, &BisectWindow::updateFrameNumText);
connect(ui->slidePercentage, &QSlider::sliderReleased, this, &BisectWindow::updatePercentText);
connect(ui->editFrameNumber, &QLineEdit::editingFinished, this, &BisectWindow::updateFrameNumSlider);
connect(ui->editPercentage, &QLineEdit::editingFinished, this, &BisectWindow::updatePercentSlider);
}
BisectWindow::~BisectWindow()
{
delete ui;
}
void BisectWindow::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
refreshIDList();
refreshFrameNumbers();
updateFrameNumText();
updatePercentText();
}
void BisectWindow::refreshIDList()
{
int id;
for (int i = 0; i < modelFrames->count(); i++)
{
id = modelFrames->at(i).ID;
if (!foundID.contains(id))
{
foundID.append(id);
}
}
std::sort(foundID.begin(), foundID.end());
foreach (int id, foundID) {
ui->cbIDLower->addItem(Utility::formatNumber(id));
ui->cbIDUpper->addItem(Utility::formatNumber(id));
}
}
void BisectWindow::refreshFrameNumbers()
{
ui->labelMainListNum->setText(QString::number(modelFrames->count()));
ui->labelSplitNum->setText(QString::number(splitFrames.count()));
ui->slideFrameNumber->setMaximum(modelFrames->count());
}
void BisectWindow::updatedFrames(int numFrames)
{
if (numFrames == -1) //all frames deleted
{
refreshFrameNumbers();
}
else if (numFrames == -2) //all new set of frames. Reset
{
refreshFrameNumbers();
refreshIDList();
}
else //just got some new frames. See if they are relevant.
{
}
}
void BisectWindow::handleCalculateButton()
{
splitFrames.clear();
bool saveLower = ui->rbLowerSection->isChecked();
int targetFrameNum;
if (ui->rbFrameNumber->isChecked() || ui->rbPercentage->isChecked())
{
if (ui->rbFrameNumber->isChecked()) targetFrameNum = ui->slideFrameNumber->value();
else targetFrameNum = modelFrames->count() * ui->slidePercentage->value() / 10000;
if (saveLower)
{
for (int i = 0; i < targetFrameNum; i++) splitFrames.append(modelFrames->at(i));
}
else
{
for (int i = targetFrameNum; i < modelFrames->count(); i++) splitFrames.append(modelFrames->at(i));
}
}
else if (ui->rbIDRange->isChecked())
{
uint32_t lowerID = Utility::ParseStringToNum2(ui->cbIDLower->currentText());
uint32_t upperID = Utility::ParseStringToNum2(ui->cbIDUpper->currentText());
for (int i = 0; i < modelFrames->count(); i++)
{
if (modelFrames->at(i).ID >= lowerID && modelFrames->at(i).ID <= upperID) splitFrames.append(modelFrames->at(i));
}
}
refreshFrameNumbers();
}
void BisectWindow::handleReplaceButton()
{
}
void BisectWindow::handleSaveButton()
{
QMessageBox msg;
QString filename;
if (FrameFileIO::saveFrameFile(filename, &splitFrames))
{
msg.setText(tr("Successfully saved file"));
}
else
{
msg.setText(tr("Error while attempting to save."));
}
msg.exec();
}
void BisectWindow::updateFrameNumSlider()
{
ui->slideFrameNumber->setValue(ui->editFrameNumber->text().toInt());
}
void BisectWindow::updatePercentSlider()
{
ui->slidePercentage->setValue(ui->editPercentage->text().toFloat() * 100);
}
void BisectWindow::updateFrameNumText()
{
ui->editFrameNumber->setText(QString::number(ui->slideFrameNumber->value()));
}
void BisectWindow::updatePercentText()
{
ui->editPercentage->setText(QString::number(ui->slidePercentage->value() / 100.0f));
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef BISECTWINDOW_H
#define BISECTWINDOW_H
#include <QDialog>
#include "can_structs.h"
namespace Ui {
class BisectWindow;
}
class BisectWindow : public QDialog
{
Q_OBJECT
public:
explicit BisectWindow(const QVector<CANFrame> *frames, QWidget *parent = 0);
~BisectWindow();
void showEvent(QShowEvent*);
signals:
void sendCANFrame(const CANFrame *, int);
void sendFrameBatch(const QList<CANFrame> *);
private slots:
void updatedFrames(int numFrames);
void handleSaveButton();
void handleReplaceButton();
void handleCalculateButton();
void updateFrameNumSlider();
void updatePercentSlider();
void updateFrameNumText();
void updatePercentText();
private:
Ui::BisectWindow *ui;
const QVector<CANFrame> *modelFrames;
QVector<CANFrame> splitFrames;
QList<int> foundID;
void refreshIDList();
void refreshFrameNumbers();
};
#endif // BISECTWINDOW_H
+21 -5
View File
@@ -1,21 +1,37 @@
#ifndef CAN_STRUCTS_H #ifndef CAN_STRUCTS_H
#define CAN_STRUCTS_H #define CAN_STRUCTS_H
#include <QObject>
#include <QVector> #include <QVector>
#include <stdint.h> #include <stdint.h>
class CANFrame struct CANFrame
{ {
public: public:
int ID; uint32_t ID;
int bus; uint32_t bus;
bool extended; bool extended;
bool isReceived; //did we receive this or send it? bool isReceived; //did we receive this or send it?
int len; uint32_t len;
unsigned char data[8]; unsigned char data[8];
uint64_t timestamp; uint64_t timestamp;
}; };
class CANFlt
{
public:
quint32 id;
quint32 mask;
QObject * observer; //used to target the specific object that setup this filter
bool operator ==(const CANFlt &b) const
{
if ( (id == b.id) && (mask == b.mask) && (observer == b.observer) ) return true;
return false;
}
};
struct J1939ID struct J1939ID
{ {
public: public:
@@ -32,7 +48,7 @@ public:
struct ISOTP_MESSAGE struct ISOTP_MESSAGE
{ {
public: public:
int ID; uint32_t ID;
int bus; int bus;
bool extended; bool extended;
bool isReceived; bool isReceived;
+1 -1
View File
@@ -10,7 +10,7 @@ public:
void setFilter(uint32_t id, uint32_t mask, int bus); void setFilter(uint32_t id, uint32_t mask, int bus);
bool checkFilter(uint32_t id, int bus); bool checkFilter(uint32_t id, int bus);
private: public:
uint32_t ID; uint32_t ID;
uint32_t mask; uint32_t mask;
int bus; int bus;
+36 -32
View File
@@ -3,6 +3,15 @@
#include <QFile> #include <QFile>
#include "utility.h" #include "utility.h"
CANFrameModel::~CANFrameModel()
{
frames.clear();
filteredFrames.clear();
filters.clear();
}
int CANFrameModel::rowCount(const QModelIndex &parent) const int CANFrameModel::rowCount(const QModelIndex &parent) const
{ {
Q_UNUSED(parent); Q_UNUSED(parent);
@@ -38,12 +47,12 @@ CANFrameModel::CANFrameModel(QObject *parent)
if (QSysInfo::WordSize > 32) if (QSysInfo::WordSize > 32)
{ {
qDebug() << "64 bit OS detected. Requesting a large preallocation"; qDebug() << "64 bit OS detected. Requesting a large preallocation";
preallocSize = 50000000; preallocSize = 20000000;
} }
else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down. else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down.
{ {
qDebug() << "32 bit OS detected. Requesting a much restricted prealloc"; qDebug() << "32 bit OS detected. Requesting a much restricted prealloc";
preallocSize = 5000000; preallocSize = 4000000;
} }
frames.reserve(preallocSize); frames.reserve(preallocSize);
@@ -122,7 +131,7 @@ void CANFrameModel::setOverwriteMode(bool mode)
endResetModel(); endResetModel();
} }
void CANFrameModel::setFilterState(int ID, bool state) void CANFrameModel::setFilterState(unsigned int ID, bool state)
{ {
if (!filters.contains(ID)) return; if (!filters.contains(ID)) return;
filters[ID] = state; filters[ID] = state;
@@ -235,15 +244,15 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
DBC_MESSAGE *msg = dbcHandler->findMessage(thisFrame); DBC_MESSAGE *msg = dbcHandler->findMessage(thisFrame);
if (msg != NULL) if (msg != NULL)
{ {
tempString.append("\r\n"); tempString.append("\n");
tempString.append(msg->name + " " + msg->comment + "\r\n"); tempString.append(msg->name + " " + msg->comment + "\n");
for (int j = 0; j < msg->sigHandler->getCount(); j++) for (int j = 0; j < msg->sigHandler->getCount(); j++)
{ {
QString sigString; QString sigString;
if (msg->sigHandler->findSignalByIdx(j)->processAsText(thisFrame, sigString)) if (msg->sigHandler->findSignalByIdx(j)->processAsText(thisFrame, sigString))
{ {
tempString.append(sigString); tempString.append(sigString);
tempString.append("\r\n"); tempString.append("\n");
} }
} }
} }
@@ -254,7 +263,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
return QVariant(); return QVariant();
} }
} }
else
return QVariant(); return QVariant();
} }
@@ -298,8 +307,10 @@ QVariant CANFrameModel::headerData(int section, Qt::Orientation orientation,
return QVariant(); return QVariant();
} }
void CANFrameModel::addFrame(const CANFrame &frame, bool autoRefresh = false)
void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false)
{ {
/*TODO: remove mutex */
mutex.lock(); mutex.lock();
CANFrame tempFrame; CANFrame tempFrame;
tempFrame = frame; tempFrame = frame;
@@ -361,6 +372,15 @@ void CANFrameModel::addFrame(const CANFrame &frame, bool autoRefresh = false)
mutex.unlock(); mutex.unlock();
} }
void CANFrameModel::addFrames(const CANConnection*, const QVector<CANFrame>& pFrames)
{
foreach(const CANFrame& frame, pFrames)
{
addFrame(frame);
}
}
void CANFrameModel::sendRefresh() void CANFrameModel::sendRefresh()
{ {
qDebug() << "Sending mass refresh"; qDebug() << "Sending mass refresh";
@@ -392,38 +412,22 @@ void CANFrameModel::sendRefresh(int pos)
//issue a refresh for the last num entries in the model. //issue a refresh for the last num entries in the model.
//used by the serial worker to do batch updates so it doesn't //used by the serial worker to do batch updates so it doesn't
//have to send thousands of messages per second //have to send thousands of messages per second
void CANFrameModel::sendBulkRefresh(int num) int CANFrameModel::sendBulkRefresh()
{ {
//yes, num was sent to us by the serial worker but we actually have a better idea int num = filteredFrames.count() - lastUpdateNumFrames;
//of how many by tracking the number we last knew about as opposed to how many rows there if (num <= 0) return 0;
//are now.
num = filteredFrames.count() - lastUpdateNumFrames;
if (num < 0) return; if (num == 0 && !overwriteDups) return 0;
if (filteredFrames.count() == 0) return 0;
//qDebug() << "Num: " << num;
if (num == 0 && !overwriteDups) return;
if (filteredFrames.count() == 0) return;
lastUpdateNumFrames += num; //done this way to avoid asking for filteredFrames.count() again lastUpdateNumFrames += num; //done this way to avoid asking for filteredFrames.count() again
qDebug() << "Bulk refresh of " << num; qDebug() << "Bulk refresh of " << num;
if (!overwriteDups)
{
//if (num > filteredFrames.count()) num = filteredFrames.count();
//qDebug() << "From " << (filteredFrames.count() - num) << " to " << (filteredFrames.count() - 1);
//beginInsertRows(QModelIndex(), filteredFrames.count() - num, filteredFrames.count() - 1);
//endInsertRows();
beginResetModel(); beginResetModel();
endResetModel(); endResetModel();
}
else return num;
{
beginResetModel();
endResetModel();
}
} }
void CANFrameModel::clearFrames() void CANFrameModel::clearFrames()
@@ -476,7 +480,7 @@ void CANFrameModel::insertFrames(const QVector<CANFrame> &newFrames)
if (needFilterRefresh) emit updatedFiltersList(); if (needFilterRefresh) emit updatedFiltersList();
} }
int CANFrameModel::getIndexFromTimeID(int ID, double timestamp) int CANFrameModel::getIndexFromTimeID(unsigned int ID, double timestamp)
{ {
int bestIndex = -1; int bestIndex = -1;
uint64_t intTimeStamp = timestamp * 1000000l; uint64_t intTimeStamp = timestamp * 1000000l;
+10 -5
View File
@@ -7,7 +7,8 @@
#include <QDebug> #include <QDebug>
#include <QMutex> #include <QMutex>
#include "can_structs.h" #include "can_structs.h"
#include "dbchandler.h" #include "dbc/dbchandler.h"
#include "connections/canconnection.h"
class CANFrameModel: public QAbstractTableModel class CANFrameModel: public QAbstractTableModel
{ {
@@ -15,6 +16,7 @@ class CANFrameModel: public QAbstractTableModel
public: public:
CANFrameModel(QObject *parent = 0); CANFrameModel(QObject *parent = 0);
virtual ~CANFrameModel();
int rowCount(const QModelIndex &parent = QModelIndex()) const; int rowCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const; QVariant data(const QModelIndex &index, int role) const;
@@ -23,16 +25,15 @@ public:
int columnCount(const QModelIndex &) const; int columnCount(const QModelIndex &) const;
int totalFrameCount(); int totalFrameCount();
void addFrame(const CANFrame &, bool);
void sendRefresh(); void sendRefresh();
void sendRefresh(int); void sendRefresh(int);
void sendBulkRefresh(int); int sendBulkRefresh();
void clearFrames(); void clearFrames();
void setDBCHandler(DBCHandler *); void setDBCHandler(DBCHandler *);
void setInterpetMode(bool); void setInterpetMode(bool);
void setOverwriteMode(bool); void setOverwriteMode(bool);
void setHexMode(bool); void setHexMode(bool);
void setFilterState(int ID, bool state); void setFilterState(unsigned int ID, bool state);
void setAllFilters(bool state); void setAllFilters(bool state);
void setSecondsMode(bool); void setSecondsMode(bool);
void loadFilterFile(QString filename); void loadFilterFile(QString filename);
@@ -41,11 +42,15 @@ public:
void recalcOverwrite(); void recalcOverwrite();
bool needsFilterRefresh(); bool needsFilterRefresh();
void insertFrames(const QVector<CANFrame> &newFrames); void insertFrames(const QVector<CANFrame> &newFrames);
int getIndexFromTimeID(int ID, double timestamp); int getIndexFromTimeID(unsigned int ID, double timestamp);
const QVector<CANFrame> *getListReference() const; //thou shalt not modify these frames externally! const QVector<CANFrame> *getListReference() const; //thou shalt not modify these frames externally!
const QVector<CANFrame> *getFilteredListReference() const; //Thus saith the Lord, NO. const QVector<CANFrame> *getFilteredListReference() const; //Thus saith the Lord, NO.
const QMap<int, bool> *getFiltersReference() const; //this neither const QMap<int, bool> *getFiltersReference() const; //this neither
public slots:
void addFrame(const CANFrame&, bool);
void addFrames(const CANConnection*, const QVector<CANFrame>&);
signals: signals:
void updatedFiltersList(); void updatedFiltersList();
+2 -2
View File
@@ -1,12 +1,12 @@
#ifndef CONFIG #ifndef CONFIG
#define CONFIG #define CONFIG
#define VERSION 157 #define VERSION 161
//try to keep this in sync. //try to keep this in sync.
//SavvyCAN will complain if you connect a GVRET board with a revision //SavvyCAN will complain if you connect a GVRET board with a revision
//less than this number. //less than this number.
#define CURRENT_GVRET_VER 331 #define CURRENT_GVRET_VER 334
#endif // CONFIG #endif // CONFIG
+76
View File
@@ -0,0 +1,76 @@
#include <QObject>
#include "canbus.h"
CANBus::CANBus()
{
speed = 250000;
listenOnly = false;
singleWire = false;
active = false;
}
CANBus::CANBus(const CANBus& pBus) :
speed(pBus.speed),
listenOnly(pBus.listenOnly),
singleWire(pBus.singleWire),
active(pBus.active) {}
bool CANBus::operator==(const CANBus& bus) const{
return speed == bus.speed &&
listenOnly == bus.listenOnly &&
singleWire == bus.singleWire &&
active == bus.active;
}
void CANBus::setSpeed(int newSpeed){
speed = newSpeed;
}
void CANBus::setListenOnly(bool mode){
listenOnly = mode;
}
void CANBus::setSingleWire(bool mode){
singleWire = mode;
}
void CANBus::setEnabled(bool mode){
active = mode;
}
int CANBus::getSpeed(){
return speed;
}
bool CANBus::isListenOnly(){
return listenOnly;
}
bool CANBus::isSingleWire(){
return singleWire;
}
bool CANBus::isActive(){
return active;
}
QDataStream& operator<<( QDataStream & pStream, const CANBus& pCanBus )
{
pStream << pCanBus.speed;
pStream << pCanBus.listenOnly;
pStream << pCanBus.singleWire;
pStream << pCanBus.active;
return pStream;
}
QDataStream & operator>>(QDataStream & pStream, CANBus& pCanBus)
{
pStream >> pCanBus.speed;
pStream >> pCanBus.listenOnly;
pStream >> pCanBus.singleWire;
pStream >> pCanBus.active;
return pStream;
}
+34
View File
@@ -0,0 +1,34 @@
#ifndef CANBus_H
#define CANBus_H
#include <QDataStream>
class CANBus
{
public:
CANBus();
CANBus(const CANBus&);
bool operator==(const CANBus&) const;
virtual ~CANBus(){};
int speed;
bool listenOnly;
bool singleWire;
bool active; //is this bus turned on?
void setSpeed(int); // new speed
void setListenOnly(bool); //bool for whether to only listen
void setSingleWire(bool); //bool for whether to use single wire mode
void setEnabled(bool); //whether this bus should be enabled or not.
int getSpeed();
bool isListenOnly();
bool isSingleWire();
bool isActive();
};
QDataStream& operator<<( QDataStream & pStream, const CANBus& pCanBus );
QDataStream & operator>>(QDataStream & pStream, CANBus& pCanBus);
Q_DECLARE_METATYPE(CANBus);
#endif // CANBus_H
+24
View File
@@ -0,0 +1,24 @@
#ifndef CANCONCONST_H
#define CANCONCONST_H
namespace CANCon {
/**
* @brief The status enum
*/
enum status
{
NOT_CONNECTED, /*!< device is not connected */
CONNECTED /*!< device is connected */
};
enum type
{
GVRET_SERIAL,
KVASER,
SOCKETCAN,
NONE
};
}
#endif // CANCONCONST_H
+19
View File
@@ -0,0 +1,19 @@
#include <QString>
#include "canconfactory.h"
#include "socketcan.h"
#include "gvretserial.h"
using namespace CANCon;
CANConnection* CanConFactory::create(type pType, QString pPortName)
{
switch(pType) {
case SOCKETCAN:
return new SocketCan(pPortName);
case GVRET_SERIAL:
return new GVRetSerial(pPortName);
default: {}
}
return NULL;
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef CANCONFACTORY_H
#define CANCONFACTORY_H
#include "canconconst.h"
#include "canconnection.h"
class CanConFactory
{
public:
static CANConnection* create(CANCon::type, QString pPortName);
};
#endif // CANCONFACTORY_H
+234
View File
@@ -0,0 +1,234 @@
#include <QDateTime>
#include "canconmanager.h"
CANConManager* CANConManager::mInstance = NULL;
CANConManager* CANConManager::getInstance()
{
if(!mInstance)
mInstance = new CANConManager();
return mInstance;
}
CANConManager::CANConManager(QObject *parent): QObject(parent)
{
connect(&mTimer, SIGNAL(timeout()), this, SLOT(refreshCanList()));
mTimer.setInterval(125); /*tick 8 times a second */
mTimer.setSingleShot(false);
mTimer.start();
resetTimeBasis();
}
void CANConManager::resetTimeBasis()
{
mTimestampBasis = QDateTime::currentMSecsSinceEpoch() * 1000;
}
CANConManager::~CANConManager()
{
mTimer.stop();
mInstance = NULL;
}
void CANConManager::add(CANConnection* pConn_p)
{
mConns.append(pConn_p);
emit connectionStatusUpdated(getNumBuses());
}
void CANConManager::remove(CANConnection* pConn_p)
{
//disconnect(pConn_p, 0, this, 0);
mConns.removeOne(pConn_p);
emit connectionStatusUpdated(getNumBuses());
}
//Get total number of buses currently registered with the program
int CANConManager::getNumBuses()
{
int buses = 0;
foreach(CANConnection* conn_p, mConns)
{
buses += conn_p->getNumBuses();
}
return buses;
}
void CANConManager::refreshCanList()
{
QObject* sender_p = QObject::sender();
if( sender_p != &mTimer)
{
/* if we are not the sender, the signal is coming from a connection */
/* refresh only the given connection */
if(mConns.contains((CANConnection*) sender_p))
refreshConnection((CANConnection*)sender_p);
}
else
{
foreach (CANConnection* conn_p, mConns)
refreshConnection((CANConnection*)conn_p);
}
}
uint64_t CANConManager::getTimeBasis()
{
return mTimestampBasis;
}
QList<CANConnection*>& CANConManager::getConnections()
{
return mConns;
}
CANConnection* CANConManager::getByName(const QString& pName) const
{
foreach(CANConnection* conn_p, mConns)
{
if(conn_p->getPort() == pName)
return conn_p;
}
return NULL;
}
void CANConManager::refreshConnection(CANConnection* pConn_p)
{
if (pConn_p->getQueue().peek() == NULL) return;
CANFrame* frame_p = NULL;
QVector<CANFrame> frames;
//Each connection only knows about its own bus numbers
//so this variable is used to fix that up to turn local bus numbers
//into system global bus numbers for display.
int busBase = 0;
foreach (CANConnection* conn, mConns)
{
if (conn != pConn_p) busBase += conn->getNumBuses();
else break;
}
//qDebug() << "Bus fixup number: " << busBase;
while( (frame_p = pConn_p->getQueue().peek() ) ) {
frame_p->bus += busBase;
//qDebug() << "Rx of frame from bus: " << frame_p->bus;
frames.append(*frame_p);
pConn_p->getQueue().dequeue();
}
if(frames.size())
emit framesReceived(pConn_p, frames);
}
/*
* Uses the requested bus to look up which CANConnection object handles this bus based on the order of
* the objects and how many buses they implement. For instance, if the request is to send on bus 2
* and there is a GVRET object first then a socketcan object it'll send on the socketcan object as
* gvret will have claimed buses 0 and 1 and socketcan bus 2. But, each actual CANConnection expects
* its own bus numbers to start at zero so the frame bus number has to be offset accordingly.
* Also keep in mind that the CANConnection "sendFrame" function uses a blocking queued connection
* and so will force the frame to be delivered before it keeps going. This allows on the stack variables
* to be used but is slow. This function uses an on the stack copy of the frame so the way it works
* is a good thing but performance will suffer. TODO: Investigate a way to use non-blocking calls.
*/
bool CANConManager::sendFrame(const CANFrame& pFrame)
{
int busBase = 0;
CANFrame workingFrame = pFrame;
CANFrame *txFrame;
foreach (CANConnection* conn, mConns)
{
//check if this CAN connection is supposed to handle the requested bus
if (pFrame.bus < (uint32_t)(busBase + conn->getNumBuses()))
{
workingFrame.bus -= busBase;
workingFrame.isReceived = false;
workingFrame.timestamp = ((QDateTime::currentMSecsSinceEpoch() * 1000) - mTimestampBasis);
txFrame = conn->getQueue().get();
*txFrame = workingFrame;
conn->getQueue().queue();
return conn->sendFrame(workingFrame);
}
busBase += conn->getNumBuses();
}
return false;
}
bool CANConManager::sendFrames(const QList<CANFrame>& pFrames)
{
foreach(const CANFrame& frame, pFrames)
{
if(!sendFrame(frame))
return false;
}
return true;
}
//For each device associated with buses go through and see if that device has a bus
//that the filter should apply to. If so forward the data on but fudge
//the bus numbers if bus wasn't -1 so that they're local to the device
bool CANConManager::addTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QObject *receiver)
{
int tempBusVal;
int busBase = 0;
foreach (CANConnection* conn, mConns)
{
if (pBusId == -1) conn->addTargettedFrame(pBusId, ID, mask, receiver);
else
{
tempBusVal = pBusId >> busBase;
tempBusVal &= ((1 << conn->getNumBuses()) - 1);
if (tempBusVal) {
qDebug() << "Forwarding targetted frame setting to a connection object";
conn->addTargettedFrame(tempBusVal, ID, mask, receiver);
}
}
busBase += conn->getNumBuses();
}
return true;
}
bool CANConManager::removeTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QObject *receiver)
{
int tempBusVal;
int busBase = 0;
foreach (CANConnection* conn, mConns)
{
if (pBusId == -1) conn->removeTargettedFrame(pBusId, ID, mask, receiver);
else
{
tempBusVal = pBusId >> busBase;
tempBusVal &= ((1 << conn->getNumBuses()) - 1);
if (tempBusVal) conn->removeTargettedFrame(tempBusVal, ID, mask, receiver);
}
busBase += conn->getNumBuses();
}
return true;
}
bool CANConManager::removeAllTargettedFrames(QObject *receiver)
{
foreach (CANConnection* conn, mConns)
{
conn->removeAllTargettedFrames(receiver);
}
return true;
}
+79
View File
@@ -0,0 +1,79 @@
#ifndef CANCONMANAGER_H
#define CANCONMANAGER_H
#include <QObject>
#include <QTimer>
#include "canconnection.h"
class CANConManager : public QObject
{
Q_OBJECT
public:
static CANConManager* getInstance();
virtual ~CANConManager();
void add(CANConnection* pConn_p);
void remove(CANConnection* pConn_p);
QList<CANConnection*>& getConnections();
CANConnection* getByName(const QString& pName) const;
uint64_t getTimeBasis();
void resetTimeBasis();
int getNumBuses();
/**
* @brief sendFrame sends a single frame out the desired bus
* @param pFrame - reference to a CANFrame struct that has been filled out for sending
* @return bool specifying whether the send succeeded or not
* @note Finds which CANConnection object is responsible for this bus and automatically converts bus number to pass properly to CANConnection
*/
bool sendFrame(const CANFrame& pFrame);
//just the multi-frame version of above function.
bool sendFrames(const QList<CANFrame>& pFrames);
/**
* @brief Add a new filter for the targetted frames. If a frame matches it will immediately be sent via the targettedFrameReceived signal
* @param pBusId - Which bus to bond to. -1 for any, otherwise a bitfield of buses (but 0 = first bus, etc)
* @param ID - 11 or 29 bit ID to match against
* @param mask - 11 or 29 bit mask used for filter
* @param receiver - Pointer to a QObject that wants to receive notification when filter is matched
* @return true if filter was able to be added, false otherwise.
*/
bool addTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QObject *receiver);
/**
* @brief Try to find a matching filter in the list and remove it, no longer targetting those frames
* @param pBusId - Which bus to bond to. Doesn't have to match the call to addTargettedFrame exactly. You could disconnect just one bus for instance.
* @param ID - 11 or 29 bit ID to match against
* @param mask - 11 or 29 bit mask used for filter
* @param receiver - Pointer to a QObject that wants to receive notification when filter is matched
* @return true if filter was found and deleted, false otherwise.
*/
bool removeTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QObject *receiver);
bool removeAllTargettedFrames(QObject *receiver);
signals:
void framesReceived(CANConnection* pConn_p, QVector<CANFrame>& pFrames);
void connectionStatusUpdated(int conns);
private slots:
void refreshCanList();
private:
explicit CANConManager(QObject *parent = 0);
void refreshConnection(CANConnection* pConn_p);
static CANConManager* mInstance;
QList<CANConnection*> mConns;
QTimer mTimer;
uint64_t mTimestampBasis;
};
#endif // CANCONNECTIONMODEL_H
+363
View File
@@ -0,0 +1,363 @@
#include <QThread>
#include "canconnection.h"
struct BusData {
CANBus mBus;
bool mConfigured;
QVector<CANFlt> mTargettedFrames;
};
CANConnection::CANConnection(QString pPort,
CANCon::type pType,
int pNumBuses,
int pQueueLen,
bool pUseThread) :
mQueue(),
mNumBuses(pNumBuses),
mPort(pPort),
mType(pType),
mIsCapSuspended(false),
mStatus(CANCon::NOT_CONNECTED),
mStarted(false),
mThread_p(NULL)
{
/* register types */
qRegisterMetaType<CANBus>("CANBus");
qRegisterMetaType<CANFrame>("CANFrame");
qRegisterMetaType<CANCon::status>("CANCon::status");
qRegisterMetaType<CANFlt>("CANFlt");
/* set queue size */
mQueue.setSize(pQueueLen); /*TODO add check on returned value */
/* allocate buses */
/* TODO: change those tables for a vector */
mBusData_p = new BusData[mNumBuses];
for(int i=0 ; i<mNumBuses ; i++) {
mBusData_p[i].mConfigured = false;
}
/* if needed, create a thread and move ourself into it */
if(pUseThread) {
mThread_p = new QThread();
}
}
CANConnection::~CANConnection()
{
/* stop and delete thread */
if(mThread_p) {
mThread_p->quit();
mThread_p->wait();
delete mThread_p;
mThread_p = NULL;
}
if(mBusData_p) {
delete[] mBusData_p;
mBusData_p = NULL;
}
}
void CANConnection::start()
{
if( mThread_p && (mThread_p != QThread::currentThread()) )
{
/* move ourself to the thread */
moveToThread(mThread_p); /*TODO handle errors */
/* connect started() */
connect(mThread_p, SIGNAL(started()), this, SLOT(start()));
/* start the thread */
mThread_p->start(QThread::HighPriority);
return;
}
/* set started flag */
mStarted = true;
/* in multithread case, this will be called before entering thread event loop */
return piStarted();
}
void CANConnection::suspend(bool pSuspend)
{
/* execute in mThread_p context */
if( mThread_p && (mThread_p != QThread::currentThread()) ) {
QMetaObject::invokeMethod(this, "suspend",
Qt::BlockingQueuedConnection,
Q_ARG(bool, pSuspend));
return;
}
return piSuspend(pSuspend);
}
void CANConnection::stop()
{
/* 1) execute in mThread_p context */
if( mThread_p && mStarted && (mThread_p != QThread::currentThread()) )
{
/* if thread is finished, it means we call this function for the second time so we can leave */
if( !mThread_p->isFinished() )
{
/* we need to call piStop() */
QMetaObject::invokeMethod(this, "stop",
Qt::BlockingQueuedConnection);
/* 3) stop thread */
mThread_p->quit();
if(!mThread_p->wait()) {
qDebug() << "can't stop thread";
}
}
return;
}
/* 2) call piStop in mThread context */
return piStop();
}
bool CANConnection::getBusSettings(int pBusIdx, CANBus& pBus)
{
/* make sure we execute in mThread context */
if( mThread_p && (mThread_p != QThread::currentThread()) ) {
bool ret;
QMetaObject::invokeMethod(this, "getBusSettings",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, ret),
Q_ARG(int , pBusIdx),
Q_ARG(CANBus& , pBus));
return ret;
}
return piGetBusSettings(pBusIdx, pBus);
}
void CANConnection::setBusSettings(int pBusIdx, CANBus pBus)
{
/* make sure we execute in mThread context */
if( mThread_p && (mThread_p != QThread::currentThread()) ) {
QMetaObject::invokeMethod(this, "setBusSettings",
Qt::BlockingQueuedConnection,
Q_ARG(int, pBusIdx),
Q_ARG(CANBus, pBus));
return;
}
return piSetBusSettings(pBusIdx, pBus);
}
bool CANConnection::sendFrame(const CANFrame& pFrame)
{
/* make sure we execute in mThread context */
if( mThread_p && (mThread_p != QThread::currentThread()) )
{
bool ret;
QMetaObject::invokeMethod(this, "sendFrame",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, ret),
Q_ARG(const CANFrame&, pFrame));
return ret;
}
return piSendFrame(pFrame);
}
bool CANConnection::sendFrames(const QList<CANFrame>& pFrames)
{
/* make sure we execute in mThread context */
if( mThread_p && (mThread_p != QThread::currentThread()) )
{
bool ret;
QMetaObject::invokeMethod(this, "sendFrames",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, ret),
Q_ARG(const QList<CANFrame>&, pFrames));
return ret;
}
return piSendFrames(pFrames);
}
int CANConnection::getNumBuses() const{
return mNumBuses;
}
bool CANConnection::isConfigured(int pBusId) {
if( pBusId < 0 || pBusId >= getNumBuses())
return false;
return mBusData_p[pBusId].mConfigured;
}
void CANConnection::setConfigured(int pBusId, bool pConfigured) {
if( pBusId < 0 || pBusId >= getNumBuses())
return;
mBusData_p[pBusId].mConfigured = pConfigured;
}
bool CANConnection::getBusConfig(int pBusId, CANBus& pBus) {
if( pBusId < 0 || pBusId >= getNumBuses() || !isConfigured(pBusId))
return false;
pBus = mBusData_p[pBusId].mBus;
return true;
}
void CANConnection::setBusConfig(int pBusId, CANBus& pBus) {
if( pBusId < 0 || pBusId >= getNumBuses())
return;
mBusData_p[pBusId].mConfigured = true;
mBusData_p[pBusId].mBus = pBus;
}
QString CANConnection::getPort() {
return mPort;
}
LFQueue<CANFrame>& CANConnection::getQueue() {
return mQueue;
}
CANCon::type CANConnection::getType() {
return mType;
}
CANCon::status CANConnection::getStatus() {
return (CANCon::status) mStatus.load();
}
void CANConnection::setStatus(CANCon::status pStatus) {
mStatus.store(pStatus);
}
bool CANConnection::isCapSuspended() {
return mIsCapSuspended;
}
void CANConnection::setCapSuspended(bool pIsSuspended) {
mIsCapSuspended = pIsSuspended;
}
bool CANConnection::addTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QObject *receiver)
{
/*
if( mThread_p && (mThread_p != QThread::currentThread()) ) {
bool ret;
QMetaObject::invokeMethod(this, "addTargettedFrame",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, ret),
Q_ARG(int, pBusId),
Q_ARG(uint32_t , ID),
Q_ARG(uint32_t , mask),
Q_ARG(QObject *, receiver));
return ret;
}
*/
/* sanity checks */
if(pBusId < -1 || pBusId >= (1 << getNumBuses()))
return false;
for (int i = 0; i < getNumBuses(); i++)
{
if ( (pBusId == -1) || (pBusId && (1 << i)) ) {
qDebug() << "Connection is registering a new targetted frame filter, local bus " << i;
CANFlt target;
target.id = ID;
target.mask = mask;
target.observer = receiver;
mBusData_p[i].mTargettedFrames.append(target);
}
}
return true;
}
bool CANConnection::removeTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QObject *receiver)
{
/*
if( mThread_p && (mThread_p != QThread::currentThread()) ) {
bool ret;
QMetaObject::invokeMethod(this, "removeTargettedFrame",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, ret),
Q_ARG(int, pBusId),
Q_ARG(uint32_t , ID),
Q_ARG(uint32_t , mask),
Q_ARG(QObject *, receiver));
return ret;
}
*/
/* sanity checks */
if(pBusId < -1 || pBusId >= (1 << getNumBuses()))
return false;
for (int i = 0; i < getNumBuses(); i++)
{
if (pBusId == -1 || (pBusId && (1 << i)))
{
CANFlt target;
target.id = ID;
target.mask = mask;
target.observer = receiver;
mBusData_p[i].mTargettedFrames.removeAll(target);
}
}
return true;
}
bool CANConnection::removeAllTargettedFrames(QObject *receiver)
{
for (int i = 0; i < getNumBuses(); i++) {
foreach (const CANFlt filt, mBusData_p[i].mTargettedFrames)
{
if (filt.observer == receiver) mBusData_p[i].mTargettedFrames.removeOne(filt);
}
}
return true;
}
void CANConnection::checkTargettedFrame(CANFrame &frame)
{
unsigned int maskedID;
qDebug() << "Got frame with ID " << frame.ID << " on bus " << frame.bus;
foreach (const CANFlt filt, mBusData_p[frame.bus].mTargettedFrames)
{
qDebug() << "Checking filter with id " << filt.id << " mask " << filt.mask;
maskedID = frame.ID & filt.mask;
if (maskedID == filt.id) {
qDebug() << "In connection object I got a targetted frame. Forwarding it.";
QMetaObject::invokeMethod(filt.observer, "gotTargettedFrame",Qt::QueuedConnection, Q_ARG(CANFrame, frame));
}
}
}
bool CANConnection::piSendFrames(const QList<CANFrame>& pFrames)
{
foreach(const CANFrame& frame, pFrames)
{
if(!piSendFrame(frame))
return false;
}
return true;
}
+296
View File
@@ -0,0 +1,296 @@
#ifndef CANCONNECTION_H
#define CANCONNECTION_H
#include <Qt>
#include <QObject>
#include "utils/lfqueue.h"
#include "can_structs.h"
#include "canbus.h"
#include "canconconst.h"
struct BusData;
class CANConnection : public QObject
{
Q_OBJECT
protected:
/**
* @brief CANConnection constructor
* @param pPort: string containing port name
* @param pType: the type of connection @ref CANCon::type
* @param pNumBuses: the number of buses the device has
* @param pQueueLen: the length of the lock free queue to use
* @param pUseThread: if set to true, object will be execute in a dedicated thread
*/
CANConnection(QString pPort,
CANCon::type pType,
int pNumBuses,
int pQueueLen,
bool pUseThread);
public:
/**
* @brief CANConnection destructor
*/
virtual ~CANConnection();
/**
* @brief getNumBuses
* @return returns the number of buses of the device
*/
int getNumBuses() const;
/**
* @brief getPort
* @return returns the port name of the device
*/
QString getPort();
/**
* @brief getQueue
* @return the lock free queue of the device
*/
LFQueue<CANFrame>& getQueue();
/**
* @brief getType
* @return the @ref CANCon::type of the device
*/
CANCon::type getType();
/**
* @brief getStatus
* @return the @ref CANCon::status of the device (either connected or not)
*/
CANCon::status getStatus();
signals:
/*not implemented yet */
void error(const QString &);
void deviceInfo(int, int); //First param = driver version (or version of whatever you want), second param a status byte
//bus number, bus speed, status (bit 0 = enabled, 1 = single wire, 2 = listen only)
//3 = Use value stored for enabled, 4 = use value passed for single wire, 5 = use value passed for listen only
//6 = use value passed for speed. This allows bus status to be updated but set that some things aren't really
//being passed. Just set for things that really are being updated.
void busStatus(int, int, int);
/**
* @brief event sent when a frame matching a filter is received
*/
void targettedFrameReceived(CANFrame frame);
/**
* @brief event emitted when the CANCon::status of the connection changes (connected->not_connected or the other way round)
* @param pStatus: the new status of the device
*/
void status(CANCon::status pStatus);
public slots:
/**
* @brief start the device. This calls piStarted
* @note starts the working thread if required (piStarted is called in the working thread context)
*/
void start();
/**
* @brief stop the device. This calls piStop
* @note if a working thread is used, piStop is called before exiting the working thread
*/
void stop();
/**
* @brief setBusSettings
* @param pBusIdx: the index of the bus for which settings have to be set
* @param pBus: the settings to set
* @note this calls piSetBusSettings in the working thread context (if one has been started)
*/
void setBusSettings(int pBusIdx, CANBus pBus);
/**
* @brief getBusSettings
* @param pBusIdx: the index of the bus for which settings have to be retrieved
* @param pBus: the CANBus struct to fill with information
* @return true if operation succeeds, false if pBusIdx is invalid or bus has not been configured yet
* @note this calls piGetBusSettings in the working thread context (if one has been started)
*/
bool getBusSettings(int pBusIdx, CANBus& pBus);
/**
* @brief suspends/restarts data capture
* @param pSuspend: suspends capture if true else restarts it
* @note this calls piSuspend (in the working thread context if one has been started)
* @note the caller shall not access the queue when capture is suspended,
* @note the callee is expected to flush the queue
*/
void suspend(bool pSuspend);
/**
* @brief provides device with the frame to send
* @param pFrame: the frame to send
* @return false if parameter is invalid (bus id for instance)
* @note this calls piSendFrame (in the working thread context if one has been started)
*/
bool sendFrame(const CANFrame& pFrame);
/**
* @brief provides device with a list of frames to send
* @param pFrame: the list of frames to send
* @return false if parameter is invalid (bus id for instance)
* @note this calls piSendFrameBatch (in the working thread context if one has been started)
*/
bool sendFrames(const QList<CANFrame>& pFrames);
/**
* @brief Add a new filter for the targetted frames. If a frame matches it will immediately be sent via the targettedFrameReceived signal
* @param pBusId - Which bus to bond to. -1 for any, otherwise a bitfield of buses (but 0 = first bus, etc)
* @param ID - 11 or 29 bit ID to match against
* @param mask - 11 or 29 bit mask used for filter
* @param receiver - Pointer to a QObject that wants to receive notification when filter is matched
* @return true if filter was able to be added, false otherwise.
*/
bool addTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QObject *receiver);
/**
* @brief Try to find a matching filter in the list and remove it, no longer targetting those frames
* @param pBusId - Which bus to bond to. Doesn't have to match the call to addTargettedFrame exactly. You could disconnect just one bus for instance.
* @param ID - 11 or 29 bit ID to match against
* @param mask - 11 or 29 bit mask used for filter
* @param receiver - Pointer to a QObject that wants to receive notification when filter is matched
* @return true if filter was found and deleted, false otherwise.
*/
bool removeTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QObject *receiver);
/**
* @brief Removes all registered filters for the passed receiver
* @param receiver - Pointer to a QObject that registered one or more filters
* @return true if filter(s) was/were found and deleted, false otherwise.
*/
bool removeAllTargettedFrames(QObject *receiver);
protected:
//determine if the passed frame is part of a filter or not.
void checkTargettedFrame(CANFrame &frame);
/**
* @brief setStatus
* @param pStatus: the status to set
*/
void setStatus(CANCon::status pStatus);
/**
* @brief isConfigured
* @param pBusId
* @return true if bus is configured
*/
bool isConfigured(int pBusId);
/**
* @brief setConfigured
* @param pBusId
* @param pConfigured
* @note it is not necessary to call this function to set pBusId configured, it is enough to call @ref setBusConfig
*/
void setConfigured(int pBusId, bool pConfigured);
/**
* @brief getBusConfig
* @param pBusId
* @param pBus
* @return true if operation succeeds, false if pBusIdx is invalid or bus has not been configured yet
*/
bool getBusConfig(int pBusId, CANBus& pBus);
/**
* @brief setBusConfig
* @param pBusId: the index of the bus for which settings have to be set
* @param pBus: the settings to set
*/
void setBusConfig(int pBusId, CANBus& pBus);
/**
* @brief isCapSuspended
* @return true if the capture is suspended
*/
bool isCapSuspended();
/**
* @brief setCapSuspended
* @param pIsSuspended
*/
void setCapSuspended(bool pIsSuspended);
protected:
/**************************************************************/
/*********** protected interface to implement *******/
/**************************************************************/
/**
* @brief starts the device
*/
virtual void piStarted() = 0;
/**
* @brief stops the device
*/
virtual void piStop() = 0;
/**
* @brief piSetBusSettings
* @param pBusIdx: the index of the bus for which settings have to be set
* @param pBus: the settings to set
*/
virtual void piSetBusSettings(int pBusIdx, CANBus pBus) = 0;
/**
* @brief piGetBusSettings
* @param pBusIdx: the index of the bus for which settings have to be retrieved
* @param pBus: the CANBus struct to fill with information
* @return true if operation succeeds, false if pBusIdx is invalid or bus has not been configured yet
*/
virtual bool piGetBusSettings(int pBusIdx, CANBus& pBus) = 0;
/**
* @brief suspends/restarts data capture
* @param pSuspend: suspends capture if true else restarts it
* @note the caller will not access the queue when capture is suspended, so it is safe for callee to flush the queue
*/
virtual void piSuspend(bool pSuspend) = 0;
/**
* @brief provides device with the frame to send
* @param pFrame: the frame to send
* @return false if parameter is invalid (bus id for instance)
*/
virtual bool piSendFrame(const CANFrame&) = 0;
/**
* @brief provides device with a list of frames to send
* @param pFrame: the list of frames to send
* @return false if parameter is invalid (bus id for instance)
* @note implementing this function is optional
*/
virtual bool piSendFrames(const QList<CANFrame>&);
private:
LFQueue<CANFrame> mQueue;
const int mNumBuses;
const QString mPort;
const CANCon::type mType;
bool mIsCapSuspended;
QAtomicInt mStatus;
bool mStarted;
BusData* mBusData_p;
QThread* mThread_p;
};
#endif // CANCONNECTION_H
+190
View File
@@ -0,0 +1,190 @@
#include "canconnectionmodel.h"
#include "connections/canconnection.h"
#include "connections/canconmanager.h"
CANConnectionModel::CANConnectionModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
CANConnectionModel::~CANConnectionModel()
{
}
QVariant CANConnectionModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal)
{
switch (section)
{
case 0:
return QString(tr("Bus"));
break;
case 1:
return QString(tr("Type"));
break;
case 2:
return QString(tr("Port"));
break;
case 3:
return QString(tr("Speed"));
break;
case 4:
return QString(tr("Listen Only"));
break;
case 5:
return QString(tr("Single Wire"));
break;
case 6:
return QString(tr("Status"));
break;
case 7:
return QString(tr("Active"));
break;
}
}
else
return QString::number(section + 1);
return QVariant();
}
int CANConnectionModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 7;
}
int CANConnectionModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
int rows=0;
QList<CANConnection*>& conns = CANConManager::getInstance()->getConnections();
foreach(const CANConnection* conn_p, conns)
rows+=conn_p->getNumBuses();
return rows;
}
QVariant CANConnectionModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role == Qt::DisplayRole) {
int busId;
CANConnection *conn_p = getAtIdx(index.row(), busId);
if(!conn_p)
return QVariant();
CANBus bus;
bool ret;
ret = conn_p->getBusSettings(busId, bus);
if(!ret) return QVariant();
switch (index.column())
{
case 0: //bus
//return QString::number(busId);
return QString::number(index.row());
break;
case 1: //type
if (conn_p)
switch (conn_p->getType()) {
case CANCon::KVASER: return "KVASER";
case CANCon::SOCKETCAN: return "SocketCAN";
case CANCon::GVRET_SERIAL: return "GVRET";
default: {}
}
else qDebug() << "Tried to show connection type but connection was NULL";
break;
case 2: //port
if (conn_p) return conn_p->getPort();
else qDebug() << "Tried to show connection port but connection was NULL";
break;
case 3: //speed
return QString::number(bus.speed);
case 4: //Listen Only
return (bus.listenOnly) ? "True" : "False";
case 5: //Single Wire
return (bus.singleWire) ? "True" : "False";
case 6: //Status
return (conn_p->getStatus()==CANCon::CONNECTED) ? "Connected" : "Not Connected";
case 7: //Active
return (bus.active) ? "True" : "False";
default: {}
}
}
return QVariant();
}
void CANConnectionModel::add(CANConnection* pConn_p)
{
CANConManager* manager = CANConManager::getInstance();
beginResetModel();
manager->add(pConn_p);
endResetModel();
}
void CANConnectionModel::remove(CANConnection* pConn_p)
{
CANConManager* manager = CANConManager::getInstance();
beginResetModel();
manager->remove(pConn_p);
endResetModel();
}
CANConnection* CANConnectionModel::getAtIdx(int pIdx, int& pBusId) const
{
if (pIdx < 0)
return NULL;
int i=0;
QList<CANConnection*>& conns = CANConManager::getInstance()->getConnections();
foreach(CANConnection* conn_p, conns)
{
if( i <= pIdx && pIdx < i+conn_p->getNumBuses() ) {
pBusId = pIdx - i;
return conn_p;
}
i+= conn_p->getNumBuses();
}
return NULL;
}
void CANConnectionModel::refresh(int pIndex)
{
QModelIndex begin;
QModelIndex end;
if(pIndex>=0) {
begin = createIndex(pIndex, 0);
end = createIndex(pIndex, columnCount()-1);
}
else {
begin = createIndex(0, 0);
end = createIndex(rowCount()-1, columnCount()-1);
}
dataChanged(begin, end, QVector<int>(Qt::DisplayRole));
}
+33
View File
@@ -0,0 +1,33 @@
#ifndef CANCONNECTIONMODEL_H
#define CANCONNECTIONMODEL_H
#include <QAbstractTableModel>
#include "canbus.h"
#include "connections/canconnection.h"
#include "connectionwindow.h"
class CANConnectionModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit CANConnectionModel(QObject *parent = 0);
virtual ~CANConnectionModel();
// from abstractmodel:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
void add(CANConnection* pConn_p);
void remove(CANConnection* pConn_p);
CANConnection* getAtIdx(int, int&) const;
void refresh(int pIndex=-1);
};
#endif // CANCONNECTIONMODEL_H
+512
View File
@@ -0,0 +1,512 @@
#include <QCanBus>
#include <QThread>
#include "connectionwindow.h"
#include "mainwindow.h"
#include "ui_connectionwindow.h"
#include "connections/canconfactory.h"
#include "connections/canconmanager.h"
#include "canbus.h"
ConnectionWindow::ConnectionWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::ConnectionWindow)
{
ui->setupUi(this);
QSettings settings;
qRegisterMetaType<CANBus>("CANBus");
qRegisterMetaType<const CANFrame *>("const CANFrame *");
qRegisterMetaType<const QList<CANFrame> *>("const QList<CANFrame> *");
connModel = new CANConnectionModel(this);
ui->tableConnections->setModel(connModel);
ui->tableConnections->setColumnWidth(0, 50);
ui->tableConnections->setColumnWidth(1, 110);
ui->tableConnections->setColumnWidth(2, 110);
ui->tableConnections->setColumnWidth(3, 110);
ui->tableConnections->setColumnWidth(4, 75);
ui->tableConnections->setColumnWidth(5, 75);
ui->tableConnections->setColumnWidth(6, 75);
ui->tableConnections->setColumnWidth(7, 75);
ui->ckSingleWire->setChecked(settings.value("Main/SingleWireMode", false).toBool());
ui->cbSpeed->addItem(tr("125000"));
ui->cbSpeed->addItem(tr("250000"));
ui->cbSpeed->addItem(tr("500000"));
ui->cbSpeed->addItem(tr("1000000"));
ui->cbSpeed->addItem(tr("33333"));
/* load connection configuration */
loadConnections();
ui->rbSocketCAN->setEnabled(isSocketCanAvailable());
#ifdef Q_OS_WIN
ui->rbKvaser->setEnabled(true);
#endif
connect(ui->btnOK, &QAbstractButton::clicked, this, &ConnectionWindow::handleOKButton);
connect(ui->rbGVRET, &QAbstractButton::clicked, this, &ConnectionWindow::handleConnTypeChanged);
connect(ui->rbKvaser, &QAbstractButton::clicked, this, &ConnectionWindow::handleConnTypeChanged);
connect(ui->rbSocketCAN, &QAbstractButton::clicked, this, &ConnectionWindow::handleConnTypeChanged);
connect(ui->btnRevert, &QPushButton::clicked, this, &ConnectionWindow::handleRevert);
connect(ui->tableConnections->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &ConnectionWindow::currentRowChanged);
connect(ui->btnNewConn, &QPushButton::clicked, this, &ConnectionWindow::handleNewConn);
connect(ui->btnActivateAll, &QPushButton::clicked, this, &ConnectionWindow::handleEnableAll);
connect(ui->btnDeactivateAll, &QPushButton::clicked, this, &ConnectionWindow::handleDisableAll);
connect(ui->btnRemoveBus, &QPushButton::clicked, this, &ConnectionWindow::handleRemoveConn);
}
ConnectionWindow::~ConnectionWindow()
{
QList<CANConnection*>& conns = CANConManager::getInstance()->getConnections();
CANConnection* conn_p;
/* save configuration */
saveConnections();
/* delete connections */
while(!conns.isEmpty())
{
conn_p = conns.takeFirst();
conn_p->stop();
delete conn_p;
}
delete ui;
}
void ConnectionWindow::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
qDebug() << "Show connectionwindow";
ui->tableConnections->selectRow(0);
currentRowChanged(ui->tableConnections->currentIndex(), ui->tableConnections->currentIndex());
}
void ConnectionWindow::setSuspendAll(bool pSuspend)
{
QList<CANConnection*>& conns = CANConManager::getInstance()->getConnections();
foreach(CANConnection* conn_p, conns)
conn_p->suspend(pSuspend);
connModel->refresh();
}
void ConnectionWindow::setActiveAll(bool pActive)
{
CANBus bus;
QList<CANConnection*>& conns = CANConManager::getInstance()->getConnections();
foreach(CANConnection* conn_p, conns)
{
for(int i=0 ; i<conn_p->getNumBuses() ; i++) {
if( conn_p->getBusSettings(i, bus) ) {
bus.active = pActive;
conn_p->setBusSettings(i, bus);
}
}
}
connModel->refresh();
}
void ConnectionWindow::handleNewConn()
{
ui->tableConnections->setCurrentIndex(QModelIndex());
currentRowChanged(ui->tableConnections->currentIndex(), ui->tableConnections->currentIndex());
}
void ConnectionWindow::handleEnableAll()
{
setActiveAll(true);
}
void ConnectionWindow::handleDisableAll()
{
setActiveAll(false);
}
void ConnectionWindow::handleConnTypeChanged()
{
if (ui->rbGVRET->isChecked()) selectSerial();
if (ui->rbKvaser->isChecked()) selectKvaser();
if (ui->rbSocketCAN->isChecked()) selectSocketCan();
}
/* status */
void ConnectionWindow::connectionStatus(CANCon::status pStatus)
{
Q_UNUSED(pStatus);
qDebug() << "Connectionstatus changed";
connModel->refresh();
}
void ConnectionWindow::handleOKButton()
{
int whichRow = ui->tableConnections->selectionModel()->currentIndex().row();
CANConnection* conn_p = NULL;
if (whichRow > -1)
{
/* set information for selected connection */
int busId;
CANBus bus;
bool ret;
conn_p = connModel->getAtIdx(whichRow, busId);
if(!conn_p) return;
ret = conn_p->getBusSettings(busId, bus);
if(!ret) return;
bus.setListenOnly(ui->ckListenOnly->isChecked());
bus.setSingleWire(ui->ckSingleWire->isChecked());
bus.setEnabled(ui->ckEnabled->isChecked());
bus.setSpeed(ui->cbSpeed->currentText().toInt());
/* update bus settings */
conn_p->setBusSettings(busId, bus);
connModel->refresh(whichRow);
}
else if( ! CANConManager::getInstance()->getByName(getPortName()) )
{
/* create connection */
conn_p = create(getConnectionType(), getPortName());
if(!conn_p)
return;
for (int i=0 ; i<conn_p->getNumBuses() ; i++) {
/* set bus configuration */
CANBus bus;
bus.active = ui->ckEnabled->isChecked();
bus.listenOnly = ui->ckListenOnly->isChecked();
bus.singleWire = ui->ckSingleWire->isChecked();
bus.speed = ui->cbSpeed->currentText().toInt();
/* update bus settings */
conn_p->setBusSettings(i, bus);
}
/* add connection to model */
connModel->add(conn_p);
}
}
void ConnectionWindow::currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{
Q_UNUSED(previous);
int selIdx = current.row();
/* enable / diable connection type */
ui->stPort->setEnabled(selIdx==-1);
ui->gbType->setEnabled(selIdx==-1);
ui->lPort->setEnabled(selIdx==-1);
/* set parameters */
if (selIdx == -1)
{
ui->btnOK->setText(tr("Create New Connection"));
ui->rbGVRET->setChecked(true);
ui->ckListenOnly->setChecked(false);
ui->ckSingleWire->setChecked(false);
ui->ckEnabled->setChecked(false);
setSpeed(0);
setPortName(CANCon::GVRET_SERIAL, "");
}
else
{
int busId;
bool ret;
CANBus bus;
CANConnection* conn_p = connModel->getAtIdx(selIdx, busId);
if(!conn_p) return;
ret = conn_p->getBusSettings(busId, bus);
if(!ret) return;
ui->btnOK->setText(tr("Update Connection Settings"));
ui->ckListenOnly->setChecked(bus.isListenOnly());
ui->ckSingleWire->setChecked(bus.isSingleWire());
ui->ckEnabled->setChecked(bus.isActive());
setSpeed(bus.getSpeed());
setPortName(conn_p->getType(), conn_p->getPort());
}
}
void ConnectionWindow::selectSerial()
{
/* set combobox page visible */
ui->stPort->setCurrentWidget(ui->cbPage);
ui->cbSpeed->setEnabled(true);
ui->cbPort->clear();
ports = QSerialPortInfo::availablePorts();
for (int i = 0; i < ports.count(); i++)
ui->cbPort->addItem(ports[i].portName());
}
void ConnectionWindow::selectKvaser()
{
/* set combobox page visible */
ui->stPort->setCurrentWidget(ui->cbPage);
ui->cbSpeed->setEnabled(false);
}
void ConnectionWindow::selectSocketCan()
{
/* set edit text page visible */
ui->stPort->setCurrentWidget(ui->etPage);
}
void ConnectionWindow::setSpeed(int speed0)
{
for (int i = 0; i < ui->cbSpeed->count(); i++)
{
if (ui->cbSpeed->itemText(i).toInt() == speed0)
{
ui->cbSpeed->setCurrentIndex(i);
return;
}
}
/* add custom speed */
ui->cbSpeed->addItem(QString::number(speed0));
ui->cbSpeed->setCurrentIndex(ui->cbSpeed->count() - 1);
}
void ConnectionWindow::setPortName(CANCon::type pType, QString pPortName)
{
switch(pType)
{
case CANCon::GVRET_SERIAL:
ui->rbGVRET->setChecked(true);
ui->cbSpeed->setEnabled(true);
ui->ckListenOnly->setEnabled(true);
ui->ckSingleWire->setEnabled(true);
break;
case CANCon::KVASER:
ui->rbKvaser->setChecked(true);
break;
case CANCon::SOCKETCAN:
ui->rbSocketCAN->setChecked(true);
//you can't configure any of the below three with socketcan so dim them out
ui->cbSpeed->setEnabled(false);
ui->ckListenOnly->setEnabled(false);
ui->ckSingleWire->setEnabled(false);
break;
default: {}
}
/* refresh names whenever needed */
handleConnTypeChanged();
switch(pType)
{
case CANCon::GVRET_SERIAL:
{
int idx = ui->cbPort->findText(pPortName);
if( idx<0 ) idx=0;
ui->cbPort->setCurrentIndex(idx);
break;
}
case CANCon::SOCKETCAN:
{
ui->lePort->setText(pPortName);
break;
}
default: {}
}
}
//-1 means leave it at whatever it booted up to. 0 means disable. Otherwise the actual rate we want.
int ConnectionWindow::getSpeed()
{
switch (ui->cbSpeed->currentIndex())
{
case -1:
case 0:
return -1;
case 1:
return 0;
default:
return (ui->cbSpeed->currentText().toInt());
}
}
QString ConnectionWindow::getPortName()
{
switch( getConnectionType() ) {
case CANCon::GVRET_SERIAL:
case CANCon::KVASER:
return ui->cbPort->currentText();
case CANCon::SOCKETCAN:
return ui->lePort->text();
default:
qDebug() << "getPortName: can't get port";
}
return "";
}
CANCon::type ConnectionWindow::getConnectionType()
{
if (ui->rbGVRET->isChecked()) return CANCon::GVRET_SERIAL;
if (ui->rbKvaser->isChecked()) return CANCon::KVASER;
if (ui->rbSocketCAN->isChecked()) return CANCon::SOCKETCAN;
qDebug() << "getConnectionType: error";
return CANCon::NONE;
}
void ConnectionWindow::setSWMode(bool mode)
{
ui->ckSingleWire->setChecked(mode);
}
bool ConnectionWindow::getSWMode()
{
if (ui->ckSingleWire->checkState() == Qt::Checked) return true;
return false;
}
void ConnectionWindow::handleRemoveConn()
{
int selIdx = ui->tableConnections->selectionModel()->currentIndex().row();
if (selIdx <0) return;
qDebug() << "remove connection at index: " << selIdx;
int busId;
CANConnection* conn_p = connModel->getAtIdx(selIdx, busId);
if(!conn_p) return;
/* remove connection from model & manager */
connModel->remove(conn_p);
/* stop and delete connection */
conn_p->stop();
delete conn_p;
/* select first connection in list */
ui->tableConnections->selectRow(0);
}
void ConnectionWindow::handleRevert()
{
}
bool ConnectionWindow::isSocketCanAvailable()
{
#ifdef Q_OS_LINUX
foreach (const QByteArray &backend, QCanBus::instance()->plugins()) {
if (backend == "socketcan")
return true;
}
#endif
return false;
}
CANConnection* ConnectionWindow::create(CANCon::type pTye, QString pPortName)
{
CANConnection* conn_p;
/* create connection */
conn_p = CanConFactory::create(pTye, pPortName);
if(conn_p)
{
/* connect signal */
connect(conn_p, SIGNAL(status(CANCon::status)),
this, SLOT(connectionStatus(CANCon::status)));
/*TODO add return value and checks */
conn_p->start();
}
return conn_p;
}
void ConnectionWindow::loadConnections()
{
qRegisterMetaTypeStreamOperators<QVector<QString>>();
qRegisterMetaTypeStreamOperators<QVector<int>>();
qRegisterMetaTypeStreamOperators<CANBus>();
qRegisterMetaTypeStreamOperators<QList<CANBus>>();
QSettings settings;
/* fill connection list */
QVector<QString> portNames = settings.value("connections/portNames").value<QVector<QString>>();
QVector<int> devTypes = settings.value("connections/types").value<QVector<int>>();
QList<CANBus> busses = settings.value("connections/busses").value<QList<CANBus>>();
for(int i=0 ; i<portNames.count() ; i++)
{
CANConnection* conn_p = create((CANCon::type)devTypes[i], portNames[i]);
if(conn_p)
{
for(int j=0 ; j<conn_p->getNumBuses() ; j++)
conn_p->setBusSettings(j, busses.takeFirst());
}
/* add connection to model */
connModel->add(conn_p);
}
if (connModel->rowCount() > 0) {
ui->tableConnections->selectRow(0);
}
}
void ConnectionWindow::saveConnections()
{
QList<CANConnection*>& conns = CANConManager::getInstance()->getConnections();
QSettings settings;
QVector<QString> portNames;
QVector<int> devTypes;
QList<CANBus> busses;
/* save connections */
foreach(CANConnection* conn_p, conns)
{
portNames.append(conn_p->getPort());
devTypes.append(conn_p->getType());
for(int i=0 ; i<conn_p->getNumBuses() ; i++)
{
CANBus bus;
conn_p->getBusSettings(i, bus);
busses.append(bus);
}
}
settings.setValue("connections/portNames", QVariant::fromValue(portNames));
settings.setValue("connections/types", QVariant::fromValue(devTypes));
settings.setValue("connections/busses", QVariant::fromValue(busses));
}
+76
View File
@@ -0,0 +1,76 @@
#ifndef CONNECTIONWINDOW_H
#define CONNECTIONWINDOW_H
#include <QSerialPortInfo>
#include <QDialog>
#include <QDebug>
#include <QSettings>
#include <QTimer>
#include <QItemSelection>
#include "canconnectionmodel.h"
#include "connections/canconnection.h"
class CANConnectionModel;
namespace Ui {
class ConnectionWindow;
}
class ConnectionWindow : public QDialog
{
Q_OBJECT
public:
explicit ConnectionWindow(QWidget *parent = 0);
~ConnectionWindow();
void showEvent(QShowEvent *);
CANCon::type getConnectionType();
bool getSWMode();
signals:
void updateBusSettings(CANBus *bus);
void updatePortName(QString port);
public slots:
void setSpeed(int speed0);
void setSWMode(bool mode);
void setSuspendAll(bool pSuspend);
private slots:
void handleOKButton();
void handleConnTypeChanged();
void currentRowChanged(const QModelIndex &current, const QModelIndex &previous);
void handleRemoveConn();
void handleEnableAll();
void handleDisableAll();
void handleRevert();
void handleNewConn();
void connectionStatus(CANCon::status);
private:
Ui::ConnectionWindow *ui;
QList<QSerialPortInfo> ports;
QSettings *settings;
CANConnectionModel *connModel;
void selectSerial();
void selectKvaser();
void selectSocketCan();
bool isSocketCanAvailable();
int getSpeed();
QString getPortName();
void setPortName(CANCon::type pType, QString pPortName);
void setActiveAll(bool pActive);
CANConnection* create(CANCon::type pTye, QString pPortName);
void loadConnections();
void saveConnections();
};
#endif // CONNECTIONWINDOW_H
+318 -212
View File
@@ -1,56 +1,190 @@
#include "serialworker.h" #include <QObject>
#include <QSerialPort>
#include <QDebug> #include <QDebug>
#include <QTimer> #include <QCanBusFrame>
#include <QSerialPortInfo>
#include <QSettings> #include <QSettings>
SerialWorker::SerialWorker(CANFrameModel *model, QObject *parent) : QObject(parent) #include "gvretserial.h"
GVRetSerial::GVRetSerial(QString portName) :
CANConnection(portName, CANCon::GVRET_SERIAL, 2, 4000, true),
mTimer(this) /*NB: set this as parent of timer to manage it from working thread */
{ {
qDebug() << "GVRetSerial()";
serial = NULL; serial = NULL;
rx_state = IDLE; rx_state = IDLE;
rx_step = 0; rx_step = 0;
buildFrame = new CANFrame;
canModel = model;
ticker = NULL;
framesRapid = 0;
capturing = true;
gotValidated = true; gotValidated = true;
isAutoRestart = false; isAutoRestart = false;
targetID = -1;
txTimestampBasis = QDateTime::currentMSecsSinceEpoch(); timeBasis = 0;
lastSystemTimeBasis = 0;
timeAtGVRETSync = 0;
readSettings(); readSettings();
} }
SerialWorker::~SerialWorker()
{
if (serial != NULL)
{
if (serial->isOpen())
{
serial->clear();
serial->close();
} GVRetSerial::~GVRetSerial()
serial->disconnect(); //disconnect all signals {
delete serial; stop();
} qDebug() << "~GVRetSerial()";
if (ticker != NULL) ticker->stop();
} }
void SerialWorker::run()
{
ticker = new QTimer;
connect(ticker, SIGNAL(timeout()), this, SLOT(handleTick()));
ticker->setInterval(250); //tick four times per second void GVRetSerial::piStarted()
ticker->setSingleShot(false); //keep ticking {
ticker->start(); connectDevice();
/* start timer */
connect(&mTimer, SIGNAL(timeout()), this, SLOT(handleTick()));
mTimer.setInterval(250); //tick four times per second
mTimer.setSingleShot(false); //keep ticking
mTimer.start();
} }
void SerialWorker::readSettings()
void GVRetSerial::piSuspend(bool pSuspend)
{
/* update capSuspended */
setCapSuspended(pSuspend);
/* flush queue if we are suspended */
if(isCapSuspended())
getQueue().flush();
}
void GVRetSerial::piStop()
{
mTimer.stop();
disconnectDevice();
}
bool GVRetSerial::piGetBusSettings(int pBusIdx, CANBus& pBus)
{
return getBusConfig(pBusIdx, pBus);
}
void GVRetSerial::piSetBusSettings(int pBusIdx, CANBus bus)
{
/* sanity checks */
if( (pBusIdx < 0) || pBusIdx >= getNumBuses())
return;
/* copy bus config */
setBusConfig(pBusIdx, bus);
qDebug() << "About to update bus " << pBusIdx << " on GVRET";
if (pBusIdx == 0)
{
can0Baud = bus.getSpeed();
can0Baud |= 0x80000000;
if (bus.isActive())
{
can0Baud |= 0x40000000;
can0Enabled = true;
}
else can0Enabled = false;
if (bus.isListenOnly())
{
can0Baud |= 0x20000000;
can0ListenOnly = true;
}
else can0ListenOnly = false;
}
else if (pBusIdx == 1)
{
can1Baud = bus.getSpeed();
can1Baud |= 0x80000000;
if (bus.isActive())
{
can1Baud |= 0x40000000;
can1Enabled = true;
}
else can1Enabled = false;
if (bus.isListenOnly())
{
can1Baud |= 0x20000000;
can1ListenOnly = true;
}
else can1ListenOnly = false;
if (bus.isSingleWire())
{
can1Baud |= 0x10000000;
deviceSingleWireMode = 1;
}
else deviceSingleWireMode = 0;
}
/* update baud rates */
QByteArray buffer;
qDebug() << "Got signal to update bauds. 1: " << can0Baud <<" 2: " << can1Baud;
buffer[0] = (char)0xF1; //start of a command over serial
buffer[1] = 5; //setup canbus
buffer[2] = (unsigned char)(can0Baud & 0xFF); //four bytes of ID LSB first
buffer[3] = (unsigned char)(can0Baud >> 8);
buffer[4] = (unsigned char)(can0Baud >> 16);
buffer[5] = (unsigned char)(can0Baud >> 24);
buffer[6] = (unsigned char)(can1Baud & 0xFF); //four bytes of ID LSB first
buffer[7] = (unsigned char)(can1Baud >> 8);
buffer[8] = (unsigned char)(can1Baud >> 16);
buffer[9] = (unsigned char)(can1Baud >> 24);
buffer[10] = 0;
if (serial == NULL) return;
if (!serial->isOpen()) return;
serial->write(buffer);
}
bool GVRetSerial::piSendFrame(const CANFrame& frame)
{
QByteArray buffer;
unsigned int c;
int ID;
//qDebug() << "Sending out GVRET frame with id " << frame.ID << " on bus " << frame.bus;
framesRapid++;
if (serial == NULL) return false;
if (!serial->isOpen()) return false;
//if (!isConnected) return false;
ID = frame.ID;
if (frame.extended) ID |= 1 << 31;
buffer[0] = (char)0xF1; //start of a command over serial
buffer[1] = 0; //command ID for sending a CANBUS frame
buffer[2] = (unsigned char)(ID & 0xFF); //four bytes of ID LSB first
buffer[3] = (unsigned char)(ID >> 8);
buffer[4] = (unsigned char)(ID >> 16);
buffer[5] = (unsigned char)(ID >> 24);
buffer[6] = (unsigned char)((frame.bus) & 1);
buffer[7] = (unsigned char)frame.len;
for (c = 0; c < frame.len; c++)
{
buffer[8 + c] = frame.data[c];
}
buffer[8 + frame.len] = 0;
//qDebug() << "writing " << buffer.length() << " bytes to serial port";
serial->write(buffer);
return true;
}
/****************************************************************/
void GVRetSerial::readSettings()
{ {
QSettings settings; QSettings settings;
@@ -59,30 +193,25 @@ void SerialWorker::readSettings()
doValidation = true; doValidation = true;
} }
else doValidation = false; else doValidation = false;
//doValidation=false;
} }
void SerialWorker::setSerialPort(QSerialPortInfo *port)
void GVRetSerial::connectDevice()
{ {
QSettings settings; QSettings settings;
currentPort = port; /* disconnect device */
if(serial)
disconnectDevice();
if (serial != NULL) /* open new device */
{ serial = new QSerialPort(QSerialPortInfo(getPort()));
if (serial->isOpen()) if(!serial) {
{ qDebug() << "can't open serial port " << getPort();
serial->clear(); return;
serial->close();
}
serial->disconnect(); //disconnect all signals
delete serial;
} }
serial = new QSerialPort(*port); /* configure */
qDebug() << "Serial port name is " << port->portName();
//serial->setBaudRate(10000000); //more speed! probably does nothing for USB serial
serial->setDataBits(serial->Data8); serial->setDataBits(serial->Data8);
serial->setFlowControl(serial->HardwareControl); //this is important though serial->setFlowControl(serial->HardwareControl); //this is important though
if (!serial->open(QIODevice::ReadWrite)) if (!serial->open(QIODevice::ReadWrite))
@@ -91,6 +220,8 @@ void SerialWorker::setSerialPort(QSerialPortInfo *port)
} }
serial->setDataTerminalReady(true); //you do need to set these or the fan gets dirty serial->setDataTerminalReady(true); //you do need to set these or the fan gets dirty
serial->setRequestToSend(true); serial->setRequestToSend(true);
QByteArray output; QByteArray output;
output.append((char)0xE7); //this puts the device into binary comm mode output.append((char)0xE7); //this puts the device into binary comm mode
output.append((char)0xE7); output.append((char)0xE7);
@@ -101,7 +232,7 @@ void SerialWorker::setSerialPort(QSerialPortInfo *port)
output.append((char)0xF1); //another command to the GVRET output.append((char)0xF1); //another command to the GVRET
output.append((char)0x07); //request device information output.append((char)0x07); //request device information
output.append((char)0xF1); /*output.append((char)0xF1);
output.append((char)0x08); //setting singlewire mode output.append((char)0x08); //setting singlewire mode
if (settings.value("Main/SingleWireMode", false).toBool()) if (settings.value("Main/SingleWireMode", false).toBool())
{ {
@@ -110,7 +241,7 @@ void SerialWorker::setSerialPort(QSerialPortInfo *port)
else else
{ {
output.append((char)0xFF); //signal we don't want single wire mode output.append((char)0xFF); //signal we don't want single wire mode
} }*/
output.append((char)0xF1); //yet another command output.append((char)0xF1); //yet another command
output.append((char)0x09); //comm validation command output.append((char)0x09); //comm validation command
@@ -121,26 +252,51 @@ void SerialWorker::setSerialPort(QSerialPortInfo *port)
continuousTimeSync = true; continuousTimeSync = true;
serial->write(output); serial->write(output);
if (doValidation) connected = false;
else connected = true; if(doValidation) {
QTimer::singleShot(1000, this, SLOT(connectionTimeout()));
}
else {
setStatus(CANCon::CONNECTED);
emit status(getStatus());
}
/* connect reading event */
connect(serial, SIGNAL(readyRead()), this, SLOT(readSerialData())); connect(serial, SIGNAL(readyRead()), this, SLOT(readSerialData()));
if (doValidation) QTimer::singleShot(1000, this, SLOT(connectionTimeout()));
} }
void SerialWorker::connectionTimeout()
{ void GVRetSerial::disconnectDevice() {
//one second after trying to connect are we actually connected? if (serial != NULL)
if (!connected) //no?
{ {
//then emit the the failure signal and see if anyone cares if (serial->isOpen())
qDebug() << "Failed to connect to GVRET at that com port"; {
//ticker->stop(); serial->clear();
closeSerialPort(); //make sure it's properly closed anyway serial->close();
emit connectionFailure();
}
serial->disconnect(); //disconnect all signals
delete serial;
serial = NULL;
} }
} }
void SerialWorker::readSerialData()
void GVRetSerial::connectionTimeout()
{
//one second after trying to connect are we actually connected?
//if (CANCon::NOT_CONNECTED==getStatus()) //no?
if (!gotValidated)
{
//then emit the the failure signal and see if anyone cares
qDebug() << "Failed to connect to GVRET at that com port";
disconnectDevice();
}
}
void GVRetSerial::readSerialData()
{ {
QByteArray data = serial->readAll(); QByteArray data = serial->readAll();
unsigned char c; unsigned char c;
@@ -148,86 +304,13 @@ void SerialWorker::readSerialData()
for (int i = 0; i < data.length(); i++) for (int i = 0; i < data.length(); i++)
{ {
c = data.at(i); c = data.at(i);
//qDebug() << c << " " << QString::number(c, 16) << " " << QString(c);
procRXChar(c); procRXChar(c);
} }
if (framesRapid > 0)
{
emit frameUpdateRapid(framesRapid);
framesRapid = 0;
}
} }
void SerialWorker::sendFrame(const CANFrame *frame, int bus = 0)
{
QByteArray buffer;
int c;
int ID;
CANFrame tempFrame = *frame;
tempFrame.isReceived = false;
tempFrame.timestamp = ((QDateTime::currentMSecsSinceEpoch() - txTimestampBasis) * 1000);
//qDebug() << "Sending out frame with id " << frame->ID; void GVRetSerial::procRXChar(unsigned char c)
//show our sent frames in the list too. This happens even if we're not connected.
canModel->addFrame(tempFrame, false);
framesRapid++;
if (serial == NULL) return;
if (!serial->isOpen()) return;
if (!connected) return;
ID = frame->ID;
if (frame->extended) ID |= 1 << 31;
buffer[0] = (char)0xF1; //start of a command over serial
buffer[1] = 0; //command ID for sending a CANBUS frame
buffer[2] = (unsigned char)(ID & 0xFF); //four bytes of ID LSB first
buffer[3] = (unsigned char)(ID >> 8);
buffer[4] = (unsigned char)(ID >> 16);
buffer[5] = (unsigned char)(ID >> 24);
buffer[6] = (unsigned char)(bus & 1);
buffer[7] = (unsigned char)frame->len;
for (c = 0; c < frame->len; c++)
{
buffer[8 + c] = frame->data[c];
}
buffer[8 + frame->len] = 0;
//qDebug() << "writing " << buffer.length() << " bytes to serial port";
serial->write(buffer);
}
//a simple way for another thread to pass us a bunch of frames to send.
//Don't get carried away here. The GVRET firmware only has finite
//buffers and besides, the other end will get buried in traffic.
void SerialWorker::sendFrameBatch(const QList<CANFrame> *frames)
{
sendBulkMutex.lock();
for (int i = 0; i < frames->length(); i++) sendFrame(&frames->at(i), frames->at(i).bus);
sendBulkMutex.unlock();
}
void SerialWorker::updateBaudRates(int Speed1, int Speed2)
{
QByteArray buffer;
qDebug() << "Got signal to update bauds. 1: " << Speed1 <<" 2: " << Speed2;
buffer[0] = (char)0xF1; //start of a command over serial
buffer[1] = 5; //setup canbus
buffer[2] = (unsigned char)(Speed1 & 0xFF); //four bytes of ID LSB first
buffer[3] = (unsigned char)(Speed1 >> 8);
buffer[4] = (unsigned char)(Speed1 >> 16);
buffer[5] = (unsigned char)(Speed1 >> 24);
buffer[6] = (unsigned char)(Speed2 & 0xFF); //four bytes of ID LSB first
buffer[7] = (unsigned char)(Speed2 >> 8);
buffer[8] = (unsigned char)(Speed2 >> 16);
buffer[9] = (unsigned char)(Speed2 >> 24);
buffer[10] = 0;
if (serial == NULL) return;
if (!serial->isOpen()) return;
serial->write(buffer);
}
void SerialWorker::procRXChar(unsigned char c)
{ {
switch (rx_state) switch (rx_state)
{ {
@@ -277,58 +360,70 @@ void SerialWorker::procRXChar(unsigned char c)
switch (rx_step) switch (rx_step)
{ {
case 0: case 0:
buildFrame->timestamp = c; buildFrame.timestamp = c;
break; break;
case 1: case 1:
buildFrame->timestamp |= (uint)(c << 8); buildFrame.timestamp |= (uint)(c << 8);
break; break;
case 2: case 2:
buildFrame->timestamp |= (uint)c << 16; buildFrame.timestamp |= (uint)c << 16;
break; break;
case 3: case 3:
buildFrame->timestamp |= (uint)c << 24; buildFrame.timestamp |= (uint)c << 24;
buildFrame.timestamp += timeBasis;
break; break;
case 4: case 4:
buildFrame->ID = c; buildFrame.ID = c;
break; break;
case 5: case 5:
buildFrame->ID |= c << 8; buildFrame.ID |= c << 8;
break; break;
case 6: case 6:
buildFrame->ID |= c << 16; buildFrame.ID |= c << 16;
break; break;
case 7: case 7:
buildFrame->ID |= c << 24; buildFrame.ID |= c << 24;
if ((buildFrame->ID & 1 << 31) == 1 << 31) if ((buildFrame.ID & 1 << 31) == 1u << 31)
{ {
buildFrame->ID &= 0x7FFFFFFF; buildFrame.ID &= 0x7FFFFFFF;
buildFrame->extended = true; buildFrame.extended = true;
} }
else buildFrame->extended = false; else buildFrame.extended = false;
break; break;
case 8: case 8:
buildFrame->len = c & 0xF; buildFrame.len = c & 0xF;
if (buildFrame->len > 8) buildFrame->len = 8; if (buildFrame.len > 8) buildFrame.len = 8;
buildFrame->bus = (c & 0xF0) >> 4; buildFrame.bus = (c & 0xF0) >> 4;
break; break;
default: default:
if (rx_step < buildFrame->len + 9) if (rx_step < buildFrame.len + 9)
{ {
buildFrame->data[rx_step - 9] = c; buildFrame.data[rx_step - 9] = c;
} }
else else
{ {
rx_state = IDLE; rx_state = IDLE;
rx_step = 0; rx_step = 0;
//qDebug() << "emit from serial handler to main form id: " << buildFrame->ID; buildFrame.isReceived = true;
if (capturing)
if (!isCapSuspended())
{ {
buildFrame->isReceived = true; /* get frame from queue */
canModel->addFrame(*buildFrame, false); CANFrame* frame_p = getQueue().get();
if(frame_p) {
//qDebug() << "GVRET got frame on bus " << frame_p->bus;
/* copy frame */
*frame_p = buildFrame;
checkTargettedFrame(buildFrame);
/* enqueue frame */
getQueue().queue();
}
else
qDebug() << "can't get a frame, ERROR";
//take the time the frame came in and try to resync the time base. //take the time the frame came in and try to resync the time base.
if (continuousTimeSync) txTimestampBasis = QDateTime::currentMSecsSinceEpoch() - (buildFrame->timestamp / 1000); //if (continuousTimeSync) txTimestampBasis = QDateTime::currentMSecsSinceEpoch() - (buildFrame.timestamp / 1000);
framesRapid++;
if (buildFrame->ID == targetID) emit gotTargettedFrame(canModel->rowCount() - 1);
} }
} }
break; break;
@@ -350,7 +445,10 @@ void SerialWorker::procRXChar(unsigned char c)
case 3: case 3:
buildTimeBasis += ((uint32_t)c << 24); buildTimeBasis += ((uint32_t)c << 24);
qDebug() << "GVRET firmware reports timestamp of " << buildTimeBasis; qDebug() << "GVRET firmware reports timestamp of " << buildTimeBasis;
txTimestampBasis = QDateTime::currentMSecsSinceEpoch() - ((uint64_t)buildTimeBasis / (uint64_t)1000ull); timeAtGVRETSync = QDateTime::currentMSecsSinceEpoch() * 1000;
rebuildLocalTimeBasis();
continuousTimeSync = false; continuousTimeSync = false;
rx_state = IDLE; rx_state = IDLE;
break; break;
@@ -381,7 +479,8 @@ void SerialWorker::procRXChar(unsigned char c)
switch (rx_step) switch (rx_step)
{ {
case 0: case 0:
can0Enabled = c; can0Enabled = (c & 0xF);
can0ListenOnly = (c >> 4);
break; break;
case 1: case 1:
can0Baud = c; can0Baud = c;
@@ -396,7 +495,9 @@ void SerialWorker::procRXChar(unsigned char c)
can0Baud |= c << 24; can0Baud |= c << 24;
break; break;
case 5: case 5:
can1Enabled = c; can1Enabled = (c & 0xF);
can1ListenOnly = (c >> 4);
deviceSingleWireMode = (c >> 6);
break; break;
case 6: case 6:
can1Baud = c; can1Baud = c;
@@ -412,10 +513,28 @@ void SerialWorker::procRXChar(unsigned char c)
rx_state = IDLE; rx_state = IDLE;
qDebug() << "Baud 0 = " << can0Baud; qDebug() << "Baud 0 = " << can0Baud;
qDebug() << "Baud 1 = " << can1Baud; qDebug() << "Baud 1 = " << can1Baud;
if (!can1Enabled) can1Baud = 0;
if (!can0Enabled) can0Baud = 0; can0Baud |= 0x80000000;
connected = true; if (can0Enabled) can0Baud |= 0x40000000;
emit connectionSuccess(can0Baud, can1Baud); if (can0ListenOnly) can0Baud |= 0x20000000;
can1Baud |= 0x80000000;
if (can1Enabled) can1Baud |= 0x40000000;
if (can1ListenOnly) can1Baud |= 0x20000000;
if (deviceSingleWireMode > 0) can1Baud |= 0x10000000;
setStatus(CANCon::CONNECTED);
emit status(getStatus());
int can0Status = 0x78; //updating everything we can update
int can1Status = 0x78;
if (can0Enabled) can0Status +=1;
if (can0ListenOnly) can0Status += 4;
if (can1Enabled) can1Status += 1;
if (deviceSingleWireMode > 0) can1Status += 2;
if (can1ListenOnly) can1Status += 4;
//emit busStatus(busBase, can0Baud & 0xFFFFF, can0Status);
//emit busStatus(busBase + 1, can1Baud & 0xFFFFF, can1Status);
break; break;
} }
rx_step++; rx_step++;
@@ -458,11 +577,29 @@ void SerialWorker::procRXChar(unsigned char c)
} }
} }
void SerialWorker::handleTick() void GVRetSerial::rebuildLocalTimeBasis()
{ {
//qDebug() << "Tick!"; qDebug() << "Rebuilding GVRET time base. GVRET local base = " << buildTimeBasis;
if (connected) /*
our time basis is the value we have to modulate the main system basis by in order
to sync the GVRET timestamps to the rest of the system.
The rest of the system uses CANConManager::getInstance()->getTimeBasis as the basis.
GVRET returns to us the current time since boot up in microseconds.
timeAtGVRETSync stores the "system" timestamp when the GVRET timestamp was retrieved.
*/
lastSystemTimeBasis = CANConManager::getInstance()->getTimeBasis();
int64_t systemDelta = timeAtGVRETSync - lastSystemTimeBasis;
int32_t localDelta = buildTimeBasis - systemDelta;
timeBasis = -localDelta;
}
void GVRetSerial::handleTick()
{
if (lastSystemTimeBasis != CANConManager::getInstance()->getTimeBasis()) rebuildLocalTimeBasis();
//qDebug() << "Tick!";
/*
if( CANCon::CONNECTED == getStatus() )
{ {
if (!gotValidated && doValidation) if (!gotValidated && doValidation)
{ {
@@ -470,24 +607,23 @@ void SerialWorker::handleTick()
if (serial->isOpen()) //if it's still false we have a problem... if (serial->isOpen()) //if it's still false we have a problem...
{ {
qDebug() << "Comm validation failed. "; qDebug() << "Comm validation failed. ";
closeSerialPort(); //start by stopping everything.
setStatus(CANCon::NOT_CONNECTED);
emit status(getStatus());
disconnectDevice(); //start by stopping everything.
//Then wait 500ms and restart the connection automatically //Then wait 500ms and restart the connection automatically
QTimer::singleShot(500, this, SLOT(handleReconnect())); QTimer::singleShot(500, this, SLOT(connectDevice()));
return; return;
} }
} }
} }
*/
if (doValidation && serial && serial->isOpen()) sendCommValidation(); if (doValidation && serial && serial->isOpen()) sendCommValidation();
} }
void SerialWorker::handleReconnect()
{
qDebug() << "Automatically reopening the connection";
setSerialPort(currentPort); //then go back through the re-init
}
void SerialWorker::sendCommValidation() void GVRetSerial::sendCommValidation()
{ {
QByteArray output; QByteArray output;
@@ -501,35 +637,5 @@ void SerialWorker::sendCommValidation()
serial->write(output); serial->write(output);
} }
//totally shuts down the whole thing
void SerialWorker::closeSerialPort()
{
if (serial == NULL) return;
if (serial->isOpen())
{
serial->clear();
serial->close();
}
serial->disconnect();
//do not stop the ticker here. It always stays running now.
//ticker->stop();
delete serial;
serial = NULL;
}
void SerialWorker::stopFrameCapture()
{
qDebug() << "Stopping frame capture";
capturing = false;
}
void SerialWorker::startFrameCapture()
{
qDebug() << "Starting up frame capture";
capturing = true;
}
void SerialWorker::targetFrameID(int target)
{
targetID = target;
}
+93
View File
@@ -0,0 +1,93 @@
#ifndef GVRETSERIAL_H
#define GVRETSERIAL_H
#include <QSerialPort>
#include <QCanBusDevice>
#include <QThread>
#include <QTimer>
/*************/
#include <QDateTime>
/*************/
#include "canframemodel.h"
#include "canconnection.h"
#include "canconmanager.h"
namespace SERIALSTATE {
enum STATE //keep this enum synchronized with the Arduino firmware project
{
IDLE,
GET_COMMAND,
BUILD_CAN_FRAME,
TIME_SYNC,
GET_DIG_INPUTS,
GET_ANALOG_INPUTS,
SET_DIG_OUTPUTS,
SETUP_CANBUS,
GET_CANBUS_PARAMS,
GET_DEVICE_INFO,
SET_SINGLEWIRE_MODE
};
}
using namespace SERIALSTATE;
class GVRetSerial : public CANConnection
{
Q_OBJECT
public:
GVRetSerial(QString portName);
virtual ~GVRetSerial();
protected:
virtual void piStarted();
virtual void piStop();
virtual void piSetBusSettings(int pBusIdx, CANBus pBus);
virtual bool piGetBusSettings(int pBusIdx, CANBus& pBus);
virtual void piSuspend(bool pSuspend);
virtual bool piSendFrame(const CANFrame&) ;
void disconnectDevice();
private slots:
void connectDevice();
void connectionTimeout();
void readSerialData();
void handleTick();
private:
void readSettings();
void procRXChar(unsigned char);
void sendCommValidation();
void rebuildLocalTimeBasis();
protected:
QTimer mTimer;
QThread mThread;
bool doValidation;
bool gotValidated;
bool isAutoRestart;
bool continuousTimeSync;
QSerialPort *serial;
int framesRapid;
STATE rx_state;
uint32_t rx_step;
CANFrame buildFrame;
int can0Baud, can1Baud;
bool can0Enabled, can1Enabled;
bool can0ListenOnly, can1ListenOnly;
int deviceBuildNum;
int deviceSingleWireMode;
uint32_t buildTimeBasis;
int32_t timeBasis;
uint64_t lastSystemTimeBasis;
uint64_t timeAtGVRETSync;
};
#endif // GVRETSERIAL_H
+240
View File
@@ -0,0 +1,240 @@
#include <QObject>
#include <QDebug>
#include <QCanBusFrame>
#include "socketcan.h"
/***********************************/
/**** class definition ****/
/***********************************/
SocketCan::SocketCan(QString portName) :
CANConnection(portName, CANCon::SOCKETCAN, 1, 4000, true),
mDev_p(NULL),
mTimer(this) /*NB: set connection as parent of timer to manage it from working thread */
{
}
SocketCan::~SocketCan()
{
stop();
}
void SocketCan::piStarted()
{
connect(&mTimer, SIGNAL(timeout()), this, SLOT(testConnection()));
mTimer.setInterval(1000);
mTimer.setSingleShot(false); //keep ticking
mTimer.start();
}
void SocketCan::piSuspend(bool pSuspend)
{
/* update capSuspended */
setCapSuspended(pSuspend);
/* flush queue if we are suspended */
if(isCapSuspended())
getQueue().flush();
}
void SocketCan::piStop() {
mTimer.stop();
disconnectDevice();
}
bool SocketCan::piGetBusSettings(int pBusIdx, CANBus& pBus)
{
return getBusConfig(pBusIdx, pBus);
}
void SocketCan::piSetBusSettings(int pBusIdx, CANBus bus)
{
/* sanity checks */
if(0 != pBusIdx)
return;
/* disconnect device if we have one connected */
if(mDev_p)
disconnectDevice();
/* copy bus config */
setBusConfig(0, bus);
/* if bus is not active we are done */
if(!bus.active)
return;
/* create device */
mDev_p = QCanBus::instance()->createDevice("socketcan", getPort());
if (!mDev_p) {
disconnectDevice();
qDebug() << "can't create device";
return;
}
/* connect slots */
connect(mDev_p, &QCanBusDevice::errorOccurred, this, &SocketCan::errorReceived);
connect(mDev_p, &QCanBusDevice::framesWritten, this, &SocketCan::framesWritten);
connect(mDev_p, &QCanBusDevice::framesReceived, this, &SocketCan::framesReceived);
/* set configuration */
/*if (p.useConfigurationEnabled) {
foreach (const SettingsDialog::ConfigurationItem &item, p.configurations)
mDev->setConfigurationParameter(item.first, item.second);
}*/
//You cannot set the speed of a socketcan interface, it has to be set with console commands.
//mDev_p->setConfigurationParameter(QCanBusDevice::BitRateKey, bus.speed);
/* connect device */
if (!mDev_p->connectDevice()) {
disconnectDevice();
qDebug() << "can't connect device";
}
}
bool SocketCan::piSendFrame(const CANFrame& pFrame)
{
/* sanity checks */
if(0 != pFrame.bus || pFrame.len>8)
return false;
/* fill frame */
QCanBusFrame frame;
frame.setFrameId(pFrame.ID);
frame.setExtendedFrameFormat(false);
frame.setPayload(QByteArray((const char*)pFrame.data, pFrame.len));
return mDev_p->writeFrame(frame);
}
/***********************************/
/**** private methods ****/
/***********************************/
/* disconnect device */
void SocketCan::disconnectDevice() {
if(mDev_p) {
mDev_p->disconnectDevice();
delete mDev_p;
mDev_p = Q_NULLPTR;
}
}
void SocketCan::errorReceived(QCanBusDevice::CanBusError error) const
{
switch (error) {
case QCanBusDevice::ReadError:
case QCanBusDevice::WriteError:
case QCanBusDevice::ConnectionError:
case QCanBusDevice::ConfigurationError:
case QCanBusDevice::UnknownError:
qWarning() << mDev_p->errorString();
default:
break;
}
}
void SocketCan::framesWritten(qint64 count)
{
Q_UNUSED(count);
//qDebug() << "Number of frames written:" << count;
}
void SocketCan::framesReceived()
{
uint64_t timeBasis = CANConManager::getInstance()->getTimeBasis();
/* sanity checks */
if(!mDev_p)
return;
/* read frame */
while(true)
{
const QCanBusFrame recFrame = mDev_p->readFrame();
/* exit case */
if(!recFrame.isValid())
break;
/* drop frame if capture is suspended */
if(isCapSuspended())
continue;
/* check frame */
if( !recFrame.payload().isEmpty() &&
recFrame.payload().length()<=8 )
{
CANFrame* frame_p = getQueue().get();
if(frame_p) {
frame_p->len = recFrame.payload().length();
frame_p->bus = 0;
memcpy(frame_p->data, recFrame.payload().data(), frame_p->len);
frame_p->extended = false;
frame_p->ID = recFrame.frameId();
frame_p->isReceived = true;
frame_p->timestamp = (recFrame.timeStamp().seconds()*1000000 + recFrame.timeStamp().microSeconds()) - timeBasis;
checkTargettedFrame(*frame_p);
/* enqueue frame */
getQueue().queue();
}
#if 0
else
qDebug() << "can't get a frame, ERROR";
#endif
}
}
}
void SocketCan::testConnection() {
QCanBusDevice* dev_p = QCanBus::instance()->createDevice("socketcan", getPort());
switch(getStatus())
{
case CANCon::CONNECTED:
if (!dev_p || !dev_p->connectDevice()) {
/* we have lost connectivity */
disconnectDevice();
setStatus(CANCon::NOT_CONNECTED);
emit status(getStatus());
}
break;
case CANCon::NOT_CONNECTED:
if (dev_p && dev_p->connectDevice()) {
if(!mDev_p) {
/* try to reconnect */
CANBus bus;
if(getBusConfig(0, bus))
setBusSettings(0, bus);
}
/* disconnect test instance */
dev_p->disconnectDevice();
setStatus(CANCon::CONNECTED);
emit status(getStatus());
}
break;
default: {}
}
if(dev_p)
delete dev_p;
}
+45
View File
@@ -0,0 +1,45 @@
#ifndef SocketCan_H
#define SocketCan_H
#include <QObject>
#include <QCanBus>
#include <QTimer>
#include <qthread.h>
#include "canframemodel.h"
#include "canconnection.h"
#include "canconmanager.h"
class SocketCan : public CANConnection
{
Q_OBJECT
public:
SocketCan(QString portName);
virtual ~SocketCan();
protected:
virtual void piStarted();
virtual void piStop();
virtual void piSetBusSettings(int pBusIdx, CANBus pBus);
virtual bool piGetBusSettings(int pBusIdx, CANBus& pBus);
virtual void piSuspend(bool pSuspend);
virtual bool piSendFrame(const CANFrame&);
void disconnectDevice();
private slots:
void errorReceived(QCanBusDevice::CanBusError) const;
void framesWritten(qint64 count);
void framesReceived();
void testConnection();
protected:
QCanBusDevice* mDev_p;
QTimer mTimer;
};
#endif // SocketCan_H
-247
View File
@@ -1,247 +0,0 @@
#include "connectionwindow.h"
#include "ui_connectionwindow.h"
#include <QtNetwork/QNetworkInterface>
ConnectionWindow::ConnectionWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::ConnectionWindow)
{
ui->setupUi(this);
settings = new QSettings();
int temp = settings->value("Main/DefaultConnectionType", 0).toInt();
if (temp == 0) currentConnType = ConnectionType::GVRET_SERIAL;
if (temp == 1) currentConnType = ConnectionType::KVASER;
if (temp == 2) currentConnType = ConnectionType::SOCKETCAN;
currentPortName = settings->value("Main/DefaultConnectionPort", "").toString();
currentSpeed1 = -1;
currentSpeed2 = -1;
ui->ckSingleWire->setChecked(settings->value("Main/SingleWireMode", false).toBool());
ui->cbSpeed0->addItem(tr("<Default>"));
ui->cbSpeed0->addItem(tr("Disabled"));
ui->cbSpeed0->addItem(tr("125000"));
ui->cbSpeed0->addItem(tr("250000"));
ui->cbSpeed0->addItem(tr("500000"));
ui->cbSpeed0->addItem(tr("1000000"));
ui->cbSpeed0->addItem(tr("33333"));
ui->cbSpeed1->addItem(tr("<Default>"));
ui->cbSpeed1->addItem(tr("Disabled"));
ui->cbSpeed1->addItem(tr("125000"));
ui->cbSpeed1->addItem(tr("250000"));
ui->cbSpeed1->addItem(tr("500000"));
ui->cbSpeed1->addItem(tr("1000000"));
ui->cbSpeed1->addItem(tr("33333"));
#ifdef Q_OS_LINUX
ui->rbSocketCAN->setEnabled(true);
#endif
#ifdef Q_OS_WIN
ui->rbKvaser->setEnabled(true);
#endif
connect(ui->btnOK, SIGNAL(clicked(bool)), this, SLOT(handleOKButton()));
connect(ui->rbGVRET, SIGNAL(toggled(bool)), this, SLOT(handleConnTypeChanged()));
connect(ui->rbKvaser, SIGNAL(toggled(bool)), this, SLOT(handleConnTypeChanged()));
connect(ui->rbSocketCAN, SIGNAL(toggled(bool)), this, SLOT(handleConnTypeChanged()));
}
ConnectionWindow::~ConnectionWindow()
{
delete settings;
delete ui;
}
void ConnectionWindow::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
qDebug() << "Show connectionwindow";
handleConnTypeChanged();
}
void ConnectionWindow::handleConnTypeChanged()
{
if (ui->rbGVRET->isChecked()) getSerialPorts();
if (ui->rbKvaser->isChecked()) getKvaserPorts();
if (ui->rbSocketCAN->isChecked()) getSocketcanPorts();
}
void ConnectionWindow::handleOKButton()
{
QString conn;
int connType = 0;
if (ui->rbGVRET->isChecked())
{
conn = "GVRET";
connType = 0;
currentConnType = ConnectionType::GVRET_SERIAL;
}
if (ui->rbKvaser->isChecked())
{
conn = "KVASER";
connType = 1;
currentConnType = ConnectionType::KVASER;
}
if (ui->rbSocketCAN->isChecked())
{
conn = "SOCKETCAN";
connType = 2;
currentConnType = ConnectionType::SOCKETCAN;
}
currentPortName = getPortName();
currentSpeed1 = getSpeed0();
currentSpeed2 = getSpeed1();
settings->setValue("Main/DefaultConnectionPort", currentPortName);
settings->setValue("Main/DefaultConnectionType", connType);
settings->setValue("Main/SingleWireMode", ui->ckSingleWire->isChecked());
emit updateConnectionSettings(conn, getPortName(), getSpeed0(), getSpeed1());
this->close();
}
void ConnectionWindow::getSerialPorts()
{
ui->cbPort->clear();
ports = QSerialPortInfo::availablePorts();
for (int i = 0; i < ports.count(); i++)
{
ui->cbPort->addItem(ports[i].portName());
if (currentPortName == ports[i].portName()) ui->cbPort->setCurrentIndex(i);
}
}
void ConnectionWindow::getKvaserPorts()
{
}
void ConnectionWindow::getSocketcanPorts()
{
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
QString interfaceName;
ui->cbPort->clear();
foreach (QNetworkInterface interface, interfaces)
{
interfaceName = interface.name().toLower();
qDebug() << "Interface: " << interface.name();
if (interfaceName.contains("can"))
{
ui->cbPort->addItem(interfaceName);
}
}
}
void ConnectionWindow::setSpeeds(int speed0, int speed1)
{
bool found = false;
qDebug() << speed0 << "X" << speed1;
for (int i = 0; i < ui->cbSpeed0->count(); i++)
{
if (ui->cbSpeed0->itemText(i).toInt() == speed0)
{
ui->cbSpeed0->setCurrentIndex(i);
found = true;
}
}
if (!found)
{
ui->cbSpeed0->addItem(QString::number(speed0));
ui->cbSpeed0->setCurrentIndex(ui->cbSpeed0->count() - 1);
}
found = false;
for (int i = 0; i < ui->cbSpeed1->count(); i++)
{
if (ui->cbSpeed1->itemText(i).toInt() == speed1)
{
ui->cbSpeed1->setCurrentIndex(i);
found = true;
}
}
if (!found)
{
ui->cbSpeed1->addItem(QString::number(speed1));
ui->cbSpeed1->setCurrentIndex(ui->cbSpeed1->count() - 1);
}
}
//-1 means leave it at whatever it booted up to. 0 means disable. Otherwise the actual rate we want.
int ConnectionWindow::getSpeed0()
{
switch (ui->cbSpeed0->currentIndex())
{
case -1:
return -1;
break;
case 0:
return -1;
break;
case 1:
return 0;
break;
default:
return (ui->cbSpeed0->currentText().toInt());
break;
}
}
int ConnectionWindow::getSpeed1()
{
switch (ui->cbSpeed1->currentIndex())
{
case -1:
return -1;
break;
case 0:
return -1;
break;
case 1:
return 0;
break;
default:
return (ui->cbSpeed1->currentText().toInt());
break;
}
}
QString ConnectionWindow::getPortName()
{
return (ui->cbPort->currentText());
}
ConnectionType::ConnectionType ConnectionWindow::getConnectionType()
{
if (ui->rbGVRET->isChecked()) return ConnectionType::GVRET_SERIAL;
if (ui->rbKvaser->isChecked()) return ConnectionType::KVASER;
if (ui->rbSocketCAN->isChecked()) return ConnectionType::SOCKETCAN;
}
void ConnectionWindow::setCAN1SWMode(bool mode)
{
ui->ckSingleWire->setChecked(mode);
}
bool ConnectionWindow::getCAN1SWMode()
{
if (ui->ckSingleWire->checkState() == Qt::Checked) return true;
return false;
}
-62
View File
@@ -1,62 +0,0 @@
#ifndef CONNECTIONWINDOW_H
#define CONNECTIONWINDOW_H
#include <QSerialPortInfo>
#include <QDialog>
#include <QDebug>
#include <QSettings>
namespace Ui {
class ConnectionWindow;
}
namespace ConnectionType
{
enum ConnectionType
{
GVRET_SERIAL,
KVASER,
SOCKETCAN
};
}
class ConnectionWindow : public QDialog
{
Q_OBJECT
public:
explicit ConnectionWindow(QWidget *parent = 0);
~ConnectionWindow();
void showEvent(QShowEvent *);
int getSpeed0();
int getSpeed1();
QString getPortName(); //name of port to connect to
ConnectionType::ConnectionType getConnectionType();
bool getCAN1SWMode();
signals:
void updateConnectionSettings(QString connectionType, QString port, int speed0, int speed1);
public slots:
void setSpeeds(int speed0, int speed1);
void setCAN1SWMode(bool mode);
private slots:
void handleOKButton();
void handleConnTypeChanged();
private:
Ui::ConnectionWindow *ui;
QList<QSerialPortInfo> ports;
QSettings *settings;
ConnectionType::ConnectionType currentConnType;
QString currentPortName;
int currentSpeed1, currentSpeed2;
void getSerialPorts();
void getKvaserPorts();
void getSocketcanPorts();
};
#endif // CONNECTIONWINDOW_H
-117
View File
@@ -1,117 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConnectionWindow</class>
<widget class="QWidget" name="ConnectionWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>335</width>
<height>235</height>
</rect>
</property>
<property name="windowTitle">
<string>Connection Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Connection Type</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QRadioButton" name="rbGVRET">
<property name="text">
<string>GVRET Serial</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbKvaser">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Kvaser</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbSocketCAN">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>SocketCAN</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Port:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cbPort"/>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>CAN0 Speed</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>CAN1 Speed</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="cbSpeed0"/>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="cbSpeed1"/>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="ckSingleWire">
<property name="text">
<string>Set CAN1 to Single Wire Mode</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnOK">
<property name="text">
<string>Update Settings</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
View File
+7 -5
View File
@@ -37,6 +37,7 @@ bool DBCSignalHandler::addSignal(DBC_SIGNAL &sig)
bool DBCSignalHandler::removeSignal(DBC_SIGNAL *sig) bool DBCSignalHandler::removeSignal(DBC_SIGNAL *sig)
{ {
Q_UNUSED(sig);
//if (sigs.removeAll(*sig) > 0) return true; //if (sigs.removeAll(*sig) > 0) return true;
return false; return false;
} }
@@ -75,7 +76,7 @@ int DBCSignalHandler::getCount()
return sigs.count(); return sigs.count();
} }
DBC_MESSAGE* DBCMessageHandler::findMsgByID(int id) DBC_MESSAGE* DBCMessageHandler::findMsgByID(uint32_t id)
{ {
if (messages.count() == 0) return NULL; if (messages.count() == 0) return NULL;
for (int i = 0; i < messages.count(); i++) for (int i = 0; i < messages.count(); i++)
@@ -117,6 +118,7 @@ bool DBCMessageHandler::addMessage(DBC_MESSAGE &msg)
bool DBCMessageHandler::removeMessage(DBC_MESSAGE *msg) bool DBCMessageHandler::removeMessage(DBC_MESSAGE *msg)
{ {
Q_UNUSED(msg);
//if (messages.removeAll(*msg) > 0) return true; //if (messages.removeAll(*msg) > 0) return true;
return false; return false;
} }
@@ -130,7 +132,7 @@ bool DBCMessageHandler::removeMessageByIndex(int idx)
return true; return true;
} }
bool DBCMessageHandler::removeMessage(int ID) bool DBCMessageHandler::removeMessage(uint32_t ID)
{ {
bool foundSome = false; bool foundSome = false;
if (messages.count() == 0) return false; if (messages.count() == 0) return false;
@@ -302,7 +304,7 @@ void DBCFile::loadFile(QString fileName)
{ {
int offset = 0; int offset = 0;
bool isMultiplexor = false; bool isMultiplexor = false;
bool isMultiplexed = false; //bool isMultiplexed = false;
DBC_SIGNAL sig; DBC_SIGNAL sig;
sig.multiplexValue = 0; sig.multiplexValue = 0;
@@ -326,7 +328,7 @@ void DBCFile::loadFile(QString fileName)
if (match.hasMatch()) if (match.hasMatch())
{ {
qDebug() << "Multiplexed signal"; qDebug() << "Multiplexed signal";
isMultiplexed = true; //isMultiplexed = true;
sig.isMultiplexed = true; sig.isMultiplexed = true;
sig.multiplexValue = match.captured(2).toInt(); sig.multiplexValue = match.captured(2).toInt();
offset = 1; offset = 1;
@@ -805,7 +807,7 @@ DBC_MESSAGE* DBCHandler::findMessage(const CANFrame &frame)
{ {
for(int i = 0; i < loadedFiles.count(); i++) for(int i = 0; i < loadedFiles.count(); i++)
{ {
if (loadedFiles[i].getAssocBus() == -1 || frame.bus == loadedFiles[i].getAssocBus()) if (loadedFiles[i].getAssocBus() == -1 || frame.bus == (unsigned int)loadedFiles[i].getAssocBus())
{ {
DBC_MESSAGE* msg = loadedFiles[i].messageHandler->findMsgByID(frame.ID); DBC_MESSAGE* msg = loadedFiles[i].messageHandler->findMsgByID(frame.ID);
if (msg != NULL) return msg; if (msg != NULL) return msg;
+2 -2
View File
@@ -32,13 +32,13 @@ class DBCMessageHandler: public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
DBC_MESSAGE *findMsgByID(int id); DBC_MESSAGE *findMsgByID(uint32_t id);
DBC_MESSAGE *findMsgByIdx(int idx); DBC_MESSAGE *findMsgByIdx(int idx);
DBC_MESSAGE *findMsgByName(QString name); DBC_MESSAGE *findMsgByName(QString name);
bool addMessage(DBC_MESSAGE &msg); bool addMessage(DBC_MESSAGE &msg);
bool removeMessage(DBC_MESSAGE *msg); bool removeMessage(DBC_MESSAGE *msg);
bool removeMessageByIndex(int idx); bool removeMessageByIndex(int idx);
bool removeMessage(int ID); bool removeMessage(uint32_t ID);
bool removeMessage(QString name); bool removeMessage(QString name);
void removeAllMessages(); void removeAllMessages();
int getCount(); int getCount();
@@ -114,6 +114,7 @@ void DBCLoadSaveWindow::cellChanged(int row, int col)
void DBCLoadSaveWindow::cellDoubleClicked(int row, int col) void DBCLoadSaveWindow::cellDoubleClicked(int row, int col)
{ {
Q_UNUSED(col)
editorWindow->setFileIdx(row); editorWindow->setFileIdx(row);
editorWindow->show(); editorWindow->show();
} }
+85 -93
View File
@@ -5,6 +5,8 @@
#include <QMessageBox> #include <QMessageBox>
#include <QSettings> #include <QSettings>
#define MT_COLUMN_COUNT 5
DBCMainEditor::DBCMainEditor(DBCHandler *handler, const QVector<CANFrame> *frames, QWidget *parent) : DBCMainEditor::DBCMainEditor(DBCHandler *handler, const QVector<CANFrame> *frames, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::DBCMainEditor) ui(new Ui::DBCMainEditor)
@@ -26,7 +28,7 @@ DBCMainEditor::DBCMainEditor(DBCHandler *handler, const QVector<CANFrame> *frame
QStringList headers2; QStringList headers2;
headers2 << "Msg ID" << "Msg Name" << "Data Len" << "Signals" << "Comment"; headers2 << "Msg ID" << "Msg Name" << "Data Len" << "Signals" << "Comment";
ui->MessagesTable->setColumnCount(5); ui->MessagesTable->setColumnCount(MT_COLUMN_COUNT);
ui->MessagesTable->setColumnWidth(0, 80); ui->MessagesTable->setColumnWidth(0, 80);
ui->MessagesTable->setColumnWidth(1, 240); ui->MessagesTable->setColumnWidth(1, 240);
ui->MessagesTable->setColumnWidth(2, 80); ui->MessagesTable->setColumnWidth(2, 80);
@@ -210,148 +212,125 @@ void DBCMainEditor::onCellChangedNode(int row,int col)
void DBCMainEditor::onCellChangedMessage(int row,int col) void DBCMainEditor::onCellChangedMessage(int row,int col)
{ {
QTableWidgetItem* item = NULL;
bool ret = false;
DBC_MESSAGE *msg = NULL;
uint msgID;
if (inhibitCellChanged) return; if (inhibitCellChanged) return;
qDebug() << "Editing row: " << row << " col: " << col;
QTableWidgetItem *replacement = NULL;
int msgID;
QString msgName;
int msgLen;
QString msgComment;
DBC_MESSAGE newMsg;
DBC_NODE *node = dbcFile->findNodeByIdx(ui->NodesTable->currentRow()); DBC_NODE *node = dbcFile->findNodeByIdx(ui->NodesTable->currentRow());
DBC_MESSAGE *msg;
if (node == NULL) if (node == NULL)
{ {
qDebug() << "No node set?!? This is bad!"; qDebug() << "No node set?!? This is bad!";
return; return;
//dbcHandler->findNodeByIdx(0);
} }
msgID = Utility::ParseStringToNum(ui->MessagesTable->item(row, 0)->text()); item = ui->MessagesTable->item(row, 0);
qDebug() << "Msg ID of edited: " << msgID; if(!item) return;
msgID = Utility::ParseStringToNum2(item->text(), &ret);
msg = dbcFile->messageHandler->findMsgByID(msgID); msg = dbcFile->messageHandler->findMsgByID(msgID);
switch(col) switch(col)
{ {
case 0: //msg id case 0: //msg id
if (row == ui->MessagesTable->rowCount() - 1) //new record
{ {
if (dbcFile->messageHandler->findMsgByID(msgID) != NULL) /* sanity checks */
if(!ret)
{
/* bad message id */
ui->MessagesTable->item(row, 0)->setText("");
return;
}
if (msg != NULL)
{ {
QMessageBox msg; QMessageBox msg;
msg.setParent(0); msg.setParent(0);
msg.setText("An existing msg with that ID already exists! Aborting!"); msg.setText("An existing msg with that ID already exists! Aborting!");
msg.exec(); msg.exec();
ui->MessagesTable->item(row, 0)->setText("");
return; return;
} }
/* insert row */
DBC_MESSAGE newMsg;
newMsg.ID = msgID; newMsg.ID = msgID;
newMsg.name = ""; newMsg.name = "";
newMsg.sender = node; newMsg.sender = node;
newMsg.len = 0; newMsg.len = 0;
for (int i = 0; i < referenceFrames->length(); i++) for (int i = 0; i < referenceFrames->length(); i++)
{ {
if (referenceFrames->at(i).ID == msgID) if ((uint) referenceFrames->at(i).ID == msgID)
{ {
newMsg.len = referenceFrames->at(i).len; newMsg.len = referenceFrames->at(i).len;
break; break;
} }
} }
dbcFile->messageHandler->addMessage(newMsg); dbcFile->messageHandler->addMessage(newMsg);
}
else //editing an existing record
{
if (msg != NULL) msg->ID = msgID;
}
inhibitCellChanged = true;
replacement = new QTableWidgetItem(Utility::formatNumber(msgID));
ui->MessagesTable->setItem(row, col, replacement);
replacement = new QTableWidgetItem(QString::number(newMsg.len));
ui->MessagesTable->setItem(row, 2, replacement);
inhibitCellChanged = false;
break;
/* insert message in table */
inhibitCellChanged = true;
item = ui->MessagesTable->item(row, 0);
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
item->setText(Utility::formatNumber(msgID));
for(int i=1 ; i<MT_COLUMN_COUNT ; i++)
{
item = ui->MessagesTable->item(row, i);
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
/* set length */
item = ui->MessagesTable->item(row, 2);
item->setText(QString::number(newMsg.len));
inhibitCellChanged = false;
/* insert a new row */
insertBlankRow();
break;
}
case 1: //msg name case 1: //msg name
msgName = ui->MessagesTable->item(row, col)->text().simplified().replace(' ', '_'); {
QString msgName = ui->MessagesTable->item(row, 1)->text().simplified().replace(' ', '_');
if (msgName.length() == 0) return; if (msgName.length() == 0) return;
if (row == ui->MessagesTable->rowCount() - 1) //new record if( ret && (msg!=NULL) )
msg->name = msgName;
break;
}
case 2: //data length
{ {
if (dbcFile->messageHandler->findMsgByName(msgName) != NULL) bool parseOk = false;
uint msgLen = ui->MessagesTable->item(row, col)->text().toUInt(&parseOk);
/* sanity checks */
if(!parseOk)
{ {
QMessageBox msg; ui->MessagesTable->item(row, col)->setText("");
msg.setParent(0);
msg.setText("An existing msg with that name already exists! Aborting!");
msg.exec();
return; return;
} }
newMsg.ID = -1; if (msgLen > 8)
newMsg.name = msgName;
newMsg.sender = node;
dbcFile->messageHandler->addMessage(newMsg);
}
else
{ {
if (msg != NULL) msg->name = msgName; msgLen = 8;
ui->MessagesTable->item(row, col)->setText(QString::number(msgLen));
} }
inhibitCellChanged = true;
replacement = new QTableWidgetItem(msgName);
ui->MessagesTable->setItem(row, col, replacement);
inhibitCellChanged = false;
break;
case 2: //data length
msgLen = ui->MessagesTable->item(row, col)->text().toInt();
if (msgLen < 0) msgLen = 0;
if (msgLen > 8) msgLen = 8;
if (row == ui->MessagesTable->rowCount() - 1) //new record
{
DBC_MESSAGE newMsg;
newMsg.ID = -1;
newMsg.name = "";
newMsg.len = msgLen;
newMsg.sender = node;
dbcFile->messageHandler->addMessage(newMsg);
}
else //editing an existing record
{
if (msg != NULL) msg->len = msgLen;
}
inhibitCellChanged = true;
replacement = new QTableWidgetItem(QString::number(msgLen, 16));
ui->MessagesTable->setItem(row, col, replacement);
inhibitCellChanged = false;
if( ret && (msg!=NULL) )
msg->len = msgLen;
break; break;
}
case 3: //signals (number) - we don't handle anything here. User cannot directly change this value case 3: //signals (number) - we don't handle anything here. User cannot directly change this value
break; break;
case 4: //comment case 4: //comment
msgComment = ui->MessagesTable->item(row, col)->text().simplified();
if (row == ui->MessagesTable->rowCount() - 1) //new record
{ {
DBC_MESSAGE newMsg; QString msgComment = ui->MessagesTable->item(row, col)->text().simplified();
newMsg.ID = -1; if( ret && (msgComment!=NULL) )
newMsg.name = ""; msg->comment = msgComment;
newMsg.len = 0;
newMsg.comment = msgComment;
newMsg.sender = node;
dbcFile->messageHandler->addMessage(newMsg);
}
else //editing an existing record
{
if (msg != NULL) msg->comment = msgComment;
}
inhibitCellChanged = true;
replacement = new QTableWidgetItem(msgComment);
ui->MessagesTable->setItem(row, col, replacement);
inhibitCellChanged = false;
break; break;
} }
if (row == ui->MessagesTable->rowCount() - 1)
{
ui->MessagesTable->insertRow(ui->MessagesTable->rowCount());
} }
ui->MessagesTable->setCurrentCell(row, col); ui->MessagesTable->setCurrentCell(row, col);
@@ -426,6 +405,7 @@ void DBCMainEditor::refreshNodesTable()
//insert a fresh entry at the bottom that contains nothing //insert a fresh entry at the bottom that contains nothing
ui->NodesTable->insertRow(ui->NodesTable->rowCount()); ui->NodesTable->insertRow(ui->NodesTable->rowCount());
ui->NodesTable->selectRow(0);
} }
void DBCMainEditor::refreshMessagesTable(const DBC_NODE *node) void DBCMainEditor::refreshMessagesTable(const DBC_NODE *node)
@@ -466,5 +446,17 @@ void DBCMainEditor::refreshMessagesTable(const DBC_NODE *node)
} }
//insert blank record that can be used to add new messages //insert blank record that can be used to add new messages
ui->MessagesTable->insertRow(ui->MessagesTable->rowCount()); insertBlankRow();
}
void DBCMainEditor::insertBlankRow()
{
int rowIdx = ui->MessagesTable->rowCount();
ui->MessagesTable->insertRow(rowIdx);
for(int i=1 ; i<MT_COLUMN_COUNT ; i++)
{
QTableWidgetItem *item = new QTableWidgetItem("");
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
ui->MessagesTable->setItem(rowIdx, i, item);
}
} }
+1
View File
@@ -46,6 +46,7 @@ private:
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
void readSettings(); void readSettings();
void writeSettings(); void writeSettings();
void insertBlankRow();
}; };
@@ -348,6 +348,10 @@ void DBCSignalEditor::addNewSignal()
void DBCSignalEditor::deleteCurrentSignal() void DBCSignalEditor::deleteCurrentSignal()
{ {
int currIdx = ui->signalsList->currentRow(); int currIdx = ui->signalsList->currentRow();
if(currIdx==ui->signalsList->count()-1)
return;
if (currIdx > -1) if (currIdx > -1)
{ {
delete(ui->signalsList->item(currIdx)); delete(ui->signalsList->item(currIdx));
-24
View File
@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DeltaWindow</class>
<widget class="QDialog" name="DeltaWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>978</width>
<height>654</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTableView" name="tableView"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+16 -12
View File
@@ -36,6 +36,7 @@ FirmwareUploaderWindow::FirmwareUploaderWindow(const QVector<CANFrame> *frames,
FirmwareUploaderWindow::~FirmwareUploaderWindow() FirmwareUploaderWindow::~FirmwareUploaderWindow()
{ {
timer->stop(); timer->stop();
CANConManager::getInstance()->removeAllTargettedFrames(this);
delete timer; delete timer;
delete ui; delete ui;
} }
@@ -47,7 +48,7 @@ void FirmwareUploaderWindow::updateProgress()
void FirmwareUploaderWindow::updatedFrames(int numFrames) void FirmwareUploaderWindow::updatedFrames(int numFrames)
{ {
CANFrame thisFrame; //CANFrame thisFrame;
if (numFrames == -1) //all frames deleted. if (numFrames == -1) //all frames deleted.
{ {
} }
@@ -66,10 +67,10 @@ void FirmwareUploaderWindow::updatedFrames(int numFrames)
} }
} }
void FirmwareUploaderWindow::gotTargettedFrame(int frameLoc) void FirmwareUploaderWindow::gotTargettedFrame(CANFrame frame)
{ {
const CANFrame &frame = modelFrames->at(frameLoc); qDebug() << "FUW: Got targetted frame with id " << frame.ID;
if (frame.ID == (baseAddress + 0x10)) { if (frame.ID == (uint32_t)(baseAddress + 0x10)) {
qDebug() << "Start firmware reply"; qDebug() << "Start firmware reply";
if ((frame.data[0] == 0xAD) && (frame.data[1] == 0xDE)) if ((frame.data[0] == 0xAD) && (frame.data[1] == 0xDE))
{ {
@@ -81,7 +82,7 @@ void FirmwareUploaderWindow::gotTargettedFrame(int frameLoc)
if ((frame.data[6] == ((token >> 16) & 0xFF)) && (frame.data[7] == ((token >> 24) & 0xFF))) if ((frame.data[6] == ((token >> 16) & 0xFF)) && (frame.data[7] == ((token >> 24) & 0xFF)))
{ {
qDebug() << "starting firmware process"; qDebug() << "starting firmware process";
MainWindow::getReference()->setTargettedID(baseAddress + 0x20); //MainWindow::getReference()->setTargettedID(baseAddress + 0x20);
transferInProgress = true; transferInProgress = true;
sendFirmwareChunk(); sendFirmwareChunk();
} }
@@ -90,7 +91,7 @@ void FirmwareUploaderWindow::gotTargettedFrame(int frameLoc)
} }
} }
if (frame.ID == (baseAddress + 0x20)) { if (frame.ID == (uint32_t)(baseAddress + 0x20)) {
qDebug() << "Firmware reception success reply"; qDebug() << "Firmware reception success reply";
int seq = frame.data[0] + (256 * frame.data[1]); int seq = frame.data[0] + (256 * frame.data[1]);
if (seq == currentSendingPosition) if (seq == currentSendingPosition)
@@ -126,6 +127,7 @@ void FirmwareUploaderWindow::sendFirmwareChunk()
int xorByte = 0; int xorByte = 0;
output->extended = false; output->extended = false;
output->len = 7; output->len = 7;
output->bus = bus;
output->ID = baseAddress + 0x16; output->ID = baseAddress + 0x16;
output->data[0] = currentSendingPosition & 0xFF; output->data[0] = currentSendingPosition & 0xFF;
output->data[1] = (currentSendingPosition >> 8) & 0xFF; output->data[1] = (currentSendingPosition >> 8) & 0xFF;
@@ -135,7 +137,7 @@ void FirmwareUploaderWindow::sendFirmwareChunk()
output->data[5] = firmwareData[firmwareLocation++]; output->data[5] = firmwareData[firmwareLocation++];
for (int i = 0; i < 6; i++) xorByte = xorByte ^ output->data[i]; for (int i = 0; i < 6; i++) xorByte = xorByte ^ output->data[i];
output->data[6] = xorByte; output->data[6] = xorByte;
sendCANFrame(output, bus); sendCANFrame(output);
timer->start(); timer->start();
} }
@@ -143,13 +145,14 @@ void FirmwareUploaderWindow::sendFirmwareEnding()
{ {
CANFrame *output = new CANFrame; CANFrame *output = new CANFrame;
output->extended = false; output->extended = false;
output->bus = bus;
output->len = 4; output->len = 4;
output->ID = baseAddress + 0x30; output->ID = baseAddress + 0x30;
output->data[3] = 0xC0; output->data[3] = 0xC0;
output->data[2] = 0xDE; output->data[2] = 0xDE;
output->data[1] = 0xFA; output->data[1] = 0xFA;
output->data[0] = 0xDE; output->data[0] = 0xDE;
sendCANFrame(output, bus); //sendCANFrame(output, bus);
} }
void FirmwareUploaderWindow::handleStartStopTransfer() void FirmwareUploaderWindow::handleStartStopTransfer()
@@ -164,10 +167,12 @@ void FirmwareUploaderWindow::handleStartStopTransfer()
bus = ui->spinBus->value(); bus = ui->spinBus->value();
baseAddress = Utility::ParseStringToNum(ui->txtBaseAddr->text()); baseAddress = Utility::ParseStringToNum(ui->txtBaseAddr->text());
qDebug() << "Base address: " + QString::number(baseAddress); qDebug() << "Base address: " + QString::number(baseAddress);
MainWindow::getReference()->setTargettedID(baseAddress + 0x10); CANConManager::getInstance()->addTargettedFrame(bus, baseAddress + 0x10, 0x7FF, this);
CANConManager::getInstance()->addTargettedFrame(bus, baseAddress + 0x20, 0x7FF, this);
CANFrame *output = new CANFrame; CANFrame *output = new CANFrame;
output->extended = false; output->extended = false;
output->len = 8; output->len = 8;
output->bus = bus;
output->ID = baseAddress; output->ID = baseAddress;
output->data[0] = 0xEF; output->data[0] = 0xEF;
@@ -178,12 +183,12 @@ void FirmwareUploaderWindow::handleStartStopTransfer()
output->data[5] = (token >> 8) & 0xFF; output->data[5] = (token >> 8) & 0xFF;
output->data[6] = (token >> 16) & 0xFF; output->data[6] = (token >> 16) & 0xFF;
output->data[7] = (token >> 24) & 0xFF; output->data[7] = (token >> 24) & 0xFF;
sendCANFrame(output, bus); sendCANFrame(output);
} }
else //stop anything in process else //stop anything in process
{ {
ui->btnStartStop->setText("Start Upload"); ui->btnStartStop->setText("Start Upload");
MainWindow::getReference()->setTargettedID(-1); CANConManager::getInstance()->removeAllTargettedFrames(this);
} }
} }
@@ -191,7 +196,6 @@ void FirmwareUploaderWindow::handleLoadFile()
{ {
QString filename; QString filename;
QFileDialog dialog; QFileDialog dialog;
bool result = false;
QStringList filters; QStringList filters;
filters.append(QString(tr("Raw firmware binary (*.bin)"))); filters.append(QString(tr("Raw firmware binary (*.bin)")));
+3 -3
View File
@@ -4,8 +4,8 @@
#include <QDialog> #include <QDialog>
#include <QTimer> #include <QTimer>
#include "can_structs.h" #include "can_structs.h"
#include "connections/canconmanager.h"
#include "utility.h" #include "utility.h"
#include "serialworker.h"
namespace Ui { namespace Ui {
class FirmwareUploaderWindow; class FirmwareUploaderWindow;
@@ -20,10 +20,10 @@ public:
~FirmwareUploaderWindow(); ~FirmwareUploaderWindow();
signals: signals:
void sendCANFrame(const CANFrame *, int); void sendCANFrame(const CANFrame *);
public slots: public slots:
void gotTargettedFrame(int frameLoc); void gotTargettedFrame(CANFrame frame);
private slots: private slots:
void handleLoadFile(); void handleLoadFile();
+31 -32
View File
@@ -246,6 +246,8 @@ bool FrameFileIO::loadVehicleSpyFile(QString filename, QVector<CANFrame> *frames
bool FrameFileIO::saveVehicleSpyFile(QString filename, const QVector<CANFrame> *frames) bool FrameFileIO::saveVehicleSpyFile(QString filename, const QVector<CANFrame> *frames)
{ {
Q_UNUSED(filename);
Q_UNUSED(frames);
return true; return true;
} }
@@ -324,7 +326,7 @@ bool FrameFileIO::loadCRTDFile(QString filename, QVector<CANFrame>* frames)
else thisFrame.isReceived = true; else thisFrame.isReceived = true;
thisFrame.bus = 0; thisFrame.bus = 0;
thisFrame.len = tokens.length() - 3; thisFrame.len = tokens.length() - 3;
for (int d = 0; d < thisFrame.len; d++) for (unsigned int d = 0; d < thisFrame.len; d++)
{ {
if (tokens[d + 3] != "") if (tokens[d + 3] != "")
{ {
@@ -381,7 +383,7 @@ bool FrameFileIO::saveCRTDFile(QString filename, const QVector<CANFrame>* frames
outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8()); outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
outFile->putChar(' '); outFile->putChar(' ');
for (int temp = 0; temp < frames->at(c).len; temp++) for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
{ {
outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8()); outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' '); outFile->putChar(' ');
@@ -440,7 +442,7 @@ bool FrameFileIO::loadPCANFile(QString filename, QVector<CANFrame>* frames)
thisFrame.bus = 0; thisFrame.bus = 0;
thisFrame.extended = false; thisFrame.extended = false;
QList<QByteArray> tokens = line.mid(41, thisFrame.len * 3).split(' '); QList<QByteArray> tokens = line.mid(41, thisFrame.len * 3).split(' ');
for (int d = 0; d < thisFrame.len; d++) for (unsigned int d = 0; d < thisFrame.len; d++)
{ {
if (tokens[d] != "") if (tokens[d] != "")
{ {
@@ -512,9 +514,9 @@ bool FrameFileIO::loadNativeCSVFile(QString filename, QVector<CANFrame>* frames)
{ {
thisFrame.isReceived = true; thisFrame.isReceived = true;
thisFrame.bus = tokens[3].toInt(); thisFrame.bus = tokens[3].toInt();
thisFrame.len = tokens[4].toInt(); thisFrame.len = tokens[4].toUInt();
for (int c = 0; c < 8; c++) thisFrame.data[c] = 0; for (int c = 0; c < 8; c++) thisFrame.data[c] = 0;
for (int d = 0; d < thisFrame.len; d++) for (unsigned int d = 0; d < thisFrame.len; d++)
thisFrame.data[d] = tokens[5 + d].toInt(NULL, 16); thisFrame.data[d] = tokens[5 + d].toInt(NULL, 16);
} }
else if (fileVersion == 2) else if (fileVersion == 2)
@@ -522,10 +524,10 @@ bool FrameFileIO::loadNativeCSVFile(QString filename, QVector<CANFrame>* frames)
if (tokens[3].at(0) == 'R') thisFrame.isReceived = true; if (tokens[3].at(0) == 'R') thisFrame.isReceived = true;
else thisFrame.isReceived = false; else thisFrame.isReceived = false;
thisFrame.bus = tokens[4].toInt(); thisFrame.bus = tokens[4].toInt();
thisFrame.len = tokens[5].toInt(); thisFrame.len = tokens[5].toUInt();
if (thisFrame.len + 6 > tokens.length()) thisFrame.len = tokens.length() - 6; if (thisFrame.len + 6 > (unsigned int) tokens.length()) thisFrame.len = tokens.length() - 6;
for (int c = 0; c < 8; c++) thisFrame.data[c] = 0; for (int c = 0; c < 8; c++) thisFrame.data[c] = 0;
for (int d = 0; d < thisFrame.len; d++) for (unsigned int d = 0; d < thisFrame.len; d++)
thisFrame.data[d] = tokens[6 + d].toInt(NULL, 16); thisFrame.data[d] = tokens[6 + d].toInt(NULL, 16);
} }
@@ -580,7 +582,7 @@ bool FrameFileIO::saveNativeCSVFile(QString filename, const QVector<CANFrame>* f
outFile->write(QString::number(frames->at(c).len).toUtf8()); outFile->write(QString::number(frames->at(c).len).toUtf8());
outFile->putChar(44); outFile->putChar(44);
for (int temp = 0; temp < 8; temp++) for (unsigned int temp = 0; temp < 8; temp++)
{ {
if (temp < frames->at(c).len) if (temp < frames->at(c).len)
outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8()); outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
@@ -636,7 +638,7 @@ bool FrameFileIO::loadGenericCSVFile(QString filename, QVector<CANFrame>* frames
QList<QByteArray> dataTok = tokens[1].split(' '); QList<QByteArray> dataTok = tokens[1].split(' ');
thisFrame.len = dataTok.length(); thisFrame.len = dataTok.length();
if (thisFrame.len > 8) thisFrame.len = 8; if (thisFrame.len > 8) thisFrame.len = 8;
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = dataTok[d].toInt(NULL, 16); for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = dataTok[d].toInt(NULL, 16);
frames->append(thisFrame); frames->append(thisFrame);
} }
@@ -674,7 +676,7 @@ bool FrameFileIO::saveGenericCSVFile(QString filename, const QVector<CANFrame>*
outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8()); outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
outFile->putChar(44); outFile->putChar(44);
for (int temp = 0; temp < frames->at(c).len; temp++) for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
{ {
outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8()); outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' '); outFile->putChar(' ');
@@ -762,10 +764,9 @@ bool FrameFileIO::loadLogFile(QString filename, QVector<CANFrame>* frames)
if (tokens[4] == "s") thisFrame.extended = false; if (tokens[4] == "s") thisFrame.extended = false;
else thisFrame.extended = true; else thisFrame.extended = true;
thisFrame.bus = tokens[2].toInt() - 1; thisFrame.bus = tokens[2].toInt() - 1;
thisFrame.len = tokens[5].toInt(); thisFrame.len = tokens[5].toUInt();
if (thisFrame.len > 8) thisFrame.len = 8; if (thisFrame.len > 8) thisFrame.len = 8;
if (thisFrame.len < 0) thisFrame.len = 0; for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = tokens[d + 6].toInt(NULL, 16);
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = tokens[d + 6].toInt(NULL, 16);
frames->append(thisFrame); frames->append(thisFrame);
} }
else foundErrors = true; else foundErrors = true;
@@ -825,7 +826,7 @@ bool FrameFileIO::saveLogFile(QString filename, const QVector<CANFrame>* frames)
else outFile->write(" s "); else outFile->write(" s ");
outFile->write(QString::number(frames->at(c).len).toUtf8() + " "); outFile->write(QString::number(frames->at(c).len).toUtf8() + " ");
for (int temp = 0; temp < frames->at(c).len; temp++) for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
{ {
outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8()); outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' '); outFile->putChar(' ');
@@ -902,7 +903,7 @@ bool FrameFileIO::loadIXXATFile(QString filename, QVector<CANFrame>* frames)
QStringList dataToks = unQuote(tokens[4]).simplified().split(' '); QStringList dataToks = unQuote(tokens[4]).simplified().split(' ');
thisFrame.len = dataToks.length(); thisFrame.len = dataToks.length();
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = dataToks[d].toInt(NULL, 16); for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = dataToks[d].toInt(NULL, 16);
frames->append(thisFrame); frames->append(thisFrame);
} }
else foundErrors = true; else foundErrors = true;
@@ -955,7 +956,7 @@ bool FrameFileIO::saveIXXATFile(QString filename, const QVector<CANFrame>* frame
else outFile->write(",\"Std\""); else outFile->write(",\"Std\"");
outFile->write(",\"\",\""); outFile->write(",\"\",\"");
for (int temp = 0; temp < frames->at(c).len; temp++) for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
{ {
outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8()); outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' '); outFile->putChar(' ');
@@ -1018,7 +1019,7 @@ bool FrameFileIO::loadCANDOFile(QString filename, QVector<CANFrame>* frames)
if (thisFrame.len <= 8 && thisFrame.ID <= 0x7FF) if (thisFrame.len <= 8 && thisFrame.ID <= 0x7FF)
{ {
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)data[4 + d]; for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)data[4 + d];
frames->append(thisFrame); frames->append(thisFrame);
} }
else foundErrors = true; else foundErrors = true;
@@ -1050,8 +1051,8 @@ bool FrameFileIO::saveCANDOFile(QString filename, const QVector<CANFrame>* frame
ms = (thisFrame.timestamp / 1000); ms = (thisFrame.timestamp / 1000);
data[0] = (((ms / 1000) % 60) << 2) + ((ms % 1000) >> 8); data[0] = (((ms / 1000) % 60) << 2) + ((ms % 1000) >> 8);
data[1] = (char)(ms & 0xFF); data[1] = (char)(ms & 0xFF);
data[2] = 0xFF; data[2] = (char)0xFF;
data[3] = 0xFF; data[3] = (char)0xFF;
for (int l = 0; l < 8; l++) data[4 + l] = 0; for (int l = 0; l < 8; l++) data[4 + l] = 0;
outFile->write(data); outFile->write(data);
@@ -1063,7 +1064,7 @@ bool FrameFileIO::saveCANDOFile(QString filename, const QVector<CANFrame>* frame
qApp->processEvents(); qApp->processEvents();
lineCounter = 0; lineCounter = 0;
} }
for (int j = 0; j < 8; j++) data[4 + j] = 0xFF; for (int j = 0; j < 8; j++) data[4 + j] = (char)0xFF;
thisFrame = frames->at(c); thisFrame = frames->at(c);
if (!thisFrame.extended) if (!thisFrame.extended)
@@ -1074,7 +1075,7 @@ bool FrameFileIO::saveCANDOFile(QString filename, const QVector<CANFrame>* frame
data[1] = (char)(ms & 0xFF); data[1] = (char)(ms & 0xFF);
data[2] = (char)(id & 0xFF); data[2] = (char)(id & 0xFF);
data[3] = (char)((id >> 8) + (thisFrame.len << 4)); data[3] = (char)((id >> 8) + (thisFrame.len << 4));
for (int d = 0; d < thisFrame.len; d++) data[4 + d] = (char)thisFrame.data[d]; for (unsigned int d = 0; d < thisFrame.len; d++) data[4 + d] = (char)thisFrame.data[d];
outFile->write(data); outFile->write(data);
} }
} }
@@ -1140,11 +1141,10 @@ bool FrameFileIO::loadMicrochipFile(QString filename, QVector<CANFrame>* frames)
if (thisFrame.ID <= 0x7FF) thisFrame.extended = false; if (thisFrame.ID <= 0x7FF) thisFrame.extended = false;
else thisFrame.extended = true; else thisFrame.extended = true;
thisFrame.bus = 0; thisFrame.bus = 0;
thisFrame.len = tokens[3].toInt(); thisFrame.len = tokens[3].toUInt();
if (thisFrame.len > 8) thisFrame.len = 8; if (thisFrame.len > 8) thisFrame.len = 8;
if (thisFrame.len < 0) thisFrame.len = 0; if (thisFrame.len + 4 > (unsigned int) tokens.length()) thisFrame.len = tokens.length() - 4;
if (thisFrame.len + 4 > tokens.length()) thisFrame.len = tokens.length() - 4; for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)Utility::ParseStringToNum(tokens[4 + d]);
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)Utility::ParseStringToNum(tokens[4 + d]);
frames->append(thisFrame); frames->append(thisFrame);
} }
else foundErrors = true; else foundErrors = true;
@@ -1206,7 +1206,7 @@ bool FrameFileIO::saveMicrochipFile(QString filename, const QVector<CANFrame>* f
outFile->write("0x" + QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8() + ";"); outFile->write("0x" + QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8() + ";");
outFile->write(QString::number(frames->at(c).len).toUtf8() + ";"); outFile->write(QString::number(frames->at(c).len).toUtf8() + ";");
for (int temp = 0; temp < frames->at(c).len; temp++) for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
{ {
outFile->write("0x" + QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8()); outFile->write("0x" + QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(';'); outFile->putChar(';');
@@ -1299,12 +1299,11 @@ bool FrameFileIO::loadTraceFile(QString filename, QVector<CANFrame>* frames)
if (thisFrame.ID <= 0x7FF) thisFrame.extended = false; if (thisFrame.ID <= 0x7FF) thisFrame.extended = false;
else thisFrame.extended = true; else thisFrame.extended = true;
thisFrame.bus = 0; thisFrame.bus = 0;
thisFrame.len = tokens[3].toInt(); thisFrame.len = tokens[3].toUInt();
if (thisFrame.len < 0) thisFrame.len = 0;
if (thisFrame.len > 8) thisFrame.len = 8; if (thisFrame.len > 8) thisFrame.len = 8;
QList<QByteArray> dataToks = tokens[4].split(' '); QList<QByteArray> dataToks = tokens[4].split(' ');
if (thisFrame.len > dataToks.length()) thisFrame.len = dataToks.length(); if (thisFrame.len > (unsigned int) dataToks.length()) thisFrame.len = (unsigned int) dataToks.length();
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)dataToks[d].toInt(NULL, 16); for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)dataToks[d].toInt(NULL, 16);
frames->append(thisFrame); frames->append(thisFrame);
} }
else foundErrors = true; else foundErrors = true;
@@ -1391,7 +1390,7 @@ bool FrameFileIO::saveTraceFile(QString filename, const QVector<CANFrame> * fram
outFile->write(QString::number(frames->at(c).len).toUtf8() + "\t"); outFile->write(QString::number(frames->at(c).len).toUtf8() + "\t");
for (int temp = 0; temp < frames->at(c).len; temp++) for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
{ {
outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8()); outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' '); outFile->putChar(' ');
+8 -2
View File
@@ -22,6 +22,14 @@ class FrameFileIO: public QObject
public: public:
FrameFileIO(); FrameFileIO();
//these present a GUI to the user and allow them to pick the file to load/save
//The QString returns the filename that was selected and so is really a sort of return value
//The QVector is used as either the target for loading or the source for saving.
//These routines call the below loading/saving functions so no need to use them directly if you don't want.
static bool loadFrameFile(QString &, QVector<CANFrame>*);
static bool saveFrameFile(QString &, const QVector<CANFrame>*);
//These do the actual loading and saving and can be used directly if you'd prefer
static bool loadCRTDFile(QString, QVector<CANFrame>*); static bool loadCRTDFile(QString, QVector<CANFrame>*);
static bool loadNativeCSVFile(QString, QVector<CANFrame>*); static bool loadNativeCSVFile(QString, QVector<CANFrame>*);
static bool loadGenericCSVFile(QString, QVector<CANFrame>*); static bool loadGenericCSVFile(QString, QVector<CANFrame>*);
@@ -40,8 +48,6 @@ public:
static bool saveIXXATFile(QString, const QVector<CANFrame>*); static bool saveIXXATFile(QString, const QVector<CANFrame>*);
static bool saveCANDOFile(QString, const QVector<CANFrame>*); static bool saveCANDOFile(QString, const QVector<CANFrame>*);
static bool saveVehicleSpyFile(QString, const QVector<CANFrame>*); static bool saveVehicleSpyFile(QString, const QVector<CANFrame>*);
static bool loadFrameFile(QString &, QVector<CANFrame>*);
static bool saveFrameFile(QString &, const QVector<CANFrame>*);
static bool loadCanDumpFile(QString, QVector<CANFrame>*); static bool loadCanDumpFile(QString, QVector<CANFrame>*);
static bool loadPCANFile(QString, QVector<CANFrame>*); static bool loadPCANFile(QString, QVector<CANFrame>*);
+24 -29
View File
@@ -4,6 +4,7 @@
#include <QFileDialog> #include <QFileDialog>
#include <QMenu> #include <QMenu>
#include <QSettings> #include <QSettings>
#include "connections/canconmanager.h"
/* /*
* Notes about new functionality: * Notes about new functionality:
@@ -18,22 +19,21 @@
* *
*/ */
FramePlaybackWindow::FramePlaybackWindow(const QVector<CANFrame> *frames, SerialWorker *worker, QWidget *parent) : FramePlaybackWindow::FramePlaybackWindow(const QVector<CANFrame> *frames, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::FramePlaybackWindow) ui(new Ui::FramePlaybackWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->comboCANBus->addItem(tr("None"));
ui->comboCANBus->addItem(tr("0")); int numBuses = CANConManager::getInstance()->getNumBuses();
ui->comboCANBus->addItem(tr("1")); for (int n = 0; n < numBuses; n++) ui->comboCANBus->addItem(QString::number(n));
ui->comboCANBus->addItem(tr("Both")); ui->comboCANBus->addItem(tr("All"));
ui->comboCANBus->addItem(tr("From File")); ui->comboCANBus->addItem(tr("From File"));
readSettings(); readSettings();
modelFrames = frames; modelFrames = frames;
serialWorker = worker;
playbackTimer = new QTimer(); playbackTimer = new QTimer();
@@ -70,9 +70,6 @@ FramePlaybackWindow::FramePlaybackWindow(const QVector<CANFrame> *frames, Serial
playbackTimer->setInterval(ui->spinPlaySpeed->value()); //set the timer to the default value of the control playbackTimer->setInterval(ui->spinPlaySpeed->value()); //set the timer to the default value of the control
connect(this, SIGNAL(sendCANFrame(const CANFrame*,int)), worker, SLOT(sendFrame(const CANFrame*,int)), Qt::QueuedConnection);
connect(this, SIGNAL(sendFrameBatch(const QList<CANFrame>*)), worker, SLOT(sendFrameBatch(const QList<CANFrame>*)), Qt::QueuedConnection);
QStringList headers; QStringList headers;
headers << "Source" << "Loops"; headers << "Source" << "Loops";
ui->tblSequence->setColumnCount(2); ui->tblSequence->setColumnCount(2);
@@ -85,8 +82,6 @@ FramePlaybackWindow::~FramePlaybackWindow()
{ {
delete ui; delete ui;
disconnect(serialWorker);
playbackTimer->stop(); playbackTimer->stop();
delete playbackTimer; delete playbackTimer;
} }
@@ -405,7 +400,7 @@ void FramePlaybackWindow::btnBackOneClick()
playbackActive = false; playbackActive = false;
updatePosition(false); updatePosition(false);
emit sendFrameBatch(&sendingBuffer); CANConManager::getInstance()->sendFrames(sendingBuffer);
} }
void FramePlaybackWindow::btnPauseClick() void FramePlaybackWindow::btnPauseClick()
@@ -456,7 +451,7 @@ void FramePlaybackWindow::btnFwdOneClick()
playbackTimer->stop(); playbackTimer->stop();
playbackActive = false; playbackActive = false;
updatePosition(true); updatePosition(true);
emit sendFrameBatch(&sendingBuffer); CANConManager::getInstance()->sendFrames(sendingBuffer);
} }
void FramePlaybackWindow::changePlaybackSpeed(int newSpeed) void FramePlaybackWindow::changePlaybackSpeed(int newSpeed)
@@ -471,8 +466,6 @@ void FramePlaybackWindow::changeLooping(bool check)
void FramePlaybackWindow::changeSendingBus(int newIdx) void FramePlaybackWindow::changeSendingBus(int newIdx)
{ {
//falls out neatly this way. 0 = no sending, 1 = bus 0, 2 = bus 1, 3 = both, 4 = from file
//the index is exactly the same as the whichSendBus bitfield.
whichBusSend = newIdx; whichBusSend = newIdx;
} }
@@ -522,7 +515,7 @@ void FramePlaybackWindow::timerTriggered()
updatePosition(false); updatePosition(false);
} }
} }
emit sendFrameBatch(&sendingBuffer); CANConManager::getInstance()->sendFrames(sendingBuffer);
} }
void FramePlaybackWindow::updatePosition(bool forward) void FramePlaybackWindow::updatePosition(bool forward)
@@ -596,23 +589,25 @@ void FramePlaybackWindow::updatePosition(bool forward)
int originalBus = thisFrame->bus; int originalBus = thisFrame->bus;
if (currentSeqItem->idFilters.find(thisFrame->ID).value()) if (currentSeqItem->idFilters.find(thisFrame->ID).value())
{ {
//index 0 is none, 1 is Bus 0, 2 is bus 1, 3 is both, 4 is from file if (whichBusSend < ui->comboCANBus->count() - 2)
if (whichBusSend & 4) {
thisFrame->bus = whichBusSend;
sendingBuffer.append(*thisFrame);
}
else if (whichBusSend == (ui->comboCANBus->count() - 2)) //all
{
for (int c = 0; c < ui->comboCANBus->count() - 2; c++)
{
thisFrame->bus = c;
sendingBuffer.append(*thisFrame);
}
}
else //from file so retain original bus and send as-is
{ {
sendingBuffer.append(*thisFrame); sendingBuffer.append(*thisFrame);
} }
if (whichBusSend & 1)
{
thisFrame->bus = 0;
sendingBuffer.append(*thisFrame);
}
if (whichBusSend & 2)
{
thisFrame->bus = 1;
sendingBuffer.append(*thisFrame);
}
thisFrame->bus = originalBus; thisFrame->bus = originalBus;
updateFrameLabel(); updateFrameLabel();
} }
} }
+1 -7
View File
@@ -5,7 +5,6 @@
#include <QListWidget> #include <QListWidget>
#include <QTimer> #include <QTimer>
#include "can_structs.h" #include "can_structs.h"
#include "serialworker.h"
#include "framefileio.h" #include "framefileio.h"
namespace Ui { namespace Ui {
@@ -27,7 +26,7 @@ class FramePlaybackWindow : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit FramePlaybackWindow(const QVector<CANFrame> *frames, SerialWorker *worker, QWidget *parent = 0); explicit FramePlaybackWindow(const QVector<CANFrame> *frames, QWidget *parent = 0);
~FramePlaybackWindow(); ~FramePlaybackWindow();
private slots: private slots:
@@ -53,10 +52,6 @@ private slots:
void saveFilters(); void saveFilters();
void loadFilters(); void loadFilters();
signals:
void sendCANFrame(const CANFrame *, int);
void sendFrameBatch(const QList<CANFrame> *);
private: private:
Ui::FramePlaybackWindow *ui; Ui::FramePlaybackWindow *ui;
QList<int> foundID; QList<int> foundID;
@@ -65,7 +60,6 @@ private:
const QVector<CANFrame> *modelFrames; const QVector<CANFrame> *modelFrames;
int currentPosition; int currentPosition;
QTimer *playbackTimer; QTimer *playbackTimer;
SerialWorker *serialWorker;
bool playbackActive; bool playbackActive;
bool playbackForward; bool playbackForward;
int whichBusSend; int whichBusSend;
+8 -8
View File
@@ -5,6 +5,7 @@
#include <QFileDialog> #include <QFileDialog>
#include <QDebug> #include <QDebug>
#include "mainwindow.h" #include "mainwindow.h"
#include "connections/canconmanager.h"
/* /*
* notes: need to ensure that you grab pointers when modifying data structures and dont * notes: need to ensure that you grab pointers when modifying data structures and dont
@@ -139,9 +140,9 @@ void FrameSenderWindow::processIncomingFrame(CANFrame *frame)
Trigger *thisTrigger = &sendingData[sd].triggers[trig]; Trigger *thisTrigger = &sendingData[sd].triggers[trig];
qDebug() << "Trigger ID: " << thisTrigger->ID; qDebug() << "Trigger ID: " << thisTrigger->ID;
qDebug() << "Frame ID: " << frame->ID; qDebug() << "Frame ID: " << frame->ID;
if (thisTrigger->ID > 0 && thisTrigger->ID == frame->ID) if (thisTrigger->ID > 0 && (uint32_t)thisTrigger->ID == frame->ID)
{ {
if (thisTrigger->bus == frame->bus || thisTrigger->bus == -1) if ((uint32_t)thisTrigger->bus == frame->bus || thisTrigger->bus == -1)
{ {
if (thisTrigger->currCount < thisTrigger->maxCount) if (thisTrigger->currCount < thisTrigger->maxCount)
{ {
@@ -151,7 +152,7 @@ void FrameSenderWindow::processIncomingFrame(CANFrame *frame)
sendingData[sd].count++; sendingData[sd].count++;
doModifiers(sd); doModifiers(sd);
updateGridRow(sd); updateGridRow(sd);
sendCANFrame(&sendingData[sd], sendingData[sd].bus); CANConManager::getInstance()->sendFrame(sendingData[sd]);
} }
else //delayed sending frame else //delayed sending frame
{ {
@@ -354,7 +355,7 @@ void FrameSenderWindow::handleTick()
doModifiers(i); doModifiers(i);
updateGridRow(i); updateGridRow(i);
qDebug() << "About to try to send a frame"; qDebug() << "About to try to send a frame";
emit sendCANFrame(&sendingData[i], sendingData[i].bus); CANConManager::getInstance()->sendFrame(sendingData[i]);
if (trigger->ID > 0) trigger->readyCount = false; //reset flag if this is a timed ID trigger if (trigger->ID > 0) trigger->readyCount = false; //reset flag if this is a timed ID trigger
} }
} }
@@ -457,7 +458,7 @@ CANFrame* FrameSenderWindow::lookupFrame(int ID, int bus)
{ {
if (!frameCache.contains(ID)) return NULL; if (!frameCache.contains(ID)) return NULL;
if (bus == -1 || frameCache[ID].bus == bus) return &frameCache[ID]; if (bus == -1 || frameCache[ID].bus == (unsigned int)bus) return &frameCache[ID];
return NULL; return NULL;
} }
@@ -471,7 +472,7 @@ void FrameSenderWindow::processModifierText(int line)
{ {
qDebug() << "processModifierText"; qDebug() << "processModifierText";
QString modString; QString modString;
bool firstOp = true; //bool firstOp = true;
bool abort = false; bool abort = false;
QString token; QString token;
ModifierOp thisOp; ModifierOp thisOp;
@@ -495,7 +496,6 @@ void FrameSenderWindow::processModifierText(int line)
{ {
Modifier thisMod; Modifier thisMod;
thisMod.destByte = 0; thisMod.destByte = 0;
firstOp = true;
QString leftSide = Utility::grabAlphaNumeric(mods[i]); QString leftSide = Utility::grabAlphaNumeric(mods[i]);
if (leftSide.startsWith("D") && leftSide.length() == 2) if (leftSide.startsWith("D") && leftSide.length() == 2)
@@ -701,7 +701,7 @@ void FrameSenderWindow::updateGridRow(int idx)
QTableWidgetItem *item = ui->tableSender->item(gridLine, 7); QTableWidgetItem *item = ui->tableSender->item(gridLine, 7);
if (item == NULL) item = new QTableWidgetItem(); if (item == NULL) item = new QTableWidgetItem();
item->setText(QString::number(temp->count)); item->setText(QString::number(temp->count));
for (int i = 0; i < temp->len; i++) for (unsigned int i = 0; i < temp->len; i++)
{ {
dataString.append(Utility::formatNumber(temp->data[i])); dataString.append(Utility::formatNumber(temp->data[i]));
dataString.append(" "); dataString.append(" ");
-3
View File
@@ -30,9 +30,6 @@ private slots:
void loadGrid(); void loadGrid();
void updatedFrames(int); void updatedFrames(int);
signals:
void sendCANFrame(const CANFrame *, int);
private: private:
Ui::FrameSenderWindow *ui; Ui::FrameSenderWindow *ui;
QList<FrameSendData> sendingData; QList<FrameSendData> sendingData;
+79 -175
View File
@@ -4,9 +4,8 @@
#include <QDateTime> #include <QDateTime>
#include <QFileDialog> #include <QFileDialog>
#include <QtSerialPort/QSerialPortInfo> #include <QtSerialPort/QSerialPortInfo>
#include "canframemodel.h" #include "connections/canconmanager.h"
#include "utility.h" #include "utility.h"
#include "serialworker.h"
/* /*
Compile for all platforms and create release (remember to include QScintilla libs) and make Win32 binary. Compile for all platforms and create release (remember to include QScintilla libs) and make Win32 binary.
@@ -47,7 +46,8 @@ MainWindow::MainWindow(QWidget *parent) :
this->setWindowTitle("Savvy CAN V" + QString::number(VERSION)); this->setWindowTitle("Savvy CAN V" + QString::number(VERSION));
model = new CANFrameModel(); model = new CANFrameModel(this); // set parent to mainwindow to prevent canframemodel to change thread (might be done by setModel but just in case)
ui->canFramesView->setModel(model); ui->canFramesView->setModel(model);
readSettings(); readSettings();
@@ -61,26 +61,6 @@ MainWindow::MainWindow(QWidget *parent) :
ui->canFramesView->setColumnWidth(6, 275); ui->canFramesView->setColumnWidth(6, 275);
QHeaderView *HorzHdr = ui->canFramesView->horizontalHeader(); QHeaderView *HorzHdr = ui->canFramesView->horizontalHeader();
HorzHdr->setStretchLastSection(true); //causes the data column to automatically fill the tableview HorzHdr->setStretchLastSection(true); //causes the data column to automatically fill the tableview
//enabling the below line kills performance in every way imaginable. Left here as a warning. Do not do this.
//ui->canFramesView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
worker = new SerialWorker(model);
worker->moveToThread(&serialWorkerThread);
connect(&serialWorkerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(&serialWorkerThread, &QThread::started, worker, &SerialWorker::run); //setup timers within the proper thread
connect(this, &MainWindow::sendSerialPort, worker, &SerialWorker::setSerialPort, Qt::QueuedConnection);
connect(worker, &SerialWorker::frameUpdateRapid, this, &MainWindow::gotFrames, Qt::QueuedConnection);
connect(this, &MainWindow::updateBaudRates, worker, &SerialWorker::updateBaudRates, Qt::QueuedConnection);
connect(this, &MainWindow::sendCANFrame, worker, &SerialWorker::sendFrame, Qt::QueuedConnection);
connect(worker, &SerialWorker::connectionSuccess, this, &MainWindow::connectionSucceeded, Qt::QueuedConnection);
connect(worker, &SerialWorker::connectionFailure, this, &MainWindow::connectionFailed, Qt::QueuedConnection);
connect(worker, &SerialWorker::deviceInfo, this, &MainWindow::gotDeviceInfo, Qt::QueuedConnection);
connect(this, &MainWindow::closeSerialPort, worker, &SerialWorker::closeSerialPort, Qt::QueuedConnection);
connect(this, &MainWindow::startFrameCapturing, worker, &SerialWorker::startFrameCapture);
connect(this, &MainWindow::stopFrameCapturing, worker, &SerialWorker::stopFrameCapture);
connect(this, &MainWindow::settingsUpdated, worker, &SerialWorker::readSettings);
serialWorkerThread.start();
serialWorkerThread.setPriority(QThread::HighPriority);
graphingWindow = NULL; graphingWindow = NULL;
frameInfoWindow = NULL; frameInfoWindow = NULL;
@@ -100,6 +80,8 @@ MainWindow::MainWindow(QWidget *parent) :
udsScanWindow = NULL; udsScanWindow = NULL;
motorctrlConfigWindow = NULL; motorctrlConfigWindow = NULL;
isoWindow = NULL; isoWindow = NULL;
snifferWindow = NULL;
bisectWindow = NULL;
dbcHandler = new DBCHandler; dbcHandler = new DBCHandler;
bDirty = false; bDirty = false;
inhibitFilterUpdate = false; inhibitFilterUpdate = false;
@@ -109,7 +91,6 @@ MainWindow::MainWindow(QWidget *parent) :
model->setDBCHandler(dbcHandler); model->setDBCHandler(dbcHandler);
connect(ui->actionSetup, SIGNAL(triggered(bool)), SLOT(showConnectionSettingsWindow())); connect(ui->actionSetup, SIGNAL(triggered(bool)), SLOT(showConnectionSettingsWindow()));
connect(ui->actionConnect, SIGNAL(triggered(bool)), this, SLOT(connButtonPress()));
connect(ui->actionOpen_Log_File, &QAction::triggered, this, &MainWindow::handleLoadFile); connect(ui->actionOpen_Log_File, &QAction::triggered, this, &MainWindow::handleLoadFile);
connect(ui->actionGraph_Dta, &QAction::triggered, this, &MainWindow::showGraphingWindow); connect(ui->actionGraph_Dta, &QAction::triggered, this, &MainWindow::showGraphingWindow);
connect(ui->actionFrame_Data_Analysis, &QAction::triggered, this, &MainWindow::showFrameDataAnalysis); connect(ui->actionFrame_Data_Analysis, &QAction::triggered, this, &MainWindow::showFrameDataAnalysis);
@@ -144,9 +125,13 @@ MainWindow::MainWindow(QWidget *parent) :
connect(ui->actionFuzzing, &QAction::triggered, this, &MainWindow::showFuzzingWindow); connect(ui->actionFuzzing, &QAction::triggered, this, &MainWindow::showFuzzingWindow);
connect(ui->actionUDS_Scanner, &QAction::triggered, this, &MainWindow::showUDSScanWindow); connect(ui->actionUDS_Scanner, &QAction::triggered, this, &MainWindow::showUDSScanWindow);
connect(ui->actionISO_TP_Decoder, &QAction::triggered, this, &MainWindow::showISOInterpreterWindow); connect(ui->actionISO_TP_Decoder, &QAction::triggered, this, &MainWindow::showISOInterpreterWindow);
connect(ui->actionSniffer, &QAction::triggered, this, &MainWindow::showSnifferWindow);
connect(ui->actionMotorControlConfig, &QAction::triggered, this, &MainWindow::showMCConfigWindow); connect(ui->actionMotorControlConfig, &QAction::triggered, this, &MainWindow::showMCConfigWindow);
connect(ui->actionCapture_Bisector, &QAction::triggered, this, &MainWindow::showBisectWindow);
lbStatusConnected.setText(tr("Not connected")); connect(CANConManager::getInstance(), &CANConManager::framesReceived, model, &CANFrameModel::addFrames);
lbStatusConnected.setText(tr("Connected to 0 buses"));
updateFileStatus(); updateFileStatus();
lbStatusDatabase.setText(tr("No DBC database loaded")); lbStatusDatabase.setText(tr("No DBC database loaded"));
ui->statusBar->addWidget(&lbStatusConnected); ui->statusBar->addWidget(&lbStatusConnected);
@@ -157,7 +142,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui->lbNumFrames->setText("0"); ui->lbNumFrames->setText("0");
connect(&updateTimer, &QTimer::timeout, this, &MainWindow::tickGUIUpdate); connect(&updateTimer, &QTimer::timeout, this, &MainWindow::tickGUIUpdate);
updateTimer.setInterval(250); updateTimer.setInterval(500); //test 250);
updateTimer.start(); updateTimer.start();
elapsedTime = new QTime; elapsedTime = new QTime;
@@ -178,15 +163,19 @@ MainWindow::MainWindow(QWidget *parent) :
qDebug() << "normal row height = " << normalRowHeight; qDebug() << "normal row height = " << normalRowHeight;
model->clearFrames(); model->clearFrames();
//connect(CANConManager::getInstance(), CANConManager::connectionStatusUpdated, this, MainWindow::connectionStatusUpdated);
connect(CANConManager::getInstance(), SIGNAL(connectionStatusUpdated(int)), this, SLOT(connectionStatusUpdated(int)));
//Automatically create the connection window so it can be updated even if we never opened it. //Automatically create the connection window so it can be updated even if we never opened it.
connectionWindow = new ConnectionWindow(); connectionWindow = new ConnectionWindow();
connect(connectionWindow, SIGNAL(updateConnectionSettings(QString,QString,int,int)), this, SLOT(updateConnectionSettings(QString,QString,int,int))); connect(this, SIGNAL(suspendCapturing(bool)), connectionWindow, SLOT(setSuspendAll(bool)));
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
serialWorkerThread.quit(); //serialWorkerThread.quit();
serialWorkerThread.wait(); //serialWorkerThread.wait();
//delete worker; //delete worker;
if (graphingWindow) if (graphingWindow)
@@ -284,13 +273,24 @@ MainWindow::~MainWindow()
isoWindow->close(); isoWindow->close();
delete isoWindow; delete isoWindow;
} }
if (snifferWindow)
{
snifferWindow->close();
delete snifferWindow;
snifferWindow = NULL;
}
delete elapsedTime; if (bisectWindow)
{
bisectWindow->close();
delete bisectWindow;
bisectWindow = NULL;
}
delete ui;
delete dbcHandler;
model->clearFrames();
delete model; delete model;
delete elapsedTime;
delete dbcHandler;
delete ui;
} }
void MainWindow::exitApp() void MainWindow::exitApp()
@@ -311,6 +311,7 @@ void MainWindow::exitApp()
if (fuzzingWindow) fuzzingWindow->close(); if (fuzzingWindow) fuzzingWindow->close();
if (udsScanWindow) udsScanWindow->close(); if (udsScanWindow) udsScanWindow->close();
if (isoWindow) isoWindow->close(); if (isoWindow) isoWindow->close();
if (snifferWindow) snifferWindow->close();
this->close(); this->close();
} }
@@ -340,16 +341,16 @@ void MainWindow::readSettings()
ui->cbAutoScroll->setChecked(true); ui->cbAutoScroll->setChecked(true);
} }
/*
int cType = settings.value("Main/DefaultConnectionType", 0).toInt(); int cType = settings.value("Main/DefaultConnectionType", 0).toInt();
if (cType == 0) connType = "GVRET"; if (cType == 0) connType = "GVRET";
if (cType == 1) connType = "KVASER"; if (cType == 1) connType = "KVASER";
if (cType == 2) connType = "SOCKETCAN"; if (cType == 2) connType = "SOCKETCAN";
portName = settings.value("Main/DefaultConnectionPort", "").toString(); portName = settings.value("Main/DefaultConnectionPort", "").toString();
canSpeed0 = -1; */
canSpeed1 = -1;
qDebug() << connType; //qDebug() << connType;
qDebug() << portName; //qDebug() << portName;
//"Main/SingleWireMode" //"Main/SingleWireMode"
@@ -380,52 +381,18 @@ void MainWindow::writeSettings()
void MainWindow::updateConnectionSettings(QString connectionType, QString port, int speed0, int speed1) void MainWindow::updateConnectionSettings(QString connectionType, QString port, int speed0, int speed1)
{ {
connType = connectionType; Q_UNUSED(connectionType);
portName = port; Q_UNUSED(port);
Q_UNUSED(speed0);
Q_UNUSED(speed1);
//connType = connectionType;
//portName = port;
canSpeed0 = speed0; //canSpeed0 = speed0;
canSpeed1 = speed1; //canSpeed1 = speed1;
if (isConnected) if (isConnected)
{ {
emit updateBaudRates(speed0, speed1); //emit updateBaudRates(speed0, speed1);
}
}
void MainWindow::connButtonPress()
{
if (!isConnected)
{
if (connType == "GVRET")
{
QList<QSerialPortInfo> ports;
ports = QSerialPortInfo::availablePorts();
for (int i = 0; i < ports.count(); i++)
{
if (ports[i].portName() == portName)
{
portInfo = ports[i];
//need to create some way to send single wire mode to serial port code
emit sendSerialPort(&portInfo);
lbStatusConnected.setText(tr("Attempting to connect to port ") + portName);
}
}
}
else if (connType == "KVASER")
{
}
else if (connType == "SOCKETCAN")
{
}
}
else
{
emit closeSerialPort();
isConnected = false;
lbStatusConnected.setText(tr("Not Connected"));
ui->actionConnect->setText(tr("Connect"));
} }
} }
@@ -517,19 +484,20 @@ void MainWindow::filterClearAll()
void MainWindow::tickGUIUpdate() void MainWindow::tickGUIUpdate()
{ {
rxFrames = model->sendBulkRefresh();
//if(rxFrames>0)
//{
int elapsed = elapsedTime->elapsed(); int elapsed = elapsedTime->elapsed();
if(elapsed) { if(elapsed) {
framesPerSec += rxFrames * 1000 / elapsed - (framesPerSec / 4); framesPerSec = rxFrames * 1000 / elapsed;
elapsedTime->restart(); elapsedTime->restart();
} }
else else
framesPerSec = 0; framesPerSec = 0;
model->sendBulkRefresh(rxFrames);
ui->lbNumFrames->setText(QString::number(model->rowCount())); ui->lbNumFrames->setText(QString::number(model->rowCount()));
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom(); if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
ui->lbFPS->setText(QString::number(framesPerSec / 4)); ui->lbFPS->setText(QString::number(framesPerSec));
if (rxFrames > 0) if (rxFrames > 0)
{ {
bDirty = true; bDirty = true;
@@ -539,6 +507,7 @@ void MainWindow::tickGUIUpdate()
if (model->needsFilterRefresh()) updateFilterList(); if (model->needsFilterRefresh()) updateFilterList();
rxFrames = 0; rxFrames = 0;
//}
} }
void MainWindow::gotFrames(int framesSinceLastUpdate) void MainWindow::gotFrames(int framesSinceLastUpdate)
@@ -572,6 +541,7 @@ void MainWindow::clearFrames()
{ {
ui->canFramesView->scrollToTop(); ui->canFramesView->scrollToTop();
model->clearFrames(); model->clearFrames();
CANConManager::getInstance()->resetTimeBasis();
ui->lbNumFrames->setText(QString::number(model->rowCount())); ui->lbNumFrames->setText(QString::number(model->rowCount()));
bDirty = false; bDirty = false;
loadedFileName = ""; loadedFileName = "";
@@ -585,16 +555,6 @@ void MainWindow::normalizeTiming()
emit framesUpdated(-2); //claim an all new set of frames because every frame was updated. emit framesUpdated(-2); //claim an all new set of frames because every frame was updated.
} }
void MainWindow::changeBaudRates()
{
int Speed1 = 0, Speed2 = 0;
//Speed1 = ui->cbSpeed1->currentText().toInt();
//Speed2 = ui->cbSpeed2->currentText().toInt();
emit updateBaudRates(Speed1, Speed2);
}
void MainWindow::handleLoadFile() void MainWindow::handleLoadFile()
{ {
QString filename; QString filename;
@@ -726,7 +686,7 @@ Data Bytes: 88 10 00 13 BB 00 06 00
outFile->write(builderString.toUtf8()); outFile->write(builderString.toUtf8());
builderString = tr("Data Bytes: "); builderString = tr("Data Bytes: ");
for (int temp = 0; temp < thisFrame.len; temp++) for (unsigned int temp = 0; temp < thisFrame.len; temp++)
{ {
builderString += Utility::formatNumber(thisFrame.data[temp]) + " "; builderString += Utility::formatNumber(thisFrame.data[temp]) + " ";
} }
@@ -761,52 +721,16 @@ void MainWindow::toggleCapture()
{ {
allowCapture = !allowCapture; allowCapture = !allowCapture;
if (allowCapture) if (allowCapture)
{
ui->btnCaptureToggle->setText("Suspend Capturing"); ui->btnCaptureToggle->setText("Suspend Capturing");
emit startFrameCapturing();
}
else else
{
ui->btnCaptureToggle->setText("Restart Capturing"); ui->btnCaptureToggle->setText("Restart Capturing");
emit stopFrameCapturing();
} emit suspendCapturing(!allowCapture);
} }
void MainWindow::connectionSucceeded(int baud0, int baud1) void MainWindow::connectionStatusUpdated(int conns)
{ {
lbStatusConnected.setText(tr("Connected to GVRET")); lbStatusConnected.setText(tr("Connected to ") + QString::number(conns) + tr(" buses"));
//finally, find the baud rate in the list of rates or
//add it to the bottom if needed (that'll be weird though...
/*
int idx = ui->cbSpeed1->findText(QString::number(baud0));
if (idx > -1) ui->cbSpeed1->setCurrentIndex(idx);
else
{
ui->cbSpeed1->addItem(QString::number(baud0));
ui->cbSpeed1->setCurrentIndex(ui->cbSpeed1->count() - 1);
}
idx = ui->cbSpeed2->findText(QString::number(baud1));
if (idx > -1) ui->cbSpeed2->setCurrentIndex(idx);
else
{
ui->cbSpeed2->addItem(QString::number(baud1));
ui->cbSpeed2->setCurrentIndex(ui->cbSpeed2->count() - 1);
}
*/
if (connectionWindow) connectionWindow->setSpeeds(baud0, baud1);
//ui->btnConnect->setEnabled(false);
ui->actionConnect->setText(tr("Disconnect"));
isConnected = true;
}
void MainWindow::connectionFailed()
{
lbStatusConnected.setText(tr("Failed to connect!"));
QMessageBox msgBox;
msgBox.setText("Connection to the GVRET firmware failed.\nYou might have an old version of GVRET\nor may have chosen the wrong serial port.");
msgBox.exec();
} }
void MainWindow::updateFileStatus() void MainWindow::updateFileStatus()
@@ -835,33 +759,6 @@ void MainWindow::updateFileStatus()
lbStatusFilename.setText(output); lbStatusFilename.setText(output);
} }
void MainWindow::gotDeviceInfo(int build, int swCAN)
{
QString str = tr("Connected to GVRET ") + QString::number(build);
if (swCAN == 1) str += "(SW)";
lbStatusConnected.setText(str);
if (build < CURRENT_GVRET_VER)
{
QMessageBox msgBox;
msgBox.setText("It appears that you are not running\nan up-to-date version of GVRET\n\nYour version: "
+ QString::number(build) +"\nCurrent Version: " + QString::number(CURRENT_GVRET_VER)
+ "\n\nPlease upgrade your firmware version.\nOtherwise, you may experience difficulties.");
msgBox.exec();
}
if (connectionWindow)
{
if (swCAN == 1) connectionWindow->setCAN1SWMode(true);
else connectionWindow->setCAN1SWMode(false);
}
}
void MainWindow::setTargettedID(int id)
{
worker->targetFrameID(id);
}
void MainWindow::showSettingsDialog() void MainWindow::showSettingsDialog()
{ {
if (!settingsDialog) if (!settingsDialog)
@@ -914,6 +811,22 @@ void MainWindow::showISOInterpreterWindow()
isoWindow->show(); isoWindow->show();
} }
void MainWindow::showSnifferWindow()
{
if (!snifferWindow)
snifferWindow = new SnifferWindow(this);
snifferWindow->show();
}
void MainWindow::showBisectWindow()
{
if (!bisectWindow)
{
bisectWindow = new BisectWindow(model->getListReference());
}
bisectWindow->show();
}
void MainWindow::showFrameSenderWindow() void MainWindow::showFrameSenderWindow()
{ {
if (!frameSenderWindow) if (!frameSenderWindow)
@@ -922,8 +835,6 @@ void MainWindow::showFrameSenderWindow()
frameSenderWindow = new FrameSenderWindow(model->getListReference()); frameSenderWindow = new FrameSenderWindow(model->getListReference());
else else
frameSenderWindow = new FrameSenderWindow(model->getFilteredListReference()); frameSenderWindow = new FrameSenderWindow(model->getFilteredListReference());
connect(frameSenderWindow, &FrameSenderWindow::sendCANFrame, worker, &SerialWorker::sendFrame);
} }
frameSenderWindow->show(); frameSenderWindow->show();
} }
@@ -933,9 +844,9 @@ void MainWindow::showPlaybackWindow()
if (!playbackWindow) if (!playbackWindow)
{ {
if (!useFiltered) if (!useFiltered)
playbackWindow = new FramePlaybackWindow(model->getListReference(), worker); playbackWindow = new FramePlaybackWindow(model->getListReference());
else else
playbackWindow = new FramePlaybackWindow(model->getFilteredListReference(), worker); playbackWindow = new FramePlaybackWindow(model->getFilteredListReference());
} }
playbackWindow->show(); playbackWindow->show();
} }
@@ -945,8 +856,6 @@ void MainWindow::showFirmwareUploaderWindow()
if (!firmwareUploaderWindow) if (!firmwareUploaderWindow)
{ {
firmwareUploaderWindow = new FirmwareUploaderWindow(model->getListReference()); firmwareUploaderWindow = new FirmwareUploaderWindow(model->getListReference());
connect(firmwareUploaderWindow, SIGNAL(sendCANFrame(const CANFrame*,int)), worker, SLOT(sendFrame(const CANFrame*,int)));
connect(worker, SIGNAL(gotTargettedFrame(int)), firmwareUploaderWindow, SLOT(gotTargettedFrame(int)));
} }
firmwareUploaderWindow->show(); firmwareUploaderWindow->show();
} }
@@ -974,8 +883,6 @@ void MainWindow::showFuzzingWindow()
if (!fuzzingWindow) if (!fuzzingWindow)
{ {
fuzzingWindow = new FuzzingWindow(model->getListReference()); fuzzingWindow = new FuzzingWindow(model->getListReference());
connect(fuzzingWindow, SIGNAL(sendCANFrame(const CANFrame*,int)), worker, SLOT(sendFrame(const CANFrame*,int)));
connect(fuzzingWindow, SIGNAL(sendFrameBatch(const QList<CANFrame>*)), worker, SLOT(sendFrameBatch(const QList<CANFrame>*)));
} }
fuzzingWindow->show(); fuzzingWindow->show();
} }
@@ -985,8 +892,8 @@ void MainWindow::showMCConfigWindow()
if (!motorctrlConfigWindow) if (!motorctrlConfigWindow)
{ {
motorctrlConfigWindow = new MotorControllerConfigWindow(model->getListReference()); motorctrlConfigWindow = new MotorControllerConfigWindow(model->getListReference());
connect(motorctrlConfigWindow, SIGNAL(sendCANFrame(const CANFrame*,int)), worker, SLOT(sendFrame(const CANFrame*,int))); //connect(motorctrlConfigWindow, SIGNAL(sendCANFrame(const CANFrame*,int)), worker, SLOT(sendFrame(const CANFrame*,int)));
connect(motorctrlConfigWindow, SIGNAL(sendFrameBatch(const QList<CANFrame>*)), worker, SLOT(sendFrameBatch(const QList<CANFrame>*))); //connect(motorctrlConfigWindow, SIGNAL(sendFrameBatch(const QList<CANFrame>*)), worker, SLOT(sendFrameBatch(const QList<CANFrame>*)));
} }
motorctrlConfigWindow->show(); motorctrlConfigWindow->show();
} }
@@ -996,7 +903,6 @@ void MainWindow::showUDSScanWindow()
if (!udsScanWindow) if (!udsScanWindow)
{ {
udsScanWindow = new UDSScanWindow(model->getListReference()); udsScanWindow = new UDSScanWindow(model->getListReference());
connect(udsScanWindow, SIGNAL(sendCANFrame(const CANFrame*,int)), worker, SLOT(sendFrame(const CANFrame*,int)));
} }
udsScanWindow->show(); udsScanWindow->show();
} }
@@ -1006,7 +912,6 @@ void MainWindow::showScriptingWindow()
if (!scriptingWindow) if (!scriptingWindow)
{ {
scriptingWindow = new ScriptingWindow(model->getListReference()); scriptingWindow = new ScriptingWindow(model->getListReference());
connect(scriptingWindow, &ScriptingWindow::sendCANFrame, worker, &SerialWorker::sendFrame);
} }
scriptingWindow->show(); scriptingWindow->show();
} }
@@ -1060,7 +965,6 @@ void MainWindow::showConnectionSettingsWindow()
if (!connectionWindow) if (!connectionWindow)
{ {
connectionWindow = new ConnectionWindow(); connectionWindow = new ConnectionWindow();
connect(connectionWindow, SIGNAL(updateConnectionSettings(QString,QString,int,int)), this, SLOT(updateConnectionSettings(QString,QString,int,int)));
} }
connectionWindow->show(); connectionWindow->show();
} }
+23 -29
View File
@@ -8,26 +8,30 @@
#include "canframemodel.h" #include "canframemodel.h"
#include "can_structs.h" #include "can_structs.h"
#include "framefileio.h" #include "framefileio.h"
#include "graphingwindow.h" #include "re/graphingwindow.h"
#include "frameinfowindow.h" #include "re/frameinfowindow.h"
#include "frameplaybackwindow.h" #include "frameplaybackwindow.h"
#include "flowviewwindow.h" #include "bisectwindow.h"
#include "re/flowviewwindow.h"
#include "framesenderwindow.h" #include "framesenderwindow.h"
#include "filecomparatorwindow.h" #include "re/filecomparatorwindow.h"
#include "dbchandler.h" #include "dbc/dbchandler.h"
#include "dbcmaineditor.h" #include "dbc/dbcmaineditor.h"
#include "mainsettingsdialog.h" #include "mainsettingsdialog.h"
#include "firmwareuploaderwindow.h" #include "firmwareuploaderwindow.h"
#include "discretestatewindow.h" #include "re/discretestatewindow.h"
#include "connectionwindow.h" #include "connections/connectionwindow.h"
#include "scriptingwindow.h" #include "scriptingwindow.h"
#include "rangestatewindow.h" #include "re/rangestatewindow.h"
#include "dbcloadsavewindow.h" #include "dbc/dbcloadsavewindow.h"
#include "fuzzingwindow.h" #include "re/fuzzingwindow.h"
#include "udsscanwindow.h" #include "re/udsscanwindow.h"
#include "isotp_interpreterwindow.h" #include "re/sniffer/snifferwindow.h"
#include "re/isotp_interpreterwindow.h"
#include "motorcontrollerconfigwindow.h" #include "motorcontrollerconfigwindow.h"
class ConnectionWindow;
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
} }
@@ -40,7 +44,6 @@ public:
explicit MainWindow(QWidget *parent = 0); explicit MainWindow(QWidget *parent = 0);
static QString loadedFileName; static QString loadedFileName;
static MainWindow *getReference(); static MainWindow *getReference();
void setTargettedID(int);
~MainWindow(); ~MainWindow();
private slots: private slots:
@@ -49,7 +52,6 @@ private slots:
void handleSaveFilteredFile(); void handleSaveFilteredFile();
void handleSaveFilters(); void handleSaveFilters();
void handleLoadFilters(); void handleLoadFilters();
void connButtonPress();
void showGraphingWindow(); void showGraphingWindow();
void showFrameDataAnalysis(); void showFrameDataAnalysis();
void clearFrames(); void clearFrames();
@@ -69,12 +71,11 @@ private slots:
void showMCConfigWindow(); void showMCConfigWindow();
void showUDSScanWindow(); void showUDSScanWindow();
void showISOInterpreterWindow(); void showISOInterpreterWindow();
void showSnifferWindow();
void showBisectWindow();
void exitApp(); void exitApp();
void handleSaveDecoded(); void handleSaveDecoded();
void changeBaudRates(); void connectionStatusUpdated(int conns);
void connectionFailed();
void gotDeviceInfo(int, int);
void connectionSucceeded(int, int);
void gridClicked(QModelIndex); void gridClicked(QModelIndex);
void gridDoubleClicked(QModelIndex); void gridDoubleClicked(QModelIndex);
void interpretToggled(bool); void interpretToggled(bool);
@@ -94,12 +95,8 @@ public slots:
void updateConnectionSettings(QString connectionType, QString port, int speed0, int speed1); void updateConnectionSettings(QString connectionType, QString port, int speed0, int speed1);
signals: signals:
void sendSerialPort(QSerialPortInfo *port);
void closeSerialPort();
void updateBaudRates(int, int);
void sendCANFrame(const CANFrame *, int); void sendCANFrame(const CANFrame *, int);
void stopFrameCapturing(); void suspendCapturing(bool);
void startFrameCapturing();
//-1 = frames cleared, -2 = a new file has been loaded (so all frames are different), otherwise # of new frames //-1 = frames cleared, -2 = a new file has been loaded (so all frames are different), otherwise # of new frames
void framesUpdated(int numFrames); //something has updated the frame list void framesUpdated(int numFrames); //something has updated the frame list
@@ -114,8 +111,6 @@ private:
//canbus related data //canbus related data
CANFrameModel *model; CANFrameModel *model;
DBCHandler *dbcHandler; DBCHandler *dbcHandler;
QThread serialWorkerThread;
SerialWorker *worker;
QByteArray inputBuffer; QByteArray inputBuffer;
QTimer updateTimer; QTimer updateTimer;
QTime *elapsedTime; QTime *elapsedTime;
@@ -146,7 +141,9 @@ private:
FuzzingWindow *fuzzingWindow; FuzzingWindow *fuzzingWindow;
UDSScanWindow *udsScanWindow; UDSScanWindow *udsScanWindow;
ISOTP_InterpreterWindow *isoWindow; ISOTP_InterpreterWindow *isoWindow;
SnifferWindow* snifferWindow;
MotorControllerConfigWindow *motorctrlConfigWindow; MotorControllerConfigWindow *motorctrlConfigWindow;
BisectWindow* bisectWindow;
//various private storage //various private storage
QLabel lbStatusConnected; QLabel lbStatusConnected;
@@ -154,9 +151,6 @@ private:
QLabel lbStatusDatabase; QLabel lbStatusDatabase;
int normalRowHeight; int normalRowHeight;
bool isConnected; bool isConnected;
QSerialPortInfo portInfo;
QString connType, portName;
int canSpeed0, canSpeed1;
//private methods //private methods
void saveDecodedTextFile(QString); void saveDecodedTextFile(QString);
@@ -267,6 +267,8 @@ void DiscreteStateWindow::handleTick()
{ {
case DWStates::IDLE: case DWStates::IDLE:
break; break;
case DWStates::DONE:
break;
case DWStates::COUNTDOWN_SIGNAL: case DWStates::COUNTDOWN_SIGNAL:
ticksUntilStateChange--; ticksUntilStateChange--;
if (ticksUntilStateChange == 0) if (ticksUntilStateChange == 0)
@@ -334,7 +336,7 @@ void DiscreteStateWindow::calculateResults()
frameCache.clear(); frameCache.clear();
for (int i = 0; i < modelFrames->count(); i++) for (int i = 0; i < modelFrames->count(); i++)
{ {
if (modelFrames->at(i).ID == it.key()) frameCache.append(modelFrames->at(i)); if (modelFrames->at(i).ID == (unsigned int)it.key()) frameCache.append(modelFrames->at(i));
} }
for (int bits = maxBits; bits >= minBits; bits--) for (int bits = maxBits; bits >= minBits; bits--)
{ {
@@ -112,7 +112,7 @@ void FileComparatorWindow::calculateDetails()
CANFrame frame = interestedFrames.at(x); CANFrame frame = interestedFrames.at(x);
if (interestedIDs.contains(frame.ID)) //if we saw this ID before then add to the QList in there if (interestedIDs.contains(frame.ID)) //if we saw this ID before then add to the QList in there
{ {
for (int y = 0; y < frame.len; y++) for (unsigned int y = 0; y < frame.len; y++)
{ {
interestedIDs[frame.ID].values[y][frame.data[y]]++; interestedIDs[frame.ID].values[y][frame.data[y]]++;
tmp = frame.data[y]; tmp = frame.data[y];
@@ -137,7 +137,7 @@ void FileComparatorWindow::calculateDetails()
} }
} }
//memset(newData->values, 0, 256 * 8); //memset(newData->values, 0, 256 * 8);
for (int y = 0; y < frame.len; y++) for (unsigned int y = 0; y < frame.len; y++)
{ {
newData->values[y][frame.data[y]] = 1; newData->values[y][frame.data[y]] = 1;
tmp = frame.data[y]; tmp = frame.data[y];
@@ -154,7 +154,7 @@ void FileComparatorWindow::calculateDetails()
CANFrame frame = referenceFrames.at(x); CANFrame frame = referenceFrames.at(x);
if (referenceIDs.contains(frame.ID)) //if we saw this ID before then add to the QList in there if (referenceIDs.contains(frame.ID)) //if we saw this ID before then add to the QList in there
{ {
for (int y = 0; y < frame.len; y++) for (unsigned int y = 0; y < frame.len; y++)
{ {
referenceIDs[frame.ID].values[y][frame.data[y]]++; referenceIDs[frame.ID].values[y][frame.data[y]]++;
tmp = frame.data[y]; tmp = frame.data[y];
@@ -177,7 +177,7 @@ void FileComparatorWindow::calculateDetails()
} }
} }
//memset(newData->values, 0, 256 * 8); //memset(newData->values, 0, 256 * 8);
for (int y = 0; y < frame.len; y++) for (unsigned int y = 0; y < frame.len; y++)
{ {
newData->values[y][frame.data[y]] = 1; newData->values[y][frame.data[y]] = 1;
tmp = frame.data[y]; tmp = frame.data[y];
+5 -5
View File
@@ -371,7 +371,7 @@ void FlowViewWindow::updatedFrames(int numFrames)
else //just got some new frames. See if they are relevant. else //just got some new frames. See if they are relevant.
{ {
if (numFrames > modelFrames->count()) return; if (numFrames > modelFrames->count()) return;
int refID; unsigned int refID;
if (frameCache.count() > 0) refID = frameCache[0].ID; if (frameCache.count() > 0) refID = frameCache[0].ID;
else refID = 0; else refID = 0;
bool needRefresh = false; bool needRefresh = false;
@@ -382,7 +382,7 @@ void FlowViewWindow::updatedFrames(int numFrames)
if (!foundID.contains(thisFrame.ID)) if (!foundID.contains(thisFrame.ID))
{ {
foundID.append(thisFrame.ID); foundID.append(thisFrame.ID);
QListWidgetItem* item = new QListWidgetItem(Utility::formatNumber(thisFrame.ID), ui->listFrameID); /*QListWidgetItem* item =*/ new QListWidgetItem(Utility::formatNumber(thisFrame.ID), ui->listFrameID);
} }
if (thisFrame.ID == refID) if (thisFrame.ID == refID)
@@ -495,7 +495,7 @@ void FlowViewWindow::refreshIDList()
if (!foundID.contains(id)) if (!foundID.contains(id))
{ {
foundID.append(id); foundID.append(id);
QListWidgetItem* item = new QListWidgetItem(Utility::formatNumber(id), ui->listFrameID); /*QListWidgetItem* item = */ new QListWidgetItem(Utility::formatNumber(id), ui->listFrameID);
} }
} }
//default is to sort in ascending order //default is to sort in ascending order
@@ -510,7 +510,7 @@ void FlowViewWindow::updateFrameLabel()
void FlowViewWindow::changeID(QString newID) void FlowViewWindow::changeID(QString newID)
{ {
//parse the ID and then load up the frame cache with just messages with that ID. //parse the ID and then load up the frame cache with just messages with that ID.
int id = Utility::ParseStringToNum(newID); uint32_t id = (uint32_t)Utility::ParseStringToNum(newID);
frameCache.clear(); frameCache.clear();
if (modelFrames->count() == 0) return; if (modelFrames->count() == 0) return;
@@ -531,7 +531,7 @@ void FlowViewWindow::changeID(QString newID)
if (frameCache.count() == 0) return; if (frameCache.count() == 0) return;
removeAllGraphs(); removeAllGraphs();
for (int c = 0; c < frameCache.at(0).len; c++) for (uint32_t c = 0; c < frameCache.at(0).len; c++)
{ {
createGraph(c); createGraph(c);
} }
@@ -84,7 +84,7 @@ void FrameInfoWindow::updatedFrames(int numFrames)
else //just got some new frames. See if they are relevant. else //just got some new frames. See if they are relevant.
{ {
if (numFrames > modelFrames->count()) return; if (numFrames > modelFrames->count()) return;
int currID = 0; unsigned int currID = 0;
if (ui->listFrameID->currentItem()) if (ui->listFrameID->currentItem())
currID = ui->listFrameID->currentItem()->text().toInt(NULL, 16); currID = ui->listFrameID->currentItem()->text().toInt(NULL, 16);
bool foundID = false; bool foundID = false;
@@ -140,7 +140,7 @@ void FrameInfoWindow::updateDetailsWindow(QString newID)
for (int i = 0; i < modelFrames->count(); i++) for (int i = 0; i < modelFrames->count(); i++)
{ {
CANFrame thisFrame = modelFrames->at(i); CANFrame thisFrame = modelFrames->at(i);
if (thisFrame.ID == targettedID) frameCache.append(thisFrame); if (thisFrame.ID == (unsigned int)targettedID) frameCache.append(thisFrame);
} }
ui->treeDetails->clear(); ui->treeDetails->clear();
+16 -12
View File
@@ -3,6 +3,7 @@
#include "utility.h" #include "utility.h"
#include <QDebug> #include <QDebug>
#include "mainwindow.h" #include "mainwindow.h"
#include "connections/canconmanager.h"
FuzzingWindow::FuzzingWindow(const QVector<CANFrame> *frames, QWidget *parent) : FuzzingWindow::FuzzingWindow(const QVector<CANFrame> *frames, QWidget *parent) :
QDialog(parent), QDialog(parent),
@@ -36,9 +37,10 @@ FuzzingWindow::FuzzingWindow(const QVector<CANFrame> *frames, QWidget *parent) :
fuzzTimer->setInterval(ui->spinTiming->value()); fuzzTimer->setInterval(ui->spinTiming->value());
ui->cbBuses->addItem(tr("0")); int numBuses = CANConManager::getInstance()->getNumBuses();
ui->cbBuses->addItem(tr("1")); for (int n = 0; n < numBuses; n++) ui->cbBuses->addItem(QString::number(n));
ui->cbBuses->addItem(tr("Both")); ui->cbBuses->addItem(tr("All"));
} }
FuzzingWindow::~FuzzingWindow() FuzzingWindow::~FuzzingWindow()
@@ -48,7 +50,6 @@ FuzzingWindow::~FuzzingWindow()
void FuzzingWindow::updatedFrames(int numFrames) void FuzzingWindow::updatedFrames(int numFrames)
{ {
CANFrame thisFrame;
int id; int id;
if (numFrames == -1) //all frames deleted. Kill the display if (numFrames == -1) //all frames deleted. Kill the display
{ {
@@ -111,8 +112,7 @@ void FuzzingWindow::timerTriggered()
{ {
CANFrame thisFrame; CANFrame thisFrame;
sendingBuffer.clear(); sendingBuffer.clear();
int buses = ui->cbBuses->currentIndex() + 1; int buses = ui->cbBuses->currentIndex();
if (buses == 0) buses = 1;
for (int count = 0; count < ui->spinBurst->value(); count++) for (int count = 0; count < ui->spinBurst->value(); count++)
{ {
thisFrame.ID = currentID; thisFrame.ID = currentID;
@@ -121,22 +121,26 @@ void FuzzingWindow::timerTriggered()
else thisFrame.extended = false; else thisFrame.extended = false;
thisFrame.bus = 0; //hard coded for now. TODO: do not hard code thisFrame.bus = 0; //hard coded for now. TODO: do not hard code
thisFrame.len = ui->spinBytes->value(); thisFrame.len = ui->spinBytes->value();
if (buses & 1)
if (buses < (ui->cbBuses->count() - 1))
{ {
thisFrame.bus = 0; thisFrame.bus = buses;
sendingBuffer.append(thisFrame); sendingBuffer.append(thisFrame);
} }
if (buses & 2) else //fuzz all the buses! HACK THE PLANET! Er, something...
{ {
thisFrame.bus = 1; for (int j = 0; j < ui->cbBuses->count() - 1; j++)
{
thisFrame.bus = j;
sendingBuffer.append(thisFrame); sendingBuffer.append(thisFrame);
} }
}
calcNextID(); calcNextID();
calcNextBitPattern(); calcNextBitPattern();
numSentFrames++; numSentFrames++;
} }
emit sendFrameBatch(&sendingBuffer); CANConManager::getInstance()->sendFrames(sendingBuffer);
ui->lblNumFrames->setText("# of sent frames: " + QString::number(numSentFrames)); ui->lblNumFrames->setText("# of sent frames: " + QString::number(numSentFrames));
} }
@@ -252,7 +256,7 @@ void FuzzingWindow::calcNextBitPattern()
for (int bit = 0; bit < 8; bit++) for (int bit = 0; bit < 8; bit++)
{ {
thisBit = bitGrid[byt * 8 + bit]; thisBit = bitGrid[byt * 8 + bit];
if (thisBit == 1 && (byt * 8 + bit) == bitAccum) if ( (thisBit == 1) && (unsigned int)(byt * 8 + bit) == bitAccum)
{ {
currentBytes[byt] |= (1 << bit); currentBytes[byt] |= (1 << bit);
} }
+1 -1
View File
@@ -29,7 +29,7 @@ public:
~FuzzingWindow(); ~FuzzingWindow();
signals: signals:
void sendCANFrame(const CANFrame *, int); void sendCANFrame(const CANFrame *);
void sendFrameBatch(const QList<CANFrame> *); void sendFrameBatch(const QList<CANFrame> *);
private slots: private slots:
+4 -1
View File
@@ -178,6 +178,7 @@ void GraphingWindow::plottableDoubleClick(QCPAbstractPlottable* plottable, QMous
void GraphingWindow::gotCenterTimeID(int32_t ID, double timestamp) void GraphingWindow::gotCenterTimeID(int32_t ID, double timestamp)
{ {
Q_UNUSED(ID)
//its problematic to try to highlight a graph since we get the ID //its problematic to try to highlight a graph since we get the ID
//and timestamp not the signal in question so there is no real way //and timestamp not the signal in question so there is no real way
//to know which graph. But, if that changes here is a stub //to know which graph. But, if that changes here is a stub
@@ -195,8 +196,8 @@ void GraphingWindow::gotCenterTimeID(int32_t ID, double timestamp)
void GraphingWindow::titleDoubleClick(QMouseEvent* event, QCPPlotTitle* title) void GraphingWindow::titleDoubleClick(QMouseEvent* event, QCPPlotTitle* title)
{ {
Q_UNUSED(event) Q_UNUSED(event)
Q_UNUSED(title)
// Set the plot title by double clicking on it // Set the plot title by double clicking on it
bool ok;
/* /*
QString newTitle = QInputDialog::getText(this, "SavvyCAN Graphing", "New plot title:", QLineEdit::Normal, title->text(), &ok); QString newTitle = QInputDialog::getText(this, "SavvyCAN Graphing", "New plot title:", QLineEdit::Normal, title->text(), &ok);
@@ -354,6 +355,8 @@ bool GraphingWindow::eventFilter(QObject *obj, QEvent *event)
// standard event processing // standard event processing
return QObject::eventFilter(obj, event); return QObject::eventFilter(obj, event);
} }
return false;
} }
void GraphingWindow::resetView() void GraphingWindow::resetView()
+1 -1
View File
@@ -3,7 +3,7 @@
#include "qcustomplot.h" #include "qcustomplot.h"
#include "can_structs.h" #include "can_structs.h"
#include "dbchandler.h" #include "dbc/dbchandler.h"
#include <QDialog> #include <QDialog>
+2 -2
View File
@@ -151,7 +151,7 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
int frameType; int frameType;
int frameLen; int frameLen;
int ln; int ln;
int offset; //int offset;
ISOTP_MESSAGE msg; ISOTP_MESSAGE msg;
ISOTP_MESSAGE *pMsg; ISOTP_MESSAGE *pMsg;
@@ -230,7 +230,7 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
} }
if (!pMsg) return; if (!pMsg) return;
ln = pMsg->len - pMsg->data.count(); ln = pMsg->len - pMsg->data.count();
offset = pMsg->data.count(); //offset = pMsg->data.count();
if (useExtendedAddressing) if (useExtendedAddressing)
{ {
if (ln > 6) ln = 6; if (ln > 6) ln = 6;
@@ -145,7 +145,6 @@ void NewGraphDialog::loadSignals(int idx)
void NewGraphDialog::bitfieldClicked(int x,int y) void NewGraphDialog::bitfieldClicked(int x,int y)
{ {
int bit = (y * 8 + (7-x)); int bit = (y * 8 + (7-x));
int res;
qDebug() << "Clicked bit: " << bit; qDebug() << "Clicked bit: " << bit;
startBit = bit; startBit = bit;
+1 -1
View File
@@ -3,7 +3,7 @@
#include <QDialog> #include <QDialog>
#include "graphingwindow.h" #include "graphingwindow.h"
#include "dbchandler.h" #include "dbc/dbchandler.h"
namespace Ui { namespace Ui {
class NewGraphDialog; class NewGraphDialog;
@@ -171,7 +171,7 @@ void RangeStateWindow::refreshFilterList()
void RangeStateWindow::recalcButton() void RangeStateWindow::recalcButton()
{ {
QHash<int, bool>::iterator iter; QHash<int, bool>::iterator iter;
int id; uint32_t id;
ui->listCandidates->clear(); ui->listCandidates->clear();
foundSignals.clear(); foundSignals.clear();
@@ -376,7 +376,7 @@ void RangeStateWindow::createGraph(QVector<int> values)
else ymin *= 0.8; else ymin *= 0.8;
ymax = maxval; ymax = maxval;
if (ymax < 0) ymax * 0.8; if (ymax < 0) ymax *= 0.8;
else ymax *= 1.2; else ymax *= 1.2;
if (fabs(ymin) < 0.01) ymin -= (ymax / 60.0); if (fabs(ymin) < 0.01) ymin -= (ymax / 60.0);
@@ -401,7 +401,7 @@ void RangeStateWindow::clickedSignalList(int idx)
{ {
if (idx == -1) return; //just in case... if (idx == -1) return; //just in case...
int id, startBit, bitLength; uint32_t id, startBit, bitLength;
bool isSigned = false, isBigEndian = false; bool isSigned = false, isBigEndian = false;
int64_t valu; int64_t valu;
+86
View File
@@ -0,0 +1,86 @@
#include <QVariant>
#include <QDebug>
#include "snifferitem.h"
SnifferItem::SnifferItem(const CANFrame& pFrame):
mNotch(0),
mID(pFrame.ID)
{
mMarker = {0,0};
mLastMarker = {0,0};
/* that's dirty */
update(pFrame);
update(pFrame);
}
SnifferItem::~SnifferItem()
{
}
quint64 SnifferItem::getId() const
{
return mID;
}
float SnifferItem::getDelta() const
{
return ((float)(mCurrentTime-mLastTime))/1000000;
}
int SnifferItem::getData(uchar i) const
{
return (i>=mCurrent.len) ? -1 : ((uchar*) &mCurrent.data)[i];
}
dc SnifferItem::dataChange(uchar i) const
{
if( i<mCurrent.len &&
((uchar*) &mLastMarker.data)[i] &&
!((uchar*) &mNotch)[i] )
{
return ((uchar*) &mCurrent.data)[i] >= ((uchar*) &mLast.data)[i] ? dc::INC : dc::DEC;
}
return dc::NO;
}
int SnifferItem::elapsed() const
{
return mTime.elapsed();
}
void SnifferItem::update(const CANFrame& pFrame)
{
/* copy current to last */
mLast = mCurrent;
mLastTime = mCurrentTime;
/* copy new value */
memcpy(&mCurrent.data, pFrame.data, 8);
mCurrent.len = pFrame.len;
mCurrentTime = pFrame.timestamp;
/* update marker */
mMarker.data |= mLast.data ^ mCurrent.data;
mMarker.len |= mLast.len ^ mCurrent.len;
/* restart timeout */
mTime.restart();
}
void SnifferItem::updateMarker()
{
mLastMarker = mMarker;
mMarker = {0, 0};
}
void SnifferItem::notch(bool pNotch)
{
if(pNotch)
mNotch |= mLastMarker.data;
else
mNotch = 0;
}
+49
View File
@@ -0,0 +1,49 @@
#ifndef SNIFFERITEM_H
#define SNIFFERITEM_H
#include <QVariant>
#include <QTime>
#include "can_structs.h"
struct fstCan
{
quint64 data;
int len;
};
enum dc
{
NO,
INC,
DEC
};
class SnifferItem
{
public:
explicit SnifferItem(const CANFrame& pFrame);
virtual ~SnifferItem();
quint64 getId() const;
float getDelta() const;
int getData(uchar i) const;
dc dataChange(uchar) const;
int elapsed() const;
void update(const CANFrame& pFrame);
void updateMarker();
void notch(bool);
private:
quint64 mID;
struct fstCan mLast;
struct fstCan mCurrent;
struct fstCan mLastMarker;
struct fstCan mMarker;
quint64 mNotch;
quint64 mLastTime;
quint64 mCurrentTime;
QTime mTime;
};
#endif // SNIFFERITEM_H
+267
View File
@@ -0,0 +1,267 @@
#include <QDebug>
#include "sniffermodel.h"
#include "snifferwindow.h"
SnifferModel::SnifferModel(QObject *parent)
: QAbstractItemModel(parent),
mFilter(false)
{
}
SnifferModel::~SnifferModel()
{
qDeleteAll(mMap);
mMap.clear();
mFilters.clear();
}
int SnifferModel::columnCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : tc::LAST+1;
}
int SnifferModel::rowCount(const QModelIndex &parent) const
{
const QMap<quint32, SnifferItem*>& map = mFilter ? mFilters : mMap;
return parent.isValid() ? 0 : map.size();
}
QVariant SnifferModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
SnifferItem *item = static_cast<SnifferItem*>(index.internalPointer());
if(!item) QVariant();
int col = index.column();
switch(role)
{
case Qt::DisplayRole:
{
switch(col)
{
case tc::DELTA:
return QString::number(item->getDelta(), 'f');
case tc::ID:
return QString("%1").arg(item->getId(), 5, 16, QLatin1Char(' ')).toUpper();
default:
break;
}
if(tc::DATA_0<=col && col <=tc::DATA_7)
{
int data = item->getData(col-tc::DATA_0);
if(data>=0)
return QString("%1").arg(data, 2, 16, QLatin1Char('0')).toUpper();
}
break;
}
case Qt::BackgroundRole:
{
if(tc::ID==col)
{
if(item->elapsed()>4000)
return QBrush(Qt::red);
}
else if(tc::DATA_0<=col && col<=tc::DATA_7)
{
dc change = item->dataChange(col-tc::DATA_0);
switch(change)
{
case dc::INC:
return QBrush(Qt::green);
case dc::DEC:
return QBrush(Qt::red);
default:
break;
}
}
break;
}
}
return QVariant();
}
Qt::ItemFlags SnifferModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
return QAbstractItemModel::flags(index);
}
QVariant SnifferModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
{
switch(section)
{
case tc::DELTA:
return QString("Delta");
case tc::ID:
return QString("ID");
default:
break;
}
if(tc::DATA_0<=section && section <=tc::DATA_7)
return QString::number(section-tc::DATA_0);
}
return QVariant();
}
QModelIndex SnifferModel::index(int row, int column, const QModelIndex &parent) const
{
if (parent.isValid())
return QModelIndex();
const QMap<quint32, SnifferItem*>& map = mFilter ? mFilters : mMap;
if(column>tc::LAST || row>=map.size())
return QModelIndex();
/* ugly but I can't find best without creating a list to keep indexes */
QMap<quint32, SnifferItem*>::const_iterator iter;
int i;
for(iter = map.begin(), i=0 ; i<row ; ++i, ++iter);
return createIndex(row, column, iter.value());
}
QModelIndex SnifferModel::parent(const QModelIndex &) const
{
return QModelIndex();
}
void SnifferModel::clear()
{
beginResetModel();
qDeleteAll(mMap);
mMap.clear();
mFilters.clear();
mFilter = false;
endResetModel();
}
void SnifferModel::refresh()
{
QMap<quint32, SnifferItem*>::iterator i;
QVector<quint32> toRemove;
SnifferItem* item;
/* update markers */
for (i = mMap.begin(); i != mMap.end(); ++i)
{
i.value()->updateMarker();
if(i.value()->elapsed()>5000)
toRemove.append(i.key());
}
if(toRemove.size())
{
beginResetModel();
foreach(quint32 id, toRemove)
{
/* remove element */
item = mMap.take(id);
mFilters.remove(id);
delete item;
/* send notification */
emit idChange(id, false);
}
endResetModel();
}
else
/* refresh data */
dataChanged(createIndex(0, 0),
createIndex(rowCount()-1, columnCount()-1), QVector<int>(Qt::DisplayRole));
}
void SnifferModel::filter(fltType pType, int pId)
{
beginResetModel();
switch(pType)
{
case fltType::NONE:
/* erase everything */
mFilter = true;
mFilters.clear();
break;
case fltType::ADD:
/* add filter to list */
mFilter = true;
mFilters[pId] = mMap[pId];
break;
case fltType::REMOVE:
/* remove filter */
if(!mFilter)
mFilters = mMap;
mFilter = true;
mFilters.remove(pId);
break;
case fltType::ALL:
/* stop filtering */
mFilter = false;
mFilters.clear();
break;
}
endResetModel();
}
/***********************************************/
/********** slots ****************/
/***********************************************/
void SnifferModel::update(CANConnection*, QVector<CANFrame>& pFrames)
{
foreach(const CANFrame& frame, pFrames)
{
if(!mMap.contains(frame.ID))
{
int index = std::distance(mMap.begin(), mMap.lowerBound(frame.ID));
/* add the frame */
beginInsertRows(QModelIndex(), index, index);
mMap[frame.ID] = new SnifferItem(frame);
endInsertRows();
emit idChange(frame.ID, true);
}
else
//updateData
mMap[frame.ID]->update(frame);
}
}
void SnifferModel::notch()
{
QMap<quint32, SnifferItem*>& map = mFilter ? mFilters : mMap;
foreach(SnifferItem* item, map)
item->notch(true);
}
void SnifferModel::unNotch()
{
QMap<quint32, SnifferItem*>& map = mFilter ? mFilters : mMap;
foreach(SnifferItem* item, map)
item->notch(false);
}
+58
View File
@@ -0,0 +1,58 @@
#ifndef SNIFFERMODEL_H
#define SNIFFERMODEL_H
#include <QAbstractItemModel>
#include <QModelIndex>
#include <QVariant>
#include <QTimer>
#include "can_structs.h"
#include "connections/canconnection.h"
#include "snifferitem.h"
enum fltType
{
ALL,
ADD,
REMOVE,
NONE
};
class SnifferModel : public QAbstractItemModel
{
Q_OBJECT
public:
explicit SnifferModel(QObject *parent = 0);
virtual ~SnifferModel();
/* from QAbstractItemModel */
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
void refresh();
void clear();
void filter(fltType pType, int pId=0);
public slots:
void update(CANConnection*, QVector<CANFrame>&);
void notch();
void unNotch();
signals:
void idChange(int, bool);
private:
QMap<quint32, SnifferItem*> mMap;
QMap<quint32, SnifferItem*> mFilters;
bool mFilter;
};
#endif // SNIFFERMODEL_H
+132
View File
@@ -0,0 +1,132 @@
#include <QDebug>
#include <QListWidgetItem>
#include "snifferwindow.h"
#include "ui_snifferwindow.h"
#include "connections/canconmanager.h"
SnifferWindow::SnifferWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::snifferWindow),
mModel(this),
mTimer(this),
mFilter(false)
{
ui->setupUi(this);
ui->treeView->setModel(&mModel);
/* set column width */
ui->treeView->setColumnWidth(tc::ID, 50);
ui->treeView->setColumnWidth(tc::LAST, 1);
for(int i=tc::DATA_0 ; i<=tc::DATA_7 ; i++)
ui->treeView->setColumnWidth(i, 30);
ui->treeView->header()->setDefaultAlignment(Qt::AlignCenter);
/* activate sorting */
ui->listWidget->setSortingEnabled(true);
/* connect timer */
connect(&mTimer, &QTimer::timeout, this, &SnifferWindow::update);
mTimer.setInterval(200);
/* connect buttons */
connect(ui->btNotch, &QPushButton::clicked, &mModel, &SnifferModel::notch);
connect(ui->btUnNotch, &QPushButton::clicked, &mModel, &SnifferModel::unNotch);
connect(ui->btAll, &QPushButton::clicked, this, &SnifferWindow::fltAll);
connect(ui->btNone, &QPushButton::clicked, this, &SnifferWindow::fltNone);
connect(&mModel, &SnifferModel::idChange, this, &SnifferWindow::idChange);
connect(ui->listWidget, &QListWidget::itemChanged, this, &SnifferWindow::itemChanged);
}
SnifferWindow::~SnifferWindow()
{
closeEvent(NULL);
delete ui;
}
void SnifferWindow::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
connect(CANConManager::getInstance(), &CANConManager::framesReceived, &mModel, &SnifferModel::update);
mTimer.start();
qDebug() << "show";
}
void SnifferWindow::closeEvent(QCloseEvent *event)
{
Q_UNUSED(event);
/* stop timer */
mTimer.stop();
/* disconnect reception of frames */
disconnect(CANConManager::getInstance(), 0, this, 0);
/* clear model */
mModel.clear();
/* clean list */
qDeleteAll(mMap);
mMap.clear();
/* reset filtering */
mFilter = false;
}
void SnifferWindow::update()
{
mModel.refresh();
}
void SnifferWindow::fltAll()
{
filter(false);
}
void SnifferWindow::fltNone()
{
filter(true);
}
void SnifferWindow::filter(bool pFilter)
{
mFilter = pFilter;
mModel.filter(mFilter ? fltType::NONE : fltType::ALL);
foreach(QListWidgetItem* item, mMap)
item->setCheckState(mFilter ? Qt::Unchecked : Qt::Checked);
}
void SnifferWindow::idChange(int pId, bool pAdd)
{
QListWidgetItem* item;
if(pAdd)
{
QString text = QString("0x") + QString("%1").arg(pId, 3, 16, QLatin1Char('0')).toUpper();
item = new QListWidgetItem(text);
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item->setCheckState(mFilter ? Qt::Unchecked : Qt::Checked);
ui->listWidget->addItem(item);
mMap[pId] = item;
}
else
{
item = mMap.take(pId);
ui->listWidget->removeItemWidget(item);
delete item;
}
}
void SnifferWindow::itemChanged(QListWidgetItem * item)
{
bool checked = (Qt::Checked == item->checkState());
if( !mFilter && checked )
return;
mModel.filter(checked ? fltType::ADD : fltType::REMOVE, mMap.key(item));
mFilter = true;
}
+56
View File
@@ -0,0 +1,56 @@
#ifndef SNIFFER_H
#define SNIFFER_H
#include <QDialog>
#include <QListWidgetItem>
#include "sniffermodel.h"
namespace Ui {
class snifferWindow;
}
enum tc
{
DELTA = 0,
ID,
DATA_0,
DATA_1,
DATA_2,
DATA_3,
DATA_4,
DATA_5,
DATA_6,
DATA_7,
LAST
};
class SnifferWindow : public QDialog
{
Q_OBJECT
public:
explicit SnifferWindow(QWidget *parent = 0);
~SnifferWindow();
void showEvent(QShowEvent*);
void closeEvent(QCloseEvent*);
public slots:
void update();
void idChange(int, bool);
void fltAll();
void fltNone();
void itemChanged(QListWidgetItem*);
private:
void filter(bool pFilter);
Ui::snifferWindow* ui;
SnifferModel mModel;
QTimer mTimer;
QMap<int, QListWidgetItem*> mMap;
bool mFilter;
};
#endif // SNIFFER_H
+23 -17
View File
@@ -1,6 +1,7 @@
#include "udsscanwindow.h" #include "udsscanwindow.h"
#include "ui_udsscanwindow.h" #include "ui_udsscanwindow.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "connections/canconmanager.h"
UDSScanWindow::UDSScanWindow(const QVector<CANFrame> *frames, QWidget *parent) : UDSScanWindow::UDSScanWindow(const QVector<CANFrame> *frames, QWidget *parent) :
QDialog(parent), QDialog(parent),
@@ -20,10 +21,9 @@ UDSScanWindow::UDSScanWindow(const QVector<CANFrame> *frames, QWidget *parent) :
connect(ui->btnScan, &QPushButton::clicked, this, &UDSScanWindow::scanUDS); connect(ui->btnScan, &QPushButton::clicked, this, &UDSScanWindow::scanUDS);
connect(waitTimer, &QTimer::timeout, this, &UDSScanWindow::timeOut); connect(waitTimer, &QTimer::timeout, this, &UDSScanWindow::timeOut);
ui->cbBuses->addItem("0"); int numBuses = CANConManager::getInstance()->getNumBuses();
ui->cbBuses->addItem("1"); for (int n = 0; n < numBuses; n++) ui->cbBuses->addItem(QString::number(n));
ui->cbBuses->addItem("Both"); ui->cbBuses->addItem(tr("All"));
} }
UDSScanWindow::~UDSScanWindow() UDSScanWindow::~UDSScanWindow()
@@ -53,8 +53,6 @@ void UDSScanWindow::scanUDS()
endID = Utility::ParseStringToNum(ui->txtEndID->text()); endID = Utility::ParseStringToNum(ui->txtEndID->text());
int buses = ui->cbBuses->currentIndex(); int buses = ui->cbBuses->currentIndex();
buses++;
if (buses < 1) buses = 1;
//start out by sending tester present to every address to see if anyone replies //start out by sending tester present to every address to see if anyone replies
for (id = startID; id <= endID; id++) for (id = startID; id <= endID; id++)
@@ -68,18 +66,22 @@ void UDSScanWindow::scanUDS()
frame.data[3] = 0;frame.data[4] = 0;frame.data[5] = 0; frame.data[3] = 0;frame.data[4] = 0;frame.data[5] = 0;
frame.data[6] = 0;frame.data[7] = 0; frame.data[6] = 0;frame.data[7] = 0;
if (buses & 1) if (buses < ui->cbBuses->count()- 1)
{ {
frame.bus = 0; frame.bus = buses;
sendingFrames.append(frame); sendingFrames.append(frame);
} }
if (buses & 2) else
{ {
frame.bus = 1; for (int c = 0; c < ui->cbBuses->count() - 1; c++)
{
frame.bus = c;
sendingFrames.append(frame); sendingFrames.append(frame);
} }
} }
}
//then try asking for the various diagnostic session types //then try asking for the various diagnostic session types
for (typ = 1; typ < 5; typ++) for (typ = 1; typ < 5; typ++)
{ {
@@ -94,18 +96,21 @@ void UDSScanWindow::scanUDS()
frame.data[3] = 0;frame.data[4] = 0;frame.data[5] = 0; frame.data[3] = 0;frame.data[4] = 0;frame.data[5] = 0;
frame.data[6] = 0;frame.data[7] = 0; frame.data[6] = 0;frame.data[7] = 0;
if (buses & 1) if (buses < ui->cbBuses->count()- 1)
{ {
frame.bus = 0; frame.bus = buses;
sendingFrames.append(frame); sendingFrames.append(frame);
} }
if (buses & 2) else
{ {
frame.bus = 1; for (int c = 0; c < ui->cbBuses->count() - 1; c++)
{
frame.bus = c;
sendingFrames.append(frame); sendingFrames.append(frame);
} }
} }
} }
}
waitTimer->start(); waitTimer->start();
currIdx = -1; currIdx = -1;
@@ -129,11 +134,12 @@ void UDSScanWindow::updatedFrames(int numFrames)
} }
//Updates here are nearly once per millisecond if there is heavy traffic. That's more like it! //Updates here are nearly once per millisecond if there is heavy traffic. That's more like it!
//TODO: I really doubt this works anymore with the new connection system. This breaks the UDS scanner for now! ;(
void UDSScanWindow::rapidFrames(int numFrames) void UDSScanWindow::rapidFrames(int numFrames)
{ {
CANFrame thisFrame; CANFrame thisFrame;
QString result; QString result;
int id; uint32_t id;
int offset = ui->spinReplyOffset->value(); int offset = ui->spinReplyOffset->value();
CANFrame sentFrame; CANFrame sentFrame;
bool gotReply = false; bool gotReply = false;
@@ -151,7 +157,7 @@ void UDSScanWindow::rapidFrames(int numFrames)
thisFrame = modelFrames->at(i); thisFrame = modelFrames->at(i);
id = thisFrame.ID; id = thisFrame.ID;
if ((id == (sentFrame.ID + offset)) || ui->cbAllowAdaptiveOffset->isChecked()) if ((id == (uint32_t)(sentFrame.ID + offset)) || ui->cbAllowAdaptiveOffset->isChecked())
{ {
int temp = thisFrame.data[0] >> 4; int temp = thisFrame.data[0] >> 4;
if (temp == 0) //single frame reply (maybe) if (temp == 0) //single frame reply (maybe)
@@ -210,7 +216,7 @@ void UDSScanWindow::sendNextMsg()
currIdx++; currIdx++;
if (currIdx < sendingFrames.count()) if (currIdx < sendingFrames.count())
{ {
emit sendCANFrame(&sendingFrames[currIdx], sendingFrames[currIdx].bus); CANConManager::getInstance()->sendFrame(sendingFrames[currIdx]);
waitTimer->start(); waitTimer->start();
} }
else else
-3
View File
@@ -17,9 +17,6 @@ public:
explicit UDSScanWindow(const QVector<CANFrame> *frames, QWidget *parent = 0); explicit UDSScanWindow(const QVector<CANFrame> *frames, QWidget *parent = 0);
~UDSScanWindow(); ~UDSScanWindow();
signals:
void sendCANFrame(const CANFrame *, int);
private slots: private slots:
void updatedFrames(int numFrames); void updatedFrames(int numFrames);
void rapidFrames(int numFrames); void rapidFrames(int numFrames);
+36 -15
View File
@@ -1,14 +1,12 @@
#include "scriptcontainer.h"
#include <QJSValueIterator> #include <QJSValueIterator>
#include <QDebug> #include <QDebug>
ScriptContainer::ScriptContainer() #include "scriptcontainer.h"
{ #include "connections/canconmanager.h"
fileName = QString();
filePath = QString();
scriptText = QString();
ScriptContainer::ScriptContainer(QString& pConName):
mConName(pConName)
{
connect(&timer, SIGNAL(timeout()), this, SLOT(tick())); connect(&timer, SIGNAL(timeout()), this, SLOT(tick()));
} }
@@ -68,6 +66,22 @@ void ScriptContainer::setFilter(QJSValue id, QJSValue mask, QJSValue bus)
CANFilter filter; CANFilter filter;
filter.setFilter(idVal, maskVal, busVal); filter.setFilter(idVal, maskVal, busVal);
filters.append(filter); filters.append(filter);
qDebug() << "FIXME setFilter";
CANConnection* conn_p = CANConManager::getInstance()->getByName(mConName);
if(conn_p)
{
CANFlt canFlt;
for(int i=0 ; i<conn_p->getNumBuses() ; i++)
{
foreach(const CANFilter& flt, filters)
{
if(flt.bus==i) {
conn_p->addTargettedFrame(busVal, idVal, maskVal, this);
}
}
}
}
} }
void ScriptContainer::setTickInterval(QJSValue interval) void ScriptContainer::setTickInterval(QJSValue interval)
@@ -86,6 +100,13 @@ void ScriptContainer::clearFilters()
{ {
qDebug() << "Called clear filters"; qDebug() << "Called clear filters";
filters.clear(); filters.clear();
qDebug() << "FIXME clearFilters";
CANConnection* conn_p = CANConManager::getInstance()->getByName(mConName);
if(conn_p)
{
conn_p->removeAllTargettedFrames(this);
}
} }
void ScriptContainer::sendFrame(QJSValue bus, QJSValue id, QJSValue length, QJSValue data) void ScriptContainer::sendFrame(QJSValue bus, QJSValue id, QJSValue length, QJSValue data)
@@ -93,25 +114,25 @@ void ScriptContainer::sendFrame(QJSValue bus, QJSValue id, QJSValue length, QJSV
CANFrame frame; CANFrame frame;
frame.extended = false; frame.extended = false;
frame.ID = id.toInt(); frame.ID = id.toInt();
frame.len = length.toInt(); frame.len = length.toUInt();
if (frame.len < 0) frame.len = 0;
if (frame.len > 8) frame.len = 8; if (frame.len > 8) frame.len = 8;
if (!data.isArray()) qDebug() << "data isn't an array"; if (!data.isArray()) qDebug() << "data isn't an array";
for (int i = 0; i < frame.len; i++) for (unsigned int i = 0; i < frame.len; i++)
{ {
frame.data[i] = (uint8_t)data.property(i).toInt(); frame.data[i] = (uint8_t)data.property(i).toInt();
} }
frame.bus = bus.toInt(); frame.bus = (uint32_t)bus.toInt();
if (frame.bus < 0) frame.bus = 0;
if (frame.bus > 1) frame.bus = 1; if (frame.bus > 1) frame.bus = 1;
if (frame.ID > 0x7FF) frame.extended = true; if (frame.ID > 0x7FF) frame.extended = true;
//qDebug() << "Sending frame from script"; qDebug() << "sending frame from script";
emit sendCANFrame(&frame, frame.bus); CANConnection* conn_p = CANConManager::getInstance()->getByName(mConName);
if(conn_p)
conn_p->sendFrame(frame);
} }
void ScriptContainer::gotFrame(const CANFrame &frame) void ScriptContainer::gotFrame(const CANFrame &frame)
@@ -125,7 +146,7 @@ void ScriptContainer::gotFrame(const CANFrame &frame)
QJSValueList args; QJSValueList args;
args << frame.bus << frame.ID << frame.len; args << frame.bus << frame.ID << frame.len;
QJSValue dataBytes = scriptEngine.newArray(frame.len); QJSValue dataBytes = scriptEngine.newArray(frame.len);
for (int j = 0; j < frame.len; j++) dataBytes.setProperty(j, QJSValue(frame.data[j])); for (unsigned int j = 0; j < frame.len; j++) dataBytes.setProperty(j, QJSValue(frame.data[j]));
args.append(dataBytes); args.append(dataBytes);
gotFrameFunction.call(args); gotFrameFunction.call(args);
return; //as soon as one filter matches we jump out return; //as soon as one filter matches we jump out
+2 -4
View File
@@ -13,12 +13,13 @@ class ScriptContainer : public QObject
Q_OBJECT Q_OBJECT
public: public:
ScriptContainer(); ScriptContainer(QString&);
void gotFrame(const CANFrame &frame); void gotFrame(const CANFrame &frame);
QString fileName; QString fileName;
QString filePath; QString filePath;
QString scriptText; QString scriptText;
QString mConName;
public slots: public slots:
void compileScript(); void compileScript();
@@ -31,9 +32,6 @@ public slots:
private slots: private slots:
void tick(); void tick();
signals:
void sendCANFrame(const CANFrame *, int);
private: private:
QJSEngine scriptEngine; QJSEngine scriptEngine;
QJSValue compiledScript; QJSValue compiledScript;
+27 -21
View File
@@ -3,9 +3,10 @@
#include <QFile> #include <QFile>
#include <QFileDialog> #include <QFileDialog>
#include <QSettings>
#include <Qsci/qscilexerjavascript.h> #include <Qsci/qscilexerjavascript.h>
#include "mainwindow.h" #include "connections/canconmanager.h"
ScriptingWindow::ScriptingWindow(const QVector<CANFrame> *frames, QWidget *parent) : ScriptingWindow::ScriptingWindow(const QVector<CANFrame> *frames, QWidget *parent) :
QDialog(parent), QDialog(parent),
@@ -23,7 +24,8 @@ ScriptingWindow::ScriptingWindow(const QVector<CANFrame> *frames, QWidget *paren
connect(ui->btnRemoveScript, &QAbstractButton::pressed, this, &ScriptingWindow::deleteCurrentScript); connect(ui->btnRemoveScript, &QAbstractButton::pressed, this, &ScriptingWindow::deleteCurrentScript);
connect(ui->btnRevertScript, &QAbstractButton::pressed, this, &ScriptingWindow::revertScript); connect(ui->btnRevertScript, &QAbstractButton::pressed, this, &ScriptingWindow::revertScript);
connect(ui->btnSaveScript, &QAbstractButton::pressed, this, &ScriptingWindow::saveScript); connect(ui->btnSaveScript, &QAbstractButton::pressed, this, &ScriptingWindow::saveScript);
connect(MainWindow::getReference(), &MainWindow::framesUpdated, this, &ScriptingWindow::updatedFrames);
connect(CANConManager::getInstance(), &CANConManager::framesReceived, this, &ScriptingWindow::newFrames);
ui->txtScriptSource->setLexer(new QsciLexerJavaScript(ui->txtScriptSource)); ui->txtScriptSource->setLexer(new QsciLexerJavaScript(ui->txtScriptSource));
} }
@@ -33,27 +35,22 @@ ScriptingWindow::~ScriptingWindow()
delete ui; delete ui;
} }
void ScriptingWindow::updatedFrames(int numFrames)
void ScriptingWindow::newFrames(const CANConnection* pConn, const QVector<CANFrame>& pFrames)
{ {
CANFrame thisFrame; /*FIXME: name of the probe and bus should be checked */
//-1 means all frames deleted and -2 means a full refresh, neither of which we care about here. Q_UNUSED(pConn);
if (numFrames > 0)
{
if (numFrames > modelFrames->count()) return;
qDebug() << "Got frames into script window: " << numFrames;
//for every new frame pass it on to each script container. The container will determine if it needs to actually
//notify the script and do that if applicable.
for (int i = modelFrames->count() - numFrames; i < modelFrames->count(); i++)
{
thisFrame = modelFrames->at(i);
for (int j = 0; j < scripts.length(); j++) for (int j = 0; j < scripts.length(); j++)
{ {
scripts[j]->gotFrame(thisFrame); foreach(const CANFrame& frame, pFrames)
} {
scripts[j]->gotFrame(frame);
} }
} }
} }
void ScriptingWindow::closeEvent(QCloseEvent *event) void ScriptingWindow::closeEvent(QCloseEvent *event)
{ {
Q_UNUSED(event); Q_UNUSED(event);
@@ -90,7 +87,6 @@ void ScriptingWindow::loadNewScript()
{ {
QString filename; QString filename;
QFileDialog dialog; QFileDialog dialog;
bool result = false;
ScriptContainer *container; ScriptContainer *container;
QStringList filters; QStringList filters;
@@ -115,13 +111,19 @@ void ScriptingWindow::loadNewScript()
QStringList fileList = filename.split('/'); QStringList fileList = filename.split('/');
QString justFileName = fileList[fileList.length() - 1]; QString justFileName = fileList[fileList.length() - 1];
ui->listLoadedScripts->addItem(justFileName); ui->listLoadedScripts->addItem(justFileName);
container = new ScriptContainer(); /* get the first connection in the list for now */
qDebug() << "FIXME: connection is always the first in list";
QString portName;
QList<CANConnection*> list = CANConManager::getInstance()->getConnections();
if(!list.isEmpty())
portName = list.first()->getPort();
container = new ScriptContainer(portName);
container->fileName = justFileName; container->fileName = justFileName;
container->filePath = filename; container->filePath = filename;
container->scriptText = contents; container->scriptText = contents;
container->setErrorWidget(ui->listErrors); container->setErrorWidget(ui->listErrors);
container->compileScript(); container->compileScript();
connect(container, &ScriptContainer::sendCANFrame, this, &ScriptingWindow::sendCANFrame);
scripts.append(container); scripts.append(container);
currentScript = container; currentScript = container;
ui->txtScriptSource->setText(container->scriptText); ui->txtScriptSource->setText(container->scriptText);
@@ -135,13 +137,17 @@ void ScriptingWindow::createNewScript()
{ {
ScriptContainer *container; ScriptContainer *container;
container = new ScriptContainer(); QString portName;
QList<CANConnection*> list = CANConManager::getInstance()->getConnections();
if(!list.isEmpty())
portName = list.first()->getPort();
container = new ScriptContainer(portName);
container->fileName = "UNNAMED_" + QString::number((qrand() % 10000)) + ".js"; container->fileName = "UNNAMED_" + QString::number((qrand() % 10000)) + ".js";
container->filePath = QString(); container->filePath = QString();
container->scriptText = QString(); container->scriptText = QString();
container->setErrorWidget(ui->listErrors); container->setErrorWidget(ui->listErrors);
connect(container, &ScriptContainer::sendCANFrame, this, &ScriptingWindow::sendCANFrame);
scripts.append(container); scripts.append(container);
ui->listLoadedScripts->addItem(container->fileName); ui->listLoadedScripts->addItem(container->fileName);
currentScript = container; currentScript = container;
+2 -8
View File
@@ -3,6 +3,7 @@
#include "can_structs.h" #include "can_structs.h"
#include "scriptcontainer.h" #include "scriptcontainer.h"
#include "connections/canconnection.h"
#include <QDialog> #include <QDialog>
#include <QJSEngine> #include <QJSEngine>
@@ -28,12 +29,7 @@ private slots:
void saveScript(); void saveScript();
void revertScript(); void revertScript();
void recompileScript(); void recompileScript();
void updatedFrames(int); void newFrames(const CANConnection*, const QVector<CANFrame>&);
public slots:
signals:
void sendCANFrame(const CANFrame *, int);
private: private:
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
@@ -44,8 +40,6 @@ private:
QList<ScriptContainer *> scripts; QList<ScriptContainer *> scripts;
ScriptContainer *currentScript; ScriptContainer *currentScript;
const QVector<CANFrame> *modelFrames; const QVector<CANFrame> *modelFrames;
}; };
#endif // SCRIPTINGWINDOW_H #endif // SCRIPTINGWINDOW_H
-96
View File
@@ -1,96 +0,0 @@
#ifndef SERIALWORKER_H
#define SERIALWORKER_H
#include <QDateTime>
#include <QObject>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QTimer>
#include "can_structs.h"
#include "canframemodel.h"
namespace SERIALSTATE {
enum STATE //keep this enum synchronized with the Arduino firmware project
{
IDLE,
GET_COMMAND,
BUILD_CAN_FRAME,
TIME_SYNC,
GET_DIG_INPUTS,
GET_ANALOG_INPUTS,
SET_DIG_OUTPUTS,
SETUP_CANBUS,
GET_CANBUS_PARAMS,
GET_DEVICE_INFO,
SET_SINGLEWIRE_MODE
};
}
using namespace SERIALSTATE;
class SerialWorker : public QObject
{
Q_OBJECT
public:
SerialWorker(CANFrameModel *model, QObject *parent = 0);
~SerialWorker();
void readSettings();
void targetFrameID(int);
signals: //we emit signals
void error(const QString &);
void frameUpdateRapid(int); //sent *much* more rapidly than the above signal - one param for # of frames
void connectionSuccess(int, int);
void connectionFailure();
void deviceInfo(int, int);
void gotTargettedFrame(int);
private slots: //we receive things in slots
void readSerialData();
void connectionTimeout();
void handleTick();
void handleReconnect();
public slots:
void run();
void setSerialPort(QSerialPortInfo*);
void closeSerialPort();
void sendFrame(const CANFrame *, int);
void sendFrameBatch(const QList<CANFrame> *);
void updateBaudRates(int, int);
void stopFrameCapture();
void startFrameCapture(); //only need to call this if previously stopped. Otherwise it's the default
private:
QString portName;
bool quit;
bool connected;
bool capturing;
bool doValidation;
bool gotValidated;
bool isAutoRestart;
bool continuousTimeSync;
QSerialPort *serial;
QSerialPortInfo *currentPort;
CANFrameModel *canModel;
QTimer *ticker;
QMutex sendBulkMutex;
int framesRapid;
int targetID;
STATE rx_state;
int rx_step;
CANFrame *buildFrame;
int can0Baud, can1Baud;
bool can0Enabled, can1Enabled;
int deviceBuildNum;
int deviceSingleWireMode;
uint64_t txTimestampBasis;
uint32_t buildTimeBasis;
void procRXChar(unsigned char);
void sendCommValidation();
};
#endif // SERIALTHREAD_H
+21
View File
@@ -0,0 +1,21 @@
#include <QtTest>
#include "tst_lfqueue.h"
#include "tst_cancon.h"
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
int status = 0;
auto ASSERT_TEST = [&status, argc, argv](QObject* obj) {
status |= QTest::qExec(obj, argc, argv);
delete obj;
};
ASSERT_TEST(new TestLFQueue());
ASSERT_TEST(new TestCanCon(CANCon::SOCKETCAN, "vcan0", 1));
return status;
}
+33
View File
@@ -0,0 +1,33 @@
QT += core gui serialbus widgets testlib serialbus
CONFIG += c++11
INCLUDEPATH += ../ ../connections
SOURCES += \
tst_lfqueue.cpp \
main.cpp \
tst_cancon.cpp \
../connections/canconfactory.cpp \
../connections/canconnection.cpp \
../connections/gvretserial.cpp \
../connections/socketcan.cpp \
../canbus.cpp
#HEADERS += \
# ../utils/lfqueue.h
target.path= .
INSTALLS += target
HEADERS += \
tst_lfqueue.h \
tst_cancon.h \
../connections/canconconst.h \
../connections/canconfactory.h \
../connections/canconnection.h \
../connections/gvretserial.h \
../connections/socketcan.h \
../canbus.h
+366
View File
@@ -0,0 +1,366 @@
#include <QtTest>
#include <QVector>
#include "tst_cancon.h"
#include "canconnection.h"
#include "canconfactory.h"
#define QVERIFYB(statement) \
do {\
if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__))\
return false;\
} while (0)
#define QCOMPAREB(actual, expected) \
do {\
if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\
return false;\
} while (0)
Q_DECLARE_METATYPE(QVector<CANFlt>);
TestCanCon::TestCanCon(CANCon::type pType, QString pPortName, int pNbBus):
mType(pType),
mPortName(pPortName),
mNbBus(pNbBus){}
void TestCanCon::create()
{
CANConnection* conn_p;
QVERIFY(pCreate(conn_p));
/* try to get an element from the queue */
QVERIFY(conn_p->getQueue().get());
if(conn_p)
delete conn_p;
}
void TestCanCon::connectToDevice()
{
CANConnection* conn_p;
QVERIFY(pCreate(conn_p));
QSignalSpy spy(conn_p, SIGNAL(status(CANCon::status)));
/* start connection */
conn_p->start();
/* wait for a signal */
for(int i=0 ; (spy.count() != 1) && (i < 10) ; i++)
QTest::qWait(500);
QCOMPARE(spy.count(), 1); // make sure the signal was emitted exactly one time
QList<QVariant> arguments = spy.takeFirst(); // take the first signal
QVERIFY(arguments.at(0).toInt() == CANCon::CONNECTED); // verify the first argument
/* stop connection */
conn_p->stop();
delete conn_p;
}
void TestCanCon::recvFrames()
{
CANConnection* conn_p;
QVERIFY(pCreate(conn_p));
/* start connection */
conn_p->start();
/* configure */
QVERIFY(pConfig(conn_p));
LFQueue<CANFrame>& queue = conn_p->getQueue();
/* wait for frames to arrive */
QTest::qWait(1000);
int i;
for(i=0 ; queue.peek() && i<1000 ; i++)
{
CANFrame* canf_p = queue.peek();
QVERIFY(pValidateFrame(conn_p, canf_p));
queue.dequeue();
}
QVERIFY(i>0);
/* stop connection */
conn_p->stop();
delete conn_p;
}
void TestCanCon::suspend()
{
CANConnection* conn_p;
QVERIFY(pCreate(conn_p));
/* start connection */
conn_p->start();
/* configure */
QVERIFY(pConfig(conn_p));
LFQueue<CANFrame>& queue = conn_p->getQueue();
/* wait for frames to arrive */
QTest::qWait(1000);
CANFrame* canf_p = queue.peek();
QVERIFY(pValidateFrame(conn_p, canf_p));
conn_p->suspend(true);
/* the queue should be flushed */
canf_p = queue.peek();
QVERIFY(!canf_p);
/* restart capture */
conn_p->suspend(false);
/* wait for frames to arrive */
QTest::qWait(1000);
/* get a frame */
canf_p = queue.peek();
QVERIFY(pValidateFrame(conn_p, canf_p));
/* stop connection */
conn_p->stop();
delete conn_p;
}
void TestCanCon::filter_data()
{
CANConnection* conn_p;
QVERIFY(pCreate(conn_p));
/* start connection */
conn_p->start();
/* configure */
QVERIFY(pConfig(conn_p));
LFQueue<CANFrame>& queue = conn_p->getQueue();
/* wait for frames to arrive */
QTest::qWait(1000);
/* find 3 different ids */
QVector<quint32> ids;
while( queue.peek() && ids.count()!=3 )
{
CANFrame* canf_p = queue.peek();
QVERIFY(pValidateFrame(conn_p, canf_p));
if(!ids.contains(canf_p->ID))
ids.append(canf_p->ID);
queue.dequeue();
}
QCOMPARE(ids.count(), 3);
/* stop connection */
conn_p->stop();
delete conn_p;
/* prepare test vector */
QTest::addColumn<QVector<CANFlt>>("filters");
QTest::addColumn<bool>("filterOut");
QTest::addColumn<bool>("signalReceived");
QTest::addColumn<QVector<quint32>>("filtered");
QVector<CANFlt> filters;
QVector<quint32> filteredIds;
/* one filter no signal*/
filters.clear();
filteredIds.clear();
filters.append({ids[0], 0xFFFF, false});
filteredIds.append(ids[0]);
QTest::newRow("1filternosignal") << filters << false << false << filteredIds;
/* one filter & signal*/
filters.clear();
filteredIds.clear();
filters.append({ids[0], 0xFFFF, true});
filteredIds.append(ids[0]);
QTest::newRow("1filtersignal") << filters << false << true << filteredIds;
/* 3 filters */
filters.clear();
filteredIds.clear();
foreach(quint32 id, ids) {
filters.append({id, 0xFFFF, false});
filteredIds.append(id);
}
QTest::newRow("3filters") << filters << false << false << filteredIds;
}
void TestCanCon::filter()
{
QFETCH(QVector<CANFlt>, filters);
QFETCH(bool, filterOut);
QFETCH(bool, signalReceived);
QFETCH(QVector<quint32>, filtered);
CANConnection* conn_p;
QVERIFY(pCreate(conn_p));
/* start connection */
conn_p->start();
/* set filters */
for(int i=0 ; i<conn_p->getNumBuses() ; i++)
QVERIFY(conn_p->setFilters(i, filters, filterOut));
/* spy signal */
QSignalSpy spy(conn_p, SIGNAL(notify()));
/* configure */
QVERIFY(pConfig(conn_p));
LFQueue<CANFrame>& queue = conn_p->getQueue();
/* wait for frames to arrive */
QTest::qWait(1000);
if(signalReceived)
QVERIFY(spy.count()>0);
int i;
for(i=0 ; queue.peek() && i<1000 ; i++)
{
CANFrame* canf_p = queue.peek();
QVERIFY(pValidateFrame(conn_p, canf_p));
if(filterOut)
QVERIFY(filtered.contains(canf_p->ID));
queue.dequeue();
}
QVERIFY(i>0);
conn_p->stop();
delete conn_p;
}
void TestCanCon::write()
{
CANConnection* conn_p;
QVERIFY(pCreate(conn_p));
/* start connection */
conn_p->start();
/* configure */
QVERIFY(pConfig(conn_p));
QList<CANFrame> frames;
/* build frames */
CANFrame frame;
frame.bus = 0;
frame.ID = 0x1DE;
frame.data[0] = 0xDE;
frame.data[1] = 0xAD;
frame.data[2] = 0xC0;
frame.data[3] = 0xDE;
frame.len = 4;
frames.append(frame);
frame.data[2] = 0xBE;
frame.data[3] = 0xEF;
frames.append(frame);
frame.data[2] = 0xDE;
frame.data[3] = 0xAD;
/* bad frame length */
unsigned int oldVal = frame.len;
frame.len = 9;
QCOMPARE(conn_p->sendFrame(frame), false);
frame.len = oldVal;
/* bad bus id */
oldVal = frame.bus;
frame.bus = 48;
QCOMPARE(conn_p->sendFrame(frame), false);
frame.bus = oldVal;
qDebug() << "Sending DE AD DE AD";
/* send */
QVERIFY(conn_p->sendFrame(frame));
/* leave some time for the frame to be sent */
QTest::qWait(1000);
qDebug() << "Sending DE AD C0 DE";
qDebug() << "Sending DE AD BE EF";
/* send */
QVERIFY(conn_p->sendFrames(frames));
/* leave some time for the frame to be sent */
QTest::qWait(1000);
conn_p->stop();
delete conn_p;
}
/*********************************************************/
bool TestCanCon::pCreate(CANConnection*& pConn_p)
{
pConn_p = CanConFactory::create(mType, mPortName);
QVERIFYB(pConn_p);
QCOMPAREB(pConn_p->getPort(), mPortName);
QCOMPAREB(pConn_p->getNumBuses(), mNbBus);
QCOMPAREB(pConn_p->getType(), mType);
QCOMPAREB(pConn_p->getStatus(), CANCon::NOT_CONNECTED);
return true;
}
bool TestCanCon::pConfig(CANConnection* pConn_p)
{
/*configure buses */
CANBus bus;
CANBus retBus;
for(int i=0 ; i<pConn_p->getNumBuses() ; i++)
{
/* TODO: fix configuration */
bus.active = true;
pConn_p->setBusSettings(i, bus);
QVERIFYB(pConn_p->getBusSettings(i, retBus));
QCOMPAREB(bus, retBus);
}
return true;
}
bool TestCanCon::pValidateFrame(CANConnection* pConn_p, CANFrame* pCan_p)
{
QVERIFYB( pCan_p );
QVERIFYB( (0<=pCan_p->bus) && (pCan_p->bus <= pConn_p->getNumBuses()) );
QVERIFYB( pCan_p->isReceived);
QVERIFYB( pCan_p->len<=8 );
QVERIFYB( (0<=pCan_p->ID) && (pCan_p->ID<2048) );
return true;
}
+33
View File
@@ -0,0 +1,33 @@
#ifndef TESTCANCON_H
#define TESTCANCON_H
#include <QObject>
#include "canconconst.h"
#include "canconnection.h"
class TestCanCon: public QObject
{
Q_OBJECT
public:
TestCanCon(CANCon::type, QString pPortName, int pNbBus);
private:
CANCon::type mType;
QString mPortName;
int mNbBus;
private slots:
void create();
void connectToDevice();
void recvFrames();
void suspend();
void filter();
void filter_data();
void write();
private:
bool pCreate(CANConnection*& pConn_p);
bool pConfig(CANConnection* pConn_p);
bool pValidateFrame(CANConnection* pConn_p, CANFrame* pCan_p);
};
#endif // TESTCANCON_H
+85
View File
@@ -0,0 +1,85 @@
#include <QtTest>
#include <QtConcurrent/qtconcurrentrun.h>
#include "utils/lfqueue.h"
#include "tst_lfqueue.h"
void TestLFQueue::setSize_data()
{
QTest::addColumn<int>("size");
QTest::addColumn<bool>("result");
QTest::newRow("-1") << -1 << false;
QTest::newRow("0") << 0 << true;
QTest::newRow("10") << 10 << true;
QTest::newRow("2000") << 20000 << true;
}
void TestLFQueue::setSize()
{
QFETCH(int, size);
QFETCH(bool, result);
LFQueue<void*> queue;
QCOMPARE(queue.setSize(size), result);
}
void readerThread(LFQueue<int>* pQueue_p, int pSize, bool pSleep) {
int* val_p;
for(int i=0; i<pSize ; i++) {
while(! (val_p = pQueue_p->peek()) );
QVERIFY(val_p);
QCOMPARE(*val_p, i);
pQueue_p->dequeue();
if(pSleep)
QThread::msleep(1);
}
}
void TestLFQueue::exchange_data()
{
QTest::addColumn<int>("size");
QTest::addColumn<bool>("writerSleep");
QTest::addColumn<bool>("readerSleep");
QTest::newRow("nosleep") << 1000 << false << false;
QTest::newRow("readersleep") << 1000 << false << true;
QTest::newRow("writersleep") << 1000 << true << false;
}
void TestLFQueue::exchange()
{
LFQueue<int> queue;
QFETCH(int, size);
QFETCH(bool, writerSleep);
QFETCH(bool, readerSleep);
int* val_p;
QCOMPARE(queue.setSize(2), true);
QFuture<void> thread = QtConcurrent::run(readerThread, &queue, size, readerSleep);
for(int i=0; i<size ; i++) {
while(! (val_p = queue.get()) );
QVERIFY(val_p);
*val_p = i;
queue.queue();
if(writerSleep)
QThread::msleep(1);
}
thread.waitForFinished();
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef TST_LFQUEUE_H
#define TST_LFQUEUE_H
#include <QObject>
class TestLFQueue: public QObject
{
Q_OBJECT
private:
private slots:
void setSize_data();
void setSize();
void exchange_data();
void exchange();
};
#endif // TST_LFQUEUE_H
+223
View File
@@ -0,0 +1,223 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BisectWindow</class>
<widget class="QDialog" name="BisectWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>692</width>
<height>319</height>
</rect>
</property>
<property name="windowTitle">
<string>Bisector Window</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Splitting Strategy:</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QRadioButton" name="rbIDRange">
<property name="text">
<string>ID Range</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cbIDLower"/>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TO</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cbIDUpper"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,10,3">
<item>
<widget class="QRadioButton" name="rbFrameNumber">
<property name="text">
<string>Frame Number</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="slideFrameNumber">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="editFrameNumber"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,10,3">
<item>
<widget class="QRadioButton" name="rbPercentage">
<property name="text">
<string>Percentage</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="slidePercentage">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="pageStep">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="editPercentage"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Save Which Side:</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QRadioButton" name="rbLowerSection">
<property name="text">
<string>Lower Section</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbUpperSection">
<property name="text">
<string>Upper Section</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLabel" name="label_4">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Number of Frames in Main List:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelMainListNum">
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Saved Frames after split:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelSplitNum">
<property name="font">
<font>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QPushButton" name="btnCalculate">
<property name="text">
<string>Calculate Split</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSaveFrames">
<property name="text">
<string>Save split frames to a new file</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnReplaceFrames">
<property name="text">
<string>Replace main list with split frames</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+268
View File
@@ -0,0 +1,268 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConnectionWindow</class>
<widget class="QWidget" name="ConnectionWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>956</width>
<height>527</height>
</rect>
</property>
<property name="windowTitle">
<string>Connection Settings</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="2,1">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Connections:</string>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="tableConnections">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QPushButton" name="btnNewConn">
<property name="text">
<string>New Connection</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnRemoveBus">
<property name="text">
<string>Remove Selected Connection</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QPushButton" name="btnActivateAll">
<property name="text">
<string>Activate All Connections</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnDeactivateAll">
<property name="text">
<string>Deactivate All Connections</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="gbType">
<property name="title">
<string>Connection Type</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QRadioButton" name="rbGVRET">
<property name="text">
<string>GVRET Serial</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbKvaser">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Kvaser</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbSocketCAN">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>SocketCAN</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="lPort">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Port:</string>
</property>
</widget>
</item>
<item>
<widget class="QStackedWidget" name="stPort">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="cbPage">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QComboBox" name="cbPort">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>341</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="etPage">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLineEdit" name="lePort">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckSingleWire">
<property name="text">
<string>Single Wire Mode</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckListenOnly">
<property name="text">
<string>Listen Only Mode</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckEnabled">
<property name="text">
<string>Enabled</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>CAN Speed</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cbSpeed"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QPushButton" name="btnOK">
<property name="text">
<string>Create New Connection</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnRevert">
<property name="text">
<string>Revert</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -11,7 +11,7 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Dialog</string> <string>Firmware Updater</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item alignment="Qt::AlignHCenter"> <item alignment="Qt::AlignHCenter">

Some files were not shown because too many files have changed in this diff Show More