From 3478ac13387ccfcc3c04c197f8ac4d43c4325c24 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 1 Mar 2026 16:12:04 -0800 Subject: [PATCH] cabana: remove QtSerialBus (#37523) --- tools/cabana/SConscript | 2 - tools/cabana/binaryview.cc | 19 +++-- tools/cabana/binaryview.h | 7 +- tools/cabana/chart/chartswidget.cc | 29 ++++---- tools/cabana/chart/chartswidget.h | 6 +- tools/cabana/chart/signalselector.cc | 4 +- tools/cabana/chart/signalselector.h | 2 +- tools/cabana/streams/socketcanstream.cc | 98 +++++++++++++++++-------- tools/cabana/streams/socketcanstream.h | 9 +-- tools/cabana/tools/findsignal.cc | 18 ++--- tools/cabana/tools/findsignal.h | 10 ++- tools/cabana/tools/findsimilarbits.cc | 19 ++--- tools/cabana/tools/findsimilarbits.h | 4 +- 13 files changed, 133 insertions(+), 94 deletions(-) diff --git a/tools/cabana/SConscript b/tools/cabana/SConscript index 5747d6e621..098a6351b7 100644 --- a/tools/cabana/SConscript +++ b/tools/cabana/SConscript @@ -68,10 +68,8 @@ base_libs = [common, messaging, cereal, visionipc, 'm', 'ssl', 'crypto', 'pthrea if arch == "Darwin": base_frameworks.append('QtCharts') - base_frameworks.append('QtSerialBus') else: base_libs.append('Qt5Charts') - base_libs.append('Qt5SerialBus') qt_libs = base_libs diff --git a/tools/cabana/binaryview.cc b/tools/cabana/binaryview.cc index 90c7c1c341..0be28f06b7 100644 --- a/tools/cabana/binaryview.cc +++ b/tools/cabana/binaryview.cc @@ -111,7 +111,8 @@ void BinaryView::highlight(const cabana::Signal *sig) { if (sig != hovered_sig) { for (int i = 0; i < model->items.size(); ++i) { auto &item_sigs = model->items[i].sigs; - if ((sig && item_sigs.contains(sig)) || (hovered_sig && item_sigs.contains(hovered_sig))) { + auto has = [](const auto &v, auto p) { return std::find(v.begin(), v.end(), p) != v.end(); }; + if ((sig && has(item_sigs, sig)) || (hovered_sig && has(item_sigs, hovered_sig))) { auto index = model->index(i / model->columnCount(), i % model->columnCount()); emit model->dataChanged(index, index, {Qt::DisplayRole}); } @@ -157,7 +158,7 @@ void BinaryView::mousePressEvent(QMouseEvent *event) { void BinaryView::highlightPosition(const QPoint &pos) { if (auto index = indexAt(viewport()->mapFromGlobal(pos)); index.isValid()) { auto item = (BinaryViewModel::Item *)index.internalPointer(); - const cabana::Signal *sig = item->sigs.isEmpty() ? nullptr : item->sigs.back(); + const cabana::Signal *sig = item->sigs.empty() ? nullptr : item->sigs.back(); highlight(sig); } } @@ -208,12 +209,12 @@ void BinaryView::refresh() { highlightPosition(QCursor::pos()); } -QSet BinaryView::getOverlappingSignals() const { - QSet overlapping; +std::set BinaryView::getOverlappingSignals() const { + std::set overlapping; for (const auto &item : model->items) { if (item.sigs.size() > 1) { for (auto s : item.sigs) { - if (s->type == cabana::Signal::Type::Normal) overlapping += s; + if (s->type == cabana::Signal::Type::Normal) overlapping.insert(s); } } } @@ -404,7 +405,9 @@ bool BinaryItemDelegate::hasSignal(const QModelIndex &index, int dx, int dy, con if (!index.isValid()) return false; auto model = (const BinaryViewModel*)(index.model()); int idx = (index.row() + dy) * model->columnCount() + index.column() + dx; - return (idx >=0 && idx < model->items.size()) ? model->items[idx].sigs.contains(sig) : false; + if (idx < 0 || idx >= (int)model->items.size()) return false; + auto &s = model->items[idx].sigs; + return std::find(s.begin(), s.end(), sig) != s.end(); } void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { @@ -421,7 +424,7 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op auto color = bin_view->resize_sig ? bin_view->resize_sig->color : option.palette.color(QPalette::Active, QPalette::Highlight); painter->fillRect(option.rect, color); painter->setPen(option.palette.color(QPalette::BrightText)); - } else if (!bin_view->selectionModel()->hasSelection() || !item->sigs.contains(bin_view->resize_sig)) { // not resizing + } else if (!bin_view->selectionModel()->hasSelection() || std::find(item->sigs.begin(), item->sigs.end(), bin_view->resize_sig) == item->sigs.end()) { // not resizing if (item->sigs.size() > 0) { for (auto &s : item->sigs) { if (s == bin_view->hovered_sig) { @@ -433,7 +436,7 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op } else if (item->valid && item->bg_color.alpha() > 0) { painter->fillRect(option.rect, item->bg_color); } - auto color_role = item->sigs.contains(bin_view->hovered_sig) ? QPalette::BrightText : QPalette::Text; + auto color_role = (std::find(item->sigs.begin(), item->sigs.end(), bin_view->hovered_sig) != item->sigs.end()) ? QPalette::BrightText : QPalette::Text; painter->setPen(option.palette.color(bin_view->is_message_active ? QPalette::Normal : QPalette::Disabled, color_role)); } diff --git a/tools/cabana/binaryview.h b/tools/cabana/binaryview.h index 920deb0018..e568228b37 100644 --- a/tools/cabana/binaryview.h +++ b/tools/cabana/binaryview.h @@ -1,10 +1,9 @@ #pragma once +#include #include #include -#include -#include #include #include @@ -51,7 +50,7 @@ public: bool is_msb = false; bool is_lsb = false; uint8_t val; - QList sigs; + std::vector sigs; bool valid = false; }; std::vector items; @@ -68,7 +67,7 @@ public: BinaryView(QWidget *parent = nullptr); void setMessage(const MessageId &message_id); void highlight(const cabana::Signal *sig); - QSet getOverlappingSignals() const; + std::set getOverlappingSignals() const; void updateState() { model->updateState(); } void paintEvent(QPaintEvent *event) override { is_message_active = can->isMessageActive(model->msg_id); diff --git a/tools/cabana/chart/chartswidget.cc b/tools/cabana/chart/chartswidget.cc index efae1dded0..acdb6d064d 100644 --- a/tools/cabana/chart/chartswidget.cc +++ b/tools/cabana/chart/chartswidget.cc @@ -166,7 +166,7 @@ void ChartsWidget::removeTab(int index) { void ChartsWidget::updateTabBar() { for (int i = 0; i < tabbar->count(); ++i) { const auto &charts_in_tab = tab_charts[tabbar->tabData(i).toInt()]; - tabbar->setTabText(i, QString("Tab %1 (%2)").arg(i + 1).arg(charts_in_tab.count())); + tabbar->setTabText(i, QString("Tab %1 (%2)").arg(i + 1).arg((int)charts_in_tab.size())); } } @@ -204,7 +204,7 @@ void ChartsWidget::showValueTip(double sec) { } void ChartsWidget::updateState() { - if (charts.isEmpty()) return; + if (charts.empty()) return; const auto &time_range = can->timeRange(); const double cur_sec = can->currentSec(); @@ -248,7 +248,7 @@ void ChartsWidget::updateToolBar() { redo_zoom_action->setVisible(is_zoomed); reset_zoom_action->setVisible(is_zoomed); reset_zoom_btn->setText(is_zoomed ? tr("%1-%2").arg(can->timeRange()->first, 0, 'f', 2).arg(can->timeRange()->second, 0, 'f', 2) : ""); - remove_all_btn->setEnabled(!charts.isEmpty()); + remove_all_btn->setEnabled(!charts.empty()); } void ChartsWidget::settingChanged() { @@ -282,9 +282,9 @@ ChartView *ChartsWidget::createChart(int pos) { chart->setMinimumWidth(CHART_MIN_WIDTH); chart->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); QObject::connect(chart, &ChartView::axisYLabelWidthChanged, align_timer, qOverload<>(&QTimer::start)); - pos = std::clamp(pos, 0, charts.size()); - charts.insert(pos, chart); - currentCharts().insert(pos, chart); + pos = std::clamp(pos, 0, (int)charts.size()); + charts.insert(charts.begin() + pos, chart); + currentCharts().insert(currentCharts().begin() + pos, chart); updateLayout(true); updateToolBar(); return chart; @@ -303,7 +303,7 @@ void ChartsWidget::showChart(const MessageId &id, const cabana::Signal *sig, boo void ChartsWidget::splitChart(ChartView *src_chart) { if (src_chart->sigs.size() > 1) { - int pos = charts.indexOf(src_chart) + 1; + int pos = std::find(charts.begin(), charts.end(), src_chart) - charts.begin() + 1; for (auto it = src_chart->sigs.begin() + 1; it != src_chart->sigs.end(); /**/) { auto c = createChart(pos); src_chart->chart()->removeSeries(it->series); @@ -434,7 +434,7 @@ void ChartsWidget::newChart() { SignalSelector dlg(tr("New Chart"), this); if (dlg.exec() == QDialog::Accepted) { auto items = dlg.seletedItems(); - if (!items.isEmpty()) { + if (!items.empty()) { auto c = createChart(); for (auto it : items) { c->addSignal(it->msg_id, it->sig); @@ -444,10 +444,10 @@ void ChartsWidget::newChart() { } void ChartsWidget::removeChart(ChartView *chart) { - charts.removeOne(chart); + charts.erase(std::remove(charts.begin(), charts.end(), chart), charts.end()); chart->deleteLater(); for (auto &[_, list] : tab_charts) { - list.removeOne(chart); + list.erase(std::remove(list.begin(), list.end(), chart), list.end()); } updateToolBar(); updateLayout(true); @@ -461,7 +461,7 @@ void ChartsWidget::removeAll() { } tab_charts.clear(); - if (!charts.isEmpty()) { + if (!charts.empty()) { for (auto c : charts) { delete c; } @@ -561,10 +561,11 @@ void ChartsContainer::dropEvent(QDropEvent *event) { auto chart = qobject_cast(event->source()); if (w != chart) { for (auto &[_, list] : charts_widget->tab_charts) { - list.removeOne(chart); + list.erase(std::remove(list.begin(), list.end(), chart), list.end()); } - int to = w ? charts_widget->currentCharts().indexOf(w) + 1 : 0; - charts_widget->currentCharts().insert(to, chart); + auto &cur = charts_widget->currentCharts(); + int to = w ? std::find(cur.begin(), cur.end(), w) - cur.begin() + 1 : 0; + cur.insert(cur.begin() + to, chart); charts_widget->updateLayout(true); charts_widget->updateTabBar(); event->acceptProposedAction(); diff --git a/tools/cabana/chart/chartswidget.h b/tools/cabana/chart/chartswidget.h index f87b1276c5..ef3fbc471a 100644 --- a/tools/cabana/chart/chartswidget.h +++ b/tools/cabana/chart/chartswidget.h @@ -81,7 +81,7 @@ private: bool eventFilter(QObject *obj, QEvent *event) override; void newTab(); void removeTab(int index); - inline QList ¤tCharts() { return tab_charts[tabbar->tabData(tabbar->currentIndex()).toInt()]; } + inline std::vector ¤tCharts() { return tab_charts[tabbar->tabData(tabbar->currentIndex()).toInt()]; } ChartView *findChart(const MessageId &id, const cabana::Signal *sig); QLabel *title_label; @@ -100,8 +100,8 @@ private: QUndoStack *zoom_undo_stack; ToolButton *remove_all_btn; - QList charts; - std::unordered_map> tab_charts; + std::vector charts; + std::unordered_map> tab_charts; TabBar *tabbar; ChartsContainer *charts_container; QScrollArea *charts_scroll; diff --git a/tools/cabana/chart/signalselector.cc b/tools/cabana/chart/signalselector.cc index 168bf824df..6f2fd8de46 100644 --- a/tools/cabana/chart/signalselector.cc +++ b/tools/cabana/chart/signalselector.cc @@ -102,8 +102,8 @@ void SignalSelector::addItemToList(QListWidget *parent, const MessageId id, cons parent->setItemWidget(new_item, label); } -QList SignalSelector::seletedItems() { - QList ret; +std::vector SignalSelector::seletedItems() { + std::vector ret; for (int i = 0; i < selected_list->count(); ++i) ret.push_back((ListItem *)selected_list->item(i)); return ret; } diff --git a/tools/cabana/chart/signalselector.h b/tools/cabana/chart/signalselector.h index f46779f044..5b6e37e56a 100644 --- a/tools/cabana/chart/signalselector.h +++ b/tools/cabana/chart/signalselector.h @@ -15,7 +15,7 @@ public: }; SignalSelector(QString title, QWidget *parent); - QList seletedItems(); + std::vector seletedItems(); inline void addSelected(const MessageId &id, const cabana::Signal *sig) { addItemToList(selected_list, id, sig, true); } private: diff --git a/tools/cabana/streams/socketcanstream.cc b/tools/cabana/streams/socketcanstream.cc index 4f558ba049..768465d5a3 100644 --- a/tools/cabana/streams/socketcanstream.cc +++ b/tools/cabana/streams/socketcanstream.cc @@ -1,6 +1,14 @@ #include "tools/cabana/streams/socketcanstream.h" +#include +#include +#include +#include +#include +#include + #include +#include #include #include #include @@ -9,7 +17,7 @@ SocketCanStream::SocketCanStream(QObject *parent, SocketCanStreamConfig config_) : config(config_), LiveStream(parent) { if (!available()) { - throw std::runtime_error("SocketCAN plugin not available"); + throw std::runtime_error("SocketCAN not available"); } qDebug() << "Connecting to SocketCAN device" << config.device.c_str(); @@ -18,50 +26,73 @@ SocketCanStream::SocketCanStream(QObject *parent, SocketCanStreamConfig config_) } } +SocketCanStream::~SocketCanStream() { + stop(); + if (sock_fd >= 0) { + ::close(sock_fd); + sock_fd = -1; + } +} + bool SocketCanStream::available() { - return QCanBus::instance()->plugins().contains("socketcan"); + int fd = socket(PF_CAN, SOCK_RAW, CAN_RAW); + if (fd < 0) return false; + ::close(fd); + return true; } bool SocketCanStream::connect() { - // Connecting might generate some warnings about missing socketcan/libsocketcan libraries - // These are expected and can be ignored, we don't need the advanced features of libsocketcan - QString errorString; - device.reset(QCanBus::instance()->createDevice("socketcan", QString::fromStdString(config.device), &errorString)); - device->setConfigurationParameter(QCanBusDevice::CanFdKey, true); - - if (!device) { - qDebug() << "Failed to create SocketCAN device" << errorString; + sock_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW); + if (sock_fd < 0) { + qDebug() << "Failed to create CAN socket"; return false; } - if (!device->connectDevice()) { - qDebug() << "Failed to connect to device"; + // Enable CAN-FD + int fd_enable = 1; + setsockopt(sock_fd, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &fd_enable, sizeof(fd_enable)); + + struct ifreq ifr = {}; + strncpy(ifr.ifr_name, config.device.c_str(), IFNAMSIZ - 1); + if (ioctl(sock_fd, SIOCGIFINDEX, &ifr) < 0) { + qDebug() << "Failed to get interface index for" << config.device.c_str(); + ::close(sock_fd); + sock_fd = -1; return false; } + struct sockaddr_can addr = {}; + addr.can_family = AF_CAN; + addr.can_ifindex = ifr.ifr_ifindex; + if (bind(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + qDebug() << "Failed to bind CAN socket"; + ::close(sock_fd); + sock_fd = -1; + return false; + } + + // Set read timeout so the thread can check for interruption + struct timeval tv = {.tv_sec = 0, .tv_usec = 100000}; // 100ms + setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + return true; } void SocketCanStream::streamThread() { - while (!QThread::currentThread()->isInterruptionRequested()) { - QThread::msleep(1); + struct canfd_frame frame; - auto frames = device->readAllFrames(); - if (frames.size() == 0) continue; + while (!QThread::currentThread()->isInterruptionRequested()) { + ssize_t nbytes = read(sock_fd, &frame, sizeof(frame)); + if (nbytes <= 0) continue; + + uint8_t len = (nbytes == CAN_MTU) ? frame.len : frame.len; // works for both CAN and CAN-FD MessageBuilder msg; auto evt = msg.initEvent(); - auto canData = evt.initCan(frames.size()); - - for (uint i = 0; i < frames.size(); i++) { - if (!frames[i].isValid()) continue; - - canData[i].setAddress(frames[i].frameId()); - canData[i].setSrc(0); - - auto payload = frames[i].payload(); - canData[i].setDat(kj::arrayPtr((uint8_t*)payload.data(), payload.size())); - } + auto canData = evt.initCan(1); + canData[0].setAddress(frame.can_id & CAN_EFF_MASK); + canData[0].setSrc(0); + canData[0].setDat(kj::arrayPtr(frame.data, len)); handleEvent(capnp::messageToFlatArray(msg)); } @@ -95,12 +126,19 @@ OpenSocketCanWidget::OpenSocketCanWidget(QWidget *parent) : AbstractOpenStreamWi void OpenSocketCanWidget::refreshDevices() { device_edit->clear(); - for (auto device : QCanBus::instance()->availableDevices(QStringLiteral("socketcan"))) { - device_edit->addItem(device.name()); + // Scan /sys/class/net/ for CAN interfaces (type 280 = ARPHRD_CAN) + QDir net_dir("/sys/class/net"); + for (const auto &iface : net_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { + QFile type_file(net_dir.filePath(iface) + "/type"); + if (type_file.open(QIODevice::ReadOnly)) { + int type = type_file.readAll().trimmed().toInt(); + if (type == 280) { + device_edit->addItem(iface); + } + } } } - AbstractStream *OpenSocketCanWidget::open() { try { return new SocketCanStream(qApp, config); diff --git a/tools/cabana/streams/socketcanstream.h b/tools/cabana/streams/socketcanstream.h index dc3cf7928a..3c5cd184f7 100644 --- a/tools/cabana/streams/socketcanstream.h +++ b/tools/cabana/streams/socketcanstream.h @@ -1,10 +1,5 @@ #pragma once -#include - -#include -#include -#include #include #include "tools/cabana/streams/livestream.h" @@ -17,7 +12,7 @@ class SocketCanStream : public LiveStream { Q_OBJECT public: SocketCanStream(QObject *parent, SocketCanStreamConfig config_ = {}); - ~SocketCanStream() { stop(); } + ~SocketCanStream(); static bool available(); inline std::string routeName() const override { @@ -29,7 +24,7 @@ protected: bool connect(); SocketCanStreamConfig config = {}; - std::unique_ptr device; + int sock_fd = -1; }; class OpenSocketCanWidget : public AbstractOpenStreamWidget { diff --git a/tools/cabana/tools/findsignal.cc b/tools/cabana/tools/findsignal.cc index 3dc28bb159..b131893942 100644 --- a/tools/cabana/tools/findsignal.cc +++ b/tools/cabana/tools/findsignal.cc @@ -33,7 +33,7 @@ void FindSignalModel::search(std::function cmp) { beginResetModel(); std::mutex lock; - const auto prev_sigs = !histories.isEmpty() ? histories.back() : initial_signals; + const auto prev_sigs = !histories.empty() ? histories.back() : initial_signals; filtered_signals.clear(); filtered_signals.reserve(prev_sigs.size()); @@ -71,11 +71,11 @@ void FindSignalModel::search(std::function cmp) { } void FindSignalModel::undo() { - if (!histories.isEmpty()) { + if (!histories.empty()) { beginResetModel(); histories.pop_back(); filtered_signals.clear(); - if (!histories.isEmpty()) filtered_signals = histories.back(); + if (!histories.empty()) filtered_signals = histories.back(); endResetModel(); } } @@ -186,7 +186,7 @@ FindSignalDlg::FindSignalDlg(QWidget *parent) : QDialog(parent, Qt::WindowFlags( } void FindSignalDlg::search() { - if (model->histories.isEmpty()) { + if (model->histories.empty()) { setInitialSignals(); } auto v1 = value1->text().toDouble(); @@ -260,12 +260,12 @@ void FindSignalDlg::setInitialSignals() { } void FindSignalDlg::modelReset() { - properties_group->setEnabled(model->histories.isEmpty()); - message_group->setEnabled(model->histories.isEmpty()); - search_btn->setText(model->histories.isEmpty() ? tr("Find") : tr("Find Next")); - reset_btn->setEnabled(!model->histories.isEmpty()); + properties_group->setEnabled(model->histories.empty()); + message_group->setEnabled(model->histories.empty()); + search_btn->setText(model->histories.empty() ? tr("Find") : tr("Find Next")); + reset_btn->setEnabled(!model->histories.empty()); undo_btn->setEnabled(model->histories.size() > 1); - search_btn->setEnabled(model->rowCount() > 0 || model->histories.isEmpty()); + search_btn->setEnabled(model->rowCount() > 0 || model->histories.empty()); stats_label->setVisible(true); stats_label->setText(tr("%1 matches. right click on an item to create signal. double click to open message").arg(model->filtered_signals.size())); } diff --git a/tools/cabana/tools/findsignal.h b/tools/cabana/tools/findsignal.h index 5ef7461fee..239a08c9c4 100644 --- a/tools/cabana/tools/findsignal.h +++ b/tools/cabana/tools/findsignal.h @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include @@ -26,14 +28,14 @@ public: QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 3; } - int rowCount(const QModelIndex &parent = QModelIndex()) const override { return std::min(filtered_signals.size(), 300); } + int rowCount(const QModelIndex &parent = QModelIndex()) const override { return std::min((int)filtered_signals.size(), 300); } void search(std::function cmp); void reset(); void undo(); - QList filtered_signals; - QList initial_signals; - QList> histories; + std::vector filtered_signals; + std::vector initial_signals; + std::vector> histories; uint64_t last_time = std::numeric_limits::max(); }; diff --git a/tools/cabana/tools/findsimilarbits.cc b/tools/cabana/tools/findsimilarbits.cc index 7cc7b5004f..8062b61199 100644 --- a/tools/cabana/tools/findsimilarbits.cc +++ b/tools/cabana/tools/findsimilarbits.cc @@ -1,6 +1,7 @@ #include "tools/cabana/tools/findsimilarbits.h" #include +#include #include #include @@ -114,10 +115,10 @@ void FindSimilarBitsDlg::find() { search_btn->setEnabled(true); } -QList FindSimilarBitsDlg::calcBits(uint8_t bus, uint32_t selected_address, int byte_idx, - int bit_idx, uint8_t find_bus, bool equal, int min_msgs_cnt) { - QHash> mismatches; - QHash msg_count; +std::vector FindSimilarBitsDlg::calcBits(uint8_t bus, uint32_t selected_address, int byte_idx, + int bit_idx, uint8_t find_bus, bool equal, int min_msgs_cnt) { + std::unordered_map> mismatches; + std::unordered_map msg_count; const auto &events = can->allEvents(); int bit_to_find = -1; for (const CanEvent *e : events) { @@ -143,14 +144,14 @@ QList FindSimilarBitsDlg::calcBits(uint8_ } } - QList result; + std::vector result; result.reserve(mismatches.size()); for (auto it = mismatches.begin(); it != mismatches.end(); ++it) { - if (auto cnt = msg_count[it.key()]; cnt > min_msgs_cnt) { - auto &mismatched = it.value(); - for (int i = 0; i < mismatched.size(); ++i) { + if (auto cnt = msg_count[it->first]; cnt > (uint32_t)min_msgs_cnt) { + auto &mismatched = it->second; + for (int i = 0; i < (int)mismatched.size(); ++i) { if (float perc = (mismatched[i] / (double)cnt) * 100; perc < 50) { - result.push_back({it.key(), (uint32_t)i / 8, (uint32_t)i % 8, mismatched[i], cnt, perc}); + result.push_back({it->first, (uint32_t)i / 8, (uint32_t)i % 8, mismatched[i], cnt, perc}); } } } diff --git a/tools/cabana/tools/findsimilarbits.h b/tools/cabana/tools/findsimilarbits.h index 77bfac19ca..3451360654 100644 --- a/tools/cabana/tools/findsimilarbits.h +++ b/tools/cabana/tools/findsimilarbits.h @@ -1,5 +1,7 @@ #pragma once +#include + #include #include #include @@ -22,7 +24,7 @@ private: uint32_t address, byte_idx, bit_idx, mismatches, total; float perc; }; - QList calcBits(uint8_t bus, uint32_t selected_address, int byte_idx, int bit_idx, uint8_t find_bus, + std::vector calcBits(uint8_t bus, uint32_t selected_address, int byte_idx, int bit_idx, uint8_t find_bus, bool equal, int min_msgs_cnt); void find();