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 
53 struct can {
55  struct io_handle base;
56 #if !defined(LELY_NO_CANFD) && defined(CANFD_MTU)
57  int canfd;
59 #endif
60  unsigned int ifindex;
63  unsigned int ifflags;
68  int state;
73  int error;
74 };
75 
76 static void can_fini(struct io_handle *handle);
77 static int can_flags(struct io_handle *handle, int flags);
78 static ssize_t can_read(struct io_handle *handle, void *buf, size_t nbytes);
79 static ssize_t can_write(
80  struct io_handle *handle, const void *buf, size_t nbytes);
81 
82 static 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 
89 static 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 
93 static 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 
97 static 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 
104 io_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 
193 error_alloc_handle:
194 #ifdef HAVE_SYS_IOCTL_H
195 error_ioctl:
196 #endif
197 error_bind:
198 error_if_nametoindex:
199 #ifdef HAVE_LINUX_CAN_RAW_H
200 error_setsockopt:
201 #endif
202  close(s);
203 error_socket:
204  errno = errsv;
205  return IO_HANDLE_ERROR;
206 }
207 
208 #ifndef LELY_NO_CAN
209 
210 int
211 io_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 
270 int
271 io_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 
316 int
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 
348 int
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 
382 int
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 
422 error:
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 
431 int
432 io_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 
453 int
454 io_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 
493 int
494 io_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 
531 int
532 io_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 
575 error_setattr:
576 error_newlink:
577  close(fd);
578 error_socket:
579 error_param:
580  errno = errsv;
581  return result;
582 }
583 
584 int
585 io_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
604  if (__unlikely(io_rtnl_getattr(fd, 0, 0, can->ifindex, &can->ifflags,
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 
622 int
623 io_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
642  if (__unlikely(io_rtnl_setattr(fd, 0, 0, can->ifindex, can->ifflags,
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 
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 (__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 
706 error_setsockopt:
707  fcntl(handle->fd, F_SETFL, arg);
708 error_fcntl:
709  errno = errsv;
710  return -1;
711 }
712 
713 static ssize_t
714 can_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 
727 static ssize_t
728 can_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 
741 static int
742 can_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)
777  if (frame->data[2] & CAN_ERR_PROT_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 
803 static int
804 can_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 
832 static int
833 can_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
A CAN or CAN FD format frame.
Definition: msg.h:88
unsigned int ifindex
The interface index.
Definition: can.c:61
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
A bit stuffing error.
Definition: can.h:41
This header file is part of the C11 and POSIX compatibility library; it includes <string.h> and defines any missing functionality.
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 io_can_get_state(io_handle_t handle)
Obtains the state of a CAN device.
Definition: can.c:383
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
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
unsigned int ifflags
The active flag word of the device.
Definition: can.c:63
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
A form error.
Definition: can.h:45
int io_rtnl_socket(__u32 pid, __u32 groups)
Opens an rtnetlink socket.
Definition: rtnl.c:55
int io_can_stop(io_handle_t handle)
Stops transmission and reception on a CAN device.
Definition: can.c:349
The error passive state (TX/RX error count < 256).
Definition: can.h:31
struct io_handle base
The I/O device base handle.
Definition: can.c:55
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
#define MIN(a, b)
Returns the minimum of a and b.
Definition: util.h:57
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 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
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 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
A CAN device.
Definition: io.h:47
This is the internal header file of the I/O handle declarations.
io_handle_t io_handle_acquire(io_handle_t handle)
Increments the reference count of an I/O device handle.
Definition: handle.c:32
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
This header file is part of the utilities library; it contains the native and platform-independent er...
#define __likely(x)
Indicates to the compiler that the expression is most-likely true.
Definition: features.h:273
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
#define CAN_FLAG_EDL
The Extended Data Length (EDL) flag.
Definition: msg.h:55
The bus off state (TX/RX error count >= 256).
Definition: can.h:33
Do not close the native file descriptor when closing an I/O device.
Definition: io.h:60
int can_msg2canfd_frame(const struct can_msg *src, struct canfd_frame *dst)
Converts a can_msg frame to a SocketCAN CAN FD frame.
#define IO_HANDLE_ERROR
The value of an invalid I/O device handle.
Definition: io.h:34
const struct io_handle_vtab * vtab
A pointer to the virtual table.
Definition: handle.h:43
The virtual table of an I/O device handle.
Definition: handle.h:74
The error active state (TX/RX error count < 128).
Definition: can.h:29
Receive own messages (i.e., sent by the same device).
Definition: io.h:64
#define __unlikely(x)
Indicates to the compiler that the expression is most-likely false.
Definition: features.h:286
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
This is the internal header file of the I/O library.
int flags
The I/O device flags (any combination of IO_FLAG_NO_CLOSE and IO_FLAG_NONBLOCK).
Definition: handle.h:62
This header file is part of the I/O library; it contains the Controller Area Network (CAN) declaratio...
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
A CAN device.
Definition: can.c:53
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
Perform I/O operations in non-blocking mode.
Definition: io.h:62
int state
The state of the CAN controller (one of CAN_STATE_ACTIVE, CAN_STATE_PASSIVE or CAN_STATE_BUSOFF).
Definition: can.c:68
An acknowledgment error.
Definition: can.h:47
int io_can_start(io_handle_t handle)
Starts transmission and reception on a CAN device.
Definition: can.c:317
#define RTA_TAIL(rta)
Returns the address of the next attribute.
Definition: rtnl.h:35
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 fd
The native file descriptor.
Definition: handle.h:56
int io_can_read(io_handle_t handle, struct can_msg *msg)
Reads a single CAN or CAN FD frame.
Definition: can.c:211
This is the internal header file of the rtnetlink declarations.
A CRC sequence error.
Definition: can.h:43
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 header file is part of the CAN library; it contains the SocketCAN interface declarations.
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
A single bit error.
Definition: can.h:39
An I/O device handle.
Definition: handle.h:41
io_handle_t io_open_can(const char *path)
Opens a CAN device.
Definition: can.c:104