diff --git a/bus_protocols/isotp_handler.cpp b/bus_protocols/isotp_handler.cpp index dde42ba..67a6148 100644 --- a/bus_protocols/isotp_handler.cpp +++ b/bus_protocols/isotp_handler.cpp @@ -55,8 +55,9 @@ void ISOTP_HANDLER::sendISOTPFrame(int bus, int ID, QVector data) frame.bus = bus; frame.extended = false; frame.ID = ID; - frame.len = data.length() + 1; - frame.data[0] = frame.len - 1; + frame.len = 8; + for (int b = 0; b < 8; b++) frame.data[b] = 0xAA; + frame.data[0] = data.length(); for (int i = 0; i < frame.data[0]; i++) frame.data[i + 1] = data[i]; CANConManager::getInstance()->sendFrame(frame); } @@ -66,18 +67,20 @@ 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; 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++]; CANConManager::getInstance()->sendFrame(frame); while (currByte < data.length()) { + for (int b = 0; b < 8; b++) frame.data[b] = 0xAA; frame.data[0] = 0x20 + index; index = (index + 1) & 0xF; int bytesToGo = data.length() - currByte; if (bytesToGo > 7) bytesToGo = 7; for (int i = 0; i < bytesToGo; i++) frame.data[1 + i] = data[currByte++]; - frame.len = 1 + bytesToGo; + frame.len = 8; CANConManager::getInstance()->sendFrame(frame); } } diff --git a/bus_protocols/uds_handler.cpp b/bus_protocols/uds_handler.cpp index 0e30bd7..438517c 100644 --- a/bus_protocols/uds_handler.cpp +++ b/bus_protocols/uds_handler.cpp @@ -56,70 +56,70 @@ QVector UDS_SERVICE_DESC = { QVector UDS_NEG_RESPONSE = { - {0x10, "UDS_NEG_GENERAL_REJECT", "General rejection (no other codes matched)"}, - {0x11, "UDS_NEG_SERVICE_NOTSUPP", "ECU does not support this service code"}, - {0x12, "UDS_NEG_SUBFUNCT_NOTSUPP", "ECU does not support the requested sub function"}, - {0x13, "UDS_NEG_INVALID_FORMAT", "Invalid request length or format error"}, - {0x14, "UDS_NEG_RESPONSE_TOOLONG", "Response would be too long to send"}, - {0x21, "UDS_NEG_BUSY", "ECU is busy. Try again later"}, - {0x22, "UDS_NEG_COND_INCORR", "A prereq. condition was not met"}, - {0x24, "UDS_NEG_REQ_SEQ_ERR", "Invalid sequence of requests"}, - {0x25, "UDS_NEG_SUBNET_NORESP", "ECU tried to gateway request but response timed out"}, - {0x26, "UDS_NEG_FAILURE", "A failure (indicated in a DTC) is preventing a reply"}, - {0x31, "UDS_NEG_REQ_OUTOFRANGE", "A parameter is outside of the valid range"}, - {0x33, "UDS_NEG_SECURITY_DENIED", "Security access was denied. (invalid seq or ECU not unlocked?)"}, - {0x35, "UDS_NEG_INVALID_KEY", "Key passed was invalid. Failure counter has been incremented."}, - {0x36, "UDS_NEG_EXCEED_ATTEMPTS", "Key failed too many times. ECU security access locked out"}, - {0x37, "UDS_NEG_TIMEDELAY", "Security access too soon after last attempt"}, - {0x38, "UDS_NEG_EXT_SECUR_1", "Extended security failure code 1"}, - {0x39, "UDS_NEG_EXT_SECUR_2", "Extended security failure code 2"}, - {0x3A, "UDS_NEG_EXT_SECUR_3", "Extended security failure code 3"}, - {0x3B, "UDS_NEG_EXT_SECUR_4", "Extended security failure code 4"}, - {0x3C, "UDS_NEG_EXT_SECUR_5", "Extended security failure code 5"}, - {0x3D, "UDS_NEG_EXT_SECUR_6", "Extended security failure code 6"}, - {0x3E, "UDS_NEG_EXT_SECUR_7", "Extended security failure code 7"}, - {0x3F, "UDS_NEG_EXT_SECUR_8", "Extended security failure code 8"}, - {0x40, "UDS_NEG_EXT_SECUR_9", "Extended security failure code 9"}, - {0x41, "UDS_NEG_EXT_SECUR_10", "Extended security failure code 10"}, - {0x42, "UDS_NEG_EXT_SECUR_11", "Extended security failure code 11"}, - {0x43, "UDS_NEG_EXT_SECUR_12", "Extended security failure code 12"}, - {0x44, "UDS_NEG_EXT_SECUR_13", "Extended security failure code 13"}, - {0x45, "UDS_NEG_EXT_SECUR_14", "Extended security failure code 14"}, - {0x46, "UDS_NEG_EXT_SECUR_15", "Extended security failure code 15"}, - {0x47, "UDS_NEG_EXT_SECUR_16", "Extended security failure code 16"}, - {0x48, "UDS_NEG_EXT_SECUR_17", "Extended security failure code 17"}, - {0x49, "UDS_NEG_EXT_SECUR_18", "Extended security failure code 18"}, - {0x4A, "UDS_NEG_EXT_SECUR_19", "Extended security failure code 19"}, - {0x4B, "UDS_NEG_EXT_SECUR_20", "Extended security failure code 20"}, - {0x4C, "UDS_NEG_EXT_SECUR_21", "Extended security failure code 21"}, - {0x4D, "UDS_NEG_EXT_SECUR_22", "Extended security failure code 22"}, - {0x4E, "UDS_NEG_EXT_SECUR_23", "Extended security failure code 23"}, - {0x4F, "UDS_NEG_EXT_SECUR_24", "Extended security failure code 24"}, - {0x70, "UDS_NEG_UPLOAD_DOWNLOAD", "Fault when attempting to start upload/download"}, - {0x71, "UDS_NEG_TRX_SUSPENDED", "Transfer aborting due to a fault"}, - {0x72, "UDS_NEG_GEN_PROGRAMMING", "Fault while attempting to write to ECU memory"}, - {0x73, "UDS_NEG_WRONG_BLOCK_SEQ", "Invalid sequence value detected during transfer"}, - {0x78, "UDS_NEG_RESP_PENDING", "Request successful but ECU still busy - Response pending"}, - {0x7E, "UDS_NEG_SUBFUNCT_CURRSESS", "ECU does not support this subfunction in current session type"}, - {0x7F, "UDS_NEG_SERVICE_CURRSESS", "ECU does not support this service in current session type"}, - {0x81, "UDS_NEG_RPM_TOOHIGH", "RPM is too high to execute request"}, - {0x82, "UDS_NEG_RPM_TOOLOW", "RPM is too low to execute request"}, - {0x83, "UDS_NEG_ENGINE_RUNNING", "Cannot execute request while engine is running"}, - {0x84, "UDS_NEG_ENGINE_NOTRUNNING", "Cannot execute request while engine is off"}, - {0x85, "UDS_NEG_ENG_RUNTIME_LOW", "Cannot execute request until engine has run for longer"}, - {0x86, "UDS_NEG_TEMPERATURE_HIGH", "Cannot execute request until temperature is lower"}, - {0x87, "UDS_NEG_TEMPERATURE_LOW", "Cannot execute request until temperature is higher"}, - {0x88, "UDS_NEG_SPEED_HIGH", "Cannot execute request until vehicle slows down"}, - {0x89, "UDS_NEG_SPEED_LOW", "Cannot execute request until vehicle is going faster"}, - {0x8A, "UDS_NEG_PEDAL_HIGH", "Cannot execute request until throttle is lower"}, - {0x8B, "UDS_NEG_PEDAL_LOW", "Cannot execute request until throttle is higher"}, - {0x8C, "UDS_NEG_NOT_NEUTRAL", "Cannot execute request until transmission is in neutral"}, - {0x8D, "UDS_NEG_NOT_INGEAR", "Cannot execute request until vehicle is in gear"}, - {0x8F, "UDS_NEG_BRAKE_NOTPRESSED", "Cannot execute request until brake pedal is pressed (Hold down)"}, - {0x90, "UDS_NEG_NOT_PARK", "Cannot execute request until vehicle is in park"}, - {0x91, "UDS_NEG_CLUTCH_LOCKED", "Cannot execute request while clutch is locked"}, - {0x92, "UDS_NEG_VOLTAGE_HIGH", "Cannot execute request until voltage is lower"}, - {0x93, "UDS_NEG_VOLTAGE_LOW", "Cannot execute request until voltage is higher"}, + {0x10, "GENERAL_REJECT", "General rejection (no other codes matched)"}, + {0x11, "SERVICE_NOTSUPP", "ECU does not support this service code"}, + {0x12, "SUBFUNCT_NOTSUPP", "ECU does not support the requested sub function"}, + {0x13, "INVALID_FORMAT", "Invalid request length or format error"}, + {0x14, "RESPONSE_TOOLONG", "Response would be too long to send"}, + {0x21, "BUSY", "ECU is busy. Try again later"}, + {0x22, "COND_INCORR", "A prereq. condition was not met"}, + {0x24, "REQ_SEQ_ERR", "Invalid sequence of requests"}, + {0x25, "SUBNET_NORESP", "ECU tried to gateway request but response timed out"}, + {0x26, "FAILURE", "A failure (indicated in a DTC) is preventing a reply"}, + {0x31, "REQ_OUTOFRANGE", "A parameter is outside of the valid range"}, + {0x33, "SECURITY_DENIED", "Security access was denied. (invalid seq or ECU not unlocked?)"}, + {0x35, "INVALID_KEY", "Key passed was invalid. Failure counter has been incremented."}, + {0x36, "EXCEED_ATTEMPTS", "Key failed too many times. ECU security access locked out"}, + {0x37, "TIMEDELAY", "Security access too soon after last attempt"}, + {0x38, "EXT_SECUR_1", "Extended security failure code 1"}, + {0x39, "EXT_SECUR_2", "Extended security failure code 2"}, + {0x3A, "EXT_SECUR_3", "Extended security failure code 3"}, + {0x3B, "EXT_SECUR_4", "Extended security failure code 4"}, + {0x3C, "EXT_SECUR_5", "Extended security failure code 5"}, + {0x3D, "EXT_SECUR_6", "Extended security failure code 6"}, + {0x3E, "EXT_SECUR_7", "Extended security failure code 7"}, + {0x3F, "EXT_SECUR_8", "Extended security failure code 8"}, + {0x40, "EXT_SECUR_9", "Extended security failure code 9"}, + {0x41, "EXT_SECUR_10", "Extended security failure code 10"}, + {0x42, "EXT_SECUR_11", "Extended security failure code 11"}, + {0x43, "EXT_SECUR_12", "Extended security failure code 12"}, + {0x44, "EXT_SECUR_13", "Extended security failure code 13"}, + {0x45, "EXT_SECUR_14", "Extended security failure code 14"}, + {0x46, "EXT_SECUR_15", "Extended security failure code 15"}, + {0x47, "EXT_SECUR_16", "Extended security failure code 16"}, + {0x48, "EXT_SECUR_17", "Extended security failure code 17"}, + {0x49, "EXT_SECUR_18", "Extended security failure code 18"}, + {0x4A, "EXT_SECUR_19", "Extended security failure code 19"}, + {0x4B, "EXT_SECUR_20", "Extended security failure code 20"}, + {0x4C, "EXT_SECUR_21", "Extended security failure code 21"}, + {0x4D, "EXT_SECUR_22", "Extended security failure code 22"}, + {0x4E, "EXT_SECUR_23", "Extended security failure code 23"}, + {0x4F, "EXT_SECUR_24", "Extended security failure code 24"}, + {0x70, "UPLOAD_DOWNLOAD", "Fault when attempting to start upload/download"}, + {0x71, "TRX_SUSPENDED", "Transfer aborting due to a fault"}, + {0x72, "GEN_PROGRAMMING", "Fault while attempting to write to ECU memory"}, + {0x73, "WRONG_BLOCK_SEQ", "Invalid sequence value detected during transfer"}, + {0x78, "RESP_PENDING", "Request successful but ECU still busy - Response pending"}, + {0x7E, "SUBFUNCT_CURRSESS", "ECU does not support this subfunction in current session type"}, + {0x7F, "SERVICE_CURRSESS", "ECU does not support this service in current session type"}, + {0x81, "RPM_TOOHIGH", "RPM is too high to execute request"}, + {0x82, "RPM_TOOLOW", "RPM is too low to execute request"}, + {0x83, "ENGINE_RUNNING", "Cannot execute request while engine is running"}, + {0x84, "ENGINE_NOTRUNNING", "Cannot execute request while engine is off"}, + {0x85, "ENG_RUNTIME_LOW", "Cannot execute request until engine has run for longer"}, + {0x86, "TEMPERATURE_HIGH", "Cannot execute request until temperature is lower"}, + {0x87, "TEMPERATURE_LOW", "Cannot execute request until temperature is higher"}, + {0x88, "SPEED_HIGH", "Cannot execute request until vehicle slows down"}, + {0x89, "SPEED_LOW", "Cannot execute request until vehicle is going faster"}, + {0x8A, "PEDAL_HIGH", "Cannot execute request until throttle is lower"}, + {0x8B, "PEDAL_LOW", "Cannot execute request until throttle is higher"}, + {0x8C, "NOT_NEUTRAL", "Cannot execute request until transmission is in neutral"}, + {0x8D, "NOT_INGEAR", "Cannot execute request until vehicle is in gear"}, + {0x8F, "BRAKE_NOTPRESSED", "Cannot execute request until brake pedal is pressed (Hold down)"}, + {0x90, "NOT_PARK", "Cannot execute request until vehicle is in park"}, + {0x91, "CLUTCH_LOCKED", "Cannot execute request while clutch is locked"}, + {0x92, "VOLTAGE_HIGH", "Cannot execute request until voltage is lower"}, + {0x93, "VOLTAGE_LOW", "Cannot execute request until voltage is higher"}, }; UDS_HANDLER* UDS_HANDLER::mInstance = NULL; @@ -152,9 +152,29 @@ void UDS_HANDLER::gotISOTPFrame(ISOTP_MESSAGE &msg) 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 + if (msg.data.length() > 0) { + udsMsg.service = msg.data.at(0); + if (udsMsg.service == 0x7F) + { + udsMsg.isErrorReply = true; + if (msg.data.length() > 1) + { + udsMsg.service = msg.data.at(1); + if (msg.data.length() > 2) udsMsg.subFunc = msg.data.at(2); + else return; + } + else return; + udsMsg.data = msg.data.mid(2, -1); //don't copy error byte nor service byte + } + else + { + udsMsg.isErrorReply = false; + if (msg.data.length() > 1) udsMsg.subFunc = msg.data.at(1); + udsMsg.data = msg.data.mid(1, -1); //don't copy service byte + } + } + else return; + emit newUDSMessage(udsMsg); } @@ -207,6 +227,7 @@ QString UDS_HANDLER::getServiceShortDesc(int service) foreach (CODE_STRUCT code, UDS_SERVICE_DESC) { if (code.code == service) return code.shortDesc; + if (code.code == (service + 0x40)) return code.shortDesc; } return QString(); } @@ -216,6 +237,7 @@ QString UDS_HANDLER::getServiceLongDesc(int service) foreach (CODE_STRUCT code, UDS_SERVICE_DESC) { if (code.code == service) return code.longDesc; + if (code.code == (service + 0x40)) return code.longDesc; } return QString(); } diff --git a/bus_protocols/uds_handler.h b/bus_protocols/uds_handler.h index 62b01b7..1d625aa 100644 --- a/bus_protocols/uds_handler.h +++ b/bus_protocols/uds_handler.h @@ -73,6 +73,7 @@ class UDS_MESSAGE: public ISOTP_MESSAGE public: int service; int subFunc; + bool isErrorReply; }; class UDS_HANDLER : public QObject diff --git a/re/udsscanwindow.cpp b/re/udsscanwindow.cpp index ee2f187..dd70cd6 100644 --- a/re/udsscanwindow.cpp +++ b/re/udsscanwindow.cpp @@ -3,6 +3,7 @@ #include "mainwindow.h" #include "connections/canconmanager.h" #include "bus_protocols/uds_handler.h" +#include "utility.h" UDSScanWindow::UDSScanWindow(const QVector *frames, QWidget *parent) : QDialog(parent), @@ -24,6 +25,9 @@ UDSScanWindow::UDSScanWindow(const QVector *frames, QWidget *parent) : connect(ui->btnScan, &QPushButton::clicked, this, &UDSScanWindow::scanUDS); connect(waitTimer, &QTimer::timeout, this, &UDSScanWindow::timeOut); connect(ui->btnSaveResults, &QPushButton::clicked, this, &UDSScanWindow::saveResults); + connect(ui->ckWildcard, &QCheckBox::toggled, this, &UDSScanWindow::wildcardToggled); + connect(ui->cbAllowAdaptiveOffset, &QCheckBox::toggled, this, &UDSScanWindow::adaptiveToggled); + connect(ui->spinNumBytes, SIGNAL(valueChanged(int)), this, SLOT(numBytesChanged())); int numBuses = CANConManager::getInstance()->getNumBuses(); for (int n = 0; n < numBuses; n++) ui->cbBuses->addItem(QString::number(n)); @@ -37,6 +41,40 @@ UDSScanWindow::~UDSScanWindow() delete waitTimer; } +void UDSScanWindow::adaptiveToggled() +{ + if (ui->cbAllowAdaptiveOffset->isChecked()) ui->spinReplyOffset->setEnabled(false); + else ui->spinReplyOffset->setEnabled(true); +} + +void UDSScanWindow::wildcardToggled() +{ + bool state = false; + if (ui->ckWildcard->isChecked()) state = false; + else state = true; + + ui->ckReset->setEnabled(state); + ui->ckSecurity->setEnabled(state); + ui->ckSession->setEnabled(state); + ui->ckTester->setEnabled(state); + ui->ckReset->setChecked(false); + ui->ckSecurity->setChecked(false); + ui->ckSession->setChecked(false); + ui->ckTester->setChecked(false); + + ui->spinLowerService->setEnabled(!state); + ui->spinLowerSubfunc->setEnabled(!state); + ui->spinNumBytes->setEnabled(!state); + ui->spinUpperService->setEnabled(!state); + ui->spinUpperSubfunc->setEnabled(!state); +} + +void UDSScanWindow::numBytesChanged() +{ + uint64_t upperBound = (1 << (8 * ui->spinNumBytes->value())) - 1; + ui->spinUpperSubfunc->setMaximum(upperBound); +} + void UDSScanWindow::saveResults() { QString filename; @@ -63,18 +101,25 @@ void UDSScanWindow::saveResults() delete outFile; return; } + outFile->write("UDS Scan Log:\n\n"); + dumpNode(ui->treeResults->invisibleRootItem(), outFile, 0); - for (int i = 0; i < ui->listResults->count(); i++) - { - outFile->write(ui->listResults->item(i)->text().toUtf8()); - outFile->write("\n"); - } outFile->close(); delete outFile; } } } +void UDSScanWindow::dumpNode(QTreeWidgetItem* item, QFile *file, int indent) +{ + if (indent > 0) for (int i = 0; i < (indent - 1); i++) file->write("\t"); + file->write(item->text(0).toUtf8()); + file->write("\n"); + for( int i = 0; i < item->childCount(); ++i ) + dumpNode( item->child(i), file, indent + 1 ); + if (indent == 1) file->write("\n"); +} + void UDSScanWindow::sendOnBuses(UDS_MESSAGE test, int buses) { int busList = buses; @@ -106,20 +151,29 @@ void UDSScanWindow::scanUDS() waitTimer->setInterval(ui->spinDelay->value()); - ui->listResults->clear(); + ui->treeResults->clear(); sendingFrames.clear(); + nodeService = NULL; + nodeID = NULL; + nodeSubFunc = NULL; UDS_MESSAGE test; int typ, id; int startID, endID; startID = Utility::ParseStringToNum(ui->txtStartID->text()); endID = Utility::ParseStringToNum(ui->txtEndID->text()); + if (endID < startID) { + int temp = startID; + startID = endID; + endID = temp; + } int buses = ui->cbBuses->currentIndex(); for (id = startID; id <= endID; id++) { test.ID = id; + test.data.clear(); if (ui->ckTester->isChecked()) { @@ -148,6 +202,34 @@ void UDSScanWindow::scanUDS() test.subFunc = 1; 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 + //any way you go to generate a 1 billion frame test. + int size = (endID - startID) * (ui->spinUpperService->value() - ui->spinLowerService->value()); + size *= (ui->spinUpperSubfunc->value() - ui->spinLowerSubfunc->value()); + sendingFrames.reserve(size); + + 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))); + } + sendOnBuses(test, buses); + } + } + } } waitTimer->start(); @@ -174,6 +256,7 @@ void UDSScanWindow::updatedFrames(int numFrames) void UDSScanWindow::gotUDSReply(UDS_MESSAGE &msg) { QString result; + QString serviceShortName; uint32_t id; int offset = ui->spinReplyOffset->value(); UDS_MESSAGE sentFrame; @@ -188,54 +271,78 @@ void UDSScanWindow::gotUDSReply(UDS_MESSAGE &msg) 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 - { - if (thisFrame.data[2] == 0x40 + sendingFrames[currIdx].data[1]) - { - result = "Request on bus " + QString::number(sentFrame.bus) + " ID: " + QString::number(sentFrame.ID, 16) + " got response to mode " - + QString::number(sentFrame.data[1], 16) - + " " + QString::number(sentFrame.data[2], 16) + " with affirmation from ID " + QString::number(id, 16) - + " on bus " + QString::number(thisFrame.bus) + "."; - gotReply = true; - } - //error replies are never multiframe so the check doesn't have to be done here. - } */ + serviceShortName = UDS_HANDLER::getInstance()->getServiceShortDesc(sentFrame.service); + if (serviceShortName.length() < 3) serviceShortName = QString::number(sentFrame.service, 16); + if (msg.service == 0x40 + sendingFrames[currIdx].service) + { + setupNodes(); + QTreeWidgetItem *nodePositive = new QTreeWidgetItem(); + QString reply = "POSITIVE "; + for (int i = 0; i < msg.data.length(); i++) + { + reply.append(" "); + reply.append(Utility::formatHexNum(msg.data[i])); + } + nodePositive->setText(0, reply); + nodePositive->setForeground(0, QBrush(Qt::darkGreen)); + nodeSubFunc->addChild(nodePositive); + nodeSubFunc->setForeground(0, QBrush(Qt::darkGreen)); + gotReply = true; + } + else if ( msg.service == 0x7F) + { + 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 (gotReply) { - ui->listResults->addItem(result); + //ui->listResults->addItem(result); sendNextMsg(); } } +void UDSScanWindow::setupNodes() +{ + QString serviceShortName = UDS_HANDLER::getInstance()->getServiceShortDesc(sendingFrames[currIdx].service); + if (serviceShortName.length() < 3) serviceShortName = QString::number(sendingFrames[currIdx].service, 16); + + if (!nodeID || nodeID->text(0) != Utility::formatHexNum(sendingFrames[currIdx].ID)) + { + nodeID = new QTreeWidgetItem(); + nodeID->setText(0, Utility::formatHexNum(sendingFrames[currIdx].ID)); + ui->treeResults->addTopLevelItem(nodeID); + nodeService = NULL; + } + if (!nodeService || nodeService->text(0) != serviceShortName) + { + nodeService = new QTreeWidgetItem(); + nodeService->setText(0, serviceShortName); + nodeID->addChild(nodeService); + } + + nodeSubFunc = new QTreeWidgetItem(); + nodeSubFunc->setText(0, Utility::formatHexNum(sendingFrames[currIdx].subFunc)); + nodeService->addChild(nodeSubFunc); +} + void UDSScanWindow::timeOut() { - QString result; - result = "Request on bus " + QString::number(sendingFrames[currIdx].bus) + " ID: " + QString::number(sendingFrames[currIdx].ID, 16) + " got no response to mode " - + QString::number(sendingFrames[currIdx].service, 16) + " " + QString::number(sendingFrames[currIdx].subFunc, 16); - ui->listResults->addItem(result); + if (ui->ckShowNoReply->isChecked()) + { + setupNodes(); + QTreeWidgetItem *nodeNoReply = new QTreeWidgetItem(); + nodeNoReply->setText(0, "No Reply"); + nodeNoReply->setForeground(0, QBrush(Qt::gray)); + nodeSubFunc->addChild(nodeNoReply); + nodeSubFunc->setForeground(0, QBrush(Qt::gray)); + } sendNextMsg(); } @@ -249,6 +356,7 @@ void UDSScanWindow::sendNextMsg() { 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); waitTimer->start(); } diff --git a/re/udsscanwindow.h b/re/udsscanwindow.h index ff412b8..30b0709 100644 --- a/re/udsscanwindow.h +++ b/re/udsscanwindow.h @@ -6,6 +6,8 @@ #include "bus_protocols/uds_handler.h" #include +#include +#include namespace Ui { class UDSScanWindow; @@ -25,17 +27,24 @@ private slots: void scanUDS(); void saveResults(); void timeOut(); + void adaptiveToggled(); + void wildcardToggled(); + void numBytesChanged(); private: Ui::UDSScanWindow *ui; const QVector *modelFrames; QTimer *waitTimer; QList sendingFrames; + QTreeWidgetItem *nodeID; + QTreeWidgetItem *nodeService; + QTreeWidgetItem *nodeSubFunc; int currIdx = 0; bool currentlyRunning; void sendNextMsg(); void sendOnBuses(UDS_MESSAGE frame, int buses); + void setupNodes(); + void dumpNode(QTreeWidgetItem* item, QFile *file, int indent); }; - #endif // UDSSCANWINDOW_H diff --git a/ui/udsscanwindow.ui b/ui/udsscanwindow.ui index ab19fcd..99ac0bd 100644 --- a/ui/udsscanwindow.ui +++ b/ui/udsscanwindow.ui @@ -22,7 +22,16 @@ - + + + false + + + + 1 + + + @@ -69,6 +78,13 @@ + + + + Show Tests with no Replies + + + @@ -102,45 +118,6 @@ - - - - - - Scan Types: - - - - - - - Tester Present - - - - - - - Session Control - - - - - - - ECU Reset - - - - - - - Security Access - - - - - @@ -178,6 +155,169 @@ + + + + + + Scan Types: + + + + + + + Tester Present + + + + + + + Session Control + + + + + + + ECU Reset + + + + + + + Security Access + + + + + + + Wildcard + + + + + + + + + + + Lower Service: + + + + + + + false + + + 255 + + + 16 + + + + + + + Upper Service: + + + + + + + false + + + 255 + + + 255 + + + 16 + + + + + + + + + + + Subfunction Bytes: + + + + + + + false + + + 1 + + + 4 + + + 1 + + + + + + + Lower Bound: + + + + + + + false + + + 255 + + + 16 + + + + + + + Upper Bound: + + + + + + + false + + + 255 + + + 255 + + + 16 + + + + +