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;
317 #endif // !LELY_NO_CAN
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) {
385 #endif // HAVE_LINUX_CAN_NETLINK_H && HAVE_LINUX_RTNETLINK_H
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) {
657 #endif // HAVE_LINUX_CAN_NETLINK_H && HAVE_LINUX_RTNETLINK_H
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);
865 #endif // HAVE_LINUX_CAN_NETLINK_H && HAVE_LINUX_RTNETLINK_H
867 #endif // __linux__ && HAVE_LINUX_CAN_H
869 #endif // !LELY_NO_STDIO