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