diff --git a/bus_protocols/uds_handler.cpp b/bus_protocols/uds_handler.cpp index 438517c..112eb06 100644 --- a/bus_protocols/uds_handler.cpp +++ b/bus_protocols/uds_handler.cpp @@ -122,6 +122,15 @@ QVector UDS_NEG_RESPONSE = {0x93, "VOLTAGE_LOW", "Cannot execute request until voltage is higher"}, }; +UDS_MESSAGE::UDS_MESSAGE() +{ + subFunc = 0; + service = 0; + subFuncLen = 1; + extended = false; + isErrorReply = false; +} + UDS_HANDLER* UDS_HANDLER::mInstance = NULL; UDS_HANDLER* UDS_HANDLER::getInstance() @@ -198,27 +207,22 @@ void UDS_HANDLER::setReception(bool mode) } } -void UDS_HANDLER::sendUDSFrame(int bus, int ID, int service, QVector payload) -{ - QVector data; - if (bus < 0) return; - if (bus >= CANConManager::getInstance()->getNumBuses()) return; - if (service < 0 || service > 0xFF) return; - data.append(service); - data.append(payload); - ISOTP_HANDLER::getInstance()->sendISOTPFrame(bus, ID, data); - qDebug() << "Sent UDS service: " << getServiceShortDesc(service) << " on bus " << bus; -} - void UDS_HANDLER::sendUDSFrame(const UDS_MESSAGE &msg) { 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); + for (int b = msg.subFuncLen - 1; b >= 0; b--) + { + data.append((msg.subFunc >> (8 * b)) & 0xFF); + } + data.append(msg.data); ISOTP_HANDLER::getInstance()->sendISOTPFrame(msg.bus, msg.ID, data); + qDebug() << "Sent UDS service: " << getServiceShortDesc(msg.service) << " on bus " << msg.bus; } diff --git a/bus_protocols/uds_handler.h b/bus_protocols/uds_handler.h index 1d625aa..8e745a3 100644 --- a/bus_protocols/uds_handler.h +++ b/bus_protocols/uds_handler.h @@ -73,7 +73,10 @@ class UDS_MESSAGE: public ISOTP_MESSAGE public: int service; int subFunc; + int subFuncLen; bool isErrorReply; + + UDS_MESSAGE(); }; class UDS_HANDLER : public QObject @@ -85,7 +88,6 @@ public: void setExtendedAddressing(bool mode); 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); diff --git a/connections/canconnection.cpp b/connections/canconnection.cpp index cdfb748..4f8905e 100644 --- a/connections/canconnection.cpp +++ b/connections/canconnection.cpp @@ -343,7 +343,7 @@ bool CANConnection::removeAllTargettedFrames(QObject *receiver) void CANConnection::checkTargettedFrame(CANFrame &frame) { unsigned int maskedID; - qDebug() << "Got frame with ID " << frame.ID << " on bus " << frame.bus; + //qDebug() << "Got frame with ID " << frame.ID << " on bus " << frame.bus; foreach (const CANFlt filt, mBusData_p[frame.bus].mTargettedFrames) { qDebug() << "Checking filter with id " << filt.id << " mask " << filt.mask; diff --git a/re/udsscanwindow.cpp b/re/udsscanwindow.cpp index 4ff3f1d..8d241fa 100644 --- a/re/udsscanwindow.cpp +++ b/re/udsscanwindow.cpp @@ -223,6 +223,7 @@ void UDSScanWindow::scanUDS() test.subFunc = 0; sendOnBuses(test, buses); } + if (ui->ckSession->isChecked()) { for (typ = 1; typ < 4; typ++) //try each type of session access @@ -232,22 +233,45 @@ void UDSScanWindow::scanUDS() sendOnBuses(test, buses); } } + if (ui->ckReset->isChecked()) //try to command a reset of the ECU. You're likely to know if it works. ;) { test.service = UDS_SERVICES::ECU_RESET; test.subFunc = 1; sendOnBuses(test, buses); } + if (ui->ckSecurity->isChecked()) //try to enter security mode - very likely to get a response if an ECU exists. { test.service = UDS_SERVICES::SECURITY_ACCESS; test.subFunc = 1; sendOnBuses(test, buses); } + + if (ui->ckReadByAddr->isChecked()) + { + test.subFuncLen = ui->spinNumBytes->value(); + test.service = UDS_SERVICES::READ_BY_ADDR; + for (int subf = ui->spinLowerSubfunc->value(); subf <= ui->spinUpperSubfunc->value(); subf++) + { + test.subFunc = subf; + sendOnBuses(test, buses); + } + } + + if (ui->ckReadByID->isChecked()) + { + test.subFuncLen = ui->spinNumBytes->value(); + test.service = UDS_SERVICES::READ_BY_ID; + for (int subf = ui->spinLowerSubfunc->value(); subf <= ui->spinUpperSubfunc->value(); subf++) + { + test.subFunc = subf; + sendOnBuses(test, buses); + } + } + if (ui->ckWildcard->isChecked()) { - int numBytes = ui->spinNumBytes->value(); - //preallocate the whole buffer so we don't have to keep updating the size and moving as we go. //TODO: this shows a downside to the current method - it might potentially need to create a huge //number of frames here. Of course, the rest of the system will do the same so I guess it's a bad idea @@ -256,18 +280,14 @@ void UDSScanWindow::scanUDS() size *= (ui->spinUpperSubfunc->value() - ui->spinLowerSubfunc->value()); sendingFrames.reserve(size); + test.subFuncLen = ui->spinNumBytes->value(); + for (typ = ui->spinLowerService->value(); typ <= ui->spinUpperService->value(); typ++) { test.service = typ; for (int subTyp = ui->spinLowerSubfunc->value(); subTyp <= ui->spinUpperSubfunc->value(); subTyp++) { - test.data.clear(); - //multi-byte data sent big endian (largest value byte first) so plan accordingly. - test.subFunc = subTyp >> (8 * (numBytes - 1)); - for (int by = 1; by < numBytes; by++) - { - test.data.append(subTyp >> (8 * (numBytes - by))); - } + test.subFunc = subTyp; sendOnBuses(test, buses); } } @@ -278,6 +298,8 @@ void UDSScanWindow::scanUDS() currIdx = -1; currentlyRunning = true; ui->btnScan->setText("Abort Scan"); + ui->progressBar->setValue(0); + ui->progressBar->setMaximum(sendingFrames.length()); sendNextMsg(); } @@ -311,6 +333,8 @@ void UDSScanWindow::gotUDSReply(UDS_MESSAGE &msg) id = msg.ID; + qDebug() << "UDS message ID " << msg.ID << " service: " << msg.service << " subfunc: " << msg.subFunc; + if ((id == (uint32_t)(sentFrame.ID + offset)) || ui->cbAllowAdaptiveOffset->isChecked()) { serviceShortName = UDS_HANDLER::getInstance()->getServiceShortDesc(sentFrame.service); @@ -332,15 +356,19 @@ void UDSScanWindow::gotUDSReply(UDS_MESSAGE &msg) nodeSubFunc->setForeground(0, QBrush(Qt::darkGreen)); gotReply = true; } - else if ( msg.service == 0x7F) + else if ( msg.isErrorReply && msg.service == sendingFrames[currIdx].service) { - setupNodes(); - QTreeWidgetItem *nodeNegative = new QTreeWidgetItem(); - nodeNegative->setText(0, "NEGATIVE - " + UDS_HANDLER::getInstance()->getNegativeResponseShort(msg.data[1])); - nodeNegative->setForeground(0, QBrush(Qt::darkRed)); - nodeSubFunc->addChild(nodeNegative); - nodeSubFunc->setForeground(0, QBrush(Qt::darkRed)); - gotReply = true; + if (msg.data.length()) + { + setupNodes(); + QTreeWidgetItem *nodeNegative = new QTreeWidgetItem(); + qDebug() << ui->spinNumBytes->value(); + nodeNegative->setText(0, "NEGATIVE - " + UDS_HANDLER::getInstance()->getNegativeResponseShort(msg.data[0])); + nodeNegative->setForeground(0, QBrush(Qt::darkRed)); + nodeSubFunc->addChild(nodeNegative); + nodeSubFunc->setForeground(0, QBrush(Qt::darkRed)); + gotReply = true; + } } } if (gotReply) @@ -391,15 +419,10 @@ void UDSScanWindow::timeOut() void UDSScanWindow::sendNextMsg() { - QVector data; - currIdx++; if (currIdx < sendingFrames.count()) { - data.clear(); - data.append(sendingFrames[currIdx].subFunc); - data.append(sendingFrames[currIdx].data); - UDS_HANDLER::getInstance()->sendUDSFrame(sendingFrames[currIdx].bus, sendingFrames[currIdx].ID, sendingFrames[currIdx].service, data); + UDS_HANDLER::getInstance()->sendUDSFrame(sendingFrames[currIdx]); waitTimer->start(); } else @@ -408,4 +431,5 @@ void UDSScanWindow::sendNextMsg() ui->btnScan->setText("Start Scan"); currentlyRunning = false; } + ui->progressBar->setValue(currIdx); } diff --git a/ui/udsscanwindow.ui b/ui/udsscanwindow.ui index 4f51117..c305706 100644 --- a/ui/udsscanwindow.ui +++ b/ui/udsscanwindow.ui @@ -87,7 +87,7 @@ 536870911 - 2024 + 2023 16 @@ -101,6 +101,9 @@ Show Tests with no Replies + + true + @@ -116,6 +119,9 @@ + + false + -128 @@ -132,6 +138,9 @@ Allow adaptive reply offset + + true + @@ -354,6 +363,13 @@ + + + + 0 + + +