cabana darwin

This commit is contained in:
firestar5683
2026-04-15 22:44:30 -05:00
parent 34d8f95a11
commit 9c9f88a1e2
3 changed files with 79 additions and 0 deletions
+2
View File
@@ -12,6 +12,7 @@ if arch == "Darwin":
qt_env['QTDIR'] = f"{brew_prefix}/opt/qt@5"
qt_dirs = [
os.path.join(qt_env['QTDIR'], "include"),
os.path.join(qt_env['QTDIR'], "include", "QtSerialBus"),
]
qt_dirs += [f"{qt_env['QTDIR']}/include/Qt{m}" for m in qt_modules]
qt_env["LINKFLAGS"] += ["-F" + os.path.join(qt_env['QTDIR'], "lib")]
@@ -59,6 +60,7 @@ base_libs = [common, messaging, cereal, visionipc, 'm', 'ssl', 'crypto', 'pthrea
if arch == "Darwin":
base_frameworks.append('OpenCL')
base_frameworks.append('QtCharts')
base_frameworks.append('QtSerialBus')
else:
base_libs.append('OpenCL')
base_libs.append('Qt5Charts')
+66
View File
@@ -1,14 +1,20 @@
#include "tools/cabana/streams/socketcanstream.h"
#if defined(__linux__)
#include <cstring>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>
#endif
#include <QDebug>
#if defined(__linux__)
#include <QDir>
#include <QFile>
#endif
#include <QFormLayout>
#include <QHBoxLayout>
#include <QMessageBox>
@@ -17,7 +23,11 @@
SocketCanStream::SocketCanStream(QObject *parent, SocketCanStreamConfig config_) : config(config_), LiveStream(parent) {
if (!available()) {
#if defined(__linux__)
throw std::runtime_error("SocketCAN not available");
#else
throw std::runtime_error("SocketCAN plugin not available");
#endif
}
qDebug() << "Connecting to SocketCAN device" << config.device;
@@ -28,20 +38,27 @@ SocketCanStream::SocketCanStream(QObject *parent, SocketCanStreamConfig config_)
SocketCanStream::~SocketCanStream() {
stop();
#if defined(__linux__)
if (sock_fd >= 0) {
::close(sock_fd);
sock_fd = -1;
}
#endif
}
bool SocketCanStream::available() {
#if defined(__linux__)
int fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (fd < 0) return false;
::close(fd);
return true;
#else
return QCanBus::instance()->plugins().contains("socketcan");
#endif
}
bool SocketCanStream::connect() {
#if defined(__linux__)
sock_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (sock_fd < 0) {
qDebug() << "Failed to create CAN socket";
@@ -74,9 +91,28 @@ bool SocketCanStream::connect() {
setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
return true;
#else
// Connecting might generate warnings about missing socketcan/libsocketcan helpers.
// Cabana only needs the basic SocketCAN plugin path.
QString error_string;
device.reset(QCanBus::instance()->createDevice("socketcan", config.device, &error_string));
if (!device) {
qDebug() << "Failed to create SocketCAN device" << error_string;
return false;
}
device->setConfigurationParameter(QCanBusDevice::CanFdKey, true);
if (!device->connectDevice()) {
qDebug() << "Failed to connect to device";
return false;
}
return true;
#endif
}
void SocketCanStream::streamThread() {
#if defined(__linux__)
struct canfd_frame frame;
while (!QThread::currentThread()->isInterruptionRequested()) {
ssize_t nbytes = read(sock_fd, &frame, sizeof(frame));
@@ -92,6 +128,30 @@ void SocketCanStream::streamThread() {
handleEvent(capnp::messageToFlatArray(msg));
}
#else
while (!QThread::currentThread()->isInterruptionRequested()) {
QThread::msleep(1);
auto frames = device->readAllFrames();
if (frames.empty()) continue;
MessageBuilder msg;
auto evt = msg.initEvent();
auto can_data = evt.initCan(frames.size());
for (uint i = 0; i < frames.size(); ++i) {
if (!frames[i].isValid()) continue;
can_data[i].setAddress(frames[i].frameId());
can_data[i].setSrc(0);
auto payload = frames[i].payload();
can_data[i].setDat(kj::arrayPtr(reinterpret_cast<uint8_t *>(payload.data()), payload.size()));
}
handleEvent(capnp::messageToFlatArray(msg));
}
#endif
}
OpenSocketCanWidget::OpenSocketCanWidget(QWidget *parent) : AbstractOpenStreamWidget(parent) {
@@ -121,6 +181,7 @@ OpenSocketCanWidget::OpenSocketCanWidget(QWidget *parent) : AbstractOpenStreamWi
void OpenSocketCanWidget::refreshDevices() {
device_edit->clear();
#if defined(__linux__)
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");
@@ -131,6 +192,11 @@ void OpenSocketCanWidget::refreshDevices() {
}
}
}
#else
for (const auto &device_info : QCanBus::instance()->availableDevices(QStringLiteral("socketcan"))) {
device_edit->addItem(device_info.name());
}
#endif
}
AbstractStream *OpenSocketCanWidget::open() {
+11
View File
@@ -1,6 +1,13 @@
#pragma once
#include <memory>
#include <QComboBox>
#if !defined(__linux__)
#include <QtSerialBus/QCanBus>
#include <QtSerialBus/QCanBusDevice>
#include <QtSerialBus/QCanBusDeviceInfo>
#endif
#include "tools/cabana/streams/livestream.h"
@@ -24,7 +31,11 @@ protected:
bool connect();
SocketCanStreamConfig config = {};
#if defined(__linux__)
int sock_fd = -1;
#else
std::unique_ptr<QCanBusDevice> device;
#endif
};
class OpenSocketCanWidget : public AbstractOpenStreamWidget {