cabana: fix find similar bits
diff --git a/tools/cabana/tools/findsimilarbits.cc b/tools/cabana/tools/findsimilarbits.cc
index 5fa5bcf7b82cd6..cb5dbc0845e6b2 100644
--- a/tools/cabana/tools/findsimilarbits.cc
+++ b/tools/cabana/tools/findsimilarbits.cc
@@ -25,14 +25,28 @@ FindSimilarBitsDlg::FindSimilarBitsDlg(QWidget *parent) : QDialog(parent) {
   }
   bus_combo->model()->sort(0);
   bus_combo->setCurrentIndex(0);
+
+  msg_cb = new QComboBox(this);
+  for (auto &[address, msg] : dbc()->messages()) {
+    msg_cb->addItem(msg.name, address);
+  }
+  msg_cb->model()->sort(0);
+  msg_cb->setCurrentIndex(0);
+
+  byte_idx_sb = new QSpinBox(this);
+  byte_idx_sb->setRange(0, 63);
+
+  bit_idx_sb = new QSpinBox(this);
+  bit_idx_sb->setRange(0, 7);
+
   form_layout->addWidget(new QLabel("Bus"));
   form_layout->addWidget(bus_combo);
+  form_layout->addWidget(msg_cb);
+  form_layout->addWidget(new QLabel("Byte Index"));
+  form_layout->addWidget(byte_idx_sb);
+  form_layout->addWidget(new QLabel("Bit Index"));
+  form_layout->addWidget(bit_idx_sb);
 
-  bit_combo = new QComboBox(this);
-  bit_combo->addItems({"0", "1"});
-  bit_combo->setCurrentIndex(1);
-  form_layout->addWidget(new QLabel("Bit"));
-  form_layout->addWidget(bit_combo);
 
   min_msgs = new QLineEdit(this);
   min_msgs->setValidator(new QIntValidator(this));
@@ -56,10 +70,11 @@ FindSimilarBitsDlg::FindSimilarBitsDlg(QWidget *parent) : QDialog(parent) {
 void FindSimilarBitsDlg::find() {
   search_btn->setEnabled(false);
   table->clear();
-  auto msg_mismatched = calcBits(bus_combo->currentText().toUInt(), bit_combo->currentIndex(), min_msgs->text().toInt());
+  uint32_t selected_address = msg_cb->currentData().toUInt();
+  auto msg_mismatched = calcBits(bus_combo->currentText().toUInt(), selected_address, byte_idx_sb->value(), bit_idx_sb->value(), min_msgs->text().toInt());
   table->setRowCount(msg_mismatched.size());
   table->setColumnCount(6);
-  table->setHorizontalHeaderLabels({"address", "byte idx", "bit idx", "mismatches", "total", "perc%"});
+  table->setHorizontalHeaderLabels({"address", "byte idx", "bit idx", "mismatches", "total msgs", "% mismatched"});
   for (int i = 0; i < msg_mismatched.size(); ++i) {
     auto &m = msg_mismatched[i];
     table->setItem(i, 0, new QTableWidgetItem(QString("%1").arg(m.address, 1, 16)));
@@ -72,18 +87,25 @@ void FindSimilarBitsDlg::find() {
   search_btn->setEnabled(true);
 }
 
-QList<FindSimilarBitsDlg::mismatched_struct> FindSimilarBitsDlg::calcBits(uint8_t bus, int bit_to_find, int min_msgs_cnt) {
+QList<FindSimilarBitsDlg::mismatched_struct> FindSimilarBitsDlg::calcBits(uint8_t bus, uint32_t selected_address, int byte_idx, int bit_idx, int min_msgs_cnt) {
   QHash<uint32_t, QVector<uint32_t>> mismatches;
   QHash<uint32_t, uint32_t> msg_count;
   auto events = can->events();
+  qDebug() << bus << selected_address << byte_idx << bit_idx;
+  int bit_to_find = -1;
   for (auto e : *events) {
     if (e->which == cereal::Event::Which::CAN) {
       for (const auto &c : e->event.getCan()) {
         if (c.getSrc() == bus) {
+          const auto dat = c.getDat();
           uint32_t address = c.getAddress();
+          if (address == selected_address && dat.size() > byte_idx) {
+            bit_to_find = ((dat[byte_idx] >> (7 - bit_idx)) & 1) != 0;
+          }
           ++msg_count[address];
+          if (bit_to_find == -1) continue;
+
           auto &mismatched = mismatches[address];
-          const auto dat = c.getDat();
           if (mismatched.size() < dat.size() * 8) {
             mismatched.resize(dat.size() * 8);
           }
@@ -104,12 +126,12 @@ QList<FindSimilarBitsDlg::mismatched_struct> FindSimilarBitsDlg::calcBits(uint8_
     if (auto cnt = msg_count[it.key()]; cnt > min_msgs_cnt) {
       auto &mismatched = it.value();
       for (int i = 0; i < mismatched.size(); ++i) {
-        if (uint32_t perc = (mismatched[i] / (double)cnt) * 100; perc < 50) {
+        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});
         }
       }
     }
   }
-  std::sort(result.begin(), result.end(), [](auto &l, auto &r) { return l.perc > r.perc; });
+  std::sort(result.begin(), result.end(), [](auto &l, auto &r) { return l.perc < r.perc; });
   return result;
 }
diff --git a/tools/cabana/tools/findsimilarbits.h b/tools/cabana/tools/findsimilarbits.h
index 79db4a1c69a081..8083999909278d 100644
--- a/tools/cabana/tools/findsimilarbits.h
+++ b/tools/cabana/tools/findsimilarbits.h
@@ -3,6 +3,7 @@
 #include <QComboBox>
 #include <QDialog>
 #include <QLineEdit>
+#include <QSpinBox>
 #include <QTableWidget>
 
 class FindSimilarBitsDlg : public QDialog {
@@ -11,13 +12,15 @@ class FindSimilarBitsDlg : public QDialog {
 
 private:
   struct mismatched_struct {
-    uint32_t address, byte_idx, bit_idx, mismatches, total, perc;
+    uint32_t address, byte_idx, bit_idx, mismatches, total;
+    float perc;
   };
-  QList<mismatched_struct> calcBits(uint8_t bus, int bit_to_find, int min_msgs_cnt);
+  QList<mismatched_struct> calcBits(uint8_t bus, uint32_t selected_address, int byte_idx, int bit_idx, int min_msgs_cnt);
   void find();
 
   QTableWidget *table;
-  QComboBox *bus_combo, *bit_combo;
+  QComboBox *bus_combo, *msg_cb;
+  QSpinBox *byte_idx_sb, *bit_idx_sb;
   QPushButton *search_btn;
   QLineEdit *min_msgs;
 };

dynamic get `bit_to_find` from selected message bit:

>  if (address == selected_address && dat.size() > byte_idx) {
            bit_to_find = ((dat[byte_idx] >> (7 - bit_idx)) & 1) != 0;
          }

![2023-01-11_17-04](https://user-images.githubusercontent.com/27770/211763712-8da1914e-9513-4550-a659-303b9db86056.png)


@sshane Is it right to do like this? any comments?