Skip to content

Commit

Permalink
Merge pull request #697 from CCGene/master
Browse files Browse the repository at this point in the history
Added canlogserver CAN remote capture
  • Loading branch information
collin80 authored Nov 21, 2023
2 parents 1999da8 + 2ded46c commit 7508ce5
Show file tree
Hide file tree
Showing 9 changed files with 280 additions and 0 deletions.
2 changes: 2 additions & 0 deletions SavvyCAN.pro
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ ICON = icons/SavvyIcon.icns

SOURCES += main.cpp\
canbridgewindow.cpp \
connections/canlogserver.cpp \
connections/canserver.cpp \
connections/lawicel_serial.cpp \
connections/mqtt_bus.cpp \
Expand Down Expand Up @@ -104,6 +105,7 @@ HEADERS += mainwindow.h \
can_structs.h \
canbridgewindow.h \
canframemodel.h \
connections/canlogserver.h \
connections/canserver.h \
connections/lawicel_serial.h \
connections/socketcand.h \
Expand Down
1 change: 1 addition & 0 deletions connections/canconconst.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace CANCon {
MQTT,
LAWICEL,
CANSERVER,
CANLOGSERVER,
NONE
};
}
Expand Down
3 changes: 3 additions & 0 deletions connections/canconfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "socketcand.h"
#include "lawicel_serial.h"
#include "canserver.h"
#include "canlogserver.h"

using namespace CANCon;

Expand All @@ -29,6 +30,8 @@ CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDri
return new MQTT_BUS(pPortName);
case CANSERVER:
return new CANserver(pPortName);
case CANLOGSERVER:
return new CanLogServer(pPortName);
default: {}
}

Expand Down
1 change: 1 addition & 0 deletions connections/canconnectionmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const
case CANCon::KAYAK: return "socketcand";
case CANCon::LAWICEL: return "LAWICEL";
case CANCon::CANSERVER: return "CANserver";
case CANCon::CANLOGSERVER: return "CanLogServer";
default: {}
}
else qDebug() << "Tried to show connection type but connection was nullptr";
Expand Down
186 changes: 186 additions & 0 deletions connections/canlogserver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
#include <QObject>
#include <QDebug>
#include <QCanBusFrame>
#include <QSettings>
#include <QStringBuilder>
#include <QtNetwork>

#include "utility.h"
#include "canlogserver.h"

CanLogServer::CanLogServer(QString serverAddressString) :
CANConnection(serverAddressString, "CanLogserver", CANCon::CANLOGSERVER, 0, 0, 1, 4000, true),
m_ptcpSocket(new QTcpSocket(this))
{

qDebug() << "Canlogserver: " << "Constructing new Connection...";

CANBus bus_info;
bus_info.setActive(true);
bus_info.setListenOnly(true);
bus_info.setSpeed(500000);

setBusConfig(0, bus_info);

// Connect data ready signal
connect(m_ptcpSocket, SIGNAL(readyRead()), this, SLOT(readNetworkData()));
// Connect network connected signal
connect(m_ptcpSocket, SIGNAL(connected()),this, SLOT(networkConnected()));
// Connect network disconnected signal
connect(m_ptcpSocket, SIGNAL(disconnected()),this, SLOT(networkDisconnected()));
// Save address
this->m_qsAddress = serverAddressString;
}


CanLogServer::~CanLogServer()
{
qDebug() << "Canlogserver: " << "Deconstructing Connection...";

stop();

m_ptcpSocket->close();
delete m_ptcpSocket;
m_ptcpSocket = NULL;
}

