socketcan.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014-2015 Pavel Kirienko <pavel.kirienko@gmail.com>
3  * Ilia Sheremet <illia.sheremet@gmail.com>
4  */
5 
6 #pragma once
7 
8 #include <cassert>
9 #include <cstdint>
10 #include <queue>
11 #include <vector>
12 #include <map>
13 #include <unordered_set>
14 #include <memory>
15 #include <algorithm>
16 
17 #include <fcntl.h>
18 #include <sys/socket.h>
19 #include <sys/ioctl.h>
20 #include <net/if.h>
21 #include <linux/can.h>
22 #include <linux/can/raw.h>
23 #include <poll.h>
24 
25 #include <uavcan/uavcan.hpp>
26 #include <uavcan_linux/clock.hpp>
28 
29 
30 namespace uavcan_linux
31 {
35 enum class SocketCanError
36 {
39  TxTimeout
40 };
41 
61 {
62  static inline ::can_frame makeSocketCanFrame(const uavcan::CanFrame& uavcan_frame)
63  {
64  ::can_frame sockcan_frame = ::can_frame();
65  sockcan_frame.can_id = uavcan_frame.id & uavcan::CanFrame::MaskExtID;
66  sockcan_frame.can_dlc = uavcan_frame.dlc;
67  (void)std::copy(uavcan_frame.data, uavcan_frame.data + uavcan_frame.dlc, sockcan_frame.data);
68  if (uavcan_frame.isExtended())
69  {
70  sockcan_frame.can_id |= CAN_EFF_FLAG;
71  }
72  if (uavcan_frame.isErrorFrame())
73  {
74  sockcan_frame.can_id |= CAN_ERR_FLAG;
75  }
76  if (uavcan_frame.isRemoteTransmissionRequest())
77  {
78  sockcan_frame.can_id |= CAN_RTR_FLAG;
79  }
80  return sockcan_frame;
81  }
82 
83  static inline uavcan::CanFrame makeUavcanFrame(const ::can_frame& sockcan_frame)
84  {
85  uavcan::CanFrame uavcan_frame(sockcan_frame.can_id & CAN_EFF_MASK, sockcan_frame.data, sockcan_frame.can_dlc);
86  if (sockcan_frame.can_id & CAN_EFF_FLAG)
87  {
88  uavcan_frame.id |= uavcan::CanFrame::FlagEFF;
89  }
90  if (sockcan_frame.can_id & CAN_ERR_FLAG)
91  {
92  uavcan_frame.id |= uavcan::CanFrame::FlagERR;
93  }
94  if (sockcan_frame.can_id & CAN_RTR_FLAG)
95  {
96  uavcan_frame.id |= uavcan::CanFrame::FlagRTR;
97  }
98  return uavcan_frame;
99  }
100 
101  struct TxItem
102  {
107 
108  TxItem(const uavcan::CanFrame& arg_frame, uavcan::MonotonicTime arg_deadline,
109  uavcan::CanIOFlags arg_flags, std::uint64_t arg_order)
110  : frame(arg_frame)
111  , deadline(arg_deadline)
112  , flags(arg_flags)
113  , order(arg_order)
114  { }
115 
116  bool operator<(const TxItem& rhs) const
117  {
118  if (frame.priorityLowerThan(rhs.frame))
119  {
120  return true;
121  }
122  if (frame.priorityHigherThan(rhs.frame))
123  {
124  return false;
125  }
126  return order > rhs.order;
127  }
128  };
129 
130  struct RxItem
131  {
136 
138  : flags(0)
139  { }
140  };
141 
143  const int fd_;
144 
147 
149 
150  std::map<SocketCanError, std::uint64_t> errors_;
151 
152  std::priority_queue<TxItem> tx_queue_; // TODO: Use pool allocator
153  std::queue<RxItem> rx_queue_; // TODO: Use pool allocator
154  std::unordered_multiset<std::uint32_t> pending_loopback_ids_; // TODO: Use pool allocator
155 
156  std::vector<::can_filter> hw_filters_container_;
157 
159 
161  {
164  }
165 
167  {
169  {
171  }
172  else
173  {
174  assert(0); // Loopback for a frame that we didn't send.
175  }
176  }
177 
179  {
180  if (pending_loopback_ids_.count(frame.id) > 0)
181  {
182  (void)pending_loopback_ids_.erase(frame.id);
183  return true;
184  }
185  return false;
186  }
187 
188  int write(const uavcan::CanFrame& frame) const
189  {
190  errno = 0;
191 
192  const ::can_frame sockcan_frame = makeSocketCanFrame(frame);
193 
194  const int res = ::write(fd_, &sockcan_frame, sizeof(sockcan_frame));
195  if (res <= 0)
196  {
197  if (errno == ENOBUFS || errno == EAGAIN) // Writing is not possible atm, not an error
198  {
199  return 0;
200  }
201  return res;
202  }
203  if (res != sizeof(sockcan_frame))
204  {
205  return -1;
206  }
207  return 1;
208  }
209 
217  int read(uavcan::CanFrame& frame, uavcan::UtcTime& ts_utc, bool& loopback) const
218  {
219  auto iov = ::iovec();
220  auto sockcan_frame = ::can_frame();
221  iov.iov_base = &sockcan_frame;
222  iov.iov_len = sizeof(sockcan_frame);
223 
224  static constexpr size_t ControlSize = sizeof(cmsghdr) + sizeof(::timeval);
225  using ControlStorage = typename std::aligned_storage<ControlSize>::type;
226  ControlStorage control_storage;
227  auto control = reinterpret_cast<std::uint8_t *>(&control_storage);
228  std::fill(control, control + ControlSize, 0x00);
229 
230  auto msg = ::msghdr();
231  msg.msg_iov = &iov;
232  msg.msg_iovlen = 1;
233  msg.msg_control = control;
234  msg.msg_controllen = ControlSize;
235 
236  const int res = ::recvmsg(fd_, &msg, MSG_DONTWAIT);
237  if (res <= 0)
238  {
239  return (res < 0 && errno == EWOULDBLOCK) ? 0 : res;
240  }
241  /*
242  * Flags
243  */
244  loopback = (msg.msg_flags & static_cast<int>(MSG_CONFIRM)) != 0;
245 
246  if (!loopback && !checkHWFilters(sockcan_frame))
247  {
248  return 0;
249  }
250 
251  frame = makeUavcanFrame(sockcan_frame);
252  /*
253  * Timestamp
254  */
255  const ::cmsghdr* const cmsg = CMSG_FIRSTHDR(&msg);
256  assert(cmsg != nullptr);
257  if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP)
258  {
259  auto tv = ::timeval();
260  (void)std::memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv)); // Copy to avoid alignment problems
261  assert(tv.tv_sec >= 0 && tv.tv_usec >= 0);
262  ts_utc = uavcan::UtcTime::fromUSec(std::uint64_t(tv.tv_sec) * 1000000ULL + tv.tv_usec);
263  }
264  else
265  {
266  assert(0);
267  return -1;
268  }
269  return 1;
270  }
271 
272  void pollWrite()
273  {
274  while (hasReadyTx())
275  {
276  const TxItem tx = tx_queue_.top();
277 
278  if (tx.deadline >= clock_.getMonotonic())
279  {
280  const int res = write(tx.frame);
281  if (res == 1) // Transmitted successfully
282  {
285  {
286  (void)pending_loopback_ids_.insert(tx.frame.id);
287  }
288  }
289  else if (res == 0) // Not transmitted, nor is it an error
290  {
291  break; // Leaving the loop, the frame remains enqueued for the next retry
292  }
293  else // Transmission error
294  {
296  }
297  }
298  else
299  {
301  }
302 
303  // Removing the frame from the queue even if transmission failed
304  tx_queue_.pop();
305  }
306  }
307 
308  void pollRead()
309  {
310  while (true)
311  {
312  RxItem rx;
313  rx.ts_mono = clock_.getMonotonic(); // Monotonic timestamp is not required to be precise (unlike UTC)
314  bool loopback = false;
315  const int res = read(rx.frame, rx.ts_utc, loopback);
316  if (res == 1)
317  {
318  assert(!rx.ts_utc.isZero());
319  bool accept = true;
320  if (loopback) // We receive loopback for all CAN frames
321  {
324  accept = wasInPendingLoopbackSet(rx.frame); // Do we need to send this loopback into the lib?
325  }
326  if (accept)
327  {
329  rx_queue_.push(rx);
330  }
331  }
332  else if (res == 0)
333  {
334  break;
335  }
336  else
337  {
339  break;
340  }
341  }
342  }
343 
347  bool checkHWFilters(const ::can_frame& frame) const
348  {
349  if (!hw_filters_container_.empty())
350  {
351  for (auto& f : hw_filters_container_)
352  {
353  if (((frame.can_id & f.can_mask) ^ f.can_id) == 0)
354  {
355  return true;
356  }
357  }
358  return false;
359  }
360  else
361  {
362  return true;
363  }
364  }
365 
366 public:
372  SocketCanIface(const SystemClock& clock, int socket_fd, int max_frames_in_socket_tx_queue = 2)
373  : clock_(clock)
374  , fd_(socket_fd)
375  , max_frames_in_socket_tx_queue_(max_frames_in_socket_tx_queue)
376  {
377  assert(fd_ >= 0);
378  }
379 
383  virtual ~SocketCanIface()
384  {
385  UAVCAN_TRACE("SocketCAN", "SocketCanIface: Closing fd %d", fd_);
386  (void)::close(fd_);
387  }
388 
393  const uavcan::CanIOFlags flags) override
394  {
395  tx_queue_.emplace(frame, tx_deadline, flags, tx_frame_counter_);
397  pollRead(); // Read poll is necessary because it can release the pending TX flag
398  pollWrite();
399  return 1;
400  }
401 
407  uavcan::UtcTime& out_ts_utc, uavcan::CanIOFlags& out_flags) override
408  {
409  if (rx_queue_.empty())
410  {
411  pollRead(); // This allows to use the socket not calling poll() explicitly.
412  if (rx_queue_.empty())
413  {
414  return 0;
415  }
416  }
417  {
418  const RxItem& rx = rx_queue_.front();
419  out_frame = rx.frame;
420  out_ts_monotonic = rx.ts_mono;
421  out_ts_utc = rx.ts_utc;
422  out_flags = rx.flags;
423  }
424  rx_queue_.pop();
425  return 1;
426  }
427 
433  void poll(bool read, bool write)
434  {
435  if (read)
436  {
437  pollRead(); // Read poll must be executed first because it may decrement frames_in_socket_tx_queue_
438  }
439  if (write)
440  {
441  pollWrite();
442  }
443  }
444 
445  bool hasReadyRx() const { return !rx_queue_.empty(); }
446  bool hasReadyTx() const
447  {
449  }
450 
452  const std::uint16_t num_configs) override
453  {
454  if (filter_configs == nullptr)
455  {
456  assert(0);
457  return -1;
458  }
459  hw_filters_container_.clear();
460  hw_filters_container_.resize(num_configs);
461 
462  for (unsigned i = 0; i < num_configs; i++)
463  {
464  const uavcan::CanFilterConfig& fc = filter_configs[i];
467  if (fc.id & uavcan::CanFrame::FlagEFF)
468  {
469  hw_filters_container_[i].can_id |= CAN_EFF_FLAG;
470  }
471  if (fc.id & uavcan::CanFrame::FlagRTR)
472  {
473  hw_filters_container_[i].can_id |= CAN_RTR_FLAG;
474  }
476  {
477  hw_filters_container_[i].can_mask |= CAN_EFF_FLAG;
478  }
480  {
481  hw_filters_container_[i].can_mask |= CAN_RTR_FLAG;
482  }
483  }
484 
485  return 0;
486  }
487 
492  static constexpr unsigned NumFilters = 8;
493  std::uint16_t getNumFilters() const override { return NumFilters; }
494 
495 
499  std::uint64_t getErrorCount() const override
500  {
501  std::uint64_t ec = 0;
502  for (auto& kv : errors_) { ec += kv.second; }
503  return ec;
504  }
505 
509  const decltype(errors_) & getErrors() const { return errors_; }
510 
511  int getFileDescriptor() const { return fd_; }
512 
518  static int openSocket(const std::string& iface_name)
519  {
520  errno = 0;
521 
522  const int s = ::socket(PF_CAN, SOCK_RAW, CAN_RAW);
523  if (s < 0)
524  {
525  return s;
526  }
527 
528  class RaiiCloser
529  {
530  int fd_;
531  public:
532  RaiiCloser(int filedesc) : fd_(filedesc)
533  {
534  assert(fd_ >= 0);
535  }
536  ~RaiiCloser()
537  {
538  if (fd_ >= 0)
539  {
540  UAVCAN_TRACE("SocketCAN", "RaiiCloser: Closing fd %d", fd_);
541  (void)::close(fd_);
542  }
543  }
544  void disarm() { fd_ = -1; }
545  } raii_closer(s);
546 
547  // Detect the iface index
548  auto ifr = ::ifreq();
549  if (iface_name.length() >= IFNAMSIZ)
550  {
551  errno = ENAMETOOLONG;
552  return -1;
553  }
554  (void)std::strncpy(ifr.ifr_name, iface_name.c_str(), iface_name.length());
555  if (::ioctl(s, SIOCGIFINDEX, &ifr) < 0 || ifr.ifr_ifindex < 0)
556  {
557  return -1;
558  }
559 
560  // Bind to the specified CAN iface
561  {
562  auto addr = ::sockaddr_can();
563  addr.can_family = AF_CAN;
564  addr.can_ifindex = ifr.ifr_ifindex;
565  if (::bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0)
566  {
567  return -1;
568  }
569  }
570 
571  // Configure
572  {
573  const int on = 1;
574  // Timestamping
575  if (::setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)) < 0)
576  {
577  return -1;
578  }
579  // Socket loopback
580  if (::setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &on, sizeof(on)) < 0)
581  {
582  return -1;
583  }
584  // Non-blocking
585  if (::fcntl(s, F_SETFL, O_NONBLOCK) < 0)
586  {
587  return -1;
588  }
589  }
590 
591  // Validate the resulting socket
592  {
593  int socket_error = 0;
594  ::socklen_t errlen = sizeof(socket_error);
595  (void)::getsockopt(s, SOL_SOCKET, SO_ERROR, reinterpret_cast<void*>(&socket_error), &errlen);
596  if (socket_error != 0)
597  {
598  errno = socket_error;
599  return -1;
600  }
601  }
602 
603  raii_closer.disarm();
604  return s;
605  }
606 };
607 
619 {
621  {
622  bool down_ = false;
623 
624  public:
625  IfaceWrapper(const SystemClock& clock, int fd) : SocketCanIface(clock, fd) { }
626 
627  void updateDownStatusFromPollResult(const ::pollfd& pfd)
628  {
629  assert(pfd.fd == this->getFileDescriptor());
630  if (!down_ && (pfd.revents & POLLERR))
631  {
632  int error = 0;
633  ::socklen_t errlen = sizeof(error);
634  (void)::getsockopt(pfd.fd, SOL_SOCKET, SO_ERROR, reinterpret_cast<void*>(&error), &errlen);
635 
636  down_ = error == ENETDOWN || error == ENODEV;
637 
638  UAVCAN_TRACE("SocketCAN", "Iface %d is dead; error %d", this->getFileDescriptor(), error);
639  }
640  }
641 
642  bool isDown() const { return down_; }
643  };
644 
646  std::vector<std::unique_ptr<IfaceWrapper>> ifaces_;
647 
648 public:
652  explicit SocketCanDriver(const SystemClock& clock)
653  : clock_(clock)
654  {
655  ifaces_.reserve(uavcan::MaxCanIfaces);
656  }
657 
666  uavcan::MonotonicTime blocking_deadline) override
667  {
668  // Detecting whether we need to block at all
669  bool need_block = (inout_masks.write == 0); // Write queue is infinite
670  for (unsigned i = 0; need_block && (i < ifaces_.size()); i++)
671  {
672  const bool need_read = inout_masks.read & (1 << i);
673  if (need_read && ifaces_[i]->hasReadyRx())
674  {
675  need_block = false;
676  }
677  }
678 
679  if (need_block)
680  {
681  // Poll FD set setup
682  ::pollfd pollfds[uavcan::MaxCanIfaces] = {};
683  unsigned num_pollfds = 0;
684  IfaceWrapper* pollfd_index_to_iface[uavcan::MaxCanIfaces] = { };
685 
686  for (unsigned i = 0; i < ifaces_.size(); i++)
687  {
688  if (!ifaces_[i]->isDown())
689  {
690  pollfds[num_pollfds].fd = ifaces_[i]->getFileDescriptor();
691  pollfds[num_pollfds].events = POLLIN;
692  if (ifaces_[i]->hasReadyTx() || (inout_masks.write & (1U << i)))
693  {
694  pollfds[num_pollfds].events |= POLLOUT;
695  }
696  pollfd_index_to_iface[num_pollfds] = ifaces_[i].get();
697  num_pollfds++;
698  }
699  }
700 
701  // This is where we abort when the last iface goes down
702  if (num_pollfds == 0)
703  {
704  throw AllIfacesDownException();
705  }
706 
707  // Timeout conversion
708  const std::int64_t timeout_usec = (blocking_deadline - clock_.getMonotonic()).toUSec();
709  auto ts = ::timespec();
710  if (timeout_usec > 0)
711  {
712  ts.tv_sec = timeout_usec / 1000000LL;
713  ts.tv_nsec = (timeout_usec % 1000000LL) * 1000;
714  }
715 
716  // Blocking here
717  const int res = ::ppoll(pollfds, num_pollfds, &ts, nullptr);
718  if (res < 0)
719  {
720  return res;
721  }
722 
723  // Handling poll output
724  for (unsigned i = 0; i < num_pollfds; i++)
725  {
726  pollfd_index_to_iface[i]->updateDownStatusFromPollResult(pollfds[i]);
727 
728  const bool poll_read = pollfds[i].revents & POLLIN;
729  const bool poll_write = pollfds[i].revents & POLLOUT;
730  pollfd_index_to_iface[i]->poll(poll_read, poll_write);
731  }
732  }
733 
734  // Writing the output masks
735  inout_masks = uavcan::CanSelectMasks();
736  for (unsigned i = 0; i < ifaces_.size(); i++)
737  {
738  if (!ifaces_[i]->isDown())
739  {
740  inout_masks.write |= std::uint8_t(1U << i); // Always ready to write if not down
741  }
742  if (ifaces_[i]->hasReadyRx())
743  {
744  inout_masks.read |= std::uint8_t(1U << i); // Readability depends only on RX buf, even if down
745  }
746  }
747 
748  // Return value is irrelevant as long as it's non-negative
749  return ifaces_.size();
750  }
751 
752  SocketCanIface* getIface(std::uint8_t iface_index) override
753  {
754  return (iface_index >= ifaces_.size()) ? nullptr : ifaces_[iface_index].get();
755  }
756 
757  std::uint8_t getNumIfaces() const override { return ifaces_.size(); }
758 
765  int addIface(const std::string& iface_name)
766  {
767  if (ifaces_.size() >= uavcan::MaxCanIfaces)
768  {
769  return -1;
770  }
771 
772  // Open the socket
773  const int fd = SocketCanIface::openSocket(iface_name);
774  if (fd < 0)
775  {
776  return fd;
777  }
778 
779  // Construct the iface - upon successful construction the iface will take ownership of the fd.
780  try
781  {
782  ifaces_.emplace_back(new IfaceWrapper(clock_, fd));
783  }
784  catch (...)
785  {
786  (void)::close(fd);
787  throw;
788  }
789 
790  UAVCAN_TRACE("SocketCAN", "New iface '%s' fd %d", iface_name.c_str(), fd);
791 
792  return ifaces_.size() - 1;
793  }
794 
798  bool isIfaceDown(std::uint8_t iface_index) const
799  {
800  return ifaces_.at(iface_index)->isDown();
801  }
802 };
803 
804 }
uavcan_linux::SocketCanIface::pollWrite
void pollWrite()
Definition: socketcan.hpp:272
uavcan_linux::SocketCanIface::TxItem::flags
uavcan::CanIOFlags flags
Definition: socketcan.hpp:105
uavcan::CanFrame::FlagEFF
static const uint32_t FlagEFF
Extended frame format.
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:28
uavcan_linux::SocketCanError::SocketReadFailure
@ SocketReadFailure
uavcan_linux::SocketCanIface::configureFilters
std::int16_t configureFilters(const uavcan::CanFilterConfig *const filter_configs, const std::uint16_t num_configs) override
Definition: socketcan.hpp:451
uavcan_linux::SocketCanIface::RxItem::frame
uavcan::CanFrame frame
Definition: socketcan.hpp:132
uavcan::CanFrame::FlagERR
static const uint32_t FlagERR
Error frame.
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:30
uavcan_linux::SocketCanIface::RxItem::ts_mono
uavcan::MonotonicTime ts_mono
Definition: socketcan.hpp:133
uavcan_linux::SocketCanIface::TxItem::TxItem
TxItem(const uavcan::CanFrame &arg_frame, uavcan::MonotonicTime arg_deadline, uavcan::CanIOFlags arg_flags, std::uint64_t arg_order)
Definition: socketcan.hpp:108
uavcan::uint64_t
std::uint64_t uint64_t
Definition: std.hpp:27
uavcan_linux::SocketCanIface::getNumFilters
std::uint16_t getNumFilters() const override
Definition: socketcan.hpp:493
uavcan_linux::SocketCanIface::incrementNumFramesInSocketTxQueue
void incrementNumFramesInSocketTxQueue()
Definition: socketcan.hpp:160
uavcan_linux::SocketCanIface::TxItem
Definition: socketcan.hpp:101
uavcan_linux::SocketCanDriver::IfaceWrapper::isDown
bool isDown() const
Definition: socketcan.hpp:642
uavcan_linux::SocketCanIface::receive
std::int16_t receive(uavcan::CanFrame &out_frame, uavcan::MonotonicTime &out_ts_monotonic, uavcan::UtcTime &out_ts_utc, uavcan::CanIOFlags &out_flags) override
Definition: socketcan.hpp:406
uavcan::UtcTime
Implicitly convertible to/from uavcan.Timestamp.
Definition: time.hpp:191
uavcan_linux::SocketCanIface::hw_filters_container_
std::vector<::can_filter > hw_filters_container_
Definition: socketcan.hpp:156
uavcan_linux::SystemClock::getPrivateAdjustment
uavcan::UtcDuration getPrivateAdjustment() const
Definition: platform_specific_components/linux/libuavcan/include/uavcan_linux/clock.hpp:172
pyuavcan_v0.driver.socketcan.CAN_EFF_MASK
int CAN_EFF_MASK
Definition: socketcan.py:149
uavcan_linux::SocketCanDriver::SocketCanDriver
SocketCanDriver(const SystemClock &clock)
Definition: socketcan.hpp:652
pyuavcan_v0.dsdl.parser.error
def error(fmt, *args)
Definition: parser.py:722
uavcan_linux::SocketCanDriver::IfaceWrapper::IfaceWrapper
IfaceWrapper(const SystemClock &clock, int fd)
Definition: socketcan.hpp:625
uavcan_linux::AllIfacesDownException
Definition: exception.hpp:63
pyuavcan_v0.driver.socketcan.CAN_EFF_FLAG
int CAN_EFF_FLAG
Definition: socketcan.py:148
uavcan_linux::SocketCanDriver::isIfaceDown
bool isIfaceDown(std::uint8_t iface_index) const
Definition: socketcan.hpp:798
uavcan_linux::SocketCanIface::makeUavcanFrame
static uavcan::CanFrame makeUavcanFrame(const ::can_frame &sockcan_frame)
Definition: socketcan.hpp:83
uavcan_linux::SocketCanIface::wasInPendingLoopbackSet
bool wasInPendingLoopbackSet(const uavcan::CanFrame &frame)
Definition: socketcan.hpp:178
uavcan_linux::SocketCanIface::registerError
void registerError(SocketCanError e)
Definition: socketcan.hpp:158
uavcan::ICanDriver
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:207
uavcan_linux::SocketCanDriver::addIface
int addIface(const std::string &iface_name)
Definition: socketcan.hpp:765
uavcan::CanFilterConfig
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:99
uavcan_linux::SocketCanIface::pollRead
void pollRead()
Definition: socketcan.hpp:308
uavcan::CanFrame
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:24
uavcan_linux::SocketCanDriver::IfaceWrapper::updateDownStatusFromPollResult
void updateDownStatusFromPollResult(const ::pollfd &pfd)
Definition: socketcan.hpp:627
uavcan::CanFrame::dlc
uint8_t dlc
Data Length Code.
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:36
uavcan::CanIOFlagLoopback
static const CanIOFlags CanIOFlagLoopback
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:141
pyuavcan_v0.driver.socketcan.SOL_CAN_RAW
int SOL_CAN_RAW
Definition: socketcan.py:62
UAVCAN_TRACE
#define UAVCAN_TRACE(...)
Definition: libuavcan/libuavcan/include/uavcan/debug.hpp:31
uavcan::int64_t
std::int64_t int64_t
Definition: std.hpp:32
uavcan::CanFrame::id
uint32_t id
CAN ID with flags (above)
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:34
uavcan_linux::SocketCanIface::getErrors
const decltype(errors_) & getErrors() const
Definition: socketcan.hpp:509
uavcan::MaxCanIfaces
@ MaxCanIfaces
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:19
uavcan_linux::SocketCanIface::TxItem::operator<
bool operator<(const TxItem &rhs) const
Definition: socketcan.hpp:116
uavcan_linux::SocketCanIface::checkHWFilters
bool checkHWFilters(const ::can_frame &frame) const
Definition: socketcan.hpp:347
uavcan_linux::SocketCanDriver::ifaces_
std::vector< std::unique_ptr< IfaceWrapper > > ifaces_
Definition: socketcan.hpp:646
uavcan::CanFrame::isErrorFrame
bool isErrorFrame() const
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:72
f
f
uavcan_linux::SocketCanIface::tx_frame_counter_
std::uint64_t tx_frame_counter_
Increments with every frame pushed into the TX queue.
Definition: socketcan.hpp:148
uavcan::uint16_t
std::uint16_t uint16_t
Definition: std.hpp:25
uavcan_linux::SocketCanDriver
Definition: socketcan.hpp:618
uavcan::int16_t
std::int16_t int16_t
Definition: std.hpp:30
uavcan_linux::SocketCanIface::getErrorCount
std::uint64_t getErrorCount() const override
Definition: socketcan.hpp:499
uavcan::TimeBase< UtcTime, UtcDuration >::fromUSec
static UtcTime fromUSec(uint64_t us)
Definition: time.hpp:112
uavcan_linux::SocketCanIface::hasReadyTx
bool hasReadyTx() const
Definition: socketcan.hpp:446
uavcan::CanSelectMasks::read
uint8_t read
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:121
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
uavcan::CanFrame::priorityLowerThan
bool priorityLowerThan(const CanFrame &rhs) const
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:91
uavcan_linux::SocketCanIface::write
int write(const uavcan::CanFrame &frame) const
Definition: socketcan.hpp:188
uavcan_linux::SocketCanIface::TxItem::order
std::uint64_t order
Definition: socketcan.hpp:106
uavcan::CanFilterConfig::mask
uint32_t mask
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:102
uavcan_linux::SocketCanDriver::getNumIfaces
std::uint8_t getNumIfaces() const override
Definition: socketcan.hpp:757
uavcan_linux::SocketCanError
SocketCanError
Definition: socketcan.hpp:35
uavcan_linux::SocketCanIface::hasReadyRx
bool hasReadyRx() const
Definition: socketcan.hpp:445
uavcan::CanFrame::MaskExtID
static const uint32_t MaskExtID
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:27
uavcan::CanSelectMasks
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:119
uavcan_linux::SocketCanIface::RxItem::ts_utc
uavcan::UtcTime ts_utc
Definition: socketcan.hpp:134
uavcan_linux::SocketCanIface::send
std::int16_t send(const uavcan::CanFrame &frame, const uavcan::MonotonicTime tx_deadline, const uavcan::CanIOFlags flags) override
Definition: socketcan.hpp:392
uavcan_linux::SocketCanIface::getFileDescriptor
int getFileDescriptor() const
Definition: socketcan.hpp:511
uavcan_linux::SocketCanIface::TxItem::deadline
uavcan::MonotonicTime deadline
Definition: socketcan.hpp:104
uavcan::CanSelectMasks::write
uint8_t write
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:122
uavcan::CanFrame::isRemoteTransmissionRequest
bool isRemoteTransmissionRequest() const
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:71
pyuavcan_v0.driver.socketcan.CAN_RAW
int CAN_RAW
Definition: socketcan.py:54
uavcan::TimeBase::isZero
bool isZero() const
Definition: time.hpp:123
uavcan_linux::SocketCanIface
Definition: socketcan.hpp:60
uavcan_linux::SocketCanDriver::getIface
SocketCanIface * getIface(std::uint8_t iface_index) override
Definition: socketcan.hpp:752
uavcan_linux::SocketCanIface::rx_queue_
std::queue< RxItem > rx_queue_
Definition: socketcan.hpp:153
uavcan_linux::SocketCanIface::TxItem::frame
uavcan::CanFrame frame
Definition: socketcan.hpp:103
uavcan::CanFrame::data
uint8_t data[MaxDataLen]
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:35
frame
uavcan::CanFrame frame
Definition: can.cpp:78
uavcan_linux::SocketCanIface::confirmSentFrame
void confirmSentFrame()
Definition: socketcan.hpp:166
uavcan::CanFrame::isExtended
bool isExtended() const
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:70
uavcan.hpp
uavcan_linux::SystemClock
Definition: platform_specific_components/linux/libuavcan/include/uavcan_linux/clock.hpp:33
uavcan_linux::SystemClock::getMonotonic
uavcan::MonotonicTime getMonotonic() const override
Definition: platform_specific_components/linux/libuavcan/include/uavcan_linux/clock.hpp:83
uavcan_linux::SocketCanError::TxTimeout
@ TxTimeout
uavcan_linux
Definition: platform_specific_components/linux/libuavcan/include/uavcan_linux/clock.hpp:18
uavcan_linux::SocketCanIface::RxItem::RxItem
RxItem()
Definition: socketcan.hpp:137
uavcan_linux::SocketCanDriver::select
std::int16_t select(uavcan::CanSelectMasks &inout_masks, const uavcan::CanFrame *(&)[uavcan::MaxCanIfaces], uavcan::MonotonicTime blocking_deadline) override
Definition: socketcan.hpp:664
uavcan_linux::SocketCanIface::RxItem::flags
uavcan::CanIOFlags flags
Definition: socketcan.hpp:135
uavcan_linux::SocketCanIface::errors_
std::map< SocketCanError, std::uint64_t > errors_
Definition: socketcan.hpp:150
exception.hpp
pyuavcan_v0.dsdl.signature.s
s
Definition: signature.py:73
uavcan_linux::SocketCanDriver::clock_
const SystemClock & clock_
Definition: socketcan.hpp:645
uavcan_linux::SocketCanIface::SocketCanIface
SocketCanIface(const SystemClock &clock, int socket_fd, int max_frames_in_socket_tx_queue=2)
Definition: socketcan.hpp:372
uavcan_linux::SocketCanIface::clock_
const SystemClock & clock_
Definition: socketcan.hpp:142
clock.hpp
uavcan_linux::SocketCanDriver::IfaceWrapper
Definition: socketcan.hpp:620
uavcan_linux::SocketCanError::SocketWriteFailure
@ SocketWriteFailure
uavcan::CanIOFlags
uint16_t CanIOFlags
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:140
uavcan_linux::SocketCanIface::tx_queue_
std::priority_queue< TxItem > tx_queue_
Definition: socketcan.hpp:152
uavcan_linux::SocketCanDriver::IfaceWrapper::down_
bool down_
Definition: socketcan.hpp:622
fill
static void fill(T(&a)[Size], R value)
Definition: transfer_buffer.cpp:30
uavcan_linux::SocketCanIface::frames_in_socket_tx_queue_
unsigned frames_in_socket_tx_queue_
Definition: socketcan.hpp:146
uavcan_linux::SocketCanIface::openSocket
static int openSocket(const std::string &iface_name)
Definition: socketcan.hpp:518
uavcan::MonotonicTime
Definition: time.hpp:184
uavcan_linux::SocketCanIface::fd_
const int fd_
Definition: socketcan.hpp:143
uavcan_linux::SocketCanIface::max_frames_in_socket_tx_queue_
const unsigned max_frames_in_socket_tx_queue_
Definition: socketcan.hpp:145
uavcan::CanFrame::priorityHigherThan
bool priorityHigherThan(const CanFrame &rhs) const
Definition: uc_can.cpp:19
uavcan_linux::SocketCanIface::poll
void poll(bool read, bool write)
Definition: socketcan.hpp:433
uavcan::ICanIface
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:147
pyuavcan_v0.driver.socketcan.SO_TIMESTAMP
int SO_TIMESTAMP
Definition: socketcan.py:151
pyuavcan_v0.driver.socketcan.AF_CAN
int AF_CAN
Definition: socketcan.py:57
uavcan::copy
UAVCAN_EXPORT OutputIt copy(InputIt first, InputIt last, OutputIt result)
Definition: templates.hpp:238
uavcan::CanFilterConfig::id
uint32_t id
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:101
uavcan_linux::SocketCanIface::read
int read(uavcan::CanFrame &frame, uavcan::UtcTime &ts_utc, bool &loopback) const
Definition: socketcan.hpp:217
uavcan_linux::SocketCanIface::pending_loopback_ids_
std::unordered_multiset< std::uint32_t > pending_loopback_ids_
Definition: socketcan.hpp:154
pyuavcan_v0.driver.socketcan.CAN_RAW_RECV_OWN_MSGS
int CAN_RAW_RECV_OWN_MSGS
Definition: socketcan.py:66
uavcan::CanFrame::FlagRTR
static const uint32_t FlagRTR
Remote transmission request.
Definition: libuavcan/libuavcan/include/uavcan/driver/can.hpp:29
uavcan_linux::SocketCanIface::NumFilters
static constexpr unsigned NumFilters
Definition: socketcan.hpp:492
uavcan_linux::SocketCanIface::makeSocketCanFrame
static inline ::can_frame makeSocketCanFrame(const uavcan::CanFrame &uavcan_frame)
Definition: socketcan.hpp:62
uavcan_linux::SocketCanIface::~SocketCanIface
virtual ~SocketCanIface()
Definition: socketcan.hpp:383
uavcan_linux::SocketCanIface::RxItem
Definition: socketcan.hpp:130


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:03