adding socketcand support

This commit is contained in:
Bertrand
2021-02-23 09:38:19 +01:00
parent 40553ca980
commit c49783a55b
12 changed files with 599 additions and 27 deletions
+3 -1
View File
@@ -51,6 +51,7 @@ SOURCES += main.cpp\
connections/serialbusconnection.cpp \
connections/canconfactory.cpp \
connections/gvretserial.cpp \
connections/socketcand.cpp \
connections/canconmanager.cpp \
re/sniffer/snifferitem.cpp \
re/sniffer/sniffermodel.cpp \
@@ -91,7 +92,8 @@ SOURCES += main.cpp\
HEADERS += mainwindow.h \
can_structs.h \
canframemodel.h \ \
canframemodel.h \
connections/socketcand.h \
connections/mqtt_bus.h \
mqtt/qmqtt.h \
mqtt/qmqtt_client.h \
+1
View File
@@ -18,6 +18,7 @@ namespace CANCon {
KVASER,
SERIALBUS,
REMOTE,
KAYAK,
MQTT,
NONE
};
+3
View File
@@ -3,6 +3,7 @@
#include "serialbusconnection.h"
#include "gvretserial.h"
#include "mqtt_bus.h"
#include "socketcand.h"
using namespace CANCon;
@@ -15,6 +16,8 @@ CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDri
return new GVRetSerial(pPortName, false);
case REMOTE:
return new GVRetSerial(pPortName, true); //it's a special case of GVRET connected over TCP/IP so it uses the same class
case KAYAK:
return new SocketCANd(pPortName);
case MQTT:
return new MQTT_BUS(pPortName);
default: {}
+2
View File
@@ -1,5 +1,6 @@
#include <QDateTime>
#include <QSettings>
#include <QCoreApplication>
#include "canconmanager.h"
#include "canconfactory.h"
@@ -228,6 +229,7 @@ bool CANConManager::sendFrame(const CANFrame& pFrame)
//workingFrame.timestamp -= mTimestampBasis;
}
txFrame = conn->getQueue().get();
QCoreApplication::processEvents();
*txFrame = workingFrame;
conn->getQueue().queue();
return conn->sendFrame(workingFrame);
+1
View File
@@ -85,6 +85,7 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const
case CANCon::KVASER: return "KVASER";
case CANCon::SERIALBUS: return "SerialBus";
case CANCon::GVRET_SERIAL: return "GVRET";
case CANCon::KAYAK: return "socketcand";
default: {}
}
else qDebug() << "Tried to show connection type but connection was nullptr";
+58 -9
View File
@@ -69,12 +69,17 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) :
ui->cbBusSpeed->addItem("500000");
ui->cbBusSpeed->addItem("1000000");
rxBroadcast = new QUdpSocket(this);
rxBroadcastGVRET = new QUdpSocket(this);
//Need to make sure it tries to share the address in case there are
//multiple instances of SavvyCAN running.
rxBroadcast->bind(QHostAddress::Any, 17222, QAbstractSocket::ShareAddress);
rxBroadcastGVRET->bind(QHostAddress::AnyIPv4, 17222, QAbstractSocket::ShareAddress);
connect(rxBroadcast, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
connect(rxBroadcastGVRET, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
//Doing the same for socketcand/kayak hosts:
rxBroadcastKayak = new QUdpSocket(this);
rxBroadcastKayak->bind(QHostAddress::AnyIPv4, 42000, QAbstractSocket::ShareAddress);
connect(rxBroadcastKayak, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
}
@@ -82,12 +87,56 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) :
void ConnectionWindow::readPendingDatagrams()
{
//qDebug() << "Got a UDP frame!";
while (rxBroadcast->hasPendingDatagrams()) {
QNetworkDatagram datagram = rxBroadcast->receiveDatagram();
if (!remoteDeviceIP.contains(datagram.senderAddress().toString()))
while (rxBroadcastGVRET->hasPendingDatagrams()) {
QNetworkDatagram datagram = rxBroadcastGVRET->receiveDatagram();
if (!remoteDeviceIPGVRET.contains(datagram.senderAddress().toString()))
{
remoteDeviceIP.append(datagram.senderAddress().toString());
qDebug() << "Add new remote IP " << datagram.senderAddress().toString();
remoteDeviceIPGVRET.append(datagram.senderAddress().toString());
//qDebug() << "Add new remote IP " << datagram.senderAddress().toString();
}
}
while (rxBroadcastKayak->hasPendingDatagrams()) {
QNetworkDatagram datagram = rxBroadcastKayak->receiveDatagram();
//qDebug() << "Broadcast Datagram: " << QString::fromUtf8(datagram.data());
QXmlStreamReader CANBeaconXml(QString::fromUtf8(datagram.data()));
QString KayakHost;
QString KayakBus;
while(!CANBeaconXml.atEnd() && !CANBeaconXml.hasError())
{
CANBeaconXml.readNext();
if(CANBeaconXml.name() == "CANBeacon" && !CANBeaconXml.isEndElement())
KayakHost.append(CANBeaconXml.attributes().value("name"));
if(CANBeaconXml.name() == "URL")
KayakHost.append(" (" + CANBeaconXml.readElementText() + ')');
//Kayak can theoretically send multiple busses over one ports
//TODO: implement this case in socketcand.cpp
if(CANBeaconXml.name() == "Bus" && !CANBeaconXml.isEndElement())
KayakBus.append(CANBeaconXml.attributes().value("name") + ",");
}
KayakHost = KayakBus.left(KayakBus.length() - 1) + "@" + KayakHost;
QVector<QString> connectedPorts;
if (connModel->rowCount() > 0)
{
for (int i = 0; i < connModel->rowCount(); i++)
{
CANConnection *var_conn = connModel->getAtIdx(i);
connectedPorts.append(var_conn->getPort());
}
}
if (connectedPorts.contains(KayakHost))
{
remoteDeviceKayak.removeOne(KayakHost);
}
if (!remoteDeviceKayak.contains(KayakHost) && !connectedPorts.contains(KayakHost))
{
remoteDeviceKayak.append(KayakHost);
//qDebug() << "Add new remote IP " << datagram.senderAddress().toString();
}
}
}
@@ -193,7 +242,7 @@ void ConnectionWindow::consoleEnableChanged(bool checked) {
void ConnectionWindow::handleNewConn()
{
NewConnectionDialog *thisDialog = new NewConnectionDialog(&remoteDeviceIP);
NewConnectionDialog *thisDialog = new NewConnectionDialog(&remoteDeviceIPGVRET, &remoteDeviceKayak);
CANCon::type newType;
QString newPort;
QString newDriver;
+4 -2
View File
@@ -60,8 +60,10 @@ private:
Ui::ConnectionWindow *ui;
QSettings *settings;
CANConnectionModel *connModel;
QUdpSocket *rxBroadcast;
QVector<QString> remoteDeviceIP;
QUdpSocket *rxBroadcastGVRET;
QUdpSocket *rxBroadcastKayak;
QVector<QString> remoteDeviceIPGVRET;
QVector<QString> remoteDeviceKayak;
CANConnection* create(CANCon::type pTye, QString pPortName, QString pDriver);
void populateBusDetails(int offset);
+33 -5
View File
@@ -2,13 +2,13 @@
#include "newconnectiondialog.h"
#include "ui_newconnectiondialog.h"
NewConnectionDialog::NewConnectionDialog(QVector<QString>* ips, QWidget *parent) :
NewConnectionDialog::NewConnectionDialog(QVector<QString>* gvretips, QVector<QString>* kayakhosts, QWidget *parent) :
QDialog(parent),
ui(new Ui::NewConnectionDialog),
remoteDeviceIP(ips)
remoteDeviceIPGVRET(gvretips),
remoteBusKayak(kayakhosts)
{
ui->setupUi(this);
if (isSerialBusAvailable())
{
ui->rbSocketCAN->setEnabled(true);
@@ -25,6 +25,7 @@ NewConnectionDialog::NewConnectionDialog(QVector<QString>* ips, QWidget *parent)
connect(ui->rbGVRET, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
connect(ui->rbSocketCAN, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
connect(ui->rbRemote, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
connect(ui->rbKayak, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
connect(ui->rbMQTT, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
connect(ui->cbDeviceType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NewConnectionDialog::handleDeviceTypeChanged);
@@ -34,7 +35,8 @@ NewConnectionDialog::NewConnectionDialog(QVector<QString>* ips, QWidget *parent)
ui->cbDeviceType->setHidden(true);
selectSerial();
qDebug() << "Was passed " << remoteDeviceIP->count() << " remote IPs";
qDebug() << "Was passed " << remoteDeviceIPGVRET->count() << " remote GVRET IPs";
qDebug() << "Was passed " << remoteBusKayak->count() << " remote Kayak Busses";
}
NewConnectionDialog::~NewConnectionDialog()
@@ -52,6 +54,7 @@ void NewConnectionDialog::handleConnTypeChanged()
if (ui->rbGVRET->isChecked()) selectSerial();
if (ui->rbSocketCAN->isChecked()) selectSocketCan();
if (ui->rbRemote->isChecked()) selectRemote();
if (ui->rbKayak->isChecked()) selectKayak();
if (ui->rbMQTT->isChecked()) selectMQTT();
}
@@ -99,7 +102,19 @@ void NewConnectionDialog::selectRemote()
ui->lblDeviceType->setHidden(true);
ui->cbDeviceType->setHidden(true);
ui->cbPort->clear();
foreach(QString pName, *remoteDeviceIP)
foreach(QString pName, *remoteDeviceIPGVRET)
{
ui->cbPort->addItem(pName);
}
}
void NewConnectionDialog::selectKayak()
{
ui->lPort->setText("Available Bus(ses):");
ui->lblDeviceType->setHidden(true);
ui->cbDeviceType->setHidden(true);
ui->cbPort->clear();
foreach(QString pName, *remoteBusKayak)
{
ui->cbPort->addItem(pName);
}
@@ -127,6 +142,9 @@ void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QSt
case CANCon::REMOTE:
ui->rbRemote->setChecked(true);
break;
case CANCon::KAYAK:
ui->rbKayak->setChecked(true);
break;
case CANCon::MQTT:
ui->rbMQTT->setChecked(true);
break;
@@ -162,6 +180,13 @@ void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QSt
else ui->cbPort->addItem(pPortName);
break;
}
case CANCon::KAYAK:
{
int idx = ui->cbPort->findText(pPortName);
if (idx > -1) ui->cbPort->setCurrentIndex(idx);
else ui->cbPort->addItem(pPortName);
break;
}
case CANCon::MQTT:
ui->cbPort->setCurrentText(pPortName);
break;
@@ -177,6 +202,8 @@ QString NewConnectionDialog::getPortName()
case CANCon::REMOTE:
case CANCon::MQTT:
return ui->cbPort->currentText();
case CANCon::KAYAK:
return ui->cbPort->currentText();
default:
qDebug() << "getPortName: can't get port";
}
@@ -198,6 +225,7 @@ CANCon::type NewConnectionDialog::getConnectionType()
if (ui->rbGVRET->isChecked()) return CANCon::GVRET_SERIAL;
if (ui->rbSocketCAN->isChecked()) return CANCon::SERIALBUS;
if (ui->rbRemote->isChecked()) return CANCon::REMOTE;
if (ui->rbKayak->isChecked()) return CANCon::KAYAK;
if (ui->rbMQTT->isChecked()) return CANCon::MQTT;
qDebug() << "getConnectionType: error";
+4 -2
View File
@@ -18,7 +18,7 @@ class NewConnectionDialog : public QDialog
Q_OBJECT
public:
explicit NewConnectionDialog(QVector<QString>* ips, QWidget *parent = nullptr);
explicit NewConnectionDialog(QVector<QString>* gvretips, QVector<QString>* kayakips, QWidget *parent = nullptr);
~NewConnectionDialog();
CANCon::type getConnectionType();
@@ -34,12 +34,14 @@ private:
Ui::NewConnectionDialog *ui;
QList<QSerialPortInfo> ports;
QList<QCanBusDeviceInfo> canDevices;
QVector<QString>* remoteDeviceIP;
QVector<QString>* remoteDeviceIPGVRET;
QVector<QString>* remoteBusKayak;
void selectSerial();
void selectKvaser();
void selectSocketCan();
void selectRemote();
void selectKayak();
void selectMQTT();
bool isSerialBusAvailable();
void setPortName(CANCon::type pType, QString pPortName, QString pDriver);
+393
View File
@@ -0,0 +1,393 @@
#include <QObject>
#include <QDebug>
#include <QCanBusFrame>
#include <QSerialPortInfo>
#include <QSettings>
#include <QStringBuilder>
#include <QtNetwork>
#include <QMetaObject>
#include "socketcand.h"
SocketCANd::SocketCANd(QString portName) :
CANConnection(portName, "kayak", CANCon::KAYAK, 1, 4000, true),
mTimer(this) /*NB: set this as parent of timer to manage it from working thread */
{
mTimer.setInterval(10000); //tick every 10 seconds
mTimer.setSingleShot(false); //keep ticking
connect(&mTimer, SIGNAL(timeout()), this, SLOT(checkConnection()));
sendDebug("SocketCANd()");
//tcpClient = nullptr;
hostCanIDs = portName.left(portName.indexOf("@")).split(',');
QString hostIPandPort = portName.mid(portName.indexOf("can://")+6, portName.length() - portName.indexOf("can://") - 7); //7 is lenght of 'can://' and ')'
hostIP = QHostAddress(hostIPandPort.left(hostIPandPort.indexOf(":")));
hostPort = (hostIPandPort.right(hostIPandPort.length() - hostIPandPort.lastIndexOf(":") -1)).toInt();
QVarLengthArray<QTcpSocket*> tcpClient(0);
mNumBuses = hostCanIDs.length();
mBusData.resize(mNumBuses);
reconnecting = false;
for (int i = 0; i < mNumBuses; i++)
{
rx_state.append(IDLE);
}
}
SocketCANd::~SocketCANd()
{
stop();
sendDebug("~SocketCANd()");
}
void SocketCANd::sendDebug(const QString debugText)
{
qDebug() << debugText;
debugOutput(debugText);
}
void SocketCANd::sendBytesToTCP(const QByteArray &bytes, int busNum)
{
if (tcpClient[busNum] && !tcpClient[busNum]->isOpen())
{
sendDebug("Attempt to write to TCP/IP port when it is not open!");
return;
}
QString buildDebug;
buildDebug = "Send data to " + hostIP.toString() + ":" + QString::number(hostPort) + " -> ";
foreach (int byt, bytes) {
byt = (unsigned char)byt;
buildDebug = buildDebug % QString::number(byt, 16) % " ";
}
sendDebug(buildDebug);
if (tcpClient[busNum]) tcpClient[busNum]->write(bytes);
}
void SocketCANd::sendStringToTCP(const char* data, int busNum)
{
if (tcpClient[busNum] && !tcpClient[busNum]->isOpen())
{
sendDebug("Attempt to write to TCP/IP port when it is not open!");
return;
}
QString buildDebug;
buildDebug = "Send data to " + hostIP.toString() + ":" + QString::number(hostPort) + " -> " + data;
sendDebug(buildDebug);
//qInfo() << buildDebug;
if (tcpClient[busNum]) tcpClient[busNum]->write(data);
}
void SocketCANd::piStarted()
{
connectDevice();
}
void SocketCANd::piSuspend(bool pSuspend)
{
/* update capSuspended */
setCapSuspended(pSuspend);
/* flush queue if we are suspended */
if(isCapSuspended())
getQueue().flush();
}
void SocketCANd::piStop()
{
mTimer.stop();
disconnectDevice();
}
bool SocketCANd::piGetBusSettings(int pBusIdx, CANBus& pBus)
{
return getBusConfig(pBusIdx, pBus);
}
void SocketCANd::piSetBusSettings(int pBusIdx, CANBus bus)
{
setBusConfig(pBusIdx, bus);
bus.setSpeed(250000);
}
bool SocketCANd::piSendFrame(const CANFrame& frame)
{
QByteArray buffer;
int c;
int ID;
// //calculate bus number offset (in case of multiple connections)
// //useless since SavvyCAN already delivers the right index in frame.bus
// QList<CANConnection*> connList = CANConManager::getInstance()->getConnections();
// int currentConnPos = connList.indexOf(this);
// int busOffset = 0;
// for (int i = 0; i < currentConnPos; i++)
// {
// busOffset += connList[i]->getNumBuses();
// }
// int busNum = frame.bus - busOffset;
int busNum = frame.bus;
framesRapid++;
if (tcpClient[busNum] && !tcpClient[busNum]->isOpen()) return false;
//if (!isConnected) return false;
// Doesn't make sense to send an error frame
// to an adapter
if (frame.frameId() & 0x20000000) {
return true;
}
ID = frame.frameId();
if (frame.hasExtendedFrameFormat()) ID |= 1 << 31;
QString sendStr = "< send " + QString::number(ID, 16) + " " + QString::number(frame.payload().length()) + " ";
for (c = 0; c < frame.payload().length(); c++)
{
sendStr.append(QString::number(frame.payload()[c], 16) + " ");
}
sendStr.append(">");
std::string str = sendStr.toStdString();
const char* sendCmd = str.c_str();
sendStringToTCP(sendCmd, busNum);
return true;
}
/****************************************************************/
void SocketCANd::connectDevice()
{
QSettings settings;
/* disconnect device */
/* avoiding this solution since it removes connection selection in case of connection check */
//if(tcpClient)
// disconnectDevice();
// only resetting tcpClient
for (int i = 0; i < tcpClient.length(); i++)
{
if (tcpClient[i])
{
if (tcpClient[i]->isOpen())
{
tcpClient[i]->close();
}
tcpClient[i]->disconnect();
delete tcpClient[i];
tcpClient[i] = nullptr;
}
}
tcpClient.clear();
mTimer.start();
//sendDebug("TCP Connection to a Kayak device");
for (int i = 0; i < mNumBuses; i++)
{
rx_state[i] = IDLE;
tcpClient.append(new QTcpSocket());
tcpClient[i]->connectToHost(hostIP, hostPort);
//connect(tcpClient[i], SIGNAL(readyRead()), this, SLOT(readTCPData()));
connect(tcpClient[i], SIGNAL(readyRead()), this, SLOT(invokeReadTCPData()));
sendDebug("Created TCP Socket to Kayak device " + hostCanIDs.at(i));
}
setStatus(CANCon::CONNECTED);
CANConStatus stats;
stats.conStatus = getStatus();
stats.numHardwareBuses = mNumBuses;
//signalSender = qobject_cast<QTcpSocket*>(QObject::sender());
if (!reconnecting) emit status(stats);
}
void SocketCANd::deviceConnected(int busNum)
{
sendDebug("Opening CAN on Kayak Device!");
const char* openCanCmd = ("< open " + hostCanIDs[busNum] + " >").toStdString().c_str();
sendStringToTCP(openCanCmd, busNum);
QCoreApplication::processEvents();
}
void SocketCANd::checkConnection()
{
int bufSize = 0;
for (int i = 0; i < tcpClient.length(); i++)
{
bufSize += tcpClient[i]->readBufferSize();
//sendDebug("Buffer size: " + QString::number(bufSize));
}
if (bufSize == 0)
{
reconnecting = true;
connectDevice();
sendDebug("Reconnecting to TCP Host " + hostIP.toString());
}
}
void SocketCANd::switchToRawMode(int busNum)
{
sendDebug("Switching to rawmode...");
const char* rawmodeCmd = "< rawmode >";
sendStringToTCP(rawmodeCmd, busNum);
QCoreApplication::processEvents();
}
void SocketCANd::decodeFrames(QString data, int busNum)
{
if (data.indexOf("< frame ") == -1)
{
qDebug() << "Received datagramm doesn't contain any frame: " << data;
return;
}
else
{
QString framePart = data.mid(data.indexOf("< frame "), data.length()); //remove starting beginning of payload if not < frame >
const QString frameStrConst = framePart.left(framePart.indexOf(">")+1);
QString frameStr = frameStrConst;
QStringList frameParsed = (frameStr.remove(QRegExp("^<")).remove(QRegExp(">$"))).simplified().split(' ');
buildFrame.setFrameId(frameParsed[1].toUInt(nullptr, 16));
buildFrame.bus = busNum;
if (buildFrame.frameId() > 0x7FF) buildFrame.setExtendedFrameFormat(true);
else buildFrame.setExtendedFrameFormat(false);
buildFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, frameParsed[2].toDouble() * 1000000l));
//buildFrame.len = frameParsed[3].length() * 0.5;
int framelength = frameParsed[3].length() * 0.5;
buildData.resize(framelength);
int c;
for (c = 0; c < framelength; c++)
{
bool ok;
unsigned char byteVal = frameParsed[3].mid(c*2, 2).toUInt(&ok, 16);
buildData[c] = byteVal;
}
buildFrame.setPayload(buildData);
// buildFrame.isReceived = true;
if (!isCapSuspended())
{
/* get frame from queue */
CANFrame* frame_p = getQueue().get();
if(frame_p) {
/* copy frame */
*frame_p = buildFrame;
//frame_p->remote = false;
frame_p->setFrameType(QCanBusFrame::DataFrame);
checkTargettedFrame(buildFrame);
/* enqueue frame */
getQueue().queue();
}
}
else
qDebug() << "can't get a frame, capture suspended";
if (framePart.length() > frameStrConst.length())
decodeFrames(framePart.right(framePart.length() - frameStrConst.length()), busNum);
}
}
void SocketCANd::disconnectDevice() {
for (int i = 0; i < tcpClient.length(); i++)
{
if (tcpClient[i])
{
if (tcpClient[i]->isOpen())
{
tcpClient[i]->close();
}
tcpClient[i]->disconnect();
delete tcpClient[i];
tcpClient[i] = nullptr;
}
}
tcpClient.clear();
setStatus(CANCon::NOT_CONNECTED);
CANConStatus stats;
stats.conStatus = getStatus();
stats.numHardwareBuses = mNumBuses;
emit status(stats);
}
void SocketCANd::invokeReadTCPData()
{
QTcpSocket* signalSender = qobject_cast<QTcpSocket*>(QObject::sender());
int busNum = tcpClient.indexOf(signalSender);
QMetaObject::invokeMethod(this, "readTCPData", Qt::QueuedConnection, Q_ARG(int, busNum));
}
void SocketCANd::readTCPData(int busNum)
{
QByteArray data;
if (tcpClient[busNum]) data = tcpClient[busNum]->readAll();
//sendDebug("Got data from TCP. Len = " % QString::number(data.length()));
//qDebug() << "Received datagramm: " << data;
procRXData(data, busNum);
}
void SocketCANd::procRXData(QString data, int busNum)
{
if (data != "")
{
mTimer.stop();
mTimer.start();
}
QByteArray output;
switch (rx_state.at(busNum))
{
case IDLE:
qDebug() << "Received datagramm: " << data;
if (data == "< hi >")
{
deviceConnected(busNum);
rx_state[busNum] = BCM;
}
else qInfo() << hostCanIDs[busNum] << ": Could not open bus. Host did not greet with ""< hi >"": " << data;
break;
case BCM:
qDebug() << "Received datagramm: " << data;
if (data == "< ok >")
{
switchToRawMode(busNum);
rx_state[busNum] = SWITCHING2RAW;
}
else qInfo() << hostCanIDs[busNum] << ": Could not open bus. Host did not respond with ""< ok >"": " << data;
break;
case SWITCHING2RAW:
qDebug() << "Received datagramm: " << data;
if (data == "< ok >")
{
rx_state[busNum] = RAWMODE;
}
break;
case RAWMODE:
decodeFrames(data, busNum);
break;
case ISOTP:
break;
}
}
+82
View File
@@ -0,0 +1,82 @@
#ifndef SOCKETCAND_H
#define SOCKETCAND_H
//#include <QSerialPort>
//#include <QCanBusDevice>
#include <QTimer>
#include <QTcpSocket>
#include <QHostAddress>
//#include <QUdpSocket>
/*************/
#include <QDateTime>
/*************/
#include "canframemodel.h"
#include "canconnection.h"
#include "canconmanager.h"
namespace KAYAKSTATE {
enum MODE
{
IDLE, //NO_BUS in socketcand doc
BCM,
SWITCHING2RAW,
RAWMODE,
ISOTP
};
}
using namespace KAYAKSTATE;
class SocketCANd : public CANConnection
{
Q_OBJECT
public:
SocketCANd(QString portName);
virtual ~SocketCANd();
protected:
virtual void piStarted();
virtual void piStop();
virtual void piSetBusSettings(int pBusIdx, CANBus pBus);
virtual bool piGetBusSettings(int pBusIdx, CANBus& pBus);
virtual void piSuspend(bool pSuspend);
virtual bool piSendFrame(const CANFrame&);
void disconnectDevice();
private slots:
void connectDevice();
void checkConnection();
void readTCPData(int busNum);
void invokeReadTCPData();
void deviceConnected(int busNum);
void switchToRawMode(int busNum);
void decodeFrames(QString, int busNum);
private:
void procRXData(QString, int busNum);
void sendBytesToTCP(const QByteArray &bytes, int busNum);
void sendStringToTCP(const char* data, int busNum);
void sendDebug(const QString debugText);
protected:
QTimer mTimer;
bool reconnecting;
QVarLengthArray<QTcpSocket*> tcpClient;
QHostAddress hostIP;
int hostPort;
QList<QString> hostCanIDs;
int framesRapid;
QByteArray buildData;
QVarLengthArray<MODE> rx_state;
CANFrame buildFrame;
};
#endif // SOCKETCAND_H
+15 -8
View File
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>359</width>
<height>291</height>
<width>356</width>
<height>282</height>
</rect>
</property>
<property name="windowTitle">
@@ -26,14 +26,21 @@
<item row="0" column="0">
<widget class="QRadioButton" name="rbGVRET">
<property name="text">
<string>Serial Connection</string>
<string>Serial Connection (GVRET)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<item row="1" column="0">
<widget class="QRadioButton" name="rbRemote">
<property name="text">
<string>Network connection (GVRET)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="rbSocketCAN">
<property name="enabled">
<bool>false</bool>
@@ -43,14 +50,14 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="rbRemote">
<item row="3" column="0">
<widget class="QRadioButton" name="rbKayak">
<property name="text">
<string>Network Connection</string>
<string>socketcand (SocketCAN over Ethernet)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="4" column="0">
<widget class="QRadioButton" name="rbMQTT">
<property name="text">
<string>MQTT Connection</string>