|
|
@ -2,8 +2,24 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include <iostream> |
|
|
|
#include <iostream> |
|
|
|
|
|
|
|
|
|
|
|
#include "tools/cabana/dbc/dbcmanager.h" |
|
|
|
std::map<ScanType, std::string> scanTypeToDisplayName { |
|
|
|
#include "tools/cabana/streams/abstractstream.h" |
|
|
|
{ExactValue, "Exact value"}, |
|
|
|
|
|
|
|
{BiggerThan, "Bigger than..."}, |
|
|
|
|
|
|
|
{SmallerThan, "Smaller than..."}, |
|
|
|
|
|
|
|
{BiggerThan, "Bigger than..."}, |
|
|
|
|
|
|
|
{ValueBetween, "Value between..."}, |
|
|
|
|
|
|
|
{IncreasedValue, "Increased value"}, |
|
|
|
|
|
|
|
{IncreaseValueBy, "Increased value by..."}, |
|
|
|
|
|
|
|
{DecreasedValue, "Decreased value"}, |
|
|
|
|
|
|
|
{DecreasedValueBy, "Decreased value by..."}, |
|
|
|
|
|
|
|
{ChangedValue, "Changed value"}, |
|
|
|
|
|
|
|
{UnchangedValue, "Unchanged value"}, |
|
|
|
|
|
|
|
{UnknownInitialValue, "Unknown initial value"}, |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t getBitValue(uint64_t val, int offset, int size){ |
|
|
|
|
|
|
|
return (((1 << size) - 1) & (val >> (offset - 1))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SearchDlg::SearchDlg(QWidget *parent) : QDialog(parent) { |
|
|
|
SearchDlg::SearchDlg(QWidget *parent) : QDialog(parent) { |
|
|
|
setWindowTitle(tr("Search")); |
|
|
|
setWindowTitle(tr("Search")); |
|
|
@ -13,9 +29,12 @@ SearchDlg::SearchDlg(QWidget *parent) : QDialog(parent) { |
|
|
|
|
|
|
|
|
|
|
|
QHBoxLayout *scan_button_layout = new QHBoxLayout(); |
|
|
|
QHBoxLayout *scan_button_layout = new QHBoxLayout(); |
|
|
|
|
|
|
|
|
|
|
|
QPushButton *first_scan_button = new QPushButton(QString("First Scan"), this); |
|
|
|
first_scan_button = new QPushButton(QString("..."), this); |
|
|
|
QPushButton *next_scan_button = new QPushButton(QString("Next Scan"), this); |
|
|
|
next_scan_button = new QPushButton(QString("Next Scan"), this); |
|
|
|
QPushButton *undo_scan_button = new QPushButton(QString("Undo Scan"), this); |
|
|
|
undo_scan_button = new QPushButton(QString("Undo Scan"), this); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
undo_scan_button->setEnabled(false); |
|
|
|
|
|
|
|
next_scan_button->setEnabled(false); |
|
|
|
|
|
|
|
|
|
|
|
QObject::connect(first_scan_button, &QPushButton::clicked, [=]() { firstScan(); }); |
|
|
|
QObject::connect(first_scan_button, &QPushButton::clicked, [=]() { firstScan(); }); |
|
|
|
QObject::connect(next_scan_button, &QPushButton::clicked, [=]() { nextScan(); }); |
|
|
|
QObject::connect(next_scan_button, &QPushButton::clicked, [=]() { nextScan(); }); |
|
|
@ -27,13 +46,14 @@ SearchDlg::SearchDlg(QWidget *parent) : QDialog(parent) { |
|
|
|
|
|
|
|
|
|
|
|
QVBoxLayout *search_parameters_layout = new QVBoxLayout(); |
|
|
|
QVBoxLayout *search_parameters_layout = new QVBoxLayout(); |
|
|
|
|
|
|
|
|
|
|
|
QLineEdit *value_box = new QLineEdit(); |
|
|
|
QLineEdit *value_box1 = new QLineEdit(); |
|
|
|
value_box->setValidator( new QIntValidator(this) ); |
|
|
|
value_box1->setValidator( new QIntValidator(this) ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QObject::connect(value_box1, &QLineEdit::textChanged, [=](QString value) { scan_value1 = value.toInt(); }); |
|
|
|
|
|
|
|
|
|
|
|
QObject::connect(value_box, &QLineEdit::textChanged, [=](QString value) { scan_value = value.toInt(); }); |
|
|
|
scan_type = new QComboBox(); |
|
|
|
|
|
|
|
|
|
|
|
QComboBox *scan_type = new QComboBox(); |
|
|
|
QObject::connect(scan_type, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) { selectedScanType = (ScanType)(scan_type->itemData(index).toInt()); }); |
|
|
|
scan_type->addItem(QString("Exact Value")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QHBoxLayout *bits_min_max_layout = new QHBoxLayout(); |
|
|
|
QHBoxLayout *bits_min_max_layout = new QHBoxLayout(); |
|
|
|
|
|
|
|
|
|
|
@ -51,36 +71,97 @@ SearchDlg::SearchDlg(QWidget *parent) : QDialog(parent) { |
|
|
|
bits_min_max_layout->addWidget(bits_min); |
|
|
|
bits_min_max_layout->addWidget(bits_min); |
|
|
|
bits_min_max_layout->addWidget(bits_max); |
|
|
|
bits_min_max_layout->addWidget(bits_max); |
|
|
|
|
|
|
|
|
|
|
|
search_parameters_layout->addWidget(value_box); |
|
|
|
search_parameters_layout->addWidget(value_box1); |
|
|
|
|
|
|
|
search_parameters_layout->addWidget(scan_type); |
|
|
|
search_parameters_layout->addLayout(bits_min_max_layout); |
|
|
|
search_parameters_layout->addLayout(bits_min_max_layout); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QVBoxLayout *search_results_layout = new QVBoxLayout(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
numberOfSigsLabel = new QLabel(QString("Found: 0")); |
|
|
|
|
|
|
|
search_results_layout->addWidget(numberOfSigsLabel); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data_table = new QTableWidget(); |
|
|
|
|
|
|
|
data_table->setRowCount(1); |
|
|
|
|
|
|
|
data_table->setColumnCount(6); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
search_results_layout->addWidget(data_table); |
|
|
|
|
|
|
|
|
|
|
|
main_layout->addLayout(scan_button_layout); |
|
|
|
main_layout->addLayout(scan_button_layout); |
|
|
|
main_layout->addLayout(search_parameters_layout); |
|
|
|
main_layout->addLayout(search_parameters_layout); |
|
|
|
|
|
|
|
main_layout->addLayout(search_results_layout); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
update(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QObject::connect(can, &AbstractStream::received, this, &SearchDlg::updateRowData); |
|
|
|
|
|
|
|
QObject::connect(can, &AbstractStream::seekedTo, this, &SearchDlg::updateRowData); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint64_t getBitValue(uint64_t val, int offset, int size){ |
|
|
|
void SearchDlg::setRowData(int row, QString msgID, QString bitRange, QString currentValue, QString previousValue){ |
|
|
|
return (((1 << size) - 1) & (val >> (offset - 1))); |
|
|
|
QTableWidgetItem *msg_id = new QTableWidgetItem(msgID); |
|
|
|
|
|
|
|
data_table->setItem(row, 0, msg_id); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QTableWidgetItem *bit_range = new QTableWidgetItem(bitRange); |
|
|
|
|
|
|
|
data_table->setItem(row, 1, bit_range); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QTableWidgetItem *current_value = new QTableWidgetItem(currentValue); |
|
|
|
|
|
|
|
data_table->setItem(row, 2, current_value); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QTableWidgetItem *previous_value = new QTableWidgetItem(previousValue); |
|
|
|
|
|
|
|
data_table->setItem(row, 3, previous_value); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class Sig { |
|
|
|
void SearchDlg::updateRowData(){ |
|
|
|
public: |
|
|
|
data_table->clear(); |
|
|
|
Sig(MessageId _messageID, int _offset, int _size) : messageID(_messageID), offset(_offset), size(_size) {} |
|
|
|
data_table->setRowCount(0); |
|
|
|
|
|
|
|
|
|
|
|
MessageId messageID; |
|
|
|
if(filteredSignals.size() < 1000){ |
|
|
|
size_t offset; |
|
|
|
data_table->setRowCount(filteredSignals.size() + 1); |
|
|
|
size_t size; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t getValue(){ |
|
|
|
setRowData(0, QString("Message ID"), QString("Bit Range"), QString("Current Value"), QString("Previous Value")); |
|
|
|
auto msg = can->can_msgs[messageID]; |
|
|
|
|
|
|
|
uint64_t* data = (uint64_t*)(msg.dat.data()); |
|
|
|
int row=1; |
|
|
|
return getBitValue(*data, offset, size); |
|
|
|
for(auto &sig : filteredSignals){ |
|
|
|
|
|
|
|
setRowData(row, sig.messageID.toString(), QString("%1:%2").arg(sig.offset).arg(sig.offset+sig.size), QString::number(sig.getValue()), QString::number(sig.previousValue)); |
|
|
|
|
|
|
|
row++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SearchDlg::update(){ |
|
|
|
|
|
|
|
first_scan_button->setText(scanningStarted ? "New Scan" : "First Scan"); |
|
|
|
|
|
|
|
numberOfSigsLabel->setText(QString("Found: ") + QString::number(filteredSignals.size())); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ScanType selectedValue = (ScanType)(scan_type->currentData().toInt()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
next_scan_button->setEnabled(scanningStarted); |
|
|
|
|
|
|
|
undo_scan_button->setEnabled(false); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scan_type->clear(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int selectedIndex = -1; |
|
|
|
|
|
|
|
int i = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(auto scanType : enabledScanTypes()){ |
|
|
|
|
|
|
|
if(scanType == selectedValue) selectedIndex = i; |
|
|
|
|
|
|
|
scan_type->addItem(QString::fromStdString(scanTypeToDisplayName[scanType]), QVariant(scanType)); |
|
|
|
|
|
|
|
i++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(selectedIndex != -1){ |
|
|
|
|
|
|
|
scan_type->setCurrentIndex(selectedIndex); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
updateRowData(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(auto &sig : filteredSignals){ |
|
|
|
|
|
|
|
sig.previousValue = sig.getValue(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<Sig> getAllPossibleSignals(int bits_min, int bits_max){ |
|
|
|
std::vector<Sig> getAllPossibleSignals(int bits_min, int bits_max){ |
|
|
|
std::vector<Sig> ret; |
|
|
|
std::vector<Sig> ret; |
|
|
|
|
|
|
|
|
|
|
|
for(auto msg_id : can->can_msgs.keys()) { |
|
|
|
for(auto msg_id : can->last_msgs.keys()) { |
|
|
|
for(int i = bits_min; i < bits_max+1; i++) { |
|
|
|
for(int i = bits_min; i < bits_max+1; i++) { |
|
|
|
for(int j = 0; j < 64 - i; j++) { |
|
|
|
for(int j = 0; j < 64 - i; j++) { |
|
|
|
ret.push_back(Sig(msg_id, j, i)); |
|
|
|
ret.push_back(Sig(msg_id, j, i)); |
|
|
@ -91,23 +172,81 @@ std::vector<Sig> getAllPossibleSignals(int bits_min, int bits_max){ |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SearchDlg::firstScan(){ |
|
|
|
std::vector<ScanType> SearchDlg::enabledScanTypes(){ |
|
|
|
std::cout << scan_bits_range_min << " " << scan_bits_range_max << " " << scan_value << std::endl; |
|
|
|
if(!scanningStarted){ |
|
|
|
|
|
|
|
return std::vector<ScanType> { |
|
|
|
|
|
|
|
ExactValue, |
|
|
|
|
|
|
|
BiggerThan, |
|
|
|
|
|
|
|
SmallerThan, |
|
|
|
|
|
|
|
ValueBetween, |
|
|
|
|
|
|
|
UnknownInitialValue |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else{ |
|
|
|
|
|
|
|
return std::vector<ScanType> { |
|
|
|
|
|
|
|
ExactValue, |
|
|
|
|
|
|
|
BiggerThan, |
|
|
|
|
|
|
|
SmallerThan, |
|
|
|
|
|
|
|
ValueBetween, |
|
|
|
|
|
|
|
IncreasedValue, |
|
|
|
|
|
|
|
IncreaseValueBy, |
|
|
|
|
|
|
|
DecreasedValue, |
|
|
|
|
|
|
|
DecreasedValueBy, |
|
|
|
|
|
|
|
ChangedValue, |
|
|
|
|
|
|
|
UnchangedValue |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::vector<Sig> allPossibleValues = getAllPossibleSignals(scan_bits_range_min, scan_bits_range_max); |
|
|
|
void SearchDlg::firstScan(){ |
|
|
|
|
|
|
|
if(scanningStarted){ |
|
|
|
|
|
|
|
filteredSignals.clear(); |
|
|
|
|
|
|
|
scanningStarted = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else{ |
|
|
|
|
|
|
|
filteredSignals = getAllPossibleSignals(scan_bits_range_min, scan_bits_range_max); |
|
|
|
|
|
|
|
scanningStarted = true; |
|
|
|
|
|
|
|
|
|
|
|
std::cout << allPossibleValues.size() << std::endl; |
|
|
|
nextScan(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
update(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::vector<Sig> filteredValues; |
|
|
|
SignalFilterer* SearchDlg::getCurrentFilterer() { |
|
|
|
std::copy_if(allPossibleValues.begin(), allPossibleValues.end(), std::back_inserter(filteredValues), [=](Sig i) { |
|
|
|
if(selectedScanType == ExactValue){ |
|
|
|
return i.getValue() == scan_value; |
|
|
|
return new ExactValueSignalFilterer(scan_value1); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
if(selectedScanType == BiggerThan){ |
|
|
|
|
|
|
|
return new BiggerThanSignalFilterer(scan_value1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(selectedScanType == SmallerThan){ |
|
|
|
|
|
|
|
return new SmallerThanSignalFilterer(scan_value1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(selectedScanType == UnknownInitialValue){ |
|
|
|
|
|
|
|
return new UnknownInitialValueSignalFilter(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(selectedScanType == UnchangedValue){ |
|
|
|
|
|
|
|
return new UnchangedValueSignalFilter(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(selectedScanType == ChangedValue){ |
|
|
|
|
|
|
|
return new ChangedValueSignalFilter(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(selectedScanType == IncreasedValue){ |
|
|
|
|
|
|
|
return new IncreasedValueSignalFilter(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(selectedScanType == DecreasedValue){ |
|
|
|
|
|
|
|
return new DecreasedValueSignalFilter(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::cout << filteredValues.size() << std::endl; |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SearchDlg::nextScan(){ |
|
|
|
void SearchDlg::nextScan(){ |
|
|
|
|
|
|
|
auto filterer = getCurrentFilterer(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
filteredSignals = filterer->filter(filteredSignals); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
update(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SearchDlg::undoScan(){ |
|
|
|
void SearchDlg::undoScan(){ |
|
|
|