Lely core libraries 2.3.4
can.c
Go to the documentation of this file.
1
24#include "io.h"
25
26#if !LELY_NO_STDIO
27
28#include <lely/util/errnum.h>
29#if !LELY_NO_CAN && defined(__linux__) && HAVE_LINUX_CAN_H
30#include <lely/can/socket.h>
31#endif
32#include "handle.h"
33#include <lely/io/can.h>
34#ifdef __linux
35#include "rtnl.h"
36#endif
37
38#include <assert.h>
39#include <string.h>
40
41#if defined(__linux__) && HAVE_LINUX_CAN_H
42
43#ifdef HAVE_LINUX_CAN_ERROR_H
44#include <linux/can/error.h>
45#endif
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
53#undef can_state
54#endif
55#ifdef HAVE_LINUX_CAN_RAW_H
56#include <linux/can/raw.h>
57#endif
58
60struct can {
63#if !LELY_NO_CANFD && defined(CANFD_MTU)
65 int canfd;
66#endif
68 unsigned int ifindex;
70 unsigned int ifflags;
75 int state;
80 int error;
81};
82
83static void can_fini(struct io_handle *handle);
84static int can_flags(struct io_handle *handle, int flags);
85static ssize_t can_read(struct io_handle *handle, void *buf, size_t nbytes);
86static ssize_t can_write(
87 struct io_handle *handle, const void *buf, size_t nbytes);
88
89static const struct io_handle_vtab can_vtab = { .type = IO_TYPE_CAN,
90 .size = sizeof(struct can),
91 .fini = &can_fini,
92 .flags = &can_flags,
93 .read = &can_read,
94 .write = &can_write };
95
96static int can_err(struct can *can, const struct can_frame *frame);
97
98#if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
99
100static 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);
103
104static 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);
107
108#endif
109
111io_open_can(const char *path)
112{
113 int errsv = 0;
114
115 int s = socket(AF_CAN, SOCK_RAW | SOCK_CLOEXEC, CAN_RAW);
116 if (s == -1) {
117 errsv = errno;
118 goto error_socket;
119 }
120
121#if !LELY_NO_CANFD && defined(CANFD_MTU)
122 int canfd = 0;
123#ifdef HAVE_CAN_RAW_FD_FRAMES
124 errsv = errno;
125 // clang-format off
126 if (!setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &(int){ 1 },
127 sizeof(int)))
128 // clang-format on
129 canfd = 1;
130 else
131 errno = errsv;
132#endif
133#endif
134
135#ifdef HAVE_LINUX_CAN_RAW_H
136 // clang-format off
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) {
140 // clang-format on
141 errsv = errno;
142 goto error_setsockopt;
143 }
144#endif
145
146 unsigned int ifindex = if_nametoindex(path);
147 if (!ifindex) {
148 errsv = errno;
149 goto error_if_nametoindex;
150 }
151
152 struct sockaddr_can addr = { .can_family = AF_CAN,
153 .can_ifindex = ifindex };
154
155 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
156 errsv = errno;
157 goto error_bind;
158 }
159
160#ifdef HAVE_SYS_IOCTL_H
161#if !LELY_NO_CANFD && defined(CANFD_MTU)
162 if (canfd) {
163 struct ifreq ifr;
164 if_indextoname(ifindex, ifr.ifr_name);
165 if (ioctl(s, SIOCGIFMTU, &ifr) == -1) {
166 errsv = errno;
167 goto error_ioctl;
168 }
169 canfd = ifr.ifr_mtu == CANFD_MTU;
170 }
171#endif
172
173 int ifflags = 0;
174 struct ifreq ifr;
175 if_indextoname(ifindex, ifr.ifr_name);
176 if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
177 errsv = errno;
178 goto error_ioctl;
179 }
180 ifflags = ifr.ifr_flags;
181#endif
182
183 struct io_handle *handle = io_handle_alloc(&can_vtab);
184 if (!handle) {
185 errsv = errno;
186 goto error_alloc_handle;
187 }
188
189 handle->fd = s;
190#if !LELY_NO_CANFD && defined(CANFD_MTU)
191 ((struct can *)handle)->canfd = canfd;
192#endif
193 ((struct can *)handle)->ifindex = ifindex;
194 ((struct can *)handle)->ifflags = ifflags;
195 ((struct can *)handle)->state = CAN_STATE_ACTIVE;
196 ((struct can *)handle)->error = 0;
197
198 return io_handle_acquire(handle);
199
200error_alloc_handle:
201#ifdef HAVE_SYS_IOCTL_H
202error_ioctl:
203#endif
204error_bind:
205error_if_nametoindex:
206#ifdef HAVE_LINUX_CAN_RAW_H
207error_setsockopt:
208#endif
209 close(s);
210error_socket:
211 errno = errsv;
212 return IO_HANDLE_ERROR;
213}
214
215#if !LELY_NO_CAN
216
217int
218io_can_read(io_handle_t handle, struct can_msg *msg)
219{
220 assert(msg);
221
222 if (!handle) {
223 errno = EBADF;
224 return -1;
225 }
226
227 if (handle->vtab != &can_vtab) {
228 errno = ENXIO;
229 return -1;
230 }
231 struct can *can = (struct can *)handle;
232
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));
237 if (nbytes < 0)
238 return -1;
239
240 if (nbytes == CANFD_MTU) {
241 if (frame.can_id & CAN_ERR_FLAG)
242 return can_err(can, (struct can_frame *)&frame);
243 if (canfd_frame2can_msg(&frame, msg) == -1)
244 return 0;
245 return 1;
246 } else if (nbytes == CAN_MTU) {
247 if (frame.can_id & CAN_ERR_FLAG)
248 return can_err(can, (struct can_frame *)&frame);
249 if (can_frame2can_msg((struct can_frame *)&frame, msg)
250 == -1)
251 return 0;
252 return 1;
253 }
254
255 return 0;
256 }
257#endif
258
259 struct can_frame frame = { .can_id = 0 };
260 ssize_t nbytes = can_read(handle, &frame, sizeof(frame));
261 if (nbytes < 0)
262 return -1;
263
264 if (nbytes == CAN_MTU) {
265 if (frame.can_id & CAN_ERR_FLAG)
266 return can_err(can, &frame);
267 if (can_frame2can_msg(&frame, msg) == -1)
268 return 0;
269 return 1;
270 }
271
272 return 0;
273}
274
275int
276io_can_write(io_handle_t handle, const struct can_msg *msg)
277{
278 assert(msg);
279
280 if (!handle) {
281 errno = EBADF;
282 return -1;
283 }
284
285 if (handle->vtab != &can_vtab) {
286 errno = ENXIO;
287 return -1;
288 }
289
290#if !LELY_NO_CANFD && defined(CANFD_MTU)
291 if (msg->flags & CAN_FLAG_EDL) {
292 if (!((struct can *)handle)->canfd) {
293 errno = EINVAL;
294 return -1;
295 }
296
297 struct canfd_frame frame;
298 if (can_msg2canfd_frame(msg, &frame) == -1)
299 return -1;
300 ssize_t nbytes = can_write(handle, &frame, sizeof(frame));
301 if (nbytes < 0)
302 return -1;
303
304 return nbytes == CANFD_MTU;
305 }
306#endif
307 struct can_frame frame;
308 if (can_msg2can_frame(msg, &frame) == -1)
309 return -1;
310 ssize_t nbytes = can_write(handle, &frame, sizeof(frame));
311 if (nbytes < 0)
312 return -1;
313
314 return nbytes == CAN_MTU;
315}
316
317#endif // !LELY_NO_CAN
318
319#if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
320
321int
323{
324 if (handle == IO_HANDLE_ERROR) {
325 errno = EBADF;
326 return -1;
327 }
328
329 if (handle->vtab != &can_vtab) {
330 errno = ENXIO;
331 return -1;
332 }
333 struct can *can = (struct can *)handle;
334
335 int fd = io_rtnl_socket(0, 0);
336 if (fd == -1)
337 return -1;
338
339 // clang-format off
340 if (io_rtnl_newlink(fd, 0, 0, can->ifindex, can->ifflags | IFF_UP, NULL,
341 0) == -1) {
342 // clang-format on
343 int errsv = errno;
344 close(fd);
345 errno = errsv;
346 return -1;
347 }
348 can->ifflags |= IFF_UP;
349
350 return close(fd);
351}
352
353int
355{
356 if (handle == IO_HANDLE_ERROR) {
357 errno = EBADF;
358 return -1;
359 }
360
361 if (handle->vtab != &can_vtab) {
362 errno = ENXIO;
363 return -1;
364 }
365 struct can *can = (struct can *)handle;
366
367 int fd = io_rtnl_socket(0, 0);
368 if (fd == -1)
369 return -1;
370
371 // clang-format off
372 if (io_rtnl_newlink(fd, 0, 0, can->ifindex, can->ifflags & ~IFF_UP,
373 NULL, 0) == -1) {
374 // clang-format on
375 int errsv = errno;
376 close(fd);
377 errno = errsv;
378 return -1;
379 }
380 can->ifflags &= ~IFF_UP;
381
382 return close(fd);
383}
384
385#endif // HAVE_LINUX_CAN_NETLINK_H && HAVE_LINUX_RTNETLINK_H
386
387int
389{
390 if (handle == IO_HANDLE_ERROR) {
391 errno = EBADF;
392 return -1;
393 }
394
395 if (handle->vtab != &can_vtab) {
396 errno = ENXIO;
397 return -1;
398 }
399 struct can *can = (struct can *)handle;
400
401#if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
402 int errsv = errno;
403
404 int fd = io_rtnl_socket(0, 0);
405 if (fd == -1)
406 goto error;
407
408 __u32 attr = 0;
409 // clang-format off
410 if (can_getattr(fd, 0, 0, can->ifindex, &can->ifflags, IFLA_CAN_STATE,
411 &attr, sizeof(attr)) < (int)sizeof(attr)) {
412 // clang-format on
413 close(fd);
414 goto error;
415 }
416
417 close(fd);
418
419 switch (attr) {
420 case CAN_STATE_ERROR_ACTIVE:
421 case CAN_STATE_ERROR_WARNING: can->state = CAN_STATE_ACTIVE; break;
422 case CAN_STATE_ERROR_PASSIVE: can->state = CAN_STATE_PASSIVE; break;
423 case CAN_STATE_BUS_OFF: can->state = CAN_STATE_BUSOFF; break;
424 }
425
426error:
427 // The virtual CAN driver does not provide the state through rtnetlink.
428 // This is not an error, so return the stored state.
429 errno = errsv;
430#endif
431
432 return can->state;
433}
434
435int
436io_can_get_error(io_handle_t handle, int *perror)
437{
438 if (handle == IO_HANDLE_ERROR) {
439 errno = EBADF;
440 return -1;
441 }
442
443 if (handle->vtab != &can_vtab) {
444 errno = ENXIO;
445 return -1;
446 }
447
448 if (perror)
449 *perror = ((struct can *)handle)->error;
450 ((struct can *)handle)->error = 0;
451
452 return 0;
453}
454
455#if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
456
457int
458io_can_get_ec(io_handle_t handle, uint16_t *ptxec, uint16_t *prxec)
459{
460 if (handle == IO_HANDLE_ERROR) {
461 errno = EBADF;
462 return -1;
463 }
464
465 if (handle->vtab != &can_vtab) {
466 errno = ENXIO;
467 return -1;
468 }
469 struct can *can = (struct can *)handle;
470
471 int fd = io_rtnl_socket(0, 0);
472 if (fd == -1)
473 return -1;
474
475 struct can_berr_counter attr = { 0 };
476 // clang-format off
477 if (can_getattr(fd, 0, 0, can->ifindex, &can->ifflags,
478 IFLA_CAN_BERR_COUNTER, &attr, sizeof(attr))
479 < (int)sizeof(attr)) {
480 // clang-format on
481 int errsv = errno;
482 close(fd);
483 errno = errsv;
484 return -1;
485 }
486
487 close(fd);
488
489 if (ptxec)
490 *ptxec = attr.txerr;
491 if (prxec)
492 *prxec = attr.rxerr;
493
494 return 0;
495}
496
497int
498io_can_get_bitrate(io_handle_t handle, uint32_t *pbitrate)
499{
500 if (handle == IO_HANDLE_ERROR) {
501 errno = EBADF;
502 return -1;
503 }
504
505 if (handle->vtab != &can_vtab) {
506 errno = ENXIO;
507 return -1;
508 }
509 struct can *can = (struct can *)handle;
510
511 int fd = io_rtnl_socket(0, 0);
512 if (fd == -1)
513 return -1;
514
515 struct can_bittiming attr = { 0 };
516 // clang-format off
517 if (can_getattr(fd, 0, 0, can->ifindex, &can->ifflags,
518 IFLA_CAN_BITTIMING, &attr, sizeof(attr))
519 < (int)sizeof(attr)) {
520 // clang-format on
521 int errsv = errno;
522 close(fd);
523 errno = errsv;
524 return -1;
525 }
526
527 close(fd);
528
529 if (pbitrate)
530 *pbitrate = attr.bitrate;
531
532 return 0;
533}
534
535int
536io_can_set_bitrate(io_handle_t handle, uint32_t bitrate)
537{
538 int result = -1;
539 int errsv = errno;
540
541 if (handle == IO_HANDLE_ERROR) {
542 errsv = EBADF;
543 goto error_param;
544 }
545
546 if (handle->vtab != &can_vtab) {
547 errsv = ENXIO;
548 goto error_param;
549 }
550 struct can *can = (struct can *)handle;
551
552 int fd = io_rtnl_socket(0, 0);
553 if (fd == -1) {
554 errsv = errno;
555 goto error_socket;
556 }
557
558 // Deactivate the network interface, if necessary, before changing the
559 // bitrate.
560 // clang-format off
561 if ((can->ifflags & IFF_UP) && io_rtnl_newlink(fd, 0, 0, can->ifindex,
562 can->ifflags & ~IFF_UP, NULL, 0) == -1) {
563 // clang-format on
564 errsv = errno;
565 goto error_newlink;
566 }
567
568 struct can_bittiming attr = { .bitrate = bitrate };
569 // clang-format off
570 if (can_setattr(fd, 0, 0, can->ifindex, can->ifflags,
571 IFLA_CAN_BITTIMING, &attr, sizeof(attr)) == -1) {
572 // clang-format on
573 errsv = errno;
574 goto error_setattr;
575 }
576
577 result = 0;
578
579error_setattr:
580error_newlink:
581 close(fd);
582error_socket:
583error_param:
584 errno = errsv;
585 return result;
586}
587
588int
589io_can_get_txqlen(io_handle_t handle, size_t *ptxqlen)
590{
591 if (handle == IO_HANDLE_ERROR) {
592 errno = EBADF;
593 return -1;
594 }
595
596 if (handle->vtab != &can_vtab) {
597 errno = ENXIO;
598 return -1;
599 }
600 struct can *can = (struct can *)handle;
601
602 int fd = io_rtnl_socket(0, 0);
603 if (fd == -1)
604 return -1;
605
606 __u32 attr = 0;
607 // clang-format off
608 if (io_rtnl_getattr(fd, 0, 0, can->ifindex, &can->ifflags, IFLA_TXQLEN,
609 &attr, sizeof(attr)) < (int)sizeof(attr)) {
610 // clang-format on
611 int errsv = errno;
612 close(fd);
613 errno = errsv;
614 return -1;
615 }
616
617 close(fd);
618
619 if (ptxqlen)
620 *ptxqlen = attr;
621
622 return 0;
623}
624
625int
626io_can_set_txqlen(io_handle_t handle, size_t txqlen)
627{
628 if (handle == IO_HANDLE_ERROR) {
629 errno = EBADF;
630 return -1;
631 }
632
633 if (handle->vtab != &can_vtab) {
634 errno = ENXIO;
635 return -1;
636 }
637 struct can *can = (struct can *)handle;
638
639 int fd = io_rtnl_socket(0, 0);
640 if (fd == -1)
641 return -1;
642
643 __u32 attr = txqlen;
644 // clang-format off
645 if (io_rtnl_setattr(fd, 0, 0, can->ifindex, can->ifflags, IFLA_TXQLEN,
646 &attr, sizeof(attr)) == -1) {
647 // clang-format on
648 int errsv = errno;
649 close(fd);
650 errno = errsv;
651 return -1;
652 }
653
654 return close(fd);
655}
656
657#endif // HAVE_LINUX_CAN_NETLINK_H && HAVE_LINUX_RTNETLINK_H
658
659static void
660can_fini(struct io_handle *handle)
661{
662 assert(handle);
663
664 if (!(handle->flags & IO_FLAG_NO_CLOSE))
665 close(handle->fd);
666}
667
668static int
669can_flags(struct io_handle *handle, int flags)
670{
671 assert(handle);
672
673 int arg = fcntl(handle->fd, F_GETFL, 0);
674 if (arg == -1)
675 return -1;
676
677 int errsv = 0;
678
679 if ((flags & IO_FLAG_NONBLOCK) && !(arg & O_NONBLOCK)) {
680 if (fcntl(handle->fd, F_SETFL, arg | O_NONBLOCK) == -1) {
681 errsv = errno;
682 goto error_fcntl;
683 }
684 } else if (!(flags & IO_FLAG_NONBLOCK) && (arg & O_NONBLOCK)) {
685 if (fcntl(handle->fd, F_SETFL, arg & ~O_NONBLOCK) == -1) {
686 errsv = errno;
687 goto error_fcntl;
688 }
689 }
690
691 int optval = !!(flags & IO_FLAG_LOOPBACK);
692 // clang-format off
693 if (setsockopt(handle->fd, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
694 (const char *)&optval, sizeof(optval)) == -1) {
695 // clang-format on
696 errsv = errno;
697 goto error_setsockopt;
698 }
699
700 return 0;
701
702error_setsockopt:
703 fcntl(handle->fd, F_SETFL, arg);
704error_fcntl:
705 errno = errsv;
706 return -1;
707}
708
709static ssize_t
710can_read(struct io_handle *handle, void *buf, size_t nbytes)
711{
712 assert(handle);
713
714 ssize_t result;
715 int errsv = errno;
716 do {
717 errno = errsv;
718 result = read(handle->fd, buf, nbytes);
719 } while (result == -1 && errno == EINTR);
720 return result;
721}
722
723static ssize_t
724can_write(struct io_handle *handle, const void *buf, size_t nbytes)
725{
726 assert(handle);
727
728 ssize_t result;
729 int errsv = errno;
730 do {
731 errno = errsv;
732 result = write(handle->fd, buf, nbytes);
733 } while (result == -1 && errno == EINTR);
734 return result;
735}
736
737static int
738can_err(struct can *can, const struct can_frame *frame)
739{
740 assert(can);
741 assert(frame);
742 assert(frame->can_id & CAN_ERR_FLAG);
743
744#ifdef HAVE_LINUX_CAN_ERROR_H
745 if (frame->can_dlc != CAN_ERR_DLC)
746 return 0;
747#endif
748
749 int state = can->state;
750 int error = 0;
751
752#ifdef HAVE_LINUX_CAN_ERROR_H
753 if (frame->can_id & CAN_ERR_RESTARTED)
755
756 if (frame->can_id & CAN_ERR_CRTL) {
757#ifdef CAN_ERR_CRTL_ACTIVE
758 if (frame->data[1] & CAN_ERR_CRTL_ACTIVE)
760#endif
761 // clang-format off
762 if (frame->data[1] & (CAN_ERR_CRTL_RX_PASSIVE
763 | CAN_ERR_CRTL_TX_PASSIVE))
764 // clang-format on
766 }
767
768 if (frame->can_id & CAN_ERR_PROT) {
769 if (frame->data[2] & CAN_ERR_PROT_BIT)
770 error |= CAN_ERROR_BIT;
771 if (frame->data[2] & CAN_ERR_PROT_FORM)
772 error |= CAN_ERROR_FORM;
773 if (frame->data[2] & CAN_ERR_PROT_STUFF)
774 error |= CAN_ERROR_STUFF;
775 if (frame->data[3] & CAN_ERR_PROT_LOC_CRC_SEQ)
776 error |= CAN_ERROR_CRC;
777 }
778
779 if (frame->can_id & CAN_ERR_ACK)
780 error |= CAN_ERROR_ACK;
781
782 if (frame->can_id & CAN_ERR_BUSOFF)
784#endif
785
786 can->state = state;
787 can->error = error;
788
789 // cppcheck-suppress knownConditionTrueFalse
790 if (state != CAN_STATE_ACTIVE || error) {
791 errno = EIO;
792 return -1;
793 }
794
795 return 0;
796}
797
798#if defined(HAVE_LINUX_CAN_NETLINK_H) && defined(HAVE_LINUX_RTNETLINK_H)
799
800static int
801can_getattr(int fd, __u32 seq, __u32 pid, int ifi_index,
802 unsigned int *pifi_flags, unsigned short type, void *data,
803 unsigned short payload)
804{
805 assert(data || !payload);
806
807 char buf[1024];
808
809 int len = io_rtnl_getattr(fd, seq, pid, ifi_index, pifi_flags,
810 IFLA_LINKINFO, buf, sizeof(buf));
811 if (len == -1)
812 return -1;
813
814 struct rtattr *rta =
815 io_rta_find((struct rtattr *)buf, len, IFLA_INFO_DATA);
816 if (rta)
817 rta = io_rta_find(RTA_DATA(rta), RTA_PAYLOAD(rta), type);
818 if (!rta) {
819 errno = EOPNOTSUPP;
820 return -1;
821 }
822
823 len = RTA_PAYLOAD(rta);
824 if (data)
825 memcpy(data, RTA_DATA(rta), MIN(payload, len));
826 return len;
827}
828
829static int
830can_setattr(int fd, __u32 seq, __u32 pid, int ifi_index, unsigned int ifi_flags,
831 unsigned short type, const void *data, unsigned short payload)
832{
833 assert(data || !payload);
834
835 char buf[1024];
836 int len = 0;
837
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));
843
844 len += RTA_ALIGN(info_kind->rta_len);
845
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 };
849
850 if (data) {
851 struct rtattr *rta = RTA_DATA(info_data);
852 *rta = (struct rtattr){ .rta_len = RTA_LENGTH(payload),
853 .rta_type = type };
854 memcpy(RTA_DATA(rta), data, payload);
855
856 info_data->rta_len += RTA_ALIGN(rta->rta_len);
857 }
858
859 len += RTA_ALIGN(info_data->rta_len);
860
861 return io_rtnl_setattr(fd, seq, pid, ifi_index, ifi_flags,
862 IFLA_LINKINFO, buf, len);
863}
864
865#endif // HAVE_LINUX_CAN_NETLINK_H && HAVE_LINUX_RTNETLINK_H
866
867#endif // __linux__ && HAVE_LINUX_CAN_H
868
869#endif // !LELY_NO_STDIO
@ CAN_STATE_BUSOFF
The bus off state (TX/RX error count >= 256).
Definition err.h:34
@ CAN_STATE_PASSIVE
The error passive state (TX/RX error count < 256).
Definition err.h:32
@ CAN_STATE_ACTIVE
The error active state (TX/RX error count < 128).
Definition err.h:30
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.
Definition handle.c:81
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.
Definition io.h:47
io_handle_t io_handle_acquire(io_handle_t handle)
Increments the reference count of an I/O device handle.
Definition handle.c:36
@ IO_FLAG_NONBLOCK
Perform I/O operations in non-blocking mode.
Definition io.h:62
@ IO_FLAG_LOOPBACK
Receive own messages (i.e., sent by the same device).
Definition io.h:64
@ IO_FLAG_NO_CLOSE
Do not close the native file descriptor when closing an I/O device.
Definition io.h:60
#define IO_HANDLE_ERROR
The value of an invalid I/O device handle.
Definition io.h:34
#define MIN(a, b)
Returns the minimum of a and b.
Definition util.h:57
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...
Definition can.c:436
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.
Definition can.c:626
int io_can_stop(io_handle_t handle)
Stops transmission and reception on a CAN device.
Definition can.c:354
int io_can_write(io_handle_t handle, const struct can_msg *msg)
Writes a single CAN or CAN FD frame.
Definition can.c:276
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...
Definition can.c:589
io_handle_t io_open_can(const char *path)
Opens a CAN device.
Definition can.c:111
int io_can_read(io_handle_t handle, struct can_msg *msg)
Reads a single CAN or CAN FD frame.
Definition can.c:218
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...
Definition can.c:458
int io_can_start(io_handle_t handle)
Starts transmission and reception on a CAN device.
Definition can.c:322
int io_can_set_bitrate(io_handle_t handle, uint32_t bitrate)
Sets the bitrate (in bit/s) of a CAN device.
Definition can.c:536
int io_can_get_state(io_handle_t handle)
Obtains the state of a CAN device.
Definition can.c:388
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.
Definition can.c:498
#define RTA_TAIL(rta)
Returns the address of the next attribute.
Definition rtnl.h:35
static struct rtattr * io_rta_find(struct rtattr *rta, unsigned short len, unsigned short type)
Finds an attribute in a list of attributes.
Definition rtnl.h:169
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.
Definition rtnl.c:106
int io_rtnl_socket(__u32 pid, __u32 groups)
Opens an rtnetlink socket.
Definition rtnl.c:55
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.
Definition rtnl.c:84
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.
Definition rtnl.c:179
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.
Definition can_msg.h:141
int can_frame2can_msg(const struct can_frame *src, struct can_msg *dst)
Converts a SocketCAN CAN frame to a can_msg frame.
Definition can_msg.h:51
int canfd_frame2can_msg(const struct canfd_frame *src, struct can_msg *dst)
Converts a SocketCAN CAN FD frame to a can_msg frame.
Definition can_msg.h:112
int can_msg2can_frame(const struct can_msg *src, struct can_frame *dst)
Converts a can_msg frame to a SocketCAN CAN frame.
Definition can_msg.h:80
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 error frame.
Definition err.h:28
A CAN or CAN FD format frame.
Definition msg.h:87
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...
Definition msg.h:94
A CAN device.
Definition can.c:60
struct io_handle base
The I/O device base handle.
Definition can.c:62
int error
The last error (any combination of CAN_ERROR_BIT, CAN_ERROR_STUFF, CAN_ERROR_CRC, CAN_ERROR_FORM and ...
Definition can.c:80
int state
The state of the CAN controller (one of CAN_STATE_ACTIVE, CAN_STATE_PASSIVE or CAN_STATE_BUSOFF).
Definition can.c:75
unsigned int ifflags
The active flag word of the device.
Definition can.c:70
unsigned int ifindex
The interface index.
Definition can.c:68
The virtual table of an I/O device handle.
Definition handle.h:66
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...
Definition handle.h:71
An I/O device handle.
Definition handle.h:33
int fd
The native file descriptor.
Definition handle.h:48
int flags
The I/O device flags (any combination of IO_FLAG_NO_CLOSE and IO_FLAG_NONBLOCK).
Definition handle.h:54
const struct io_handle_vtab * vtab
A pointer to the virtual table.
Definition handle.h:35
ptrdiff_t ssize_t
Used for a count of bytes or an error indication.
Definition types.h:43