Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Socket setup
- */
- static int openSocket(const std::string& iface_name)
- {
- const int s = ::socket(PF_CAN, SOCK_RAW, CAN_RAW);
- if (s < 0)
- {
- return s;
- }
- /*
- * Detect the iface index
- */
- auto ifr = ::ifreq();
- std::strncpy(ifr.ifr_name, iface_name.c_str(), IFNAMSIZ);
- if (::ioctl(s, SIOCGIFINDEX, &ifr) < 0)
- {
- return -1;
- }
- if (ifr.ifr_ifindex < 0)
- {
- return -1;
- }
- /*
- * Bind to a CAN iface
- */
- auto addr = ::sockaddr_can();
- addr.can_family = AF_CAN;
- addr.can_ifindex = ifr.ifr_ifindex;
- if (::bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0)
- {
- return -1;
- }
- /*
- * Configure
- */
- const int on = 1;
- // Timestamping
- if (::setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)) < 0)
- {
- return -1;
- }
- // Socket loopback
- if (::setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &on, sizeof(on)) < 0)
- {
- return -1;
- }
- // Non-blocking
- if (::fcntl(s, F_SETFL , O_NONBLOCK) < 0)
- {
- return -1;
- }
- return s;
- }
- /*
- * Here's the problem
- */
- int read(uavcan::CanFrame& frame, uavcan::UtcTime& ts_utc, bool& loopback) const
- {
- auto iov = ::iovec();
- auto sockcan_frame = ::can_frame();
- iov.iov_base = &sockcan_frame;
- iov.iov_len = sizeof(sockcan_frame);
- auto msg = ::msghdr();
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- const int res = ::recvmsg(fd_, &msg, MSG_DONTWAIT);
- if (res <= 0)
- {
- return res;
- }
- // At this point sockcan_frame contains valid data, i.e. generally recvmsg() works OK
- for (::cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg != nullptr; cmsg = CMSG_NXTHDR(&msg, cmsg))
- {
- // Problem: no control messages were received (msg.msg_controllen is zero)
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP)
- {
- <...>
- }
- }
- <...>
- }
Advertisement
Add Comment
Please, Sign In to add comment