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 
60 struct can {
62  struct io_handle base;
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 
83 static void can_fini(struct io_handle *handle);
84 static int can_flags(struct io_handle *handle, int flags);
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);
88 
89 static 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 
96 static 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 
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);
103 
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);
107 
108 #endif
109 
111 io_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 
200 error_alloc_handle:
201 #ifdef HAVE_SYS_IOCTL_H
202 error_ioctl:
203 #endif
204 error_bind:
205 error_if_nametoindex:
206 #ifdef HAVE_LINUX_CAN_RAW_H
207 error_setsockopt:
208 #endif
209  close(s);
210 error_socket:
211  errno = errsv;
212  return IO_HANDLE_ERROR;
213 }
214 
215 #if !LELY_NO_CAN
216 
217 int
218 io_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 
275 int
276 io_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 
321 int
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 
353 int
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 
387 int
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 
426 error:
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 
435 int
436 io_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 
457 int
458 io_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 
497 int
498 io_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 
535 int
536 io_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 
579 error_setattr:
580 error_newlink:
581  close(fd);
582 error_socket:
583 error_param:
584  errno = errsv;
585  return result;
586 }
587 
588 int
589 io_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 
625 int
626 io_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 
659 static void
660 can_fini(struct io_handle *handle)
661 {
662  assert(handle);
663 
664  if (!(handle->flags & IO_FLAG_NO_CLOSE))
665  close(handle->fd);
666 }
667 
668 static int
669 can_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 
702 error_setsockopt:
703  fcntl(handle->fd, F_SETFL, arg);
704 error_fcntl:
705  errno = errsv;
706  return -1;
707 }
708 
709 static ssize_t
710 can_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 
723 static ssize_t
724 can_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 
737 static int
738 can_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)
773  if (frame->data[2] & CAN_ERR_PROT_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 
800 static int
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)
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 
829 static int
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)
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_ERROR_FORM
A form error.
Definition: err.h:50
@ CAN_ERROR_BIT
A single bit error.
Definition: err.h:44
@ CAN_ERROR_STUFF
A bit stuffing error.
Definition: err.h:46
@ CAN_ERROR_ACK
An acknowledgment error.
Definition: err.h:52
@ CAN_ERROR_CRC
A CRC sequence error.
Definition: err.h:48
@ 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