1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the QtSerialBus module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#ifndef SOCKETCANBACKEND_H
38#define SOCKETCANBACKEND_H
39
40#include <QtSerialBus/qcanbusframe.h>
41#include <QtSerialBus/qcanbusdevice.h>
42#include <QtSerialBus/qcanbusdeviceinfo.h>
43
44#include <QtCore/qsocketnotifier.h>
45#include <QtCore/qstring.h>
46#include <QtCore/qvariant.h>
47
48// The order of the following includes is mandatory, because some
49// distributions use sa_family_t in can.h without including socket.h
50#include <sys/socket.h>
51#include <sys/uio.h>
52#include <linux/can.h>
53#include <sys/time.h>
54
55#include <memory>
56
57#ifndef CANFD_MTU
58// CAN FD support was added by Linux kernel 3.6
59// For prior kernels we redefine the missing defines here
60// they are taken from linux/can/raw.h & linux/can.h
61
62enum {
63 CAN_RAW_FD_FRAMES = 5
64};
65
66#define CAN_MAX_DLEN 8
67#define CANFD_MAX_DLEN 64
68struct canfd_frame {
69 canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
70 __u8 len; /* frame payload length in byte */
71 __u8 flags; /* additional flags for CAN FD */
72 __u8 __res0; /* reserved / padding */
73 __u8 __res1; /* reserved / padding */
74 __u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8)));
75};
76#define CAN_MTU (sizeof(struct can_frame))
77#define CANFD_MTU (sizeof(struct canfd_frame))
78
79#endif
80
81QT_BEGIN_NAMESPACE
82
83class LibSocketCan;
84
85class SocketCanBackend : public QCanBusDevice
86{
87 Q_OBJECT
88public:
89 explicit SocketCanBackend(const QString &name);
90 ~SocketCanBackend();
91
92 bool open() override;
93 void close() override;
94
95 void setConfigurationParameter(int key, const QVariant &value) override;
96
97 bool writeFrame(const QCanBusFrame &newData) override;
98
99 QString interpretErrorFrame(const QCanBusFrame &errorFrame) override;
100
101 static QList<QCanBusDeviceInfo> interfaces();
102
103private Q_SLOTS:
104 void readSocket();
105
106private:
107 void resetConfigurations();
108 bool connectSocket();
109 bool applyConfigurationParameter(int key, const QVariant &value);
110 void resetController();
111 bool hasBusStatus() const;
112 QCanBusDevice::CanBusStatus busStatus() const;
113
114 int protocol = CAN_RAW;
115 canfd_frame m_frame;
116 sockaddr_can m_address;
117 msghdr m_msg;
118 iovec m_iov;
119 sockaddr_can m_addr;
120 char m_ctrlmsg[CMSG_SPACE(sizeof(timeval)) + CMSG_SPACE(sizeof(__u32))];
121
122 qint64 canSocket = -1;
123 QSocketNotifier *notifier = nullptr;
124 std::unique_ptr<LibSocketCan> libSocketCan;
125 QString canSocketName;
126 bool canFdOptionEnabled = false;
127};
128
129QT_END_NAMESPACE
130
131#endif // SOCKETCANBACKEND_H
132

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