29 #if !LELY_NO_CAN && defined(__linux__) && HAVE_LINUX_CAN_H
41 #if defined(__linux__) && HAVE_LINUX_CAN_H
43 #ifdef HAVE_LINUX_CAN_ERROR_H
44 #include <linux/can/error.h>
46 #ifdef HAVE_LINUX_CAN_NETLINK_H
47 #define can_state can_state_
48 #define CAN_STATE_STOPPED CAN_STATE_STOPPED_
49 #define CAN_STATE_SLEEPING CAN_STATE_SLEEPING_
50 #include <linux/can/netlink.h>
51 #undef CAN_STATE_SLEEPING
52 #undef CAN_STATE_STOPPED
55 #ifdef HAVE_LINUX_CAN_RAW_H
56 #include <linux/can/raw.h>
63 #if !LELY_NO_CANFD && defined(CANFD_MTU)
83 static void can_fini(
struct io_handle *handle);
85 static ssize_t can_read(
struct io_handle *handle,
void *buf,
size_t nbytes);
86 static ssize_t can_write(
87 struct io_handle *handle,
const void *buf,
size_t nbytes);
90 .size =
sizeof(
struct can),
94 .write = &can_write };
96 static int can_err(
struct can *
can,
const struct can_frame *frame);
98 #if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
100 static int can_getattr(
int fd, __u32 seq, __u32 pid,
int ifi_index,
101 unsigned int *pifi_flags,
unsigned short type,
void *data,
102 unsigned short payload);
104 static int can_setattr(
int fd, __u32 seq, __u32 pid,
int ifi_index,
105 unsigned int ifi_flags,
unsigned short type,
const void *data,
106 unsigned short payload);
115 int s = socket(AF_CAN, SOCK_RAW | SOCK_CLOEXEC, CAN_RAW);
121 #if !LELY_NO_CANFD && defined(CANFD_MTU)
123 #ifdef HAVE_CAN_RAW_FD_FRAMES
126 if (!setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &(
int){ 1 },
135 #ifdef HAVE_LINUX_CAN_RAW_H
137 if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
138 &(can_err_mask_t){ CAN_ERR_MASK },
139 sizeof(can_err_mask_t)) == -1) {
142 goto error_setsockopt;
146 unsigned int ifindex = if_nametoindex(path);
149 goto error_if_nametoindex;
152 struct sockaddr_can addr = { .can_family = AF_CAN,
153 .can_ifindex = ifindex };
155 if (bind(s, (
struct sockaddr *)&addr,
sizeof(addr)) == -1) {
160 #ifdef HAVE_SYS_IOCTL_H
161 #if !LELY_NO_CANFD && defined(CANFD_MTU)
164 if_indextoname(ifindex, ifr.ifr_name);
165 if (ioctl(s, SIOCGIFMTU, &ifr) == -1) {
169 canfd = ifr.ifr_mtu == CANFD_MTU;
175 if_indextoname(ifindex, ifr.ifr_name);
176 if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
180 ifflags = ifr.ifr_flags;
186 goto error_alloc_handle;
190 #if !LELY_NO_CANFD && defined(CANFD_MTU)
191 ((
struct can *)handle)->canfd = canfd;
196 ((
struct can *)handle)->error = 0;
201 #ifdef HAVE_SYS_IOCTL_H
205 error_if_nametoindex:
206 #ifdef HAVE_LINUX_CAN_RAW_H
227 if (handle->
vtab != &can_vtab) {
233 #if !LELY_NO_CANFD && defined(CANFD_MTU)
234 if (((
struct can *)handle)->canfd) {
235 struct canfd_frame frame = { .can_id = 0 };
236 ssize_t nbytes = can_read(handle, &frame,
sizeof(frame));
240 if (nbytes == CANFD_MTU) {
241 if (frame.can_id & CAN_ERR_FLAG)
242 return can_err(
can, (
struct can_frame *)&frame);
246 }
else if (nbytes == CAN_MTU) {
247 if (frame.can_id & CAN_ERR_FLAG)
248 return can_err(
can, (
struct can_frame *)&frame);
259 struct can_frame frame = { .can_id = 0 };
260 ssize_t nbytes = can_read(handle, &frame,
sizeof(frame));
264 if (nbytes == CAN_MTU) {
265 if (frame.can_id & CAN_ERR_FLAG)
285 if (handle->
vtab != &can_vtab) {
290 #if !LELY_NO_CANFD && defined(CANFD_MTU)
291 if (msg->
flags & CAN_FLAG_EDL) {
292 if (!((
struct can *)handle)->canfd) {
297 struct canfd_frame frame;
300 ssize_t nbytes = can_write(handle, &frame,
sizeof(frame));
304 return nbytes == CANFD_MTU;
307 struct can_frame frame;
310 ssize_t nbytes = can_write(handle, &frame,
sizeof(frame));
314 return nbytes == CAN_MTU;
319 #if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
329 if (handle->
vtab != &can_vtab) {
361 if (handle->
vtab != &can_vtab) {
395 if (handle->
vtab != &can_vtab) {
401 #if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
411 &attr,
sizeof(attr)) < (
int)
sizeof(attr)) {
420 case CAN_STATE_ERROR_ACTIVE:
443 if (handle->
vtab != &can_vtab) {
449 *perror = ((
struct can *)handle)->error;
450 ((
struct can *)handle)->error = 0;
455 #if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
465 if (handle->
vtab != &can_vtab) {
475 struct can_berr_counter attr = { 0 };
478 IFLA_CAN_BERR_COUNTER, &attr,
sizeof(attr))
479 < (
int)
sizeof(attr)) {
505 if (handle->
vtab != &can_vtab) {
515 struct can_bittiming attr = { 0 };
518 IFLA_CAN_BITTIMING, &attr,
sizeof(attr))
519 < (
int)
sizeof(attr)) {
530 *pbitrate = attr.bitrate;
546 if (handle->
vtab != &can_vtab) {
568 struct can_bittiming attr = { .bitrate = bitrate };
571 IFLA_CAN_BITTIMING, &attr,
sizeof(attr)) == -1) {
596 if (handle->
vtab != &can_vtab) {
609 &attr,
sizeof(attr)) < (
int)
sizeof(attr)) {
633 if (handle->
vtab != &can_vtab) {
646 &attr,
sizeof(attr)) == -1) {
669 can_flags(
struct io_handle *handle,
int flags)
673 int arg = fcntl(handle->
fd, F_GETFL, 0);
680 if (fcntl(handle->
fd, F_SETFL, arg | O_NONBLOCK) == -1) {
685 if (fcntl(handle->
fd, F_SETFL, arg & ~O_NONBLOCK) == -1) {
693 if (setsockopt(handle->
fd, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
694 (
const char *)&optval,
sizeof(optval)) == -1) {
697 goto error_setsockopt;
703 fcntl(handle->
fd, F_SETFL, arg);
710 can_read(
struct io_handle *handle,
void *buf,
size_t nbytes)
718 result = read(handle->
fd, buf, nbytes);
719 }
while (result == -1 && errno == EINTR);
724 can_write(
struct io_handle *handle,
const void *buf,
size_t nbytes)
732 result = write(handle->
fd, buf, nbytes);
733 }
while (result == -1 && errno == EINTR);
742 assert(frame->can_id & CAN_ERR_FLAG);
744 #ifdef HAVE_LINUX_CAN_ERROR_H
745 if (frame->can_dlc != CAN_ERR_DLC)
752 #ifdef HAVE_LINUX_CAN_ERROR_H
753 if (frame->can_id & CAN_ERR_RESTARTED)
756 if (frame->can_id & CAN_ERR_CRTL) {
757 #ifdef CAN_ERR_CRTL_ACTIVE
758 if (frame->data[1] & CAN_ERR_CRTL_ACTIVE)
762 if (frame->data[1] & (CAN_ERR_CRTL_RX_PASSIVE
763 | CAN_ERR_CRTL_TX_PASSIVE))
768 if (frame->can_id & CAN_ERR_PROT) {
769 if (frame->data[2] & CAN_ERR_PROT_BIT)
771 if (frame->data[2] & CAN_ERR_PROT_FORM)
773 if (frame->data[2] & CAN_ERR_PROT_STUFF)
775 if (frame->data[3] & CAN_ERR_PROT_LOC_CRC_SEQ)
779 if (frame->can_id & CAN_ERR_ACK)
782 if (frame->can_id & CAN_ERR_BUSOFF)
798 #if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
801 can_getattr(
int fd, __u32 seq, __u32 pid,
int ifi_index,
802 unsigned int *pifi_flags,
unsigned short type,
void *data,
803 unsigned short payload)
805 assert(data || !payload);
810 IFLA_LINKINFO, buf,
sizeof(buf));
815 io_rta_find((
struct rtattr *)buf, len, IFLA_INFO_DATA);
817 rta =
io_rta_find(RTA_DATA(rta), RTA_PAYLOAD(rta), type);
823 len = RTA_PAYLOAD(rta);
825 memcpy(data, RTA_DATA(rta),
MIN(payload, len));
830 can_setattr(
int fd, __u32 seq, __u32 pid,
int ifi_index,
unsigned int ifi_flags,
831 unsigned short type,
const void *data,
unsigned short payload)
833 assert(data || !payload);
838 const char kind[] =
"can";
839 struct rtattr *info_kind = (
struct rtattr *)buf;
840 *info_kind = (
struct rtattr){ .rta_len = RTA_LENGTH(
sizeof(kind)),
841 .rta_type = IFLA_INFO_KIND };
842 memcpy(RTA_DATA(info_kind), kind, strlen(kind));
844 len += RTA_ALIGN(info_kind->rta_len);
846 struct rtattr *info_data =
RTA_TAIL(info_kind);
847 *info_data = (
struct rtattr){ .rta_len = RTA_LENGTH(0),
848 .rta_type = IFLA_INFO_DATA };
851 struct rtattr *rta = RTA_DATA(info_data);
852 *rta = (
struct rtattr){ .rta_len = RTA_LENGTH(payload),
854 memcpy(RTA_DATA(rta), data, payload);
856 info_data->rta_len += RTA_ALIGN(rta->rta_len);
859 len += RTA_ALIGN(info_data->rta_len);
862 IFLA_LINKINFO, buf, len);
@ CAN_ERROR_FORM
A form error.
@ CAN_ERROR_BIT
A single bit error.
@ CAN_ERROR_STUFF
A bit stuffing error.
@ CAN_ERROR_ACK
An acknowledgment error.
@ CAN_ERROR_CRC
A CRC sequence error.
@ CAN_STATE_BUSOFF
The bus off state (TX/RX error count >= 256).
@ CAN_STATE_PASSIVE
The error passive state (TX/RX error count < 256).
@ CAN_STATE_ACTIVE
The error active state (TX/RX error count < 128).
This header file is part of the utilities library; it contains the native and platform-independent er...
struct io_handle * io_handle_alloc(const struct io_handle_vtab *vtab)
Allocates a new I/O device handle from a virtual table.
This is the internal header file of the I/O handle declarations.
This header file is part of the I/O library; it contains the Controller Area Network (CAN) declaratio...
@ IO_TYPE_CAN
A CAN device.
io_handle_t io_handle_acquire(io_handle_t handle)
Increments the reference count of an I/O device handle.
@ IO_FLAG_NONBLOCK
Perform I/O operations in non-blocking mode.
@ IO_FLAG_LOOPBACK
Receive own messages (i.e., sent by the same device).
@ IO_FLAG_NO_CLOSE
Do not close the native file descriptor when closing an I/O device.
#define IO_HANDLE_ERROR
The value of an invalid I/O device handle.
#define MIN(a, b)
Returns the minimum of a and b.
int io_can_get_error(io_handle_t handle, int *perror)
Obtains and clears the current error number of a CAN device, and stores the value (any combination of...
int io_can_set_txqlen(io_handle_t handle, size_t txqlen)
Sets the length of the transmission queue (in number of CAN frames) of a CAN device.
int io_can_stop(io_handle_t handle)
Stops transmission and reception on a CAN device.
int io_can_write(io_handle_t handle, const struct can_msg *msg)
Writes a single CAN or CAN FD frame.
int io_can_get_txqlen(io_handle_t handle, size_t *ptxqlen)
Obtains the length of the transmission queue (in number of CAN frames) of a CAN device and stores the...
io_handle_t io_open_can(const char *path)
Opens a CAN device.
int io_can_read(io_handle_t handle, struct can_msg *msg)
Reads a single CAN or CAN FD frame.
int io_can_get_ec(io_handle_t handle, uint16_t *ptxec, uint16_t *prxec)
Obtains the transmit and/or receive error count of a CAN device and stores the value in *ptxec and/or...
int io_can_start(io_handle_t handle)
Starts transmission and reception on a CAN device.
int io_can_set_bitrate(io_handle_t handle, uint32_t bitrate)
Sets the bitrate (in bit/s) of a CAN device.
int io_can_get_state(io_handle_t handle)
Obtains the state of a CAN device.
int io_can_get_bitrate(io_handle_t handle, uint32_t *pbitrate)
Obtains the bitrate (in bit/s) of a CAN device and stores the value in *pbitrate.
#define RTA_TAIL(rta)
Returns the address of the next attribute.
static struct rtattr * io_rta_find(struct rtattr *rta, unsigned short len, unsigned short type)
Finds an attribute in a list of attributes.
int io_rtnl_getattr(int fd, __u32 seq, __u32 pid, int ifi_index, unsigned int *pifi_flags, unsigned short type, void *data, unsigned short payload)
Invokes io_rtnl_getlink() and retrieves a single attribute of the specified network interface.
int io_rtnl_socket(__u32 pid, __u32 groups)
Opens an rtnetlink socket.
int io_rtnl_newlink(int fd, __u32 seq, __u32 pid, int ifi_index, unsigned int ifi_flags, struct rtattr *rta, unsigned short rtalen)
Sends an RTM_NEWLINK request and waits until the acknowledgment is received.
int io_rtnl_setattr(int fd, __u32 seq, __u32 pid, int ifi_index, unsigned int ifi_flags, unsigned short type, const void *data, unsigned short payload)
Invokes io_rtnl_newlink() to set at most one attribute of the specified network interface.
This header file is part of the CAN library; it contains the SocketCAN interface declarations.
int can_msg2canfd_frame(const struct can_msg *src, struct canfd_frame *dst)
Converts a can_msg frame to a SocketCAN CAN FD frame.
int can_frame2can_msg(const struct can_frame *src, struct can_msg *dst)
Converts a SocketCAN CAN frame to a can_msg frame.
int canfd_frame2can_msg(const struct canfd_frame *src, struct can_msg *dst)
Converts a SocketCAN CAN FD frame to a can_msg frame.
int can_msg2can_frame(const struct can_msg *src, struct can_frame *dst)
Converts a can_msg frame to a SocketCAN CAN frame.
This is the internal header file of the Windows-specific I/O declarations.
This header file is part of the C11 and POSIX compatibility library; it includes <string....
A CAN or CAN FD format frame.
uint_least8_t flags
The flags (any combination of CAN_FLAG_IDE, CAN_FLAG_RTR, CAN_FLAG_FDF, CAN_FLAG_BRS and CAN_FLAG_ESI...
struct io_handle base
The I/O device base handle.
int error
The last error (any combination of CAN_ERROR_BIT, CAN_ERROR_STUFF, CAN_ERROR_CRC, CAN_ERROR_FORM and ...
int state
The state of the CAN controller (one of CAN_STATE_ACTIVE, CAN_STATE_PASSIVE or CAN_STATE_BUSOFF).
unsigned int ifflags
The active flag word of the device.
unsigned int ifindex
The interface index.
The virtual table of an I/O device handle.
int type
The type of the device (one of IO_TYPE_CAN, IO_TYPE_FILE, IO_TYPE_PIPE, IO_TYPE_SERIAL or IO_TYPE_SOC...
int fd
The native file descriptor.
int flags
The I/O device flags (any combination of IO_FLAG_NO_CLOSE and IO_FLAG_NONBLOCK).
const struct io_handle_vtab * vtab
A pointer to the virtual table.