void CanLogServer::readNetworkData()
{
// If capture is suspended bail out after reading the bytes from the network. No need to parse them
if(isCapSuspended())
return;

while (m_ptcpSocket->canReadLine()) {
// Get a complete line and remove whitespace at the start and at the end of the string
QString data = QString(m_ptcpSocket->readLine()).trimmed();
// Split to space (obtain "<(time)> <canID> <msgId#data>")
QStringList lstData = data.split(" ");
// Expect 3 item in list
if(lstData.size() == 3){
// Obtain the timestamp. Remove '(', ')' and '.' (logserver send as "(time.fraction)").
QString qstrTs = lstData[0].remove(QChar('(')).remove(QChar('.')).remove(QChar(')'));
// One bus only. TODO: Use another parameter in connection conf for spcify can bus id to capture.
QString qstrCanId = "0";
// Split frame
QStringList lstMsg = lstData[2].split("#");
// Expect 2 item (<id>#<payload>)
if(lstMsg.size() == 2){
// Extract id
QString qstrId = lstMsg[0];
// Extract payload
QString qstrPayload = lstMsg[1];
// Support only normal can message. Extended CAN not supported.
if(qstrId.size() <= 4){
// Prepare the frame
CANFrame* frame_p = getQueue().get();
// Check for frame existence
if(frame_p){
// Set frame ID
frame_p->setFrameId(qstrId.toInt(nullptr, 16));
// Extended frame NOT SUPPORTED
frame_p->setExtendedFrameFormat(0);
// Set bus id
frame_p->bus = qstrCanId.toInt();
// Set frame type
frame_p->setFrameType(QCanBusFrame::DataFrame);
// Frame is recived
frame_p->isReceived = true;
// Set timestamp
frame_p->setTimeStamp(QCanBusFrame::TimeStamp(0, qstrTs.toULongLong()));
// Set payload
frame_p->setPayload(QByteArray::fromHex(qstrPayload.toUtf8()));
// Elaborate frame
checkTargettedFrame(*frame_p);
/* enqueue frame */
getQueue().queue();
}
qDebug() << data << "---" << qstrTs << " - " << qstrId << " + " << qstrPayload;
}
}
}
}
}

void CanLogServer::networkConnected()
{
CANConStatus stats;
qDebug() << "networkConnected";

setStatus(CANCon::CONNECTED);
stats.conStatus = getStatus();
stats.numHardwareBuses = 1;
emit status(stats);
}

void CanLogServer::networkDisconnected()
{
qDebug() << "networkDisconnected";
}

void CanLogServer::piStarted()
{
this->connectToDevice();
}

void CanLogServer::piSuspend(bool pSuspend)
{
/* update capSuspended */
setCapSuspended(pSuspend);

/* flush queue if we are suspended */
if(isCapSuspended())
getQueue().flush();
}


void CanLogServer::piStop()
{
this->disconnectFromDevice();
}


bool CanLogServer::piGetBusSettings(int pBusIdx, CANBus& pBus)
{
return getBusConfig(pBusIdx, pBus);
}


void CanLogServer::piSetBusSettings(int pBusIdx, CANBus bus)
{
/* sanity checks */
if( (pBusIdx < 0) || pBusIdx >= getNumBuses())
return;

/* copy bus config */
setBusConfig(pBusIdx, bus);
}


bool CanLogServer::piSendFrame(const CANFrame& )
{
//We don't support sending frames right now
return true;
}

void CanLogServer::connectToDevice()
{
qDebug() << "Canlogserver: " << "Establishing connection to a Canlogserver device...";

QUrl url("http://" + m_qsAddress);
qDebug() << "address:" << m_qsAddress;
qDebug() << "Host:" << url.host();
qDebug() << "Port:" << url.port();
// Set status at not connected
setStatus(CANCon::NOT_CONNECTED);
// No proxy for connection
m_ptcpSocket->setProxy(QNetworkProxy::NoProxy);
// Connect to log server
m_ptcpSocket->connectToHost(url.host(), url.port());
}

void CanLogServer::disconnectFromDevice()
{
qDebug() << "Canlogserver: " << "Disconnecting...";
// Close socket
m_ptcpSocket->close();
}
57 changes: 57 additions & 0 deletions connections/canlogserver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#ifndef CANLOGSERVER_H
#define CANLOGSERVER_H

#include <stdio.h>

#include <QCanBusDevice>
#include <QThread>
#include <QTimer>
#include <QTcpSocket>

/*************/
#include <QDateTime>
/*************/

#include "canframemodel.h"
#include "canconnection.h"
#include "canconmanager.h"

class CanLogServer : public CANConnection
{
Q_OBJECT

public:
CanLogServer(QString serverAddress);
virtual ~CanLogServer();

// Interface
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&);

