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