1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef SOCKETCANBACKEND_H
5#define SOCKETCANBACKEND_H
6
7#include <QtSerialBus/qcanbusframe.h>
8#include <QtSerialBus/qcanbusdevice.h>
9#include <QtSerialBus/qcanbusdeviceinfo.h>
10
11#include <QtCore/qsocketnotifier.h>
12#include <QtCore/qstring.h>
13#include <QtCore/qvariant.h>
14
15// The order of the following includes is mandatory, because some
16// distributions use sa_family_t in can.h without including socket.h
17#include <sys/socket.h>
18#include <sys/uio.h>
19#include <linux/can.h>
20#include <sys/time.h>
21
22#include <memory>
23
24#ifndef CANFD_MTU
25// CAN FD support was added by Linux kernel 3.6
26// For prior kernels we redefine the missing defines here
27// they are taken from linux/can/raw.h & linux/can.h
28
29enum {
30 CAN_RAW_FD_FRAMES = 5
31};
32
33#define CAN_MAX_DLEN 8
34#define CANFD_MAX_DLEN 64
35struct canfd_frame {
36 canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
37 __u8 len; /* frame payload length in byte */
38 __u8 flags; /* additional flags for CAN FD */
39 __u8 __res0; /* reserved / padding */
40 __u8 __res1; /* reserved / padding */
41 __u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8)));
42};
43#define CAN_MTU (sizeof(struct can_frame))
44#define CANFD_MTU (sizeof(struct canfd_frame))
45
46#endif
47
48QT_BEGIN_NAMESPACE
49
50class LibSocketCan;
51
52class SocketCanBackend : public QCanBusDevice
53{
54 Q_OBJECT
55public:
56 explicit SocketCanBackend(const QString &name);
57 ~SocketCanBackend();
58
59 bool open() override;
60 void close() override;
61
62 void setConfigurationParameter(ConfigurationKey key, const QVariant &value) override;
63
64 bool writeFrame(const QCanBusFrame &newData) override;
65
66 QString interpretErrorFrame(const QCanBusFrame &errorFrame) override;
67
68 static QCanBusDeviceInfo socketCanDeviceInfo(const QString &deviceName);
69 static QList<QCanBusDeviceInfo> interfaces();
70
71 void resetController() override;
72 bool hasBusStatus() const override;
73 CanBusStatus busStatus() override;
74 QCanBusDeviceInfo deviceInfo() const override;
75
76private Q_SLOTS:
77 void readSocket();
78
79private:
80 void resetConfigurations();
81 bool connectSocket();
82 bool applyConfigurationParameter(ConfigurationKey key, const QVariant &value);
83
84 int protocol = CAN_RAW;
85 canfd_frame m_frame;
86 sockaddr_can m_address;
87 msghdr m_msg;
88 iovec m_iov;
89 sockaddr_can m_addr;
90 char m_ctrlmsg[CMSG_SPACE(sizeof(timeval)) + CMSG_SPACE(sizeof(__u32))];
91
92 qint64 canSocket = -1;
93 QSocketNotifier *notifier = nullptr;
94 std::unique_ptr<LibSocketCan> libSocketCan;
95 QString canSocketName;
96 bool canFdOptionEnabled = false;
97};
98
99QT_END_NAMESPACE
100
101#endif // SOCKETCANBACKEND_H
102

source code of qtserialbus/src/plugins/canbus/socketcan/socketcanbackend.h