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; int 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;
}; };
struct CANFlt
{
quint32 id;
quint32 mask;
bool notify;
};
struct J1939ID struct J1939ID
{ {
public: public:
+1 -1
View File
@@ -17,7 +17,7 @@ CANBus::CANBus(const CANBus& pBus) :
active(pBus.active) {} active(pBus.active) {}
bool CANBus::operator==(CANBus& bus) { bool CANBus::operator==(const CANBus& bus) const{
return speed == bus.speed && return speed == bus.speed &&
listenOnly == bus.listenOnly && listenOnly == bus.listenOnly &&
singleWire == bus.singleWire && singleWire == bus.singleWire &&
+1 -1
View File
@@ -7,7 +7,7 @@ class CANBus
public: public:
CANBus(); CANBus();
CANBus(const 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 */ virtual ~CANBus(){}; /*TODO: remove connection from CANBus and add CANBus as an element of CANConnection */
int speed; int speed;
bool listenOnly; bool listenOnly;
+1 -1
View File
@@ -207,7 +207,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
return QString::number(thisFrame.len); return QString::number(thisFrame.len);
break; break;
case 6: //data 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(Utility::formatNumber(thisFrame.data[i]));
tempString.append(" "); tempString.append(" ");
+114 -33
View File
@@ -1,6 +1,15 @@
#include <QThread> #include <QThread>
#include "canconnection.h" #include "canconnection.h"
struct BusData {
CANBus mBus;
bool mConfigured;
QVector<CANFlt> mFilters;
bool mFilterOut;
};
CANConnection::CANConnection(QString pPort, CANConnection::CANConnection(QString pPort,
CANCon::type pType, CANCon::type pType,
int pNumBuses, int pNumBuses,
@@ -12,24 +21,25 @@ CANConnection::CANConnection(QString pPort,
mType(pType), mType(pType),
mIsCapSuspended(false), mIsCapSuspended(false),
mStatus(CANCon::NOT_CONNECTED), mStatus(CANCon::NOT_CONNECTED),
mStarted(false),
mThread_p(NULL) mThread_p(NULL)
{ {
qDebug() << "CANConnection()";
/* register types */ /* register types */
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");
/* set queue size */ /* set queue size */
mQueue.setSize(pQueueLen); /*TODO add check on returned value */ mQueue.setSize(pQueueLen); /*TODO add check on returned value */
/* allocate buses */ /* allocate buses */
mBus = new CANBus[mNumBuses]; /* TODO: change those tables for a vector */
mConfigured = new bool[mNumBuses]; mBusData_p = new BusData[mNumBuses];
for(int i=0 ; i<mNumBuses ; i++) {
for(int i=0 ; i<mNumBuses ; i++) mBusData_p[i].mConfigured = false;
mConfigured[i] = false; mBusData_p[i].mFilterOut = false;
}
/* if needed, create a thread and move ourself into it */ /* if needed, create a thread and move ourself into it */
if(pUseThread) { if(pUseThread) {
@@ -40,7 +50,6 @@ CANConnection::CANConnection(QString pPort,
CANConnection::~CANConnection() CANConnection::~CANConnection()
{ {
qDebug() << "~CANConnection()";
/* stop and delete thread */ /* stop and delete thread */
if(mThread_p) { if(mThread_p) {
mThread_p->quit(); mThread_p->quit();
@@ -49,12 +58,10 @@ CANConnection::~CANConnection()
mThread_p = NULL; mThread_p = NULL;
} }
/* delete bus table */ if(mBusData_p) {
delete[] mBus; delete[] mBusData_p;
mBus = NULL; mBusData_p = NULL;
/* configured table */ }
delete[] mConfigured;
mConfigured = NULL;
} }
@@ -71,6 +78,9 @@ void CANConnection::start()
return; return;
} }
/* set started flag */
mStarted = true;
/* in multithread case, this will be called before entering thread event loop */ /* in multithread case, this will be called before entering thread event loop */
return piStarted(); return piStarted();
} }
@@ -93,7 +103,7 @@ void CANConnection::suspend(bool pSuspend)
void CANConnection::stop() void CANConnection::stop()
{ {
/* 1) execute in mThread_p context */ /* 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 thread is finished, it means we call this function for the second time so we can leave */
if( !mThread_p->isFinished() ) 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 */ /* 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", QMetaObject::invokeMethod(this, "sendFrame",
Qt::BlockingQueuedConnection, Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, ret),
Q_ARG(const CANFrame&, pFrame)); Q_ARG(const CANFrame&, pFrame));
return; return ret;
} }
return piSendFrame(pFrame); return piSendFrame(pFrame);
} }
void CANConnection::sendFrameBatch(const QList<CANFrame>& pFrames) bool CANConnection::sendFrames(const QList<CANFrame>& pFrames)
{ {
/* make sure we execute in mThread context */ /* make sure we execute in mThread context */
if( mThread_p && (mThread_p != QThread::currentThread()) ) { if( mThread_p && (mThread_p != QThread::currentThread()) )
QMetaObject::invokeMethod(this, "sendFrameBatch", {
bool ret;
QMetaObject::invokeMethod(this, "sendFrames",
Qt::BlockingQueuedConnection, Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, ret),
Q_ARG(const QList<CANFrame>&, pFrames)); 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) { bool CANConnection::isConfigured(int pBusId) {
if( pBusId < 0 || pBusId >= mNumBuses) if( pBusId < 0 || pBusId >= getNumBuses())
return false; return false;
return mConfigured[pBusId]; return mBusData_p[pBusId].mConfigured;
} }
void CANConnection::setConfigured(int pBusId, bool pConfigured) { void CANConnection::setConfigured(int pBusId, bool pConfigured) {
if( pBusId < 0 || pBusId >= mNumBuses) if( pBusId < 0 || pBusId >= getNumBuses())
return; return;
mConfigured[pBusId] = pConfigured; mBusData_p[pBusId].mConfigured = pConfigured;
} }
bool CANConnection::getBusConfig(int pBusId, CANBus& pBus) { bool CANConnection::getBusConfig(int pBusId, CANBus& pBus) {
if( pBusId < 0 || pBusId >= mNumBuses || !isConfigured(pBusId)) if( pBusId < 0 || pBusId >= getNumBuses() || !isConfigured(pBusId))
return false; return false;
pBus = mBus[pBusId]; pBus = mBusData_p[pBusId].mBus;
return true; return true;
} }
void CANConnection::setBusConfig(int pBusId, CANBus& pBus) { void CANConnection::setBusConfig(int pBusId, CANBus& pBus) {
if( pBusId < 0 || pBusId >= mNumBuses) if( pBusId < 0 || pBusId >= getNumBuses())
return; return;
mConfigured[pBusId] = true; mBusData_p[pBusId].mConfigured = true;
mBus[pBusId] = pBus; mBusData_p[pBusId].mBus = pBus;
} }
@@ -230,7 +246,6 @@ CANCon::status CANConnection::getStatus() {
return (CANCon::status) mStatus.load(); return (CANCon::status) mStatus.load();
} }
void CANConnection::setStatus(CANCon::status pStatus) { void CANConnection::setStatus(CANCon::status pStatus) {
mStatus.store(pStatus); mStatus.store(pStatus);
} }
@@ -243,3 +258,69 @@ void CANConnection::setCapSuspended(bool pIsSuspended) {
mIsCapSuspended = 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 "canbus.h"
#include "canconconst.h" #include "canconconst.h"
struct BusData;
class CANConnection : public QObject class CANConnection : public QObject
{ {
Q_OBJECT Q_OBJECT
public: protected:
/** /**
* @brief CANConnection constructor * @brief CANConnection constructor
@@ -28,6 +29,9 @@ public:
int pNumBuses, int pNumBuses,
int pQueueLen, int pQueueLen,
bool pUseThread); bool pUseThread);
public:
/** /**
* @brief CANConnection destructor * @brief CANConnection destructor
*/ */
@@ -76,6 +80,11 @@ signals:
//being passed. Just set for things that really are being updated. //being passed. Just set for things that really are being updated.
void busStatus(int, int, int); 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) * @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 * @param pStatus: the new status of the device
@@ -118,23 +127,34 @@ public slots:
* @brief suspends/restarts data capture * @brief suspends/restarts data capture
* @param pSuspend: suspends capture if true else restarts it * @param pSuspend: suspends capture if true else restarts it
* @note this calls piSuspend (in the working thread context if one has been started) * @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); void suspend(bool pSuspend);
/** /**
* @brief provides device with the frame to send * @brief provides device with the frame to send
* @param pFrame: 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) * @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 * @brief provides device with a list of frames to send
* @param pFrame: the 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) * @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: protected:
@@ -186,6 +206,16 @@ protected:
*/ */
void setCapSuspended(bool pIsSuspended); 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: protected:
/**************************************************************/ /**************************************************************/
@@ -227,25 +257,35 @@ protected:
/** /**
* @brief provides device with the frame to send * @brief provides device with the frame to send
* @param pFrame: 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 * @brief provides device with a list of frames to send
* @param pFrame: the 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: private:
CANBus* mBus;
bool* mConfigured;
LFQueue<CANFrame> mQueue; LFQueue<CANFrame> mQueue;
const int mNumBuses; const int mNumBuses;
const QString mPort; const QString mPort;
const CANCon::type mType; const CANCon::type mType;
bool mIsCapSuspended; bool mIsCapSuspended;
QAtomicInt mStatus; QAtomicInt mStatus;
bool mStarted;
BusData* mBusData_p;
QThread* mThread_p; QThread* mThread_p;
}; };
+2 -2
View File
@@ -141,8 +141,8 @@ void GVRetSerial::piSetBusSettings(int pBusIdx, CANBus bus)
} }
void GVRetSerial::piSendFrame(const CANFrame&) {} bool GVRetSerial::piSendFrame(const CANFrame&) {return false;}
void GVRetSerial::piSendFrameBatch(const QList<CANFrame>&){}
/****************************************************************/ /****************************************************************/
+1 -14
View File
@@ -44,18 +44,6 @@ public:
GVRetSerial(QString portName); GVRetSerial(QString portName);
virtual ~GVRetSerial(); 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: protected:
virtual void piStarted(); virtual void piStarted();
@@ -63,8 +51,7 @@ protected:
virtual void piSetBusSettings(int pBusIdx, CANBus pBus); virtual void piSetBusSettings(int pBusIdx, CANBus pBus);
virtual bool piGetBusSettings(int pBusIdx, CANBus& pBus); virtual bool piGetBusSettings(int pBusIdx, CANBus& pBus);
virtual void piSuspend(bool pSuspend); virtual void piSuspend(bool pSuspend);
virtual void piSendFrame(const CANFrame&) ; virtual bool piSendFrame(const CANFrame&) ;
virtual void piSendFrameBatch(const QList<CANFrame>&);
void disconnectDevice(); void disconnectDevice();
+25 -8
View File
@@ -15,14 +15,12 @@ SocketCan::SocketCan(QString portName) :
mDev_p(NULL), mDev_p(NULL),
mTimer(this) /*NB: set connection as parent of timer to manage it from working thread */ mTimer(this) /*NB: set connection as parent of timer to manage it from working thread */
{ {
qDebug() << "SocketCan()";
} }
SocketCan::~SocketCan() SocketCan::~SocketCan()
{ {
stop(); stop();
qDebug() << "~SocketCan()";
} }
@@ -102,8 +100,20 @@ void SocketCan::piSetBusSettings(int pBusIdx, CANBus bus)
} }
void SocketCan::piSendFrame(const CANFrame&) {} bool SocketCan::piSendFrame(const CANFrame& pFrame)
void SocketCan::piSendFrameBatch(const QList<CANFrame>&){} {
/* 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() void SocketCan::framesReceived()
{ {
/* test */
bool sndNotif = false;
/* sanity checks */ /* sanity checks */
if(!mDev_p) if(!mDev_p)
return; return;
@@ -153,7 +166,7 @@ void SocketCan::framesReceived()
/* exit case */ /* exit case */
if(!recFrame.isValid()) if(!recFrame.isValid())
return; break;
/* drop frame if capture is suspended */ /* drop frame if capture is suspended */
if(isCapSuspended()) if(isCapSuspended())
@@ -161,7 +174,8 @@ void SocketCan::framesReceived()
/* check frame */ /* check frame */
if( !recFrame.payload().isEmpty() && if( !recFrame.payload().isEmpty() &&
recFrame.payload().length()<=8) recFrame.payload().length()<=8 &&
!discard(0, recFrame.frameId(), sndNotif) )
{ {
CANFrame* frame_p = getQueue().get(); CANFrame* frame_p = getQueue().get();
if(frame_p) { if(frame_p) {
@@ -176,12 +190,15 @@ void SocketCan::framesReceived()
/* enqueue frame */ /* enqueue frame */
getQueue().queue(); getQueue().queue();
} }
#if 0
else else
qDebug() << "can't get a frame, ERROR"; 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); SocketCan(QString portName);
virtual ~SocketCan(); 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: protected:
virtual void piStarted(); virtual void piStarted();
@@ -37,8 +25,7 @@ protected:
virtual void piSetBusSettings(int pBusIdx, CANBus pBus); virtual void piSetBusSettings(int pBusIdx, CANBus pBus);
virtual bool piGetBusSettings(int pBusIdx, CANBus& pBus); virtual bool piGetBusSettings(int pBusIdx, CANBus& pBus);
virtual void piSuspend(bool pSuspend); virtual void piSuspend(bool pSuspend);
virtual void piSendFrame(const CANFrame&) ; virtual bool piSendFrame(const CANFrame&);
virtual void piSendFrameBatch(const QList<CANFrame>&);
void disconnectDevice(); void disconnectDevice();
+22 -6
View File
@@ -1,13 +1,18 @@
#include <QCanBus> #include <QCanBus>
#include <QThread>
#include "connectionwindow.h" #include "connectionwindow.h"
#include "ui_connectionwindow.h" #include "ui_connectionwindow.h"
#include "connections/canconfactory.h" #include "connections/canconfactory.h"
#define FALSE 0
#define TRUE 1
ConnectionWindow::ConnectionWindow(CANFrameModel *cModel, QWidget *parent) : ConnectionWindow::ConnectionWindow(CANFrameModel *cModel, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::ConnectionWindow) ui(new Ui::ConnectionWindow),
mRefreshReqOngoing(FALSE)
{ {
ui->setupUi(this); ui->setupUi(this);
@@ -104,17 +109,20 @@ void ConnectionWindow::showEvent(QShowEvent* event)
} }
void ConnectionWindow::refreshCanList() { void ConnectionWindow::refreshCanList() {
QList<CANConnection*>::iterator conn_p;
QList<CANConnection*>& conns = connModel->getConnections();
QList<CANConnection*>& conns = connModel->getConnections();
CANFrame* frame_p = NULL; CANFrame* frame_p = NULL;
for (conn_p = conns.begin(); conn_p != conns.end(); ++conn_p) { foreach (CANConnection* conn_p, conns)
while( (frame_p = (*conn_p)->getQueue().peek() ) ) { {
while( (frame_p = conn_p->getQueue().peek() ) ) {
canModel->addFrame(*frame_p, true); 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() void ConnectionWindow::handleNewConn()
@@ -272,8 +280,16 @@ void ConnectionWindow::handleOKButton()
connect(conn_p, SIGNAL(status(CANCon::status)), connect(conn_p, SIGNAL(status(CANCon::status)),
this, SLOT(connectionStatus(CANCon::status))); this, SLOT(connectionStatus(CANCon::status)));
//conn_p->setCallback(std::bind(&ConnectionWindow::callback, this, std::placeholders::_1));
/*TODO add return value and checks */ /*TODO add return value and checks */
conn_p->start(); 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++) { for (int i=0 ; i<conn_p->getNumBuses() ; i++) {
/* set bus configuration */ /* set bus configuration */
+1 -2
View File
@@ -8,8 +8,6 @@
#include <QDebug> #include <QDebug>
#include <QSettings> #include <QSettings>
#include <QTimer> #include <QTimer>
//#include "canconnection_old.h"
//#include "serialworker.h"
#include "canconnectionmodel.h" #include "canconnectionmodel.h"
#include "canframemodel.h" #include "canframemodel.h"
@@ -68,6 +66,7 @@ private:
CANFrameModel *canModel; CANFrameModel *canModel;
QTimer mTicker; QTimer mTicker;
QAtomicInt mRefreshReqOngoing;
void selectSerial(); void selectSerial();
void selectKvaser(); void selectKvaser();
+3 -3
View File
@@ -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];
@@ -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];
+24 -27
View File
@@ -322,7 +322,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] != "")
{ {
@@ -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->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(' ');
@@ -446,9 +446,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)
@@ -456,10 +456,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);
} }
@@ -570,7 +570,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);
} }
@@ -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->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(' ');
@@ -696,10 +696,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;
@@ -759,7 +758,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(' ');
@@ -836,7 +835,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;
@@ -889,7 +888,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(' ');
@@ -952,7 +951,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;
@@ -1008,7 +1007,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);
} }
} }
@@ -1074,11 +1073,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;
@@ -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("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(';');
@@ -1233,12 +1231,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;
@@ -1325,7 +1322,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(' ');
+2 -2
View File
@@ -157,7 +157,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;
@@ -679,7 +679,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]) + " ";
} }
+3 -4
View File
@@ -93,13 +93,12 @@ 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();
} }
@@ -125,7 +124,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
+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 += core gui serialbus widgets testlib serialbus
QT -= gui
CONFIG += c++11 CONFIG += c++11
INCLUDEPATH += ../utils INCLUDEPATH += ../ ../connections
SOURCES += \ 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 += \ #HEADERS += \
@@ -14,3 +21,13 @@ SOURCES += \
target.path= . target.path= .
INSTALLS += target 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 <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() void TestLFQueue::setSize_data()
@@ -92,7 +83,3 @@ void TestLFQueue::exchange()
thread.waitForFinished(); 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