private slots:
void readNetworkData();
void networkConnected();
void networkDisconnected();

// Utility
private:
void readSettings();
void connectToDevice();
void disconnectFromDevice();
void heartbeat();

// Attributes
protected:
QTcpSocket *m_ptcpSocket = nullptr;
QString m_qsAddress;

// QUdpSocket *_udpClient;

// QTimer *_heartbeatTimer;
};
#endif // CANLOGSERVER_H
22 changes: 22 additions & 0 deletions connections/newconnectiondialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ NewConnectionDialog::NewConnectionDialog(QVector<QString>* gvretips, QVector<QSt
connect(ui->rbMQTT, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
connect(ui->rbLawicel, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
connect(ui->rbCANserver, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);
connect(ui->rbCanlogserver, &QAbstractButton::clicked, this, &NewConnectionDialog::handleConnTypeChanged);

connect(ui->cbDeviceType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NewConnectionDialog::handleDeviceTypeChanged);
connect(ui->btnOK, &QPushButton::clicked, this, &NewConnectionDialog::handleCreateButton);
Expand Down Expand Up @@ -64,6 +65,7 @@ void NewConnectionDialog::handleConnTypeChanged()
if (ui->rbKayak->isChecked()) selectKayak();
if (ui->rbMQTT->isChecked()) selectMQTT();
if (ui->rbCANserver->isChecked()) selectCANserver();
if (ui->rbCanlogserver->isChecked()) selectCANlogserver();
}

void NewConnectionDialog::handleDeviceTypeChanged()
Expand Down Expand Up @@ -218,6 +220,20 @@ void NewConnectionDialog::selectCANserver()
ui->cbPort->clear();
}

void NewConnectionDialog::selectCANlogserver()
{
ui->lPort->setText("CANlogserver IP Address:");

ui->lblDeviceType->setHidden(true);
ui->cbDeviceType->setHidden(true);
ui->cbCANSpeed->setHidden(true);
ui->cbSerialSpeed->setHidden(true);
ui->lblCANSpeed->setHidden(true);
ui->lblSerialSpeed->setHidden(true);

ui->cbPort->clear();
}

void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QString pDriver)
{

Expand All @@ -244,6 +260,9 @@ void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QSt
case CANCon::CANSERVER:
ui->rbCANserver->setChecked(true);
break;
case CANCon::CANLOGSERVER:
ui->rbCanlogserver->setChecked(true);
break;
default: {}
}

Expand Down Expand Up @@ -288,6 +307,7 @@ void NewConnectionDialog::setPortName(CANCon::type pType, QString pPortName, QSt
ui->cbPort->setCurrentText(pPortName);
break;
case CANCon::CANSERVER:
case CANCon::CANLOGSERVER:
{
ui->cbPort->setCurrentText(pPortName);
break;
Expand All @@ -308,6 +328,7 @@ QString NewConnectionDialog::getPortName()
case CANCon::KAYAK:
return ui->cbPort->currentText();
case CANCon::CANSERVER:
case CANCon::CANLOGSERVER:
return ui->cbPort->currentText();

default:
Expand Down Expand Up @@ -353,6 +374,7 @@ CANCon::type NewConnectionDialog::getConnectionType()
if (ui->rbMQTT->isChecked()) return CANCon::MQTT;
if (ui->rbLawicel->isChecked()) return CANCon::LAWICEL;
if (ui->rbCANserver->isChecked()) return CANCon::CANSERVER;
if (ui->rbCanlogserver->isChecked()) return CANCon::CANLOGSERVER;
qDebug() << "getConnectionType: error";

return CANCon::NONE;
Expand Down
1 change: 1 addition & 0 deletions connections/newconnectiondialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public slots:
void selectMQTT();
void selectLawicel();
void selectCANserver();
void selectCANlogserver();
bool isSerialBusAvailable();
void setPortName(CANCon::type pType, QString pPortName, QString pDriver);
};
Expand Down
7 changes: 7 additions & 0 deletions ui/newconnectiondialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QRadioButton" name="rbCanlogserver">
<property name="text">
<string>CANlogserver</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down

0 comments on commit 7508ce5

Please sign in to comment.