Lots of large changes to scripting support, changes to the way

filtering works with ISOTP/UDS messages, updated version number.
This commit is contained in:
Collin Kidder
2017-08-22 21:42:30 -04:00
parent 6ef5757a4d
commit 162d79fbe9
12 changed files with 226 additions and 34 deletions
+28 -7
View File
@@ -130,7 +130,19 @@ void ISOTP_HANDLER::rapidFrames(const CANConnection* conn, const QVector<CANFram
{ {
//only process frames that we've marked are ISOTP frames //only process frames that we've marked are ISOTP frames
//unless processAll is true //unless processAll is true
if (isoIDs[thisFrame.ID] || processAll) processFrame(thisFrame); if (processAll) processFrame(thisFrame);
else
{
for (int i = 0; i < filters.count(); i++)
{
if ((thisFrame.bus == filters[i].bus) && ((thisFrame.ID & filters[i].mask) == filters[i].ID))
{
processFrame(thisFrame);
break;
}
}
}
} }
} }
@@ -327,18 +339,27 @@ void ISOTP_HANDLER::setProcessAll(bool state)
processAll = state; processAll = state;
} }
void ISOTP_HANDLER::addID(uint32_t id) void ISOTP_HANDLER::addFilter(int pBusId, uint32_t ID, uint32_t mask)
{ {
isoIDs[id] = true; CANFilter filt;
filt.ID = ID;
filt.bus = pBusId;
filt.mask = mask;
filters.append(filt);
} }
void ISOTP_HANDLER::removeID(uint32_t id) void ISOTP_HANDLER::removeFilter(int pBusId, uint32_t ID, uint32_t mask)
{ {
isoIDs.remove(id); for (int i = 0; i < filters.count(); i++)
{
if (filters[i].bus == pBusId && filters[i].ID == ID && filters[i].mask == mask) filters.removeAt(i);
}
} }
void ISOTP_HANDLER::clearAllIDs() void ISOTP_HANDLER::clearAllFilters()
{ {
isoIDs.clear(); filters.clear();
} }
+5 -4
View File
@@ -9,6 +9,7 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "canframemodel.h" #include "canframemodel.h"
#include "isotp_message.h" #include "isotp_message.h"
#include "canfilter.h"
class ISOTP_HANDLER : public QObject class ISOTP_HANDLER : public QObject
{ {
@@ -22,9 +23,9 @@ public:
void sendISOTPFrame(int bus, int ID, QVector<unsigned char> data); void sendISOTPFrame(int bus, int ID, QVector<unsigned char> data);
void setProcessAll(bool state); void setProcessAll(bool state);
void setFlowCtrl(bool state); void setFlowCtrl(bool state);
void addID(uint32_t id); void addFilter(int pBusId, uint32_t ID, uint32_t mask);
void removeID(uint32_t id); void removeFilter(int pBusId, uint32_t ID, uint32_t mask);
void clearAllIDs(); void clearAllFilters();
public slots: public slots:
void updatedFrames(int); void updatedFrames(int);
@@ -37,7 +38,7 @@ signals:
private: private:
QList<ISOTP_MESSAGE> messageBuffer; QList<ISOTP_MESSAGE> messageBuffer;
QList<CANFrame> sendingFrames; QList<CANFrame> sendingFrames;
QMap<uint32_t, bool> isoIDs; QList<CANFilter> filters;
const QVector<CANFrame> *modelFrames; const QVector<CANFrame> *modelFrames;
bool useExtendedAddressing; bool useExtendedAddressing;
bool isReceiving; bool isReceiving;
+6 -7
View File
@@ -270,19 +270,18 @@ void UDS_HANDLER::setProcessAllIDs(bool state)
isoHandler->setProcessAll(state); isoHandler->setProcessAll(state);
} }
void UDS_HANDLER::addID(uint32_t id) void UDS_HANDLER::addFilter(int pBusId, uint32_t ID, uint32_t mask)
{ {
isoHandler->addID(id); isoHandler->addFilter(pBusId, ID, mask);
} }
void UDS_HANDLER::removeID(uint32_t id) void UDS_HANDLER::removeFilter(int pBusId, uint32_t ID, uint32_t mask)
{ {
isoHandler->removeID(id); isoHandler->removeFilter(pBusId, ID, mask);
} }
void UDS_HANDLER::clearAllIDs() void UDS_HANDLER::clearAllFilters()
{ {
isoHandler->clearAllIDs(); isoHandler->clearAllFilters();
} }
+4 -3
View File
@@ -94,9 +94,10 @@ public:
void sendUDSFrame(const UDS_MESSAGE &msg); void sendUDSFrame(const UDS_MESSAGE &msg);
void setProcessAllIDs(bool state); void setProcessAllIDs(bool state);
void setFlowCtrl(bool state); void setFlowCtrl(bool state);
void addID(uint32_t id); void addFilter(int pBusId, uint32_t ID, uint32_t mask);
void removeID(uint32_t id); void removeFilter(int pBusId, uint32_t ID, uint32_t mask);
void clearAllIDs(); void clearAllFilters();
QString getServiceShortDesc(int service); QString getServiceShortDesc(int service);
QString getServiceLongDesc(int service); QString getServiceLongDesc(int service);
QString getNegativeResponseShort(int respCode); QString getNegativeResponseShort(int respCode);
+2 -2
View File
@@ -17,14 +17,14 @@ public:
uint64_t timestamp; uint64_t timestamp;
}; };
class CANFlt class CANFltObserver
{ {
public: public:
quint32 id; quint32 id;
quint32 mask; quint32 mask;
QObject * observer; //used to target the specific object that setup this filter QObject * observer; //used to target the specific object that setup this filter
bool operator ==(const CANFlt &b) const bool operator ==(const CANFltObserver &b) const
{ {
if ( (id == b.id) && (mask == b.mask) && (observer == b.observer) ) return true; if ( (id == b.id) && (mask == b.mask) && (observer == b.observer) ) return true;
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef CONFIG #ifndef CONFIG
#define CONFIG #define CONFIG
#define VERSION 173 #define VERSION 174
//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
+6 -6
View File
@@ -6,7 +6,7 @@
struct BusData { struct BusData {
CANBus mBus; CANBus mBus;
bool mConfigured; bool mConfigured;
QVector<CANFlt> mTargettedFrames; QVector<CANFltObserver> mTargettedFrames;
}; };
@@ -28,7 +28,7 @@ CANConnection::CANConnection(QString pPort,
qRegisterMetaType<CANBus>("CANBus"); qRegisterMetaType<CANBus>("CANBus");
qRegisterMetaType<CANFrame>("CANFrame"); qRegisterMetaType<CANFrame>("CANFrame");
qRegisterMetaType<CANCon::status>("CANCon::status"); qRegisterMetaType<CANCon::status>("CANCon::status");
qRegisterMetaType<CANFlt>("CANFlt"); qRegisterMetaType<CANFltObserver>("CANFlt");
/* set queue size */ /* set queue size */
mQueue.setSize(pQueueLen); /*TODO add check on returned value */ mQueue.setSize(pQueueLen); /*TODO add check on returned value */
@@ -289,7 +289,7 @@ bool CANConnection::addTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QO
return false; return false;
qDebug() << "Connection is registering a new targetted frame filter, local bus " << pBusId; qDebug() << "Connection is registering a new targetted frame filter, local bus " << pBusId;
CANFlt target; CANFltObserver target;
target.id = ID; target.id = ID;
target.mask = mask; target.mask = mask;
target.observer = receiver; target.observer = receiver;
@@ -317,7 +317,7 @@ bool CANConnection::removeTargettedFrame(int pBusId, uint32_t ID, uint32_t mask,
if(pBusId < -1 || pBusId >= getNumBuses()) if(pBusId < -1 || pBusId >= getNumBuses())
return false; return false;
CANFlt target; CANFltObserver target;
target.id = ID; target.id = ID;
target.mask = mask; target.mask = mask;
target.observer = receiver; target.observer = receiver;
@@ -329,7 +329,7 @@ bool CANConnection::removeTargettedFrame(int pBusId, uint32_t ID, uint32_t mask,
bool CANConnection::removeAllTargettedFrames(QObject *receiver) bool CANConnection::removeAllTargettedFrames(QObject *receiver)
{ {
for (int i = 0; i < getNumBuses(); i++) { for (int i = 0; i < getNumBuses(); i++) {
foreach (const CANFlt filt, mBusData_p[i].mTargettedFrames) foreach (const CANFltObserver filt, mBusData_p[i].mTargettedFrames)
{ {
if (filt.observer == receiver) mBusData_p[i].mTargettedFrames.removeOne(filt); if (filt.observer == receiver) mBusData_p[i].mTargettedFrames.removeOne(filt);
} }
@@ -345,7 +345,7 @@ void CANConnection::checkTargettedFrame(CANFrame &frame)
if (mBusData_p == 0) return; if (mBusData_p == 0) return;
if (mBusData_p[frame.bus].mTargettedFrames.length() == 0) return; if (mBusData_p[frame.bus].mTargettedFrames.length() == 0) return;
foreach (const CANFlt filt, mBusData_p[frame.bus].mTargettedFrames) foreach (const CANFltObserver filt, mBusData_p[frame.bus].mTargettedFrames)
{ {
//qDebug() << "Checking filter with id " << filt.id << " mask " << filt.mask; //qDebug() << "Checking filter with id " << filt.id << " mask " << filt.mask;
maskedID = frame.ID & filt.mask; maskedID = frame.ID & filt.mask;
+1 -1
View File
@@ -396,7 +396,7 @@ void MainWindow::tickGUIUpdate()
//{ //{
int elapsed = elapsedTime->elapsed(); int elapsed = elapsedTime->elapsed();
if(elapsed) { if(elapsed) {
framesPerSec = rxFrames * 1000 / elapsed; framesPerSec = (framesPerSec + (rxFrames * 1000 / elapsed)) / 2;
elapsedTime->restart(); elapsedTime->restart();
} }
else else
+1
View File
@@ -35,6 +35,7 @@
class ConnectionWindow; class ConnectionWindow;
class ISOTP_InterpreterWindow; class ISOTP_InterpreterWindow;
class ScriptingWindow;
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
+146 -2
View File
@@ -7,8 +7,8 @@
ScriptContainer::ScriptContainer() ScriptContainer::ScriptContainer()
{ {
canHelper = new CANScriptHelper(&scriptEngine); canHelper = new CANScriptHelper(&scriptEngine);
isoHelper = new ISOTPScriptHelper; isoHelper = new ISOTPScriptHelper(&scriptEngine);
udsHelper = new UDSScriptHelper; udsHelper = new UDSScriptHelper(&scriptEngine);
elapsedTime.start(); elapsedTime.start();
connect(&timer, SIGNAL(timeout()), this, SLOT(tick())); connect(&timer, SIGNAL(timeout()), this, SLOT(tick()));
} }
@@ -104,6 +104,9 @@ void ScriptContainer::tick()
} }
/* CANScriptHandler Methods */ /* CANScriptHandler Methods */
CANScriptHelper::CANScriptHelper(QJSEngine *engine) CANScriptHelper::CANScriptHelper(QJSEngine *engine)
@@ -186,3 +189,144 @@ void CANScriptHelper::gotTargettedFrame(const CANFrame &frame)
} }
/* ISOTPScriptHelper methods */
ISOTPScriptHelper::ISOTPScriptHelper(QJSEngine *engine)
{
scriptEngine = engine;
handler = new ISOTP_HANDLER;
connect(handler, SIGNAL(newISOMessage(ISOTP_MESSAGE)), this, SLOT(newISOMessage(ISOTP_MESSAGE)));
handler->setReception(true);
}
void ISOTPScriptHelper::clearFilters()
{
handler->clearAllFilters();
}
void ISOTPScriptHelper::setFilter(QJSValue id, QJSValue mask, QJSValue bus)
{
uint32_t idVal = id.toUInt();
uint32_t maskVal = mask.toUInt();
int busVal = bus.toInt();
qDebug() << "Called isotp set filter";
qDebug() << idVal << "*" << maskVal << "*" << busVal;
handler->addFilter(busVal, idVal, maskVal);
}
void ISOTPScriptHelper::sendISOTP(QJSValue bus, QJSValue id, QJSValue length, QJSValue data)
{
ISOTP_MESSAGE msg;
msg.extended = false;
msg.ID = id.toInt();
msg.len = length.toUInt();
if (!data.isArray()) qDebug() << "data isn't an array";
for (unsigned int i = 0; i < msg.len; i++)
{
msg.data[i] = (uint8_t)data.property(i).toInt();
}
msg.bus = (uint32_t)bus.toInt();
if (msg.ID > 0x7FF) msg.extended = true;
qDebug() << "sending isotp message from script";
handler->sendISOTPFrame(msg.bus, msg.ID, msg.data);
}
void ISOTPScriptHelper::setRxCallback(QJSValue cb)
{
gotFrameFunction = cb;
}
void ISOTPScriptHelper::newISOMessage(ISOTP_MESSAGE msg)
{
if (!gotFrameFunction.isCallable()) return; //nothing to do if we can't even call the function
//qDebug() << "Got frame in script interface";
QJSValueList args;
args << msg.bus << msg.ID << msg.len;
QJSValue dataBytes = scriptEngine->newArray(msg.len);
for (unsigned int j = 0; j < msg.len; j++) dataBytes.setProperty(j, QJSValue(msg.data[j]));
args.append(dataBytes);
gotFrameFunction.call(args);
}
/* UDSScriptHelper methods */
UDSScriptHelper::UDSScriptHelper(QJSEngine *engine)
{
scriptEngine = engine;
handler = new UDS_HANDLER;
connect(handler, SIGNAL(newUDSMessage(UDS_MESSAGE)), this, SLOT(newUDSMessage(UDS_MESSAGE)));
handler->setReception(true);
}
void UDSScriptHelper::clearFilters()
{
handler->clearAllFilters();
}
void UDSScriptHelper::setFilter(QJSValue id, QJSValue mask, QJSValue bus)
{
uint32_t idVal = id.toUInt();
uint32_t maskVal = mask.toUInt();
int busVal = bus.toInt();
qDebug() << "Called uds set filter";
qDebug() << idVal << "*" << maskVal << "*" << busVal;
handler->addFilter(busVal, idVal, maskVal);
}
void UDSScriptHelper::sendUDS(QJSValue bus, QJSValue id, QJSValue service, QJSValue sublen, QJSValue subFunc, QJSValue length, QJSValue data)
{
UDS_MESSAGE msg;
msg.extended = false;
msg.ID = id.toInt();
msg.len = length.toUInt();
msg.service = service.toUInt();
msg.subFuncLen = sublen.toUInt();
msg.subFunc = subFunc.toUInt();
if (!data.isArray()) qDebug() << "data isn't an array";
for (unsigned int i = 0; i < msg.len; i++)
{
msg.data[i] = (uint8_t)data.property(i).toInt();
}
msg.bus = (uint32_t)bus.toInt();
if (msg.ID > 0x7FF) msg.extended = true;
qDebug() << "sending UDS message from script";
handler->sendUDSFrame(msg);
}
void UDSScriptHelper::setRxCallback(QJSValue cb)
{
gotFrameFunction = cb;
}
void UDSScriptHelper::newUDSMessage(UDS_MESSAGE msg)
{
if (!gotFrameFunction.isCallable()) return; //nothing to do if we can't even call the function
//qDebug() << "Got frame in script interface";
QJSValueList args;
args << msg.bus << msg.ID << msg.service << msg.subFunc << msg.len;
QJSValue dataBytes = scriptEngine->newArray(msg.len);
for (unsigned int j = 0; j < msg.len; j++) dataBytes.setProperty(j, QJSValue(msg.data[j]));
args.append(dataBytes);
gotFrameFunction.call(args);
}
+23
View File
@@ -3,6 +3,9 @@
#include "can_structs.h" #include "can_structs.h"
#include "canfilter.h" #include "canfilter.h"
#include "bus_protocols/isotp_handler.h"
#include "bus_protocols/isotp_message.h"
#include "bus_protocols/uds_handler.h"
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QJSEngine> #include <QJSEngine>
@@ -33,17 +36,37 @@ private:
class ISOTPScriptHelper: public QObject class ISOTPScriptHelper: public QObject
{ {
Q_OBJECT Q_OBJECT
public:
ISOTPScriptHelper(QJSEngine *engine);
public slots:
void setFilter(QJSValue id, QJSValue mask, QJSValue bus);
void clearFilters();
void sendISOTP(QJSValue bus, QJSValue id, QJSValue length, QJSValue data);
void setRxCallback(QJSValue cb);
private slots:
void newISOMessage(ISOTP_MESSAGE msg);
private: private:
QJSValue gotFrameFunction; QJSValue gotFrameFunction;
QJSEngine *scriptEngine; QJSEngine *scriptEngine;
ISOTP_HANDLER *handler;
}; };
class UDSScriptHelper: public QObject class UDSScriptHelper: public QObject
{ {
Q_OBJECT Q_OBJECT
public:
UDSScriptHelper(QJSEngine *engine);
public slots:
void setFilter(QJSValue id, QJSValue mask, QJSValue bus);
void clearFilters();
void sendUDS(QJSValue bus, QJSValue id, QJSValue service, QJSValue sublen, QJSValue subFunc, QJSValue length, QJSValue data);
void setRxCallback(QJSValue cb);
private slots:
void newUDSMessage(UDS_MESSAGE msg);
private: private:
QJSValue gotFrameFunction; QJSValue gotFrameFunction;
QJSEngine *scriptEngine; QJSEngine *scriptEngine;
UDS_HANDLER *handler;
}; };
class ScriptContainer : public QObject class ScriptContainer : public QObject
+3 -1
View File
@@ -1,14 +1,16 @@
#ifndef SCRIPTINGWINDOW_H #ifndef SCRIPTINGWINDOW_H
#define SCRIPTINGWINDOW_H #define SCRIPTINGWINDOW_H
#include "can_structs.h"
#include "scriptcontainer.h" #include "scriptcontainer.h"
#include "can_structs.h"
#include "connections/canconnection.h" #include "connections/canconnection.h"
#include "jsedit.h" #include "jsedit.h"
#include <QDialog> #include <QDialog>
#include <QJSEngine> #include <QJSEngine>
class ScriptContainer;
namespace Ui { namespace Ui {
class ScriptingWindow; class ScriptingWindow;
} }