Changed the UDS Scan window quite a bit. Now there are more options

for scan types and the ability to create a list of scans to run.
This commit is contained in:
Collin Kidder
2022-10-04 19:54:55 -04:00
parent 9ebbaca668
commit 61b49c9126
3 changed files with 1010 additions and 475 deletions
+541 -150
View File
@@ -6,6 +6,23 @@
#include "utility.h"
#include "helpwindow.h"
static QVector<QString> SCANTYPE_NAMES = {
QString("Tester Present"),
QString("Session Control"),
QString("Communication Control"),
QString("ECU Reset"),
QString("Clear DTCs"),
QString("Read DTCs"),
QString("Security Access"),
QString("Read By ID"),
QString("Read By Address"),
QString("Read Scaling Data By ID"),
QString("IO Control"),
QString("Routine Control"),
QString("Custom UDS"),
};
UDSScanWindow::UDSScanWindow(const QVector<CANFrame> *frames, QWidget *parent) :
QDialog(parent),
ui(new Ui::UDSScanWindow)
@@ -21,15 +38,23 @@ UDSScanWindow::UDSScanWindow(const QVector<CANFrame> *frames, QWidget *parent) :
waitTimer->setInterval(100);
udsHandler = new UDS_HANDLER;
inhibitUpdates = false;
for (int i = 0; i < 13; i++) ui->cbScanType->addItem(SCANTYPE_NAMES[i]);
ui->cbSessType->addItem("No Change");
ui->cbSessType->addItem("Default");
ui->cbSessType->addItem("Programming");
ui->cbSessType->addItem("Extended Diag");
ui->cbSessType->addItem("Safety Sys Diag");
connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int)));
connect(udsHandler, &UDS_HANDLER::newUDSMessage, this, &UDSScanWindow::gotUDSReply);
connect(ui->btnScan, &QPushButton::clicked, this, &UDSScanWindow::scanUDS);
connect(ui->btnScanAll, &QPushButton::clicked, this, &UDSScanWindow::scanAll);
connect(ui->btnScanSelected, &QPushButton::clicked, this, &UDSScanWindow::scanSelected);
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->ckReadByAddr, &QCheckBox::toggled, this, &UDSScanWindow::readByToggled);
connect(ui->ckReadByID, &QCheckBox::toggled, this, &UDSScanWindow::readByToggled);
connect(ui->cbScanType, &QComboBox::currentTextChanged, this, &UDSScanWindow::changedScanType);
connect(ui->cbAllowAdaptiveOffset, &QCheckBox::toggled, this, &UDSScanWindow::adaptiveToggled);
connect(ui->spinNumBytes, SIGNAL(valueChanged(int)), this, SLOT(numBytesChanged()));
connect(ui->spinLowerService, SIGNAL(valueChanged(int)), this, SLOT(checkServiceRange()));
@@ -38,10 +63,23 @@ UDSScanWindow::UDSScanWindow(const QVector<CANFrame> *frames, QWidget *parent) :
connect(ui->spinUpperSubfunc, SIGNAL(valueChanged(int)), this, SLOT(checkSubFuncRange()));
connect(ui->spinStartID, SIGNAL(valueChanged(int)), this, SLOT(checkIDRange()));
connect(ui->spinEndID, SIGNAL(valueChanged(int)), this, SLOT(checkIDRange()));
connect(ui->btnAdd, &QPushButton::clicked, this, &UDSScanWindow::addNewScan);
connect(ui->btnDelete, &QPushButton::clicked, this, &UDSScanWindow::deleteSelectedScan);
connect(ui->btnSave, &QPushButton::clicked, this, &UDSScanWindow::saveScans);
connect(ui->btnLoad, &QPushButton::clicked, this, &UDSScanWindow::loadScans);
connect(ui->listScansToRun, &QListWidget::currentRowChanged, this, &UDSScanWindow::displayScanEntry);
connect(ui->ckShowNoReply, &QCheckBox::toggled, this, &UDSScanWindow::setNoReplyVal);
connect(ui->spinDelay, SIGNAL(valueChanged(int)), this, SLOT(setMaxDelayVal()));
connect(ui->spinIncrement, SIGNAL(valueChanged(int)), this, SLOT(setIncrementVal()));
connect(ui->spinReplyOffset, SIGNAL(valueChanged(int)), this, SLOT(setReplyOffset()));
connect(ui->cbSessType, &QComboBox::currentTextChanged, this, &UDSScanWindow::setSessType);
//not handling show no reply, max reply delay, reply offset, increment
int numBuses = CANConManager::getInstance()->getNumBuses();
for (int n = 0; n < numBuses; n++) ui->cbBuses->addItem(QString::number(n));
installEventFilter(this);
addNewScan();
}
UDSScanWindow::~UDSScanWindow()
@@ -71,74 +109,368 @@ bool UDSScanWindow::eventFilter(QObject *obj, QEvent *event)
return false;
}
void UDSScanWindow::displayScanEntry(int idx)
{
if (inhibitUpdates) return;
if (idx == -1) return;
currEditEntry = &scanEntries.data()[idx];
ui->spinStartID->setValue(currEditEntry->startID);
ui->spinEndID->setValue(currEditEntry->endID);
ui->spinReplyOffset->setValue(currEditEntry->idOffset);
ui->cbAllowAdaptiveOffset->setChecked(currEditEntry->bAdaptiveOffset);
ui->ckShowNoReply->setChecked(currEditEntry->bShowNoReplies);
ui->cbBuses->setCurrentIndex(currEditEntry->busToScan);
ui->spinDelay->setValue(currEditEntry->maxWaitTime);
ui->cbScanType->setCurrentIndex((int)currEditEntry->scanType);
ui->cbSessType->setCurrentIndex(currEditEntry->sessType);
ui->spinNumBytes->setValue(currEditEntry->subfunctLen);
ui->spinLowerService->setValue(currEditEntry->serviceLower);
ui->spinUpperService->setValue(currEditEntry->serviceUpper);
ui->spinLowerSubfunc->setValue(currEditEntry->subfunctLower);
ui->spinUpperSubfunc->setValue(currEditEntry->subfunctUpper);
ui->spinIncrement->setValue(currEditEntry->subfunctIncrement);
}
void UDSScanWindow::deleteSelectedScan()
{
int idx = ui->listScansToRun->currentRow();
if (idx == -1) return;
scanEntries.removeAt(idx);
QListWidgetItem *item = ui->listScansToRun->takeItem(idx);
delete item;
int rows = ui->listScansToRun->count();
ui->listScansToRun->setCurrentRow(rows - 1);
for (int i = 0; i < rows; i++)
{
QListWidgetItem *item = ui->listScansToRun->item(i);
item->setText(generateListDesc(i));
}
}
void UDSScanWindow::addNewScan()
{
ScanEntry newEntry;
newEntry.busToScan = 0;
newEntry.scanType = SCAN_TYPE::ST_TESTER_PRESENT;
newEntry.sessType = 0;
newEntry.bAdaptiveOffset = false;
newEntry.bShowNoReplies = false;
newEntry.idOffset = 8;
newEntry.startID = 0x7E0;
newEntry.endID = 0x7E7;
newEntry.maxWaitTime = 100;
newEntry.subfunctLen = 1;
newEntry.subfunctIncrement = 1;
newEntry.subfunctLower = 0;
newEntry.subfunctUpper = 0;
newEntry.serviceLower = 1;
newEntry.serviceUpper = 1;
scanEntries.append(newEntry);
displayScanEntry(scanEntries.length() - 1);
ui->listScansToRun->addItem(generateListDesc(scanEntries.length() - 1));
ui->listScansToRun->setCurrentRow(ui->listScansToRun->count() - 1);
}
void UDSScanWindow::loadScans()
{
QString filename;
QFileDialog dialog(qApp->activeWindow());
QSettings settings;
bool result = false;
QStringList filters;
filters.append(QString(tr("UDS Test Specification (*.uds *.UDS)")));
dialog.setDirectory(settings.value("FileIO/LoadSaveDirectory", dialog.directory().path()).toString());
dialog.setFileMode(QFileDialog::AnyFile);
dialog.setNameFilters(filters);
dialog.setViewMode(QFileDialog::Detail);
dialog.setAcceptMode(QFileDialog::AcceptOpen);
if (dialog.exec() == QDialog::Accepted)
{
filename = dialog.selectedFiles()[0];
QFile inFile(filename);
inFile.open(QIODevice::ReadOnly);
QDataStream load(&inFile);
int fileVersion;
load >> fileVersion;
if (fileVersion != 1)
{
QMessageBox::warning(this, "Cannot Load File", "File is not a supported version.\nCannot load it!");
return;
}
inhibitUpdates = true;;
scanEntries.clear();
ui->listScansToRun->clear();
int numEntries;
load >> numEntries;
for (int i = 0; i < numEntries; i++)
{
ScanEntry entry;
load >> entry.startID >> entry.endID;
load >> entry.idOffset >> entry.bAdaptiveOffset >> entry.bShowNoReplies;
load >> entry.busToScan >> entry.maxWaitTime >> entry.scanType;
load >> entry.sessType >> entry.subfunctLen >> entry.subfunctLower;
load >> entry.subfunctUpper >> entry.subfunctIncrement;
load >> entry.serviceLower >> entry.serviceUpper;
scanEntries.append(entry);
ui->listScansToRun->addItem(generateListDesc(scanEntries.length() - 1));
}
inFile.close();
inhibitUpdates = false;
ui->listScansToRun->setCurrentRow(ui->listScansToRun->count() - 1);
displayScanEntry(scanEntries.length() - 1);
}
}
void UDSScanWindow::saveScans()
{
QString filename;
QFileDialog dialog(qApp->activeWindow());
QSettings settings;
bool result = false;
QStringList filters;
filters.append(QString(tr("UDS Test Specification (*.uds *.UDS)")));
dialog.setDirectory(settings.value("FileIO/LoadSaveDirectory", dialog.directory().path()).toString());
dialog.setFileMode(QFileDialog::AnyFile);
dialog.setNameFilters(filters);
dialog.setViewMode(QFileDialog::Detail);
dialog.setAcceptMode(QFileDialog::AcceptSave);
if (dialog.exec() == QDialog::Accepted)
{
filename = dialog.selectedFiles()[0];
QFile outFile(filename);
outFile.open(QIODevice::WriteOnly);
QDataStream save(&outFile);
save << 1; //file version
save << scanEntries.count();
for (int i = 0; i < scanEntries.count(); i++)
{
save << scanEntries[i].startID;
save << scanEntries[i].endID;
save << scanEntries[i].idOffset;
save << scanEntries[i].bAdaptiveOffset;
save << scanEntries[i].bShowNoReplies;
save << scanEntries[i].busToScan;
save << scanEntries[i].maxWaitTime;
save << scanEntries[i].scanType;
save << scanEntries[i].sessType;
save << scanEntries[i].subfunctLen;
save << scanEntries[i].subfunctLower;
save << scanEntries[i].subfunctUpper;
save << scanEntries[i].subfunctIncrement;
save << scanEntries[i].serviceLower;
save << scanEntries[i].serviceUpper;
}
outFile.close();
}
}
QString UDSScanWindow::generateListDesc(int idx)
{
QString builder;
ScanEntry entry = scanEntries[idx];
builder = "(0x" + QString::number(entry.startID, 16) + " - 0x" + QString::number(entry.endID, 16) + ") ";
switch (entry.scanType)
{
case ST_TESTER_PRESENT:
builder += "TP";
break;
case ST_SESS_CTRL:
builder += "SESS";
break;
case ST_COMM_CTRL:
builder += "COMM";
break;
case ST_ECU_RESET:
builder += "ECU";
break;
case ST_CLEAR_DTC:
builder += "CDTC";
break;
case ST_READ_DTC:
builder += "RDTC";
break;
case ST_SEC_ACCESS:
builder += "SECU";
break;
case ST_READ_ID:
builder += "RID";
break;
case ST_READ_ADDR:
builder += "RADD";
break;
case ST_READ_SCALING:
builder += "RSCAL";
break;
case ST_IO_CTRL:
builder += "IO";
break;
case ST_ROUTINE_CTRL:
builder += "ROUT";
break;
case ST_CUSTOM:
builder += "CUST";
break;
}
return builder;
}
void UDSScanWindow::adaptiveToggled()
{
if (inhibitUpdates) return;
if (ui->cbAllowAdaptiveOffset->isChecked()) ui->spinReplyOffset->setEnabled(false);
else ui->spinReplyOffset->setEnabled(true);
if (currEditEntry) currEditEntry->bAdaptiveOffset = ui->cbAllowAdaptiveOffset->isChecked();
}
void UDSScanWindow::wildcardToggled()
void UDSScanWindow::setSessType()
{
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->ckReadByAddr->setEnabled(state);
ui->ckReadByID->setEnabled(state);
ui->ckReset->setChecked(false);
ui->ckSecurity->setChecked(false);
ui->ckSession->setChecked(false);
ui->ckTester->setChecked(false);
ui->ckReadByAddr->setChecked(false);
ui->ckReadByID->setChecked(false);
ui->spinLowerService->setEnabled(!state);
ui->spinLowerSubfunc->setEnabled(!state);
ui->spinNumBytes->setEnabled(!state);
ui->spinUpperService->setEnabled(!state);
ui->spinUpperSubfunc->setEnabled(!state);
if (inhibitUpdates) return;
if (currEditEntry) currEditEntry->sessType = ui->cbSessType->currentIndex();
}
void UDSScanWindow::readByToggled()
void UDSScanWindow::setNoReplyVal()
{
bool state = false;
if (ui->ckReadByAddr->isChecked() || ui->ckReadByID->isChecked()) state = true;
else state = false;
if (inhibitUpdates) return;
if (currEditEntry) currEditEntry->bShowNoReplies = ui->ckShowNoReply->isChecked();
}
ui->spinLowerService->setEnabled(false);
ui->spinLowerSubfunc->setEnabled(state);
ui->spinNumBytes->setEnabled(state);
ui->spinUpperService->setEnabled(false);
ui->spinUpperSubfunc->setEnabled(state);
void UDSScanWindow::setMaxDelayVal()
{
if (inhibitUpdates) return;
if (currEditEntry) currEditEntry->maxWaitTime = ui->spinDelay->value();
}
void UDSScanWindow::setIncrementVal()
{
if (inhibitUpdates) return;
if (currEditEntry) currEditEntry->subfunctIncrement = ui->spinIncrement->value();
}
void UDSScanWindow::setReplyOffset()
{
if (inhibitUpdates) return;
if (currEditEntry) currEditEntry->idOffset = ui->spinReplyOffset->value();
}
void UDSScanWindow::changedScanType()
{
if (inhibitUpdates) return;
int idx = ui->cbScanType->currentIndex();
if (idx == -1)
{
ui->cbScanType->setCurrentIndex(0);
idx = 0;
}
if (currEditEntry) currEditEntry->scanType = (SCAN_TYPE)idx;
QListWidgetItem* item = ui->listScansToRun->currentItem();
item->setText(generateListDesc(ui->listScansToRun->currentRow()));
switch (idx)
{
case ST_TESTER_PRESENT:
case ST_SESS_CTRL:
ui->cbSessType->setEnabled(false);
ui->spinLowerService->setEnabled(false);
ui->spinLowerSubfunc->setEnabled(false);
ui->spinUpperService->setEnabled(false);
ui->spinUpperSubfunc->setEnabled(false);
ui->spinNumBytes->setEnabled(false);
ui->spinIncrement->setEnabled(false);
ui->cbSessType->setCurrentIndex(0);
break;
case ST_COMM_CTRL:
case ST_ECU_RESET:
case ST_CLEAR_DTC:
case ST_SEC_ACCESS:
case ST_READ_DTC:
ui->cbSessType->setEnabled(true);
ui->spinLowerService->setEnabled(false);
ui->spinUpperService->setEnabled(false);
ui->spinLowerSubfunc->setEnabled(false);
ui->spinUpperSubfunc->setEnabled(false);
ui->spinNumBytes->setEnabled(false);
ui->spinIncrement->setEnabled(false);
break;
case ST_IO_CTRL:
case ST_ROUTINE_CTRL:
case ST_READ_SCALING:
ui->cbSessType->setEnabled(true);
ui->spinLowerService->setEnabled(false);
ui->spinUpperService->setEnabled(false);
ui->spinLowerSubfunc->setEnabled(true);
ui->spinUpperSubfunc->setEnabled(true);
ui->spinNumBytes->setEnabled(false);
ui->spinNumBytes->setValue(2);
ui->spinIncrement->setEnabled(true);
break;
case ST_READ_ID:
case ST_READ_ADDR:
ui->cbSessType->setEnabled(true);
ui->spinLowerService->setEnabled(false);
ui->spinUpperService->setEnabled(false);
ui->spinLowerSubfunc->setEnabled(true);
ui->spinUpperSubfunc->setEnabled(true);
ui->spinNumBytes->setEnabled(true);
ui->spinIncrement->setEnabled(true);
break;
case ST_CUSTOM:
ui->cbSessType->setEnabled(true);
ui->spinLowerService->setEnabled(true);
ui->spinUpperService->setEnabled(true);
ui->spinLowerSubfunc->setEnabled(true);
ui->spinUpperSubfunc->setEnabled(true);
ui->spinNumBytes->setEnabled(true);
ui->spinIncrement->setEnabled(true);
break;
}
}
void UDSScanWindow::numBytesChanged()
{
if (inhibitUpdates) return;
uint64_t upperBound = (1ull << (8ull * ui->spinNumBytes->value())) - 1;
if (upperBound > 0x7FFFFFFF) upperBound = 0x7FFFFFFF;
ui->spinUpperSubfunc->setMaximum(upperBound);
if (currEditEntry) currEditEntry->subfunctLen = ui->spinNumBytes->value();
}
void UDSScanWindow::checkIDRange()
{
if (inhibitUpdates) return;
ui->spinStartID->setMaximum(ui->spinEndID->value());
ui->spinEndID->setMinimum(ui->spinStartID->value());
if (currEditEntry) currEditEntry->startID = ui->spinStartID->value();
if (currEditEntry) currEditEntry->endID = ui->spinEndID->value();
QListWidgetItem* item = ui->listScansToRun->currentItem();
item->setText(generateListDesc(ui->listScansToRun->currentRow()));
}
void UDSScanWindow::checkServiceRange()
{
if (inhibitUpdates) return;
ui->spinLowerService->setMaximum(ui->spinUpperService->value());
ui->spinUpperService->setMinimum(ui->spinLowerService->value());
if (currEditEntry) currEditEntry->serviceLower = ui->spinLowerService->value();
if (currEditEntry) currEditEntry->serviceUpper = ui->spinUpperService->value();
}
void UDSScanWindow::checkSubFuncRange()
{
if (inhibitUpdates) return;
ui->spinLowerSubfunc->setMaximum(ui->spinUpperSubfunc->value());
ui->spinUpperSubfunc->setMinimum(ui->spinLowerSubfunc->value());
if (currEditEntry) currEditEntry->subfunctLower = ui->spinLowerSubfunc->value();
if (currEditEntry) currEditEntry->subfunctUpper = ui->spinUpperSubfunc->value();
}
void UDSScanWindow::saveResults()
@@ -196,20 +528,27 @@ void UDSScanWindow::sendOnBuses(UDS_MESSAGE test, int buses)
sendingFrames.append(test);
}
void UDSScanWindow::scanUDS()
void UDSScanWindow::scanAll()
{
if (currentlyRunning)
sendingFrames.clear();
for (int i = 0; i < scanEntries.count(); i++)
{
waitTimer->stop();
sendingFrames.clear();
udsHandler->setReception(false);
udsHandler->setProcessAllIDs(false);
udsHandler->setFlowCtrl(false);
currentlyRunning = false;
ui->btnScan->setText("Start Scan");
return;
setupScan(i);
}
startScan();
}
void UDSScanWindow::scanSelected()
{
sendingFrames.clear();
int idx = ui->listScansToRun->currentRow();
if (idx < 0) return;
setupScan(idx);
startScan();
}
void UDSScanWindow::startScan()
{
udsHandler->setReception(true);
udsHandler->setProcessAllIDs(true);
udsHandler->setFlowCtrl(true);
@@ -217,121 +556,173 @@ void UDSScanWindow::scanUDS()
waitTimer->setInterval(ui->spinDelay->value());
ui->treeResults->clear();
sendingFrames.clear();
nodeService = nullptr;
nodeID = nullptr;
nodeSubFunc = nullptr;
UDS_MESSAGE test;
int typ, id;
int startID, endID;
startID = ui->spinStartID->value();
endID = ui->spinEndID->value();
if (endID < startID) {
int temp = startID;
startID = endID;
endID = temp;
}
int buses = ui->cbBuses->currentIndex();
for (id = startID; id <= endID; id++)
{
test.setFrameId( id );
test.payload().clear();
if (ui->ckTester->isChecked())
{
test.service = UDS_SERVICES::TESTER_PRESENT;
test.subFunc = 0;
sendOnBuses(test, buses);
}
if (ui->ckSession->isChecked())
{
for (typ = 1; typ < 4; typ++) //try each type of session access
{
test.service = UDS_SERVICES::DIAG_CONTROL;
test.subFunc = typ;
sendOnBuses(test, buses);
}
}
if (ui->ckReset->isChecked()) //try to command a reset of the ECU. You're likely to know if it works. ;)
{
for (typ = 1; typ < 4; typ++) //try each type of session access
{
test.service = UDS_SERVICES::ECU_RESET;
test.subFunc = typ;
sendOnBuses(test, buses);
}
}
if (ui->ckSecurity->isChecked()) //try to enter security mode - very likely to get a response if an ECU exists.
{
for (typ = 1; typ < 0x42; typ = typ + 2) //try each type of session access. In practice only the first 1-3 are likely to work
{
test.service = UDS_SERVICES::SECURITY_ACCESS;
test.subFunc = typ;
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())
{
//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);
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.subFunc = subTyp;
sendOnBuses(test, buses);
}
}
}
}
waitTimer->start();
currIdx = -1;
currentlyRunning = true;
ui->btnScan->setText("Abort Scan");
//ui->btnScan->setText("Abort Scan");
ui->progressBar->setValue(0);
ui->progressBar->setMaximum(sendingFrames.length());
qDebug() << "Number of operations: " << sendingFrames.length();
sendNextMsg();
}
void UDSScanWindow::stopScan()
{
waitTimer->stop();
sendingFrames.clear();
udsHandler->setReception(false);
udsHandler->setProcessAllIDs(false);
udsHandler->setFlowCtrl(false);
currentlyRunning = false;
//ui->btnScan->setText("Start Scan");
}
void UDSScanWindow::setupScan(int idx)
{
UDS_MESSAGE test;
qDebug() << "Generating scan id: " << idx;
for (uint32_t id = scanEntries[idx].startID; id <= scanEntries[idx].endID; id++)
{
test.setFrameId( id );
if (scanEntries[idx].sessType > 0)
{
test.payload().clear();
test.service = UDS_SERVICES::DIAG_CONTROL;
test.subFuncLen = 1;
test.subFunc = scanEntries[ idx].sessType;
sendOnBuses(test, scanEntries[idx].busToScan);
}
test.payload().clear();
qDebug() << "Generating scan on ID " << QString::number(id, 16) << " of type " << scanEntries[idx].scanType;
switch (scanEntries[idx].scanType)
{
case ST_TESTER_PRESENT:
test.service = UDS_SERVICES::TESTER_PRESENT;
test.subFuncLen = 1;
test.subFunc = 0;
sendOnBuses(test, scanEntries[idx].busToScan);
break;
case ST_SESS_CTRL:
for (int typ = 1; typ < 4; typ++) //try each type of session access
{
test.service = UDS_SERVICES::DIAG_CONTROL;
test.subFuncLen = 1;
test.subFunc = typ;
sendOnBuses(test, scanEntries[idx].busToScan);
}
break;
case ST_COMM_CTRL:
test.service = UDS_SERVICES::COMM_CTRL;
test.subFuncLen = 2; //need two bytes for this one
test.subFunc = 0x100; //00 01 on the bus = enable Rx/Tx
sendOnBuses(test, scanEntries[idx].busToScan);
break;
case ST_ECU_RESET:
for (int typ = 1; typ < 4; typ++) //try each type of session access
{
test.service = UDS_SERVICES::ECU_RESET;
test.subFuncLen = 1;
test.subFunc = typ;
sendOnBuses(test, scanEntries[idx].busToScan);
}
break;
case ST_CLEAR_DTC:
test.service = UDS_SERVICES::CLEAR_DIAG;
test.subFuncLen = 3; //DTC groups are sent as 3 bytes
test.subFunc = 0xFFFFFF; //clear everything!
sendOnBuses(test, scanEntries[idx].busToScan);
break;
case ST_READ_DTC:
test.service = UDS_SERVICES::READ_DTC;
test.subFuncLen = 2;
test.subFunc = 0x8702; //get DTCs by mask (87 is the mask)
sendOnBuses(test, scanEntries[idx].busToScan);
break;
case ST_SEC_ACCESS:
for (int typ = 1; typ < 0x42; typ = typ + 2) //try each type of session access. In practice only the first 1-3 are likely to work
{
test.service = UDS_SERVICES::SECURITY_ACCESS;
test.subFuncLen = 1;
test.subFunc = typ;
sendOnBuses(test, scanEntries[idx].busToScan);
}
break;
case ST_READ_ID:
test.subFuncLen = scanEntries[idx].subfunctLen;
test.service = UDS_SERVICES::READ_BY_ID;
for (int subf = scanEntries[idx].subfunctLower; subf <= scanEntries[idx].subfunctUpper; subf += scanEntries[idx].subfunctIncrement)
{
test.subFunc = subf;
sendOnBuses(test, scanEntries[idx].busToScan);
}
break;
case ST_READ_ADDR:
test.subFuncLen = scanEntries[idx].subfunctLen;
test.service = UDS_SERVICES::READ_BY_ADDR;
for (int subf = scanEntries[idx].subfunctLower; subf <= scanEntries[idx].subfunctUpper; subf += scanEntries[idx].subfunctIncrement)
{
test.subFunc = subf;
sendOnBuses(test, scanEntries[idx].busToScan);
}
break;
case ST_READ_SCALING:
//sub function should always be a length of 2 though. Should conform to this in the GUI
test.subFuncLen = 2;
test.service = UDS_SERVICES::READ_SCALING_ID;
for (int subf = scanEntries[idx].subfunctLower; subf <= scanEntries[idx].subfunctUpper; subf += scanEntries[idx].subfunctIncrement)
{
test.subFunc = subf;
sendOnBuses(test, scanEntries[idx].busToScan);
}
break;
case ST_IO_CTRL:
test.subFuncLen = 3;
test.service = UDS_SERVICES::IO_CTRL;
for (int subf = scanEntries[idx].subfunctLower; subf <= scanEntries[idx].subfunctUpper; subf += scanEntries[idx].subfunctIncrement)
{
test.subFunc = subf; //the upper byte will be 0 which is what we want. 0 = Return control to ECU
sendOnBuses(test, scanEntries[idx].busToScan);
}
break;
case ST_ROUTINE_CTRL:
test.subFuncLen = 3;
test.service = UDS_SERVICES::ROUTINE_CTRL;
for (int subf = scanEntries[idx].subfunctLower; subf <= scanEntries[idx].subfunctUpper; subf += scanEntries[idx].subfunctIncrement)
{
//request results of routine for all the addresses we're testing. This is the safest thing to do.
//starting or stopping arbitrary routines is super dangerous. Don't do that unless you really know
//what the hell you're doing or something really crazy might happen.
test.subFunc = (subf << 8) + 3;
sendOnBuses(test, scanEntries[idx].busToScan);
}
break;
case ST_CUSTOM:
test.subFuncLen = scanEntries[idx].subfunctLen;
for (uint32_t typ = scanEntries[idx].serviceLower; typ <= scanEntries[idx].serviceUpper; typ++)
{
test.service = typ;
for (int subTyp = scanEntries[idx].subfunctLower; subTyp <= scanEntries[idx].subfunctUpper; subTyp += scanEntries[idx].subfunctIncrement)
{
test.subFunc = subTyp;
sendOnBuses(test, scanEntries[idx].busToScan);
}
}
break;
}
}
}
//Updates here are sent about every 1/4 second. That's fine for most windows but not this one.
void UDSScanWindow::updatedFrames(int numFrames)
{
@@ -491,7 +882,7 @@ void UDSScanWindow::sendNextMsg()
udsHandler->setReception(false);
udsHandler->setProcessAllIDs(false);
udsHandler->setFlowCtrl(false);
ui->btnScan->setText("Start Scan");
//ui->btnScan->setText("Start Scan");
currentlyRunning = false;
}
ui->progressBar->setValue(currIdx);