Add a new window that can be used to bridge two CAN buses with
selective ID forwarding.
This commit is contained in:
+4
-1
@@ -20,6 +20,7 @@ QMAKE_INFO_PLIST = Info.plist.template
|
||||
ICON = icons/SavvyIcon.icns
|
||||
|
||||
SOURCES += main.cpp\
|
||||
canbridgewindow.cpp \
|
||||
connections/canserver.cpp \
|
||||
connections/lawicel_serial.cpp \
|
||||
connections/mqtt_bus.cpp \
|
||||
@@ -101,6 +102,7 @@ SOURCES += main.cpp\
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
can_structs.h \
|
||||
canbridgewindow.h \
|
||||
canframemodel.h \
|
||||
connections/canserver.h \
|
||||
connections/lawicel_serial.h \
|
||||
@@ -191,6 +193,7 @@ HEADERS += mainwindow.h \
|
||||
pcaplite.h
|
||||
|
||||
FORMS += ui/candatagrid.ui \
|
||||
ui/canbridgewindow.ui \
|
||||
ui/dbcnodeduplicateeditor.ui \
|
||||
ui/dbccomparatorwindow.ui \
|
||||
ui/dbcmessageeditor.ui \
|
||||
@@ -220,7 +223,7 @@ FORMS += ui/candatagrid.ui \
|
||||
ui/udsscanwindow.ui \
|
||||
ui/bisectwindow.ui \
|
||||
ui/signalviewerwindow.ui \
|
||||
helpwindow.ui \
|
||||
ui/helpwindow.ui \
|
||||
ui/newconnectiondialog.ui \
|
||||
ui/temporalgraphwindow.ui
|
||||
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
#include "canbridgewindow.h"
|
||||
#include "helpwindow.h"
|
||||
#include "qevent.h"
|
||||
#include "ui_canbridgewindow.h"
|
||||
#include "filterutility.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
CANBridgeWindow::CANBridgeWindow(const QVector<CANFrame> *frames, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::CANBridgeWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
modelFrames = frames;
|
||||
|
||||
side1BusNum = 0;
|
||||
side2BusNum = 0;
|
||||
|
||||
connect(ui->cbSide1, &QComboBox::currentTextChanged, this, &CANBridgeWindow::recalcSides);
|
||||
connect(ui->cbSide2, &QComboBox::currentTextChanged, this, &CANBridgeWindow::recalcSides);
|
||||
connect(MainWindow::getReference(), &MainWindow::framesUpdated, this, &CANBridgeWindow::updatedFrames);
|
||||
connect(ui->listSide1, &QListWidget::itemChanged,
|
||||
[this] (QListWidgetItem *item)
|
||||
{
|
||||
bool checked = item->checkState() == Qt::Checked ? true:false;
|
||||
int IDval = FilterUtility::getIdAsInt(item);
|
||||
qDebug() << "ID " << IDval << " set to " << checked;
|
||||
foundIDSide1[IDval] = checked;
|
||||
});
|
||||
connect(ui->listSide2, &QListWidget::itemChanged,
|
||||
[this] (QListWidgetItem *item)
|
||||
{
|
||||
bool checked = item->checkState() == Qt::Checked ? true:false;
|
||||
int IDval = FilterUtility::getIdAsInt(item);
|
||||
foundIDSide2[IDval] = checked;
|
||||
});
|
||||
}
|
||||
|
||||
CANBridgeWindow::~CANBridgeWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void CANBridgeWindow::showEvent(QShowEvent* event)
|
||||
{
|
||||
QDialog::showEvent(event);
|
||||
//stuff to do every time this form is shown.
|
||||
ui->cbSide1->clear();
|
||||
ui->cbSide2->clear();
|
||||
int numBuses = CANConManager::getInstance()->getNumBuses();
|
||||
for (int i = 0; i < numBuses; i++)
|
||||
{
|
||||
ui->cbSide1->addItem(QString::number(i));
|
||||
ui->cbSide2->addItem(QString::number(i));
|
||||
}
|
||||
}
|
||||
|
||||
bool CANBridgeWindow::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::KeyRelease) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
switch (keyEvent->key())
|
||||
{
|
||||
case Qt::Key_F1:
|
||||
HelpWindow::getRef()->showHelp("canbridge.md");
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
// standard event processing
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
}
|
||||
|
||||
void CANBridgeWindow::recalcSides()
|
||||
{
|
||||
side1BusNum = ui->cbSide1->currentText().toInt();
|
||||
side2BusNum = ui->cbSide2->currentText().toInt();
|
||||
}
|
||||
|
||||
|
||||
void CANBridgeWindow::updatedFrames(int numFrames)
|
||||
{
|
||||
bool addedSide1 = false;
|
||||
bool addedSide2 = false;
|
||||
|
||||
if (numFrames == -1) //all frames deleted. Kill the display
|
||||
{
|
||||
}
|
||||
else if (numFrames == -2) //all new set of frames. Reset
|
||||
{
|
||||
}
|
||||
else //just got some new frames. See if they are relevant.
|
||||
{
|
||||
if (numFrames > modelFrames->count()) return;
|
||||
|
||||
for (int x = modelFrames->count() - numFrames; x < modelFrames->count(); x++)
|
||||
{
|
||||
CANFrame thisFrame = modelFrames->at(x);
|
||||
int32_t id = static_cast<int32_t>(thisFrame.frameId());
|
||||
|
||||
if (thisFrame.bus == side1BusNum)
|
||||
{
|
||||
if (!foundIDSide1.contains(id))
|
||||
{
|
||||
foundIDSide1.insert(id, true);
|
||||
FilterUtility::createCheckableFilterItem(id, true, ui->listSide1);
|
||||
addedSide1 = true;
|
||||
}
|
||||
if (ui->ckEnableSide1->isChecked()) //if we're enabled to forward traffic on this bus to the other one
|
||||
{
|
||||
if (foundIDSide1[id]) //and the checkbox for this particular ID is checked
|
||||
{
|
||||
thisFrame.bus = side2BusNum;
|
||||
CANConManager::getInstance()->sendFrame(thisFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (thisFrame.bus == side2BusNum)
|
||||
{
|
||||
if (!foundIDSide2.contains(id))
|
||||
{
|
||||
foundIDSide2.insert(id, true);
|
||||
FilterUtility::createCheckableFilterItem(id, true, ui->listSide2);
|
||||
addedSide2 = true;
|
||||
}
|
||||
if (ui->ckEnableSide2->isChecked()) //if we're enabled to forward traffic on this bus to the other one
|
||||
{
|
||||
if (foundIDSide2[id]) //and the checkbox for this particular ID is checked
|
||||
{
|
||||
thisFrame.bus = side1BusNum;
|
||||
CANConManager::getInstance()->sendFrame(thisFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//default is to sort in ascending order
|
||||
if (addedSide1) ui->listSide1->sortItems();
|
||||
if (addedSide2) ui->listSide2->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef CANBRIDGEWINDOW_H
|
||||
#define CANBRIDGEWINDOW_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "connections/canconmanager.h"
|
||||
|
||||
namespace Ui {
|
||||
class CANBridgeWindow;
|
||||
}
|
||||
|
||||
class CANBridgeWindow : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CANBridgeWindow(const QVector<CANFrame> *frames, QWidget *parent = nullptr);
|
||||
~CANBridgeWindow();
|
||||
void showEvent(QShowEvent*);
|
||||
|
||||
|
||||
private slots:
|
||||
void updatedFrames(int);
|
||||
void recalcSides();
|
||||
|
||||
private:
|
||||
Ui::CANBridgeWindow *ui;
|
||||
const QVector<CANFrame> *modelFrames;
|
||||
QMap<int, bool> foundIDSide1;
|
||||
QMap<int, bool> foundIDSide2;
|
||||
int side1BusNum;
|
||||
int side2BusNum;
|
||||
|
||||
void processIncomingFrame(CANFrame *frame);
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
};
|
||||
|
||||
#endif // CANBRIDGEWINDOW_H
|
||||
@@ -0,0 +1,13 @@
|
||||
CAN Bridge Window
|
||||
=================
|
||||
|
||||

|
||||
|
||||
Using the Bridge Window
|
||||
==========================
|
||||
|
||||
The purpose of this window is simple, to allow one to forward traffic from one bus to another. Any two buses you have connected could be bridged in this way, even if they originate on different hardware adapters. By default neither side will forward to the other. You must select different buses for Side 1 and Side 2 then enable forwarding from one to the other. You can enable bi-directional forwarding. However, this can be problematic. If you are not careful you can create an infinite loop where traffic from one side gets forwarded to the other side which then forwards to the first side, and so on.
|
||||
|
||||
If you'd like to only forward some traffic then uncheck the boxes next to IDs you do not want to forward.
|
||||
|
||||
At the moment this window is in the preliminary stages and, as mentioned above, could be prone to allowing infinite loops in some circumstances.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
+15
-1
@@ -95,6 +95,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
signalViewerWindow = nullptr;
|
||||
temporalGraphWindow = nullptr;
|
||||
dbcComparatorWindow = nullptr;
|
||||
canBridgeWindow = nullptr;
|
||||
dbcHandler = DBCHandler::getReference();
|
||||
bDirty = false;
|
||||
inhibitFilterUpdate = false;
|
||||
@@ -136,6 +137,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
connect(ui->actionSignal_Viewer, &QAction::triggered, this, &MainWindow::showSignalViewer);
|
||||
connect(ui->actionSave_Continuous_Logfile, &QAction::triggered, this, &MainWindow::handleContinousLogging);
|
||||
connect(ui->actionTemporal_Graph, &QAction::triggered, this, &MainWindow::showTemporalGraphWindow);
|
||||
connect(ui->actionCAN_Bridge, &QAction::triggered, this, &MainWindow::showCANBridgeWindow);
|
||||
|
||||
//handlers fror interactions with the main can frame view table
|
||||
connect(ui->canFramesView, &QAbstractItemView::clicked, this, &MainWindow::gridClicked);
|
||||
@@ -262,8 +264,11 @@ void MainWindow::killEmAll()
|
||||
killWindow(firmwareUploaderWindow);
|
||||
killWindow(motorctrlConfigWindow);
|
||||
killWindow(signalViewerWindow);
|
||||
killWindow(connectionWindow);
|
||||
killWindow(temporalGraphWindow);
|
||||
killWindow(canBridgeWindow);
|
||||
|
||||
//trying to kill this window can cause a fault to happen. It's closed last just in case.
|
||||
killWindow(connectionWindow);
|
||||
}
|
||||
|
||||
//forcefully close the window, kill it, and salt the earth
|
||||
@@ -1442,6 +1447,15 @@ void MainWindow::showBisectWindow()
|
||||
bisectWindow->show();
|
||||
}
|
||||
|
||||
void MainWindow::showCANBridgeWindow()
|
||||
{
|
||||
if (!canBridgeWindow)
|
||||
{
|
||||
canBridgeWindow = new CANBridgeWindow(model->getListReference());
|
||||
}
|
||||
canBridgeWindow->show();
|
||||
}
|
||||
|
||||
void MainWindow::showFrameSenderWindow()
|
||||
{
|
||||
if (!frameSenderWindow)
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "signalviewerwindow.h"
|
||||
#include "re/temporalgraphwindow.h"
|
||||
#include "re/dbccomparatorwindow.h"
|
||||
#include "canbridgewindow.h"
|
||||
|
||||
class CANConnection;
|
||||
class ConnectionWindow;
|
||||
@@ -89,6 +90,7 @@ private slots:
|
||||
void showSignalViewer();
|
||||
void showTemporalGraphWindow();
|
||||
void showDBCComparisonWindow();
|
||||
void showCANBridgeWindow();
|
||||
void exitApp();
|
||||
void handleSaveDecoded();
|
||||
void handleSaveDecodedCsv();
|
||||
@@ -183,6 +185,7 @@ private:
|
||||
SignalViewerWindow *signalViewerWindow;
|
||||
TemporalGraphWindow *temporalGraphWindow;
|
||||
DBCComparatorWindow *dbcComparatorWindow;
|
||||
CANBridgeWindow *canBridgeWindow;
|
||||
|
||||
//various private storage
|
||||
QLabel lbStatusConnected;
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CANBridgeWindow</class>
|
||||
<widget class="QDialog" name="CANBridgeWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>640</width>
|
||||
<height>480</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>CAN Bridger</string>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Side 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cbSide1"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ckEnableSide1">
|
||||
<property name="text">
|
||||
<string>Enable forwarding</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>IDs to forward to side 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="listSide1"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Side 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cbSide2"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="ckEnableSide2">
|
||||
<property name="text">
|
||||
<string>Enable forwarding</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>IDs to forward to side 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="listSide2"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+10
-4
@@ -32,7 +32,6 @@
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
@@ -81,7 +80,6 @@
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>50</weight>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
@@ -138,7 +136,6 @@
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>true</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
@@ -338,6 +335,9 @@
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@@ -368,7 +368,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>21</height>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu_RE_Tools">
|
||||
@@ -399,6 +399,7 @@
|
||||
<addaction name="actionUDS_Scanner"/>
|
||||
<addaction name="actionFirmware_Update"/>
|
||||
<addaction name="actionMotorControlConfig"/>
|
||||
<addaction name="actionCAN_Bridge"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
@@ -621,6 +622,11 @@
|
||||
<string>Save Decoded Frames CSV</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCAN_Bridge">
|
||||
<property name="text">
|
||||
<string>CAN Bridge</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
|
||||
Reference in New Issue
Block a user