Cabana : Upstream Removed These

Reference upstream commit 3478ac13387ccfcc3c04c197f8ac4d43c4325c24
This commit is contained in:
firestarsdog
2026-04-15 20:36:37 -04:00
parent 4985ab8975
commit 6cb6bb904c
3 changed files with 71 additions and 46 deletions
+4 -6
View File
@@ -57,13 +57,11 @@ base_frameworks = qt_env['FRAMEWORKS']
base_libs = [common, messaging, cereal, visionipc, 'm', 'ssl', 'crypto', 'pthread'] + qt_env["LIBS"]
if arch == "Darwin":
base_frameworks.append('OpenCL')
base_frameworks.append('QtCharts')
base_frameworks.append('QtSerialBus')
base_frameworks.append('OpenCL')
base_frameworks.append('QtCharts')
else:
base_libs.append('OpenCL')
base_libs.append('Qt5Charts')
base_libs.append('Qt5SerialBus')
base_libs.append('OpenCL')
base_libs.append('Qt5Charts')
qt_libs = base_libs
+64 -32
View File
@@ -1,6 +1,14 @@
#include "tools/cabana/streams/socketcanstream.h"
#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>
#include <QDebug>
#include <QDir>
#include <QFormLayout>
#include <QHBoxLayout>
#include <QMessageBox>
@@ -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;
@@ -18,50 +26,69 @@ 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", 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";
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.toStdString().c_str(), IFNAMSIZ - 1);
if (ioctl(sock_fd, SIOCGIFINDEX, &ifr) < 0) {
qDebug() << "Failed to get interface index for" << config.device;
::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;
}
struct timeval tv = {.tv_sec = 0, .tv_usec = 100000};
setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
return true;
}
void SocketCanStream::streamThread() {
struct canfd_frame frame;
while (!QThread::currentThread()->isInterruptionRequested()) {
QThread::msleep(1);
auto frames = device->readAllFrames();
if (frames.size() == 0) continue;
ssize_t nbytes = read(sock_fd, &frame, sizeof(frame));
if (nbytes <= 0) continue;
uint8_t len = (nbytes == CAN_MTU) ? frame.len : frame.len;
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));
}
@@ -87,20 +114,25 @@ OpenSocketCanWidget::OpenSocketCanWidget(QWidget *parent) : AbstractOpenStreamWi
main_layout->addStretch(1);
QObject::connect(refresh, &QPushButton::clicked, this, &OpenSocketCanWidget::refreshDevices);
QObject::connect(device_edit, &QComboBox::currentTextChanged, this, [=]{ config.device = device_edit->currentText(); });
QObject::connect(device_edit, &QComboBox::currentTextChanged, this, [this] { config.device = device_edit->currentText(); });
// Populate devices
refreshDevices();
}
void OpenSocketCanWidget::refreshDevices() {
device_edit->clear();
for (auto device : QCanBus::instance()->availableDevices(QStringLiteral("socketcan"))) {
device_edit->addItem(device.name());
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);
+3 -8
View File
@@ -1,23 +1,18 @@
#pragma once
#include <memory>
#include <QtSerialBus/QCanBus>
#include <QtSerialBus/QCanBusDevice>
#include <QtSerialBus/QCanBusDeviceInfo>
#include <QComboBox>
#include "tools/cabana/streams/livestream.h"
struct SocketCanStreamConfig {
QString device = ""; // TODO: support multiple devices/buses at once
QString device = "";
};
class SocketCanStream : public LiveStream {
Q_OBJECT
public:
SocketCanStream(QObject *parent, SocketCanStreamConfig config_ = {});
~SocketCanStream() { stop(); }
~SocketCanStream();
static bool available();
inline QString routeName() const override {
@@ -29,7 +24,7 @@ protected:
bool connect();
SocketCanStreamConfig config = {};
std::unique_ptr<QCanBusDevice> device;
int sock_fd = -1;
};
class OpenSocketCanWidget : public AbstractOpenStreamWidget {