From 2af1204cdd827f998c6e96708f66abd9d86ca9b4 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 16 May 2017 21:50:54 -0400 Subject: [PATCH] Additional work on UDS - now UDS scan window can get results from UDS handler instead of trying to do it all itself. --- SavvyCAN.pro | 3 +- bus_protocols/isotp_handler.h | 15 +------- bus_protocols/isotp_message.h | 18 ++++++++++ bus_protocols/uds_handler.cpp | 25 ++++++++++++++ bus_protocols/uds_handler.h | 12 +++++-- config.h | 2 +- re/udsscanwindow.cpp | 65 ++++++++++++++++------------------- re/udsscanwindow.h | 15 +++----- 8 files changed, 91 insertions(+), 64 deletions(-) create mode 100644 bus_protocols/isotp_message.h diff --git a/SavvyCAN.pro b/SavvyCAN.pro index ac6e484..a6492a3 100644 --- a/SavvyCAN.pro +++ b/SavvyCAN.pro @@ -113,7 +113,8 @@ HEADERS += mainwindow.h \ signalviewerwindow.h \ bus_protocols/isotp_handler.h \ bus_protocols/j1939_handler.h \ - bus_protocols/uds_handler.h + bus_protocols/uds_handler.h \ + bus_protocols/isotp_message.h FORMS += ui/candatagrid.ui \ ui/connectionwindow.ui \ diff --git a/bus_protocols/isotp_handler.h b/bus_protocols/isotp_handler.h index dc6a1f8..5d22c21 100644 --- a/bus_protocols/isotp_handler.h +++ b/bus_protocols/isotp_handler.h @@ -7,20 +7,7 @@ #include "can_structs.h" #include "mainwindow.h" #include "canframemodel.h" - -//the same as the CANFrame struct but with arbitrary data size. -struct ISOTP_MESSAGE -{ -public: - uint32_t ID; - int bus; - bool extended; - bool isReceived; - int len; //# of bytes this message should have (as reported) - int actualSize; //# we actually got - QVector data; - uint64_t timestamp; -}; +#include "isotp_message.h" class ISOTP_HANDLER : public QObject { diff --git a/bus_protocols/isotp_message.h b/bus_protocols/isotp_message.h new file mode 100644 index 0000000..66ed9df --- /dev/null +++ b/bus_protocols/isotp_message.h @@ -0,0 +1,18 @@ +#ifndef ISOTP_MESSAGE_H +#define ISOTP_MESSAGE_H + +//the same as the CANFrame struct but with arbitrary data size. +class ISOTP_MESSAGE +{ +public: + uint32_t ID; + int bus; + bool extended; + bool isReceived; + int len; //# of bytes this message should have (as reported) + int actualSize; //# we actually got + QVector data; + uint64_t timestamp; +}; + +#endif // ISOTP_MESSAGE_H diff --git a/bus_protocols/uds_handler.cpp b/bus_protocols/uds_handler.cpp index cb5e743..0e30bd7 100644 --- a/bus_protocols/uds_handler.cpp +++ b/bus_protocols/uds_handler.cpp @@ -1,5 +1,6 @@ #include "uds_handler.h" #include "connections/canconmanager.h" +#include "mainwindow.h" #include QVector UDS_SERVICE_DESC = { @@ -143,6 +144,18 @@ UDS_HANDLER::UDS_HANDLER() void UDS_HANDLER::gotISOTPFrame(ISOTP_MESSAGE &msg) { qDebug() << "UDS handler got ISOTP frame"; + UDS_MESSAGE udsMsg; + udsMsg.bus = msg.bus; + udsMsg.extended = msg.extended; + udsMsg.ID = msg.ID; + udsMsg.isReceived = msg.isReceived; + udsMsg.timestamp = msg.timestamp; + udsMsg.actualSize = msg.actualSize; + udsMsg.len = msg.len; + udsMsg.service = msg.data.at(0); + udsMsg.subFunc = msg.data.at(1); + udsMsg.data = msg.data.mid(1, -1); //don't copy data[0] which was service number + emit newUDSMessage(udsMsg); } void UDS_HANDLER::setReception(bool mode) @@ -177,6 +190,18 @@ void UDS_HANDLER::sendUDSFrame(int bus, int ID, int service, QVector data; + if (msg.bus < 0) return; + if (msg.bus >= CANConManager::getInstance()->getNumBuses()) return; + if (msg.service < 0 || msg.service > 0xFF) return; + data.append(msg.service); + data.append(msg.data); + ISOTP_HANDLER::getInstance()->sendISOTPFrame(msg.bus, msg.ID, data); + qDebug() << "Sent UDS service: " << getServiceShortDesc(msg.service) << " on bus " << msg.bus; +} + QString UDS_HANDLER::getServiceShortDesc(int service) { foreach (CODE_STRUCT code, UDS_SERVICE_DESC) diff --git a/bus_protocols/uds_handler.h b/bus_protocols/uds_handler.h index 315f722..62b01b7 100644 --- a/bus_protocols/uds_handler.h +++ b/bus_protocols/uds_handler.h @@ -5,7 +5,7 @@ #include #include #include "can_structs.h" -#include "isotp_handler.h" +#include "isotp_message.h" namespace UDS_SERVICES { @@ -68,6 +68,13 @@ struct CODE_STRUCT QString longDesc; }; +class UDS_MESSAGE: public ISOTP_MESSAGE +{ +public: + int service; + int subFunc; +}; + class UDS_HANDLER : public QObject { Q_OBJECT @@ -78,6 +85,7 @@ public: static UDS_HANDLER* getInstance(); void setReception(bool mode); //set whether to accept and forward frames or not void sendUDSFrame(int bus, int ID, int service, QVector payload); + void sendUDSFrame(const UDS_MESSAGE &msg); QString getServiceShortDesc(int service); QString getServiceLongDesc(int service); QString getNegativeResponseShort(int respCode); @@ -87,7 +95,7 @@ public slots: void gotISOTPFrame(ISOTP_MESSAGE &msg); signals: - void newUDSMessage(ISOTP_MESSAGE &msg); + void newUDSMessage(UDS_MESSAGE &msg); private: QList messageBuffer; diff --git a/config.h b/config.h index d89fe49..5d61a24 100644 --- a/config.h +++ b/config.h @@ -1,7 +1,7 @@ #ifndef CONFIG #define CONFIG -#define VERSION 167 +#define VERSION 168 //try to keep this in sync. //SavvyCAN will complain if you connect a GVRET board with a revision diff --git a/re/udsscanwindow.cpp b/re/udsscanwindow.cpp index ad4e103..ee2f187 100644 --- a/re/udsscanwindow.cpp +++ b/re/udsscanwindow.cpp @@ -17,8 +17,10 @@ UDSScanWindow::UDSScanWindow(const QVector *frames, QWidget *parent) : waitTimer = new QTimer; waitTimer->setInterval(100); + UDS_HANDLER::getInstance()->setReception(true); + connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int))); - connect(CANConManager::getInstance(), &CANConManager::framesReceived, this, &UDSScanWindow::rapidFrames); + connect(UDS_HANDLER::getInstance(), &UDS_HANDLER::newUDSMessage, this, &UDSScanWindow::gotUDSReply); connect(ui->btnScan, &QPushButton::clicked, this, &UDSScanWindow::scanUDS); connect(waitTimer, &QTimer::timeout, this, &UDSScanWindow::timeOut); connect(ui->btnSaveResults, &QPushButton::clicked, this, &UDSScanWindow::saveResults); @@ -73,7 +75,7 @@ void UDSScanWindow::saveResults() } } -void UDSScanWindow::sendOnBuses(UDS_TESTS test, int buses) +void UDSScanWindow::sendOnBuses(UDS_MESSAGE test, int buses) { int busList = buses; if (busList < ui->cbBuses->count() - 1) @@ -107,7 +109,7 @@ void UDSScanWindow::scanUDS() ui->listResults->clear(); sendingFrames.clear(); - UDS_TESTS test; + UDS_MESSAGE test; int typ, id; int startID, endID; startID = Utility::ParseStringToNum(ui->txtStartID->text()); @@ -169,49 +171,42 @@ void UDSScanWindow::updatedFrames(int numFrames) } } -//Updates here are nearly once per millisecond if there is heavy traffic. That's more like it! -//TODO: I really doubt this works anymore with the new connection system. This breaks the UDS scanner for now! ;( -void UDSScanWindow::rapidFrames(const CANConnection* conn, const QVector& pFrames) +void UDSScanWindow::gotUDSReply(UDS_MESSAGE &msg) { QString result; uint32_t id; int offset = ui->spinReplyOffset->value(); - UDS_TESTS sentFrame; + UDS_MESSAGE sentFrame; bool gotReply = false; - if (pFrames.length() <= 0) return; - int numSending = sendingFrames.length(); if (numSending == 0) return; if (currIdx >= numSending) return; sentFrame = sendingFrames[currIdx]; - foreach(const CANFrame& thisFrame, pFrames) - { - if (currIdx >= numSending) return; - id = thisFrame.ID; + id = msg.ID; - if ((id == (uint32_t)(sentFrame.ID + offset)) || ui->cbAllowAdaptiveOffset->isChecked()) - { - //int temp = thisFrame.data[0] >> 4; - //if (temp == 0) //single frame reply (maybe) - //{ - if (thisFrame.data[1] == 0x40 + sendingFrames[currIdx].service) - { - result = "Request on bus " + QString::number(sentFrame.bus) + " ID: " + QString::number(sentFrame.ID, 16) + " got response to mode " - + QString::number(sentFrame.service, 16) - + " " + QString::number(sentFrame.subFunc, 16) + " with affirmation from ID " + QString::number(id, 16) - + " on bus " + QString::number(thisFrame.bus) + "."; - gotReply = true; - } - else if ( thisFrame.data[1] == 0x7F) - { - result = "Request on bus " + QString::number(sentFrame.bus) + " ID: " + QString::number(sentFrame.ID, 16) + " got response to mode " - + QString::number(sentFrame.service, 16) - + " " + QString::number(sentFrame.subFunc, 16) + " with an error from ID " + QString::number(id, 16) - + " on bus " + QString::number(thisFrame.bus) + "."; - gotReply = true; - } + if ((id == (uint32_t)(sentFrame.ID + offset)) || ui->cbAllowAdaptiveOffset->isChecked()) + { + //int temp = thisFrame.data[0] >> 4; + //if (temp == 0) //single frame reply (maybe) + //{ + if (msg.service == 0x40 + sendingFrames[currIdx].service) + { + result = "Request on bus " + QString::number(sentFrame.bus) + " ID: " + QString::number(sentFrame.ID, 16) + " got response to mode " + + QString::number(sentFrame.service, 16) + + " " + QString::number(sentFrame.subFunc, 16) + " with affirmation from ID " + QString::number(id, 16) + + " on bus " + QString::number(msg.bus) + "."; + gotReply = true; + } + else if ( msg.service == 0x7F) + { + result = "Request on bus " + QString::number(sentFrame.bus) + " ID: " + QString::number(sentFrame.ID, 16) + " got response to mode " + + QString::number(sentFrame.service, 16) + + " " + QString::number(sentFrame.subFunc, 16) + " with an error from ID " + QString::number(id, 16) + + " on bus " + QString::number(msg.bus) + "."; + gotReply = true; + } //} /* if (temp == 1) //start of a multiframe reply @@ -226,7 +221,7 @@ void UDSScanWindow::rapidFrames(const CANConnection* conn, const QVector @@ -10,14 +11,6 @@ namespace Ui { class UDSScanWindow; } -struct UDS_TESTS -{ - int ID; - int bus; - int service; - int subFunc; -}; - class UDSScanWindow : public QDialog { Q_OBJECT @@ -28,7 +21,7 @@ public: private slots: void updatedFrames(int numFrames); - void rapidFrames(const CANConnection* conn, const QVector& pFrames); + void gotUDSReply(UDS_MESSAGE &msg); void scanUDS(); void saveResults(); void timeOut(); @@ -37,12 +30,12 @@ private: Ui::UDSScanWindow *ui; const QVector *modelFrames; QTimer *waitTimer; - QList sendingFrames; + QList sendingFrames; int currIdx = 0; bool currentlyRunning; void sendNextMsg(); - void sendOnBuses(UDS_TESTS frame, int buses); + void sendOnBuses(UDS_MESSAGE frame, int buses); }; #endif // UDSSCANWINDOW_H