new socketcan connection
This commit is contained in:
+162
-59
@@ -2,33 +2,7 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QCanBusFrame>
|
#include <QCanBusFrame>
|
||||||
|
|
||||||
|
#include "socketcan.h"
|
||||||
#include "canframemodel.h"
|
|
||||||
#include "canconnection_old.h"
|
|
||||||
#include "socketcanconnection.h"
|
|
||||||
|
|
||||||
/***********************************/
|
|
||||||
/**** nested class ****/
|
|
||||||
/***********************************/
|
|
||||||
|
|
||||||
|
|
||||||
BUSConfig::BUSConfig():isConfigured(false){}
|
|
||||||
|
|
||||||
void BUSConfig::reset() {
|
|
||||||
isConfigured = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BUSConfig::operator==(CANBus& bus) {
|
|
||||||
return isConfigured && speed == bus.speed &&
|
|
||||||
listenOnly == bus.listenOnly && active == bus.active;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BUSConfig::operator=(CANBus& bus) {
|
|
||||||
isConfigured = true;
|
|
||||||
speed = bus.speed;
|
|
||||||
listenOnly = bus.listenOnly;
|
|
||||||
active = bus.active;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -36,41 +10,120 @@ void BUSConfig::operator=(CANBus& bus) {
|
|||||||
/**** class definition ****/
|
/**** class definition ****/
|
||||||
/***********************************/
|
/***********************************/
|
||||||
|
|
||||||
SocketCanConnection::SocketCanConnection(CANFrameModel *model, int base) : CANConnection(model, base), mDev_p(NULL)
|
SocketCanConnection::SocketCanConnection(QString portName) :
|
||||||
|
CANConnection(portName, CANCon::SOCKETCAN, 1),
|
||||||
|
mDev_p(NULL),
|
||||||
|
mThread(NULL)
|
||||||
{
|
{
|
||||||
|
getQueue().setSize(2000); /*TODO add check on returned value */
|
||||||
|
/* move ourself to the thread */
|
||||||
|
moveToThread(&mThread);
|
||||||
|
|
||||||
qDebug() << "SocketCanConnection()";
|
qDebug() << "SocketCanConnection()";
|
||||||
qRegisterMetaType<CANFrame>("CANFrame");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SocketCanConnection::~SocketCanConnection()
|
SocketCanConnection::~SocketCanConnection()
|
||||||
{
|
{
|
||||||
|
stop();
|
||||||
qDebug() << "~SocketCanConnection()";
|
qDebug() << "~SocketCanConnection()";
|
||||||
/* stop device */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketCanConnection::updateBusSettings(CANBus bus)
|
|
||||||
{
|
|
||||||
qDebug()<<"updateBusSettings";
|
|
||||||
|
|
||||||
if(mConf == bus) return;
|
void SocketCanConnection::start() {
|
||||||
|
|
||||||
|
qDebug() << "enter thread";
|
||||||
|
mThread.start(QThread::HighPriority);
|
||||||
|
|
||||||
|
connect(&mTimer, SIGNAL(timeout()), this, SLOT(testConnection()));
|
||||||
|
mTimer.setInterval(1000);
|
||||||
|
mTimer.setSingleShot(false); //keep ticking
|
||||||
|
mTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SocketCanConnection::suspend(bool pSuspend) {
|
||||||
|
/* make sure we execute in mThread context */
|
||||||
|
if(QThread::currentThread() != &mThread) {
|
||||||
|
QMetaObject::invokeMethod(this, "suspend",
|
||||||
|
Qt::BlockingQueuedConnection,
|
||||||
|
Q_ARG(bool, pSuspend));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update capSuspended */
|
||||||
|
setCapSuspended(pSuspend);
|
||||||
|
|
||||||
|
/* flush queue if we are suspended */
|
||||||
|
if(isCapSuspended())
|
||||||
|
getQueue().flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SocketCanConnection::stop() {
|
||||||
|
mTimer.stop();
|
||||||
|
mThread.quit();
|
||||||
|
if(!mThread.wait()) {
|
||||||
|
qDebug() << "can't stop thread";
|
||||||
|
}
|
||||||
|
disconnectDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SocketCanConnection::getBusSettings(int pBusIdx, CANBus& pBus) {
|
||||||
|
/* make sure we execute in mThread context */
|
||||||
|
if(QThread::currentThread() != &mThread) {
|
||||||
|
bool ret;
|
||||||
|
QMetaObject::invokeMethod(this, "getBusSettings",
|
||||||
|
Qt::BlockingQueuedConnection,
|
||||||
|
Q_RETURN_ARG(bool, ret),
|
||||||
|
Q_ARG(int , pBusIdx),
|
||||||
|
Q_ARG(CANBus& , pBus));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getBusConfig(pBusIdx, pBus);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SocketCanConnection::setBusSettings(int pBusIdx, CANBus bus)
|
||||||
|
{
|
||||||
|
/* make sure we execute in mThread context */
|
||||||
|
if(QThread::currentThread() != &mThread) {
|
||||||
|
QMetaObject::invokeMethod(this, "setBusSettings",
|
||||||
|
Qt::BlockingQueuedConnection,
|
||||||
|
Q_ARG(int, pBusIdx),
|
||||||
|
Q_ARG(CANBus, bus));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sanity checks */
|
||||||
|
if(0 != pBusIdx)
|
||||||
|
return;
|
||||||
|
|
||||||
/* disconnect device if we have one connected */
|
/* disconnect device if we have one connected */
|
||||||
if(mDev_p) disconnect();
|
if(mDev_p)
|
||||||
|
disconnectDevice();
|
||||||
|
|
||||||
|
/* copy bus config */
|
||||||
|
setBusConfig(0, bus);
|
||||||
|
|
||||||
/* if bus is not active we are done */
|
/* if bus is not active we are done */
|
||||||
if(!bus.active) return;
|
if(!bus.active)
|
||||||
|
return;
|
||||||
|
|
||||||
/* create device */
|
/* create device */
|
||||||
mDev_p = QCanBus::instance()->createDevice("socketcan", portName);
|
mDev_p = QCanBus::instance()->createDevice("socketcan", getPort());
|
||||||
if (!mDev_p) {
|
if (!mDev_p) {
|
||||||
qDebug() << "can't create device";
|
disconnectDevice();
|
||||||
return;
|
qDebug() << "can't create device";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* connect slots */
|
/* connect slots */
|
||||||
connect(mDev_p, &QCanBusDevice::errorOccurred, this, &SocketCanConnection::errorReceived);
|
connect(mDev_p, &QCanBusDevice::errorOccurred, this, &SocketCanConnection::errorReceived);
|
||||||
connect(mDev_p, &QCanBusDevice::framesReceived, this, &SocketCanConnection::framesReceived);
|
|
||||||
connect(mDev_p, &QCanBusDevice::framesWritten, this, &SocketCanConnection::framesWritten);
|
connect(mDev_p, &QCanBusDevice::framesWritten, this, &SocketCanConnection::framesWritten);
|
||||||
|
connect(mDev_p, &QCanBusDevice::framesReceived, this, &SocketCanConnection::framesReceived);
|
||||||
|
|
||||||
/* set configuration */
|
/* set configuration */
|
||||||
/*if (p.useConfigurationEnabled) {
|
/*if (p.useConfigurationEnabled) {
|
||||||
@@ -80,19 +133,23 @@ void SocketCanConnection::updateBusSettings(CANBus bus)
|
|||||||
|
|
||||||
/* connect device */
|
/* connect device */
|
||||||
if (!mDev_p->connectDevice()) {
|
if (!mDev_p->connectDevice()) {
|
||||||
disconnect();
|
disconnectDevice();
|
||||||
qDebug() << "can't connect device";
|
qDebug() << "can't connect device";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SocketCanConnection::sendFrame(const CANFrame *) {}
|
||||||
|
void SocketCanConnection::sendFrameBatch(const QList<CANFrame> *){}
|
||||||
|
|
||||||
|
|
||||||
/***********************************/
|
/***********************************/
|
||||||
/**** private methods ****/
|
/**** private methods ****/
|
||||||
/***********************************/
|
/***********************************/
|
||||||
|
|
||||||
|
|
||||||
/* connect device */
|
/* disconnect device */
|
||||||
void SocketCanConnection::disconnect() {
|
void SocketCanConnection::disconnectDevice() {
|
||||||
if(mDev_p) {
|
if(mDev_p) {
|
||||||
mDev_p->disconnectDevice();
|
mDev_p->disconnectDevice();
|
||||||
delete mDev_p;
|
delete mDev_p;
|
||||||
@@ -123,35 +180,81 @@ void SocketCanConnection::framesWritten(qint64 count)
|
|||||||
void SocketCanConnection::framesReceived()
|
void SocketCanConnection::framesReceived()
|
||||||
{
|
{
|
||||||
/* sanity checks */
|
/* sanity checks */
|
||||||
if(!mDev_p) return;
|
if(!mDev_p)
|
||||||
|
return;
|
||||||
|
|
||||||
/* read frame */
|
/* read frame */
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
const QCanBusFrame recFrame = mDev_p->readFrame();
|
const QCanBusFrame recFrame = mDev_p->readFrame();
|
||||||
/* exit case */
|
|
||||||
if(!recFrame.isValid()) return;
|
|
||||||
|
|
||||||
|
/* exit case */
|
||||||
|
if(!recFrame.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* drop frame if capture is suspended */
|
||||||
|
if(isCapSuspended())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* check frame */
|
||||||
if(!recFrame.payload().isEmpty() &&
|
if(!recFrame.payload().isEmpty() &&
|
||||||
recFrame.payload().length()<=8)
|
recFrame.payload().length()<=8)
|
||||||
{
|
{
|
||||||
CANFrame frame;
|
CANFrame* frame_p = getQueue().get();
|
||||||
frame.len = recFrame.payload().length();
|
if(frame_p) {
|
||||||
frame.bus = 0;
|
frame_p->len = recFrame.payload().length();
|
||||||
memcpy(frame.data, recFrame.payload().data(), frame.len);
|
frame_p->bus = 0;
|
||||||
frame.extended = false;
|
memcpy(frame_p->data, recFrame.payload().data(), frame_p->len);
|
||||||
frame.ID = recFrame.frameId();
|
frame_p->extended = false;
|
||||||
frame.isReceived = true;
|
frame_p->ID = recFrame.frameId();
|
||||||
frame.timestamp = recFrame.timeStamp().microSeconds();
|
frame_p->isReceived = true;
|
||||||
|
frame_p->timestamp = recFrame.timeStamp().seconds()*1000000 + recFrame.timeStamp().microSeconds();
|
||||||
|
|
||||||
/* send frame */
|
/* enqueue frame */
|
||||||
QMetaObject::invokeMethod(model, "addFrame",
|
getQueue().queue();
|
||||||
Qt::QueuedConnection,
|
}
|
||||||
Q_ARG(CANFrame, frame),
|
else
|
||||||
Q_ARG(bool, false));
|
qDebug() << "can't get a frame, ERROR";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qDebug() << "invalid frame";
|
qDebug() << "invalid frame";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SocketCanConnection::testConnection() {
|
||||||
|
QCanBusDevice* dev_p = QCanBus::instance()->createDevice("socketcan", getPort());
|
||||||
|
|
||||||
|
switch(getStatus())
|
||||||
|
{
|
||||||
|
case CANCon::CONNECTED:
|
||||||
|
if (!dev_p || !dev_p->connectDevice()) {
|
||||||
|
/* we have lost connectivity */
|
||||||
|
disconnectDevice();
|
||||||
|
|
||||||
|
setStatus(CANCon::NOT_CONNECTED);
|
||||||
|
emit status(getStatus());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CANCon::NOT_CONNECTED:
|
||||||
|
if (dev_p && dev_p->connectDevice()) {
|
||||||
|
|
||||||
|
/* try to reconnect */
|
||||||
|
CANBus bus;
|
||||||
|
if(getBusConfig(0, bus))
|
||||||
|
setBusSettings(0, bus);
|
||||||
|
|
||||||
|
/* disconnect test instance */
|
||||||
|
dev_p->disconnectDevice();
|
||||||
|
|
||||||
|
setStatus(CANCon::CONNECTED);
|
||||||
|
emit status(getStatus());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dev_p)
|
||||||
|
delete dev_p;
|
||||||
|
}
|
||||||
|
|||||||
+41
-21
@@ -3,21 +3,11 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QCanBus>
|
#include <QCanBus>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <qthread.h>
|
||||||
|
|
||||||
#include "canframemodel.h"
|
#include "canframemodel.h"
|
||||||
#include "canconnection_old.h"
|
#include "canconnection.h"
|
||||||
|
|
||||||
class BUSConfig {
|
|
||||||
public:
|
|
||||||
BUSConfig();
|
|
||||||
void reset();
|
|
||||||
bool operator ==(CANBus&);
|
|
||||||
void operator =(CANBus&);
|
|
||||||
bool isConfigured;
|
|
||||||
int speed;
|
|
||||||
bool listenOnly;
|
|
||||||
bool active;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class SocketCanConnection : public CANConnection
|
class SocketCanConnection : public CANConnection
|
||||||
@@ -25,20 +15,50 @@ class SocketCanConnection : public CANConnection
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SocketCanConnection(CANFrameModel *, int);
|
SocketCanConnection(QString portName);
|
||||||
virtual ~SocketCanConnection() override;
|
virtual ~SocketCanConnection();
|
||||||
|
|
||||||
|
virtual void start();
|
||||||
|
virtual void stop();
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void updateBusSettings(CANBus) override;
|
|
||||||
|
|
||||||
private:
|
virtual void sendFrame(const CANFrame *);
|
||||||
void errorReceived(QCanBusDevice::CanBusError error) const;
|
virtual void sendFrameBatch(const QList<CANFrame> *);
|
||||||
|
|
||||||
|
virtual void setBusSettings(int, CANBus);
|
||||||
|
virtual bool getBusSettings(int pBusIdx, CANBus& pBus);
|
||||||
|
|
||||||
|
virtual void suspend(bool);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void disconnectDevice();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void errorReceived(QCanBusDevice::CanBusError) const;
|
||||||
void framesWritten(qint64 count);
|
void framesWritten(qint64 count);
|
||||||
void framesReceived();
|
void framesReceived();
|
||||||
void disconnect();
|
void testConnection();
|
||||||
|
|
||||||
QCanBusDevice* mDev_p;
|
protected:
|
||||||
BUSConfig mConf;
|
QCanBusDevice* mDev_p;
|
||||||
|
QTimer mTimer;
|
||||||
|
QThread mThread;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // SOCKETCANCONNECTION_H
|
#endif // SOCKETCANCONNECTION_H
|
||||||
|
|||||||
Reference in New Issue
Block a user