From 4b73cb2e263b2b0d2bbf471a8e514f25f655cb99 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sun, 20 Aug 2017 18:22:10 -0400 Subject: [PATCH] Fixes to UDS related code --- bus_protocols/isotp_handler.cpp | 33 ++++++++++++++++++++++++++++++--- bus_protocols/isotp_handler.h | 4 ++++ bus_protocols/uds_handler.cpp | 5 +++++ bus_protocols/uds_handler.h | 1 + re/udsscanwindow.cpp | 10 +++++++--- 5 files changed, 47 insertions(+), 6 deletions(-) diff --git a/bus_protocols/isotp_handler.cpp b/bus_protocols/isotp_handler.cpp index 5d8e559..18d537c 100644 --- a/bus_protocols/isotp_handler.cpp +++ b/bus_protocols/isotp_handler.cpp @@ -18,6 +18,10 @@ ISOTP_HANDLER::ISOTP_HANDLER() { useExtendedAddressing = false; isReceiving = false; + issueFlowMsgs = false; + processAll = false; + lastSenderBus = 0; + lastSenderID = 0; connect(&frameTimer, SIGNAL(timeout()), this, SLOT(frameTimerTick())); } @@ -27,6 +31,11 @@ void ISOTP_HANDLER::setExtendedAddressing(bool mode) useExtendedAddressing = mode; } +void ISOTP_HANDLER::setFlowCtrl(bool state) +{ + issueFlowMsgs = state; +} + void ISOTP_HANDLER::setReception(bool mode) { if (isReceiving == mode) return; @@ -52,13 +61,16 @@ void ISOTP_HANDLER::sendISOTPFrame(int bus, int ID, QVector data) if (bus < 0) return; if (bus >= CANConManager::getInstance()->getNumBuses()) return; + lastSenderID = ID; + lastSenderBus = bus; + if (data.length() < 8) { frame.bus = bus; frame.extended = false; frame.ID = ID; frame.len = 8; - for (int b = 0; b < 8; b++) frame.data[b] = 0xAA; + for (int b = 0; b < 8; b++) frame.data[b] = 0x00; frame.data[0] = data.length(); for (int i = 0; i < frame.data[0]; i++) frame.data[i + 1] = data[i]; CANConManager::getInstance()->sendFrame(frame); @@ -69,7 +81,7 @@ void ISOTP_HANDLER::sendISOTPFrame(int bus, int ID, QVector data) frame.ID = ID; frame.extended = false; frame.len = 8; - for (int b = 0; b < 8; b++) frame.data[b] = 0xAA; + for (int b = 0; b < 8; b++) frame.data[b] = 0x00; frame.data[0] = 0x10 + (data.length() / 256); frame.data[1] = data.length() & 0xFF; for (int i = 0; i < 6; i++) frame.data[2 + i] = data[currByte++]; @@ -81,7 +93,7 @@ void ISOTP_HANDLER::sendISOTPFrame(int bus, int ID, QVector data) frameTimer.start(); while (currByte < data.length()) { - for (int b = 0; b < 8; b++) frame.data[b] = 0xAA; + for (int b = 0; b < 8; b++) frame.data[b] = 0x00; frame.data[0] = 0x20 + index; index = (index + 1) & 0xF; int bytesToGo = data.length() - currByte; @@ -200,6 +212,21 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame) for (int j = 0; j < 6; j++) msg.data.append(frame.data[2 + j]); } messageBuffer.append(msg); + //The sending ID is set to the last ID we used to send from this class which is + //very likely to be correct. But, caution, there is a chance that it isn't. Beware. + if (issueFlowMsgs && lastSenderID > 0) + { + CANFrame outFrame; + outFrame.bus = lastSenderBus; + outFrame.extended = false; + outFrame.ID = lastSenderID; + outFrame.len = 8; + for (int b = 0; b < 8; b++) outFrame.data[b] = 0x00; + outFrame.data[0] = 0x30; //flow control, go ahead and send + outFrame.data[1] = 0; //dont ask again about flow control + outFrame.data[2] = 3; //separation time in milliseconds between messages. + CANConManager::getInstance()->sendFrame(outFrame); + } break; case 2: //subsequent frames for multi-frame messages pMsg = NULL; diff --git a/bus_protocols/isotp_handler.h b/bus_protocols/isotp_handler.h index cce3628..bda09ea 100644 --- a/bus_protocols/isotp_handler.h +++ b/bus_protocols/isotp_handler.h @@ -21,6 +21,7 @@ public: void setReception(bool mode); //set whether to accept and forward frames or not void sendISOTPFrame(int bus, int ID, QVector data); void setProcessAll(bool state); + void setFlowCtrl(bool state); void addID(uint32_t id); void removeID(uint32_t id); void clearAllIDs(); @@ -43,7 +44,10 @@ private: bool waitingForFlow; int framesUntilFlow; bool processAll; + bool issueFlowMsgs; QTimer frameTimer; + uint32_t lastSenderID; + uint32_t lastSenderBus; void processFrame(const CANFrame &frame); void checkNeedFlush(uint64_t ID); diff --git a/bus_protocols/uds_handler.cpp b/bus_protocols/uds_handler.cpp index 9aa4070..22dedfb 100644 --- a/bus_protocols/uds_handler.cpp +++ b/bus_protocols/uds_handler.cpp @@ -187,6 +187,11 @@ void UDS_HANDLER::gotISOTPFrame(ISOTP_MESSAGE msg) emit newUDSMessage(udsMsg); } +void UDS_HANDLER::setFlowCtrl(bool state) +{ + ISOTP_HANDLER::getInstance()->setFlowCtrl(state); +} + void UDS_HANDLER::setReception(bool mode) { if (isReceiving == mode) return; diff --git a/bus_protocols/uds_handler.h b/bus_protocols/uds_handler.h index e2133bb..d655b48 100644 --- a/bus_protocols/uds_handler.h +++ b/bus_protocols/uds_handler.h @@ -90,6 +90,7 @@ public: void setReception(bool mode); //set whether to accept and forward frames or not void sendUDSFrame(const UDS_MESSAGE &msg); void setProcessAllIDs(bool state); + void setFlowCtrl(bool state); void addID(uint32_t id); void removeID(uint32_t id); void clearAllIDs(); diff --git a/re/udsscanwindow.cpp b/re/udsscanwindow.cpp index 6c9100b..62d7792 100644 --- a/re/udsscanwindow.cpp +++ b/re/udsscanwindow.cpp @@ -18,9 +18,6 @@ UDSScanWindow::UDSScanWindow(const QVector *frames, QWidget *parent) : waitTimer = new QTimer; waitTimer->setInterval(100); - UDS_HANDLER::getInstance()->setReception(true); - UDS_HANDLER::getInstance()->setProcessAllIDs(true); - connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int))); connect(UDS_HANDLER::getInstance(), &UDS_HANDLER::newUDSMessage, this, &UDSScanWindow::gotUDSReply); connect(ui->btnScan, &QPushButton::clicked, this, &UDSScanWindow::scanUDS); @@ -187,11 +184,18 @@ void UDSScanWindow::scanUDS() { waitTimer->stop(); sendingFrames.clear(); + UDS_HANDLER::getInstance()->setReception(false); + UDS_HANDLER::getInstance()->setProcessAllIDs(false); + UDS_HANDLER::getInstance()->setFlowCtrl(false); currentlyRunning = false; ui->btnScan->setText("Start Scan"); return; } + UDS_HANDLER::getInstance()->setReception(true); + UDS_HANDLER::getInstance()->setProcessAllIDs(true); + UDS_HANDLER::getInstance()->setFlowCtrl(true); + waitTimer->setInterval(ui->spinDelay->value()); ui->treeResults->clear();