Merge pull request #58 from canpadawan/WIP2

test for better reactivity
This commit is contained in:
Collin Kidder
2016-06-27 19:53:04 -04:00
committed by GitHub
22 changed files with 722 additions and 150 deletions
+8 -1
View File
@@ -11,11 +11,18 @@ public:
int bus;
bool extended;
bool isReceived; //did we receive this or send it?
int len;
uint32_t len;
unsigned char data[8];
uint64_t timestamp;
};
struct CANFlt
{
quint32 id;
quint32 mask;
bool notify;
};
struct J1939ID
{
public:
+1 -1
View File
@@ -17,7 +17,7 @@ CANBus::CANBus(const CANBus& pBus) :
active(pBus.active) {}
bool CANBus::operator==(CANBus& bus) {
bool CANBus::operator==(const CANBus& bus) const{
return speed == bus.speed &&
listenOnly == bus.listenOnly &&
singleWire == bus.singleWire &&
+1 -1
View File
@@ -7,7 +7,7 @@ class CANBus
public:
CANBus();
CANBus(const CANBus&);
bool operator==(CANBus&);
bool operator==(const CANBus&) const;
virtual ~CANBus(){}; /*TODO: remove connection from CANBus and add CANBus as an element of CANConnection */
int speed;
bool listenOnly;
+1 -1
View File
@@ -207,7 +207,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
return QString::number(thisFrame.len);
break;
case 6: //data
for (int i = 0; i < thisFrame.len; i++)
for (unsigned int i = 0; i < thisFrame.len; i++)
{
tempString.append(Utility::formatNumber(thisFrame.data[i]));
tempString.append(" ");
+114 -33
View File
@@ -1,6 +1,15 @@
#include <QThread>
#include "canconnection.h"
struct BusData {
CANBus mBus;
bool mConfigured;
QVector<CANFlt> mFilters;
bool mFilterOut;
};
CANConnection::CANConnection(QString pPort,
CANCon::type pType,
int pNumBuses,
@@ -12,24 +21,25 @@ CANConnection::CANConnection(QString pPort,
mType(pType),
mIsCapSuspended(false),
mStatus(CANCon::NOT_CONNECTED),
mStarted(false),
mThread_p(NULL)
{
qDebug() << "CANConnection()";
/* 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 */
mBus = new CANBus[mNumBuses];
mConfigured = new bool[mNumBuses];
for(int i=0 ; i<mNumBuses ; i++)
mConfigured[i] = false;
/* TODO: change those tables for a vector */
mBusData_p = new BusData[mNumBuses];
for(int i=0 ; i<mNumBuses ; i++) {
mBusData_p[i].mConfigured = false;
mBusData_p[i].mFilterOut = false;
}
/* if needed, create a thread and move ourself into it */
if(pUseThread) {
@@ -40,7 +50,6 @@ CANConnection::CANConnection(QString pPort,
CANConnection::~CANConnection()
{
qDebug() << "~CANConnection()";
/* stop and delete thread */
if(mThread_p) {
mThread_p->quit();
@@ -49,12 +58,10 @@ CANConnection::~CANConnection()
mThread_p = NULL;
}
/* delete bus table */
delete[] mBus;
mBus = NULL;
/* configured table */
delete[] mConfigured;
mConfigured = NULL;
if(mBusData_p) {
delete[] mBusData_p;
mBusData_p = NULL;
}
}
@@ -71,6 +78,9 @@ void CANConnection::start()
return;
}
/* set started flag */
mStarted = true;
/* in multithread case, this will be called before entering thread event loop */
return piStarted();
}
@@ -93,7 +103,7 @@ void CANConnection::suspend(bool pSuspend)
void CANConnection::stop()
{
/* 1) execute in mThread_p context */
if( mThread_p && (mThread_p != QThread::currentThread()) )
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() )
@@ -147,31 +157,37 @@ void CANConnection::setBusSettings(int pBusIdx, CANBus pBus)
}
void CANConnection::sendFrame(const CANFrame& pFrame)
bool CANConnection::sendFrame(const CANFrame& pFrame)
{
/* make sure we execute in mThread context */
if( mThread_p && (mThread_p != QThread::currentThread()) ) {
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;
return ret;
}
return piSendFrame(pFrame);
}
void CANConnection::sendFrameBatch(const QList<CANFrame>& pFrames)
bool CANConnection::sendFrames(const QList<CANFrame>& pFrames)
{
/* make sure we execute in mThread context */
if( mThread_p && (mThread_p != QThread::currentThread()) ) {
QMetaObject::invokeMethod(this, "sendFrameBatch",
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;
return ret;
}
return piSendFrameBatch(pFrames);
return piSendFrames(pFrames);
}
@@ -181,33 +197,33 @@ int CANConnection::getNumBuses() {
bool CANConnection::isConfigured(int pBusId) {
if( pBusId < 0 || pBusId >= mNumBuses)
if( pBusId < 0 || pBusId >= getNumBuses())
return false;
return mConfigured[pBusId];
return mBusData_p[pBusId].mConfigured;
}
void CANConnection::setConfigured(int pBusId, bool pConfigured) {
if( pBusId < 0 || pBusId >= mNumBuses)
if( pBusId < 0 || pBusId >= getNumBuses())
return;
mConfigured[pBusId] = pConfigured;
mBusData_p[pBusId].mConfigured = pConfigured;
}
bool CANConnection::getBusConfig(int pBusId, CANBus& pBus) {
if( pBusId < 0 || pBusId >= mNumBuses || !isConfigured(pBusId))
if( pBusId < 0 || pBusId >= getNumBuses() || !isConfigured(pBusId))
return false;
pBus = mBus[pBusId];
pBus = mBusData_p[pBusId].mBus;
return true;
}
void CANConnection::setBusConfig(int pBusId, CANBus& pBus) {
if( pBusId < 0 || pBusId >= mNumBuses)
if( pBusId < 0 || pBusId >= getNumBuses())
return;
mConfigured[pBusId] = true;
mBus[pBusId] = pBus;
mBusData_p[pBusId].mConfigured = true;
mBusData_p[pBusId].mBus = pBus;
}
@@ -230,7 +246,6 @@ CANCon::status CANConnection::getStatus() {
return (CANCon::status) mStatus.load();
}
void CANConnection::setStatus(CANCon::status pStatus) {
mStatus.store(pStatus);
}
@@ -243,3 +258,69 @@ void CANConnection::setCapSuspended(bool pIsSuspended) {
mIsCapSuspended = pIsSuspended;
}
bool CANConnection::setFilters(int pBusId, const QVector<CANFlt>& pFilters, bool pFilterOut)
{
/* make sure we execute in mThread context */
if( mThread_p && (mThread_p != QThread::currentThread()) ) {
bool ret;
QMetaObject::invokeMethod(this, "setFilters",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, ret),
Q_ARG(int , pBusId),
Q_ARG(const QVector<CANFlt>&, pFilters),
Q_ARG(bool , pFilterOut));
return ret;
}
/* sanity checks */
if(pBusId<0 || pBusId>=getNumBuses())
return false;
/* copy filters */
mBusData_p[pBusId].mFilters = pFilters;
mBusData_p[pBusId].mFilterOut = pFilterOut;
/* set hardware filtering if available */
if(pFilterOut)
piSetFilters(pBusId, pFilters);
return true;
}
bool CANConnection::discard(int pBusId, quint32 pId, bool& pNotify)
{
if(pBusId<0 || pBusId>=getNumBuses())
return true;
foreach (const CANFlt& filter, mBusData_p[pBusId].mFilters)
{
if( (filter.id & filter.mask) == (pId & filter.mask) )
{
if(filter.notify)
pNotify = true;
return false;
}
}
return mBusData_p[pBusId].mFilterOut;
}
bool CANConnection::piSendFrames(const QList<CANFrame>& pFrames)
{
foreach(const CANFrame& frame, pFrames)
{
if(!piSendFrame(frame))
return false;
}
return true;
}
/* default implementation of piSetFilters */
void CANConnection::piSetFilters(int pBusId, const QVector<CANFlt>& pFilters)
{
Q_UNUSED(pBusId);
Q_UNUSED(pFilters);
}
+48 -8
View File
@@ -8,12 +8,13 @@
#include "canbus.h"
#include "canconconst.h"
struct BusData;
class CANConnection : public QObject
{
Q_OBJECT
public:
protected:
/**
* @brief CANConnection constructor
@@ -28,6 +29,9 @@ public:
int pNumBuses,
int pQueueLen,
bool pUseThread);
public:
/**
* @brief CANConnection destructor
*/
@@ -76,6 +80,11 @@ signals:
//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 set with notification hs been received
*/
void notify();
/**
* @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
@@ -118,23 +127,34 @@ public slots:
* @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, it is then safe for callee to flush the queue
* @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)
*/
void sendFrame(const CANFrame& pFrame);
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)
*/
void sendFrameBatch(const QList<CANFrame>& pFrames);
bool sendFrames(const QList<CANFrame>& pFrames);
/**
* @brief sets a filter list. Filters can be used to send a signal or filter out messages
* @param pFilters: a vector of can filters
* @param pFilterOut: if set to true, can frames not matching a filter are discarded
* @return true if filters have been set, false if busid is invalid
*/
bool setFilters(int pBusId, const QVector<CANFlt>& pFilters, bool pFilterOut);
protected:
@@ -186,6 +206,16 @@ protected:
*/
void setCapSuspended(bool pIsSuspended);
/**
* @brief used to check if a message shall be discarded. The function also update pNotify if a notification is expected for that message
* @param pBusId: the bus id on which the frame has been received
* @param pId: the id of the message to filter
* @param pNotify: set to true if a notification is expected, else pNotify is not set
* @return true if message shall be discarded
*/
bool discard(int pBusId, quint32 pId, bool& pNotify);
protected:
/**************************************************************/
@@ -227,25 +257,35 @@ protected:
/**
* @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 void piSendFrame(const CANFrame&) = 0;
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 void piSendFrameBatch(const QList<CANFrame>&) = 0;
virtual bool piSendFrames(const QList<CANFrame>&);
/**
* @brief sets a hardware filter list
* @param pBusId: the bus id on which filters have to be set
* @param pFilters: a vector of can filters, the notification flag of CANFilter is ignored
* @note implementing this function is optional
*/
virtual void piSetFilters(int pBusId, const QVector<CANFlt>& pFilters);
private:
CANBus* mBus;
bool* mConfigured;
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;
};
+2 -2
View File
@@ -141,8 +141,8 @@ void GVRetSerial::piSetBusSettings(int pBusIdx, CANBus bus)
}
void GVRetSerial::piSendFrame(const CANFrame&) {}
void GVRetSerial::piSendFrameBatch(const QList<CANFrame>&){}
bool GVRetSerial::piSendFrame(const CANFrame&) {return false;}
/****************************************************************/
+1 -14
View File
@@ -44,18 +44,6 @@ public:
GVRetSerial(QString portName);
virtual ~GVRetSerial();
signals:
void error(const QString &);
void status(CANCon::status);
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);
protected:
virtual void piStarted();
@@ -63,8 +51,7 @@ protected:
virtual void piSetBusSettings(int pBusIdx, CANBus pBus);
virtual bool piGetBusSettings(int pBusIdx, CANBus& pBus);
virtual void piSuspend(bool pSuspend);
virtual void piSendFrame(const CANFrame&) ;
virtual void piSendFrameBatch(const QList<CANFrame>&);
virtual bool piSendFrame(const CANFrame&) ;
void disconnectDevice();
+27 -10
View File
@@ -15,14 +15,12 @@ SocketCan::SocketCan(QString portName) :
mDev_p(NULL),
mTimer(this) /*NB: set connection as parent of timer to manage it from working thread */
{
qDebug() << "SocketCan()";
}
SocketCan::~SocketCan()
{
stop();
qDebug() << "~SocketCan()";
}
@@ -102,8 +100,20 @@ void SocketCan::piSetBusSettings(int pBusIdx, CANBus bus)
}
void SocketCan::piSendFrame(const CANFrame&) {}
void SocketCan::piSendFrameBatch(const QList<CANFrame>&){}
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);
}
/***********************************/
@@ -142,6 +152,9 @@ void SocketCan::framesWritten(qint64 count)
void SocketCan::framesReceived()
{
/* test */
bool sndNotif = false;
/* sanity checks */
if(!mDev_p)
return;
@@ -153,15 +166,16 @@ void SocketCan::framesReceived()
/* exit case */
if(!recFrame.isValid())
return;
break;
/* drop frame if capture is suspended */
if(isCapSuspended())
continue;
/* check frame */
if(!recFrame.payload().isEmpty() &&
recFrame.payload().length()<=8)
if( !recFrame.payload().isEmpty() &&
recFrame.payload().length()<=8 &&
!discard(0, recFrame.frameId(), sndNotif) )
{
CANFrame* frame_p = getQueue().get();
if(frame_p) {
@@ -176,12 +190,15 @@ void SocketCan::framesReceived()
/* enqueue frame */
getQueue().queue();
}
#if 0
else
qDebug() << "can't get a frame, ERROR";
#endif
}
else {
qDebug() << "invalid frame";
}
}
if(sndNotif) {
emit notify();
}
}
+1 -14
View File
@@ -18,18 +18,6 @@ public:
SocketCan(QString portName);
virtual ~SocketCan();
signals:
void error(const QString &);
void status(CANCon::status);
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);
protected:
virtual void piStarted();
@@ -37,8 +25,7 @@ protected:
virtual void piSetBusSettings(int pBusIdx, CANBus pBus);
virtual bool piGetBusSettings(int pBusIdx, CANBus& pBus);
virtual void piSuspend(bool pSuspend);
virtual void piSendFrame(const CANFrame&) ;
virtual void piSendFrameBatch(const QList<CANFrame>&);
virtual bool piSendFrame(const CANFrame&);
void disconnectDevice();
+22 -6
View File
@@ -1,13 +1,18 @@
#include <QCanBus>
#include <QThread>
#include "connectionwindow.h"
#include "ui_connectionwindow.h"
#include "connections/canconfactory.h"
#define FALSE 0
#define TRUE 1
ConnectionWindow::ConnectionWindow(CANFrameModel *cModel, QWidget *parent) :
QDialog(parent),
ui(new Ui::ConnectionWindow)
ui(new Ui::ConnectionWindow),
mRefreshReqOngoing(FALSE)
{
ui->setupUi(this);
@@ -104,17 +109,20 @@ void ConnectionWindow::showEvent(QShowEvent* event)
}
void ConnectionWindow::refreshCanList() {
QList<CANConnection*>::iterator conn_p;
QList<CANConnection*>& conns = connModel->getConnections();
QList<CANConnection*>& conns = connModel->getConnections();
CANFrame* frame_p = NULL;
for (conn_p = conns.begin(); conn_p != conns.end(); ++conn_p) {
while( (frame_p = (*conn_p)->getQueue().peek() ) ) {
foreach (CANConnection* conn_p, conns)
{
while( (frame_p = conn_p->getQueue().peek() ) ) {
canModel->addFrame(*frame_p, true);
(*conn_p)->getQueue().dequeue();
conn_p->getQueue().dequeue();
}
}
/* erase flag (this should be done before we start dequeuing...) */
mRefreshReqOngoing.store(FALSE);
}
void ConnectionWindow::handleNewConn()
@@ -272,8 +280,16 @@ void ConnectionWindow::handleOKButton()
connect(conn_p, SIGNAL(status(CANCon::status)),
this, SLOT(connectionStatus(CANCon::status)));
//conn_p->setCallback(std::bind(&ConnectionWindow::callback, this, std::placeholders::_1));
/*TODO add return value and checks */
conn_p->start();
/*{
QVector<CANFlt> flters;
flters.append({0x305, 0xFFFF, true});
conn_p->setFilters(0, flters, false);
connect(conn_p, SIGNAL(notify()), this, SLOT(refreshCanList()));
}*/
for (int i=0 ; i<conn_p->getNumBuses() ; i++) {
/* set bus configuration */
+1 -2
View File
@@ -8,8 +8,6 @@
#include <QDebug>
#include <QSettings>
#include <QTimer>
//#include "canconnection_old.h"
//#include "serialworker.h"
#include "canconnectionmodel.h"
#include "canframemodel.h"
@@ -68,6 +66,7 @@ private:
CANFrameModel *canModel;
QTimer mTicker;
QAtomicInt mRefreshReqOngoing;
void selectSerial();
void selectKvaser();
+3 -3
View File
@@ -112,7 +112,7 @@ void FileComparatorWindow::calculateDetails()
CANFrame frame = interestedFrames.at(x);
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]]++;
tmp = frame.data[y];
@@ -137,7 +137,7 @@ void FileComparatorWindow::calculateDetails()
}
}
//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;
tmp = frame.data[y];
@@ -177,7 +177,7 @@ void FileComparatorWindow::calculateDetails()
}
}
//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;
tmp = frame.data[y];
+24 -27
View File
@@ -322,7 +322,7 @@ bool FrameFileIO::loadCRTDFile(QString filename, QVector<CANFrame>* frames)
else thisFrame.isReceived = true;
thisFrame.bus = 0;
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] != "")
{
@@ -379,7 +379,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->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->putChar(' ');
@@ -446,9 +446,9 @@ bool FrameFileIO::loadNativeCSVFile(QString filename, QVector<CANFrame>* frames)
{
thisFrame.isReceived = true;
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 d = 0; d < thisFrame.len; d++)
for (unsigned int d = 0; d < thisFrame.len; d++)
thisFrame.data[d] = tokens[5 + d].toInt(NULL, 16);
}
else if (fileVersion == 2)
@@ -456,10 +456,10 @@ bool FrameFileIO::loadNativeCSVFile(QString filename, QVector<CANFrame>* frames)
if (tokens[3].at(0) == 'R') thisFrame.isReceived = true;
else thisFrame.isReceived = false;
thisFrame.bus = tokens[4].toInt();
thisFrame.len = tokens[5].toInt();
if (thisFrame.len + 6 > tokens.length()) thisFrame.len = tokens.length() - 6;
thisFrame.len = tokens[5].toUInt();
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 d = 0; d < thisFrame.len; d++)
for (unsigned int d = 0; d < thisFrame.len; d++)
thisFrame.data[d] = tokens[6 + d].toInt(NULL, 16);
}
@@ -570,7 +570,7 @@ bool FrameFileIO::loadGenericCSVFile(QString filename, QVector<CANFrame>* frames
QList<QByteArray> dataTok = tokens[1].split(' ');
thisFrame.len = dataTok.length();
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);
}
@@ -608,7 +608,7 @@ bool FrameFileIO::saveGenericCSVFile(QString filename, const QVector<CANFrame>*
outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
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->putChar(' ');
@@ -696,10 +696,9 @@ bool FrameFileIO::loadLogFile(QString filename, QVector<CANFrame>* frames)
if (tokens[4] == "s") thisFrame.extended = false;
else thisFrame.extended = true;
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 < 0) thisFrame.len = 0;
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = tokens[d + 6].toInt(NULL, 16);
for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = tokens[d + 6].toInt(NULL, 16);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -759,7 +758,7 @@ bool FrameFileIO::saveLogFile(QString filename, const QVector<CANFrame>* frames)
else outFile->write(" s ");
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->putChar(' ');
@@ -836,7 +835,7 @@ bool FrameFileIO::loadIXXATFile(QString filename, QVector<CANFrame>* frames)
QStringList dataToks = unQuote(tokens[4]).simplified().split(' ');
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);
}
else foundErrors = true;
@@ -889,7 +888,7 @@ bool FrameFileIO::saveIXXATFile(QString filename, const QVector<CANFrame>* frame
else outFile->write(",\"Std\"");
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->putChar(' ');
@@ -952,7 +951,7 @@ bool FrameFileIO::loadCANDOFile(QString filename, QVector<CANFrame>* frames)
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);
}
else foundErrors = true;
@@ -1008,7 +1007,7 @@ bool FrameFileIO::saveCANDOFile(QString filename, const QVector<CANFrame>* frame
data[1] = (char)(ms & 0xFF);
data[2] = (char)(id & 0xFF);
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);
}
}
@@ -1074,11 +1073,10 @@ bool FrameFileIO::loadMicrochipFile(QString filename, QVector<CANFrame>* frames)
if (thisFrame.ID <= 0x7FF) thisFrame.extended = false;
else thisFrame.extended = true;
thisFrame.bus = 0;
thisFrame.len = tokens[3].toInt();
thisFrame.len = tokens[3].toUInt();
if (thisFrame.len > 8) thisFrame.len = 8;
if (thisFrame.len < 0) thisFrame.len = 0;
if (thisFrame.len + 4 > tokens.length()) thisFrame.len = tokens.length() - 4;
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)Utility::ParseStringToNum(tokens[4 + d]);
if (thisFrame.len + 4 > (unsigned int) 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]);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -1140,7 +1138,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(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->putChar(';');
@@ -1233,12 +1231,11 @@ bool FrameFileIO::loadTraceFile(QString filename, QVector<CANFrame>* frames)
if (thisFrame.ID <= 0x7FF) thisFrame.extended = false;
else thisFrame.extended = true;
thisFrame.bus = 0;
thisFrame.len = tokens[3].toInt();
if (thisFrame.len < 0) thisFrame.len = 0;
thisFrame.len = tokens[3].toUInt();
if (thisFrame.len > 8) thisFrame.len = 8;
QList<QByteArray> dataToks = tokens[4].split(' ');
if (thisFrame.len > dataToks.length()) thisFrame.len = dataToks.length();
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)dataToks[d].toInt(NULL, 16);
if (thisFrame.len > (unsigned int) dataToks.length()) thisFrame.len = (unsigned int) dataToks.length();
for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)dataToks[d].toInt(NULL, 16);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -1325,7 +1322,7 @@ bool FrameFileIO::saveTraceFile(QString filename, const QVector<CANFrame> * fram
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->putChar(' ');
+2 -2
View File
@@ -157,7 +157,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui->lbNumFrames->setText("0");
connect(&updateTimer, &QTimer::timeout, this, &MainWindow::tickGUIUpdate);
updateTimer.setInterval(250);
updateTimer.setInterval(500); //test 250);
updateTimer.start();
elapsedTime = new QTime;
@@ -679,7 +679,7 @@ Data Bytes: 88 10 00 13 BB 00 06 00
outFile->write(builderString.toUtf8());
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]) + " ";
}
+3 -4
View File
@@ -93,13 +93,12 @@ void ScriptContainer::sendFrame(QJSValue bus, QJSValue id, QJSValue length, QJSV
CANFrame frame;
frame.extended = false;
frame.ID = id.toInt();
frame.len = length.toInt();
if (frame.len < 0) frame.len = 0;
frame.len = length.toUInt();
if (frame.len > 8) frame.len = 8;
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();
}
@@ -125,7 +124,7 @@ void ScriptContainer::gotFrame(const CANFrame &frame)
QJSValueList args;
args << frame.bus << frame.ID << 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);
gotFrameFunction.call(args);
return; //as soon as one filter matches we jump out
+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;
}
+21 -4
View File
@@ -1,12 +1,19 @@
QT += widgets testlib
QT -= gui
QT += core gui serialbus widgets testlib serialbus
CONFIG += c++11
INCLUDEPATH += ../utils
INCLUDEPATH += ../ ../connections
SOURCES += \
tst_lfqueue.cpp
tst_lfqueue.cpp \
main.cpp \
tst_cancon.cpp \
../connections/canconfactory.cpp \
../connections/canconnection.cpp \
../connections/gvretserial.cpp \
../connections/socketcan.cpp \
../canbus.cpp
#HEADERS += \
@@ -14,3 +21,13 @@ SOURCES += \
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
+4 -17
View File
@@ -1,19 +1,10 @@
#include <QtTest/QtTest>
#include <QtTest>
#include <QtConcurrent/qtconcurrentrun.h>
#include "lfqueue.h"
#include "utils/lfqueue.h"
#include "tst_lfqueue.h"
class TestLFQueue: public QObject
{
Q_OBJECT
private:
private slots:
void setSize_data();
void setSize();
void exchange_data();
void exchange();
};
void TestLFQueue::setSize_data()
@@ -92,7 +83,3 @@ void TestLFQueue::exchange()
thread.waitForFinished();
}
QTEST_MAIN(TestLFQueue)
#include "tst_lfqueue.moc"
+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