26 #if !defined(LELY_NO_CAN) && defined(__linux__) && defined(HAVE_LINUX_CAN_H) 38 #if defined(__linux__) && defined(HAVE_LINUX_CAN_H) 40 #ifdef HAVE_LINUX_CAN_ERROR_H 41 #include <linux/can/error.h> 43 #ifdef HAVE_LINUX_CAN_NETLINK_H 44 #define can_state can_state_ 45 #define CAN_STATE_STOPPED CAN_STATE_STOPPED_ 46 #define CAN_STATE_SLEEPING CAN_STATE_SLEEPING_ 47 #include <linux/can/netlink.h> 48 #undef CAN_STATE_SLEEPING 49 #undef CAN_STATE_STOPPED 52 #ifdef HAVE_LINUX_CAN_RAW_H 53 #include <linux/can/raw.h> 60 #if !defined(LELY_NO_CANFD) && defined(CANFD_MTU) 80 static void can_fini(
struct io_handle *handle);
82 static ssize_t can_read(
struct io_handle *handle,
void *buf,
size_t nbytes);
83 static ssize_t can_write(
84 struct io_handle *handle,
const void *buf,
size_t nbytes);
87 .size =
sizeof(
struct can),
91 .write = &can_write };
93 static int can_err(
struct can *
can,
const struct can_frame *frame);
95 #if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) 97 static int can_getattr(
int fd, __u32 seq, __u32 pid,
int ifi_index,
98 unsigned int *pifi_flags,
unsigned short type,
void *data,
99 unsigned short payload);
101 static int can_setattr(
int fd, __u32 seq, __u32 pid,
int ifi_index,
102 unsigned int ifi_flags,
unsigned short type,
const void *data,
103 unsigned short payload);
112 int s = socket(AF_CAN, SOCK_RAW | SOCK_CLOEXEC, CAN_RAW);
118 #if !defined(LELY_NO_CANFD) && defined(CANFD_MTU) 120 #ifdef HAVE_CAN_RAW_FD_FRAMES 123 if (!setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &(
int){ 1 },
132 #ifdef HAVE_LINUX_CAN_RAW_H 134 if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
135 &(can_err_mask_t){ CAN_ERR_MASK },
136 sizeof(can_err_mask_t)) == -1) {
139 goto error_setsockopt;
143 unsigned int ifindex = if_nametoindex(path);
146 goto error_if_nametoindex;
149 struct sockaddr_can addr = { .can_family = AF_CAN,
150 .can_ifindex = ifindex };
152 if (bind(s, (
struct sockaddr *)&addr,
sizeof(addr)) == -1) {
157 #ifdef HAVE_SYS_IOCTL_H 158 #if !defined(LELY_NO_CANFD) && defined(CANFD_MTU) 161 if_indextoname(ifindex, ifr.ifr_name);
162 if (ioctl(s, SIOCGIFMTU, &ifr) == -1) {
166 canfd = ifr.ifr_mtu == CANFD_MTU;
172 if_indextoname(ifindex, ifr.ifr_name);
173 if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
177 ifflags = ifr.ifr_flags;
183 goto error_alloc_handle;
187 #if !defined(LELY_NO_CANFD) && defined(CANFD_MTU) 188 ((
struct can *)handle)->canfd = canfd;
193 ((
struct can *)handle)->error = 0;
198 #ifdef HAVE_SYS_IOCTL_H 202 error_if_nametoindex:
203 #ifdef HAVE_LINUX_CAN_RAW_H 224 if (handle->
vtab != &can_vtab) {
228 struct can *
can = (
struct can *)handle;
230 #if !defined(LELY_NO_CANFD) && defined(CANFD_MTU) 231 if (((
struct can *)handle)->canfd) {
232 struct canfd_frame frame = { .can_id = 0 };
233 ssize_t nbytes = can_read(handle, &frame,
sizeof(frame));
237 if (nbytes == CANFD_MTU) {
238 if (frame.can_id & CAN_ERR_FLAG)
239 return can_err(can, (
struct can_frame *)&frame);
243 }
else if (nbytes == CAN_MTU) {
244 if (frame.can_id & CAN_ERR_FLAG)
245 return can_err(can, (
struct can_frame *)&frame);
256 struct can_frame frame = { .can_id = 0 };
257 ssize_t nbytes = can_read(handle, &frame,
sizeof(frame));
261 if (nbytes == CAN_MTU) {
262 if (frame.can_id & CAN_ERR_FLAG)
282 if (handle->
vtab != &can_vtab) {
287 #if !defined(LELY_NO_CANFD) && defined(CANFD_MTU) 288 if (msg->
flags & CAN_FLAG_EDL) {
289 if (!((
struct can *)handle)->canfd) {
294 struct canfd_frame frame;
297 ssize_t nbytes = can_write(handle, &frame,
sizeof(frame));
301 return nbytes == CANFD_MTU;
304 struct can_frame frame;
307 ssize_t nbytes = can_write(handle, &frame,
sizeof(frame));
311 return nbytes == CAN_MTU;
314 #endif // !LELY_NO_CAN 316 #if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) 326 if (handle->
vtab != &can_vtab) {
330 struct can *
can = (
struct can *)handle;
358 if (handle->
vtab != &can_vtab) {
362 struct can *
can = (
struct can *)handle;
382 #endif // HAVE_LINUX_CAN_NETLINK_H && HAVE_LINUX_RTNETLINK_H 392 if (handle->
vtab != &can_vtab) {
396 struct can *
can = (
struct can *)handle;
398 #if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) 407 if (can_getattr(fd, 0, 0, can->
ifindex, &can->
ifflags, IFLA_CAN_STATE,
408 &attr,
sizeof(attr)) < (
int)
sizeof(attr)) {
417 case CAN_STATE_ERROR_ACTIVE:
440 if (handle->
vtab != &can_vtab) {
446 *perror = ((
struct can *)handle)->error;
447 ((
struct can *)handle)->error = 0;
452 #if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) 462 if (handle->
vtab != &can_vtab) {
466 struct can *
can = (
struct can *)handle;
472 struct can_berr_counter attr = { 0 };
475 IFLA_CAN_BERR_COUNTER, &attr,
sizeof(attr))
476 < (
int)
sizeof(attr)) {
502 if (handle->
vtab != &can_vtab) {
506 struct can *
can = (
struct can *)handle;
512 struct can_bittiming attr = { 0 };
515 IFLA_CAN_BITTIMING, &attr,
sizeof(attr))
516 < (
int)
sizeof(attr)) {
527 *pbitrate = attr.bitrate;
543 if (handle->
vtab != &can_vtab) {
547 struct can *
can = (
struct can *)handle;
559 can->
ifflags & ~IFF_UP, NULL, 0) == -1) {
565 struct can_bittiming attr = { .bitrate = bitrate };
568 IFLA_CAN_BITTIMING, &attr,
sizeof(attr)) == -1) {
593 if (handle->
vtab != &can_vtab) {
597 struct can *
can = (
struct can *)handle;
606 &attr,
sizeof(attr)) < (
int)
sizeof(attr)) {
630 if (handle->
vtab != &can_vtab) {
634 struct can *
can = (
struct can *)handle;
643 &attr,
sizeof(attr)) == -1) {
654 #endif // HAVE_LINUX_CAN_NETLINK_H && HAVE_LINUX_RTNETLINK_H 666 can_flags(
struct io_handle *handle,
int flags)
670 int arg = fcntl(handle->
fd, F_GETFL, 0);
677 if (fcntl(handle->
fd, F_SETFL, arg | O_NONBLOCK) == -1) {
681 }
else if (!(flags & IO_FLAG_NONBLOCK) && (arg & O_NONBLOCK)) {
682 if (fcntl(handle->
fd, F_SETFL, arg & ~O_NONBLOCK) == -1) {
690 if (setsockopt(handle->
fd, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
691 (
const char *)&optval,
sizeof(optval)) == -1) {
694 goto error_setsockopt;
700 fcntl(handle->
fd, F_SETFL, arg);
707 can_read(
struct io_handle *handle,
void *buf,
size_t nbytes)
715 result = read(handle->
fd, buf, nbytes);
716 }
while (result == -1 && errno == EINTR);
721 can_write(
struct io_handle *handle,
const void *buf,
size_t nbytes)
729 result = write(handle->
fd, buf, nbytes);
730 }
while (result == -1 && errno == EINTR);
739 assert(frame->can_id & CAN_ERR_FLAG);
741 #ifdef HAVE_LINUX_CAN_ERROR_H 742 if (frame->can_dlc != CAN_ERR_DLC)
749 #ifdef HAVE_LINUX_CAN_ERROR_H 750 if (frame->can_id & CAN_ERR_RESTARTED)
753 if (frame->can_id & CAN_ERR_CRTL) {
754 #ifdef CAN_ERR_CRTL_ACTIVE 755 if (frame->data[1] & CAN_ERR_CRTL_ACTIVE)
759 if (frame->data[1] & (CAN_ERR_CRTL_RX_PASSIVE
760 | CAN_ERR_CRTL_TX_PASSIVE))
765 if (frame->can_id & CAN_ERR_PROT) {
766 if (frame->data[2] & CAN_ERR_PROT_BIT)
768 if (frame->data[2] & CAN_ERR_PROT_FORM)
770 if (frame->data[2] & CAN_ERR_PROT_STUFF)
772 if (frame->data[3] & CAN_ERR_PROT_LOC_CRC_SEQ)
776 if (frame->can_id & CAN_ERR_ACK)
779 if (frame->can_id & CAN_ERR_BUSOFF)
794 #if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H) 797 can_getattr(
int fd, __u32 seq, __u32 pid,
int ifi_index,
798 unsigned int *pifi_flags,
unsigned short type,
void *data,
799 unsigned short payload)
801 assert(data || !payload);
806 IFLA_LINKINFO, buf,
sizeof(buf));
811 io_rta_find((
struct rtattr *)buf, len, IFLA_INFO_DATA);
813 rta =
io_rta_find(RTA_DATA(rta), RTA_PAYLOAD(rta), type);
819 len = RTA_PAYLOAD(rta);
821 memcpy(data, RTA_DATA(rta),
MIN(payload, len));
826 can_setattr(
int fd, __u32 seq, __u32 pid,
int ifi_index,
unsigned int ifi_flags,
827 unsigned short type,
const void *data,
unsigned short payload)
829 assert(data || !payload);
834 const char *kind =
"can";
835 struct rtattr *info_kind = (
struct rtattr *)buf;
836 *info_kind = (
struct rtattr){ .rta_len = RTA_LENGTH(strlen(kind)),
837 .rta_type = IFLA_INFO_KIND };
838 memcpy(RTA_DATA(info_kind), kind, strlen(kind));
840 len += RTA_ALIGN(info_kind->rta_len);
842 struct rtattr *info_data =
RTA_TAIL(info_kind);
843 *info_data = (
struct rtattr){ .rta_len = RTA_LENGTH(0),
844 .rta_type = IFLA_INFO_DATA };
847 struct rtattr *rta = RTA_DATA(info_data);
848 *rta = (
struct rtattr){ .rta_len = RTA_LENGTH(payload),
850 memcpy(RTA_DATA(rta), data, payload);
852 info_data->rta_len += RTA_ALIGN(rta->rta_len);
855 len += RTA_ALIGN(info_data->rta_len);
858 IFLA_LINKINFO, buf, len);
861 #endif // HAVE_LINUX_CAN_NETLINK_H && HAVE_LINUX_RTNETLINK_H 863 #endif // __linux__ && HAVE_LINUX_CAN_H int can_msg2canfd_frame(const struct can_msg *src, struct canfd_frame *dst)
Converts a can_msg frame to a SocketCAN CAN FD frame.
A CAN or CAN FD format frame.
unsigned int ifindex
The interface index.
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 C11 and POSIX compatibility library; it includes <string.h> and defines any missing functionality.
int io_can_get_state(io_handle_t handle)
Obtains the state of a CAN device.
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.
unsigned int ifflags
The active flag word of the device.
Receive own messages (i.e., sent by the same device).
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_socket(__u32 pid, __u32 groups)
Opens an rtnetlink socket.
int io_can_stop(io_handle_t handle)
Stops transmission and reception on a CAN device.
struct io_handle base
The I/O device base handle.
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...
#define MIN(a, b)
Returns the minimum of a and b.
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 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 error
The last error (any combination of CAN_ERROR_BIT, CAN_ERROR_STUFF, CAN_ERROR_CRC, CAN_ERROR_FORM and ...
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...
This is the internal header file of the I/O handle declarations.
io_handle_t io_handle_acquire(io_handle_t handle)
Increments the reference count of an I/O device handle.
Perform I/O operations in non-blocking mode.
int io_can_set_bitrate(io_handle_t handle, uint32_t bitrate)
Sets the bitrate (in bit/s) of a CAN device.
This header file is part of the utilities library; it contains the native and platform-independent er...
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.
const struct io_handle_vtab * vtab
A pointer to the virtual table.
The virtual table of an I/O device handle.
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 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...
This is the internal header file of the I/O library.
int flags
The I/O device flags (any combination of IO_FLAG_NO_CLOSE and IO_FLAG_NONBLOCK).
This header file is part of the I/O library; it contains the Controller Area Network (CAN) declaratio...
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. ...
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...
int state
The state of the CAN controller (one of CAN_STATE_ACTIVE, CAN_STATE_PASSIVE or CAN_STATE_BUSOFF).
int io_can_start(io_handle_t handle)
Starts transmission and reception on a CAN device.
#define RTA_TAIL(rta)
Returns the address of the next attribute.
int can_msg2can_frame(const struct can_msg *src, struct can_frame *dst)
Converts a can_msg frame to a SocketCAN CAN frame.
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 fd
The native file descriptor.
int io_can_read(io_handle_t handle, struct can_msg *msg)
Reads a single CAN or CAN FD frame.
struct io_handle * io_handle_alloc(const struct io_handle_vtab *vtab)
Allocates a new I/O device handle from a virtual table.
This header file is part of the CAN library; it contains the SocketCAN interface declarations.
int io_can_write(io_handle_t handle, const struct can_msg *msg)
Writes a single CAN or 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.
The error passive state (TX/RX error count < 256).
The bus off state (TX/RX error count >= 256).
io_handle_t io_open_can(const char *path)
Opens a CAN device.
The error active state (TX/RX error count < 128).