72 struct ifreq interfaceRequestStructure;
73 const int RECEIVE_OWN_MESSAGES = 0;
74 const int DROP_MONITOR = 1;
75 const int TIMESTAMPING = 0x58;
76 const int TIMESTAMP = 1;
77 memset(&interfaceRequestStructure, 0,
sizeof(interfaceRequestStructure));
78 strncpy(interfaceRequestStructure.ifr_name,
name.c_str(),
sizeof(interfaceRequestStructure.ifr_name));
79 setsockopt(
fileDescriptor, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &RECEIVE_OWN_MESSAGES,
sizeof(RECEIVE_OWN_MESSAGES));
80 setsockopt(
fileDescriptor, SOL_SOCKET, SO_RXQ_OVFL, &DROP_MONITOR,
sizeof(DROP_MONITOR));
82 if (setsockopt(
fileDescriptor, SOL_SOCKET, SO_TIMESTAMPING, &TIMESTAMPING,
sizeof(TIMESTAMPING)) < 0)
84 setsockopt(
fileDescriptor, SOL_SOCKET, SO_TIMESTAMP, &TIMESTAMP,
sizeof(TIMESTAMP));
87 if (ioctl(
fileDescriptor, SIOCGIFINDEX, &interfaceRequestStructure) >= 0)
91 pCANDevice->can_ifindex = interfaceRequestStructure.ifr_ifindex;
111 struct pollfd pollingFileDescriptor;
115 pollingFileDescriptor.events = POLLIN;
116 pollingFileDescriptor.revents = 0;
118 if (1 == poll(&pollingFileDescriptor, 1, 100))
120 canFrame.
timestamp_us = std::numeric_limits<std::uint64_t>::max();
121 struct can_frame txFrame;
122 struct msghdr message;
123 struct iovec segment;
125 char lControlMessage[CMSG_SPACE(
sizeof(
struct timeval) + (3 *
sizeof(
struct timespec)) +
sizeof(std::uint32_t))];
127 segment.iov_base = &txFrame;
128 segment.iov_len =
sizeof(
struct can_frame);
129 message.msg_iov = &segment;
130 message.msg_iovlen = 1;
131 message.msg_control = &lControlMessage;
132 message.msg_controllen =
sizeof(lControlMessage);
134 message.msg_namelen =
sizeof(
struct sockaddr_can);
135 message.msg_flags = 0;
139 if (0 == (txFrame.can_id & CAN_ERR_FLAG))
141 if (0 != (txFrame.can_id & CAN_EFF_FLAG))
143 canFrame.
identifier = (txFrame.can_id & CAN_EFF_MASK);
148 canFrame.
identifier = (txFrame.can_id & CAN_SFF_MASK);
152 memset(canFrame.
data, 0,
sizeof(canFrame.
data));
155 for (
struct cmsghdr *pControlMessage = CMSG_FIRSTHDR(&message); (
nullptr != pControlMessage) && (SOL_SOCKET == pControlMessage->cmsg_level); pControlMessage = CMSG_NXTHDR(&message, pControlMessage))
157 switch (pControlMessage->cmsg_type)
161 struct timeval *time = (
struct timeval *)CMSG_DATA(pControlMessage);
163 if (std::numeric_limits<std::uint64_t>::max() == canFrame.
timestamp_us)
165 canFrame.
timestamp_us =
static_cast<std::uint64_t
>(time->tv_usec) + (
static_cast<std::uint64_t
>(time->tv_sec) * 1000000);
170 case SO_TIMESTAMPING:
172 struct timespec *time = (
struct timespec *)(CMSG_DATA(pControlMessage));
173 canFrame.
timestamp_us = (
static_cast<std::uint64_t
>(time[2].tv_nsec) / 1000) + (
static_cast<std::uint64_t
>(time[2].tv_sec) * 1000000);
181 else if (errno == ENETDOWN)
183 LOG_CRITICAL(
"[SocketCAN] " +
get_device_name() +
" interface is down.");
187 else if (pollingFileDescriptor.revents & (POLLERR | POLLHUP))