10 from __future__
import division, absolute_import, print_function, unicode_literals
19 from logging
import getLogger
21 from .common
import DriverError, TxQueueFullError, CANFrame, AbstractDriver
22 from .timestamp_estimator
import TimestampEstimator
30 logger = getLogger(__name__)
40 s = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
44 NATIVE_SOCKETCAN =
True
46 NATIVE_SOCKETCAN =
False
51 libc = ctypes.CDLL(ctypes.util.find_library(
"c"), use_errno=
True)
59 from socket
import SOL_SOCKET
62 SOL_CAN_RAW = SOL_CAN_BASE + CAN_RAW
64 CAN_RAW_ERR_FILTER = 2
66 CAN_RAW_RECV_OWN_MSGS = 4
72 typedef __u32 canid_t;
74 sa_family_t can_family;
77 struct { canid_t rx_id, tx_id; } tp;
82 (
"can_family", ctypes.c_uint16),
83 (
"can_ifindex", ctypes.c_int),
84 (
"can_addr_tp_rx_id", ctypes.c_uint32),
85 (
"can_addr_tp_tx_id", ctypes.c_uint32)
91 typedef __u32 canid_t;
95 __u8 data[8] __attribute__((aligned(8)));
99 (
"can_id", ctypes.c_uint32),
100 (
"can_dlc", ctypes.c_uint8),
101 (
"_pad", ctypes.c_ubyte * 3),
102 (
"data", ctypes.c_uint8 * 8)
113 buf = ctypes.create_string_buffer(bufsize)
114 nbytes = libc.read(self.
fd, ctypes.byref(buf), bufsize)
119 ctypes.memmove(ctypes.byref(frame), data, ctypes.sizeof(frame))
120 return libc.write(self.
fd, ctypes.byref(frame), ctypes.sizeof(frame))
129 socket_fd = libc.socket(AF_CAN, socket.SOCK_RAW, CAN_RAW)
133 libc.fcntl(socket_fd, fcntl.F_SETFL, os.O_NONBLOCK)
135 ifidx = libc.if_nametoindex(ifname)
136 if ctypes.get_errno() != 0:
137 raise DriverError(
'Could not determine iface index [errno %s]' % ctypes.get_errno())
140 error = libc.bind(socket_fd, ctypes.byref(addr), ctypes.sizeof(addr))
142 raise DriverError(
'Could not bind socket [errno %s]' % ctypes.get_errno())
148 CAN_EFF_FLAG = 0x80000000
149 CAN_EFF_MASK = 0x1FFFFFFF
155 FRAME_FORMAT =
'=IB3x8s'
157 TIMEVAL_FORMAT =
'@LL'
166 self.
_poll_rx.register(self.
socket.fileno(), select.POLLIN | select.POLLPRI | select.POLLERR)
178 self.
socket.setsockopt(socket.SOL_SOCKET, SO_TIMESTAMP, 1)
180 ppm =
lambda x: x / 1e6
181 milliseconds =
lambda x: x * 1e-3
186 fixed_delay=milliseconds(0.001),
187 max_phase_error_to_resync=milliseconds(50))
190 mono = time.monotonic()
193 mono_to_real_offset = est_real - mono
194 return value - mono_to_real_offset
206 message_id = frame.id | (CAN_EFF_FLAG
if frame.extended
else 0)
207 message_pad = bytes(frame.data) + b
'\x00' * (8 - len(frame.data))
208 raw_message = struct.pack(self.
FRAME_FORMAT, message_id, len(frame.data), message_pad)
212 frame.ts_monotonic = time.monotonic()
213 frame.ts_real = time.time()
215 except OSError
as ex:
216 if ex.errno == errno.ENOBUFS:
222 except Exception
as ex:
231 if isinstance(item, Exception):
234 if isinstance(item, CANFrame):
237 raise DriverError(
'Unexpected item in write feedback queue: %r' % item)
247 timeout = -1
if timeout
is None else (timeout * 1000)
257 socket.CMSG_SPACE(ancillary_len))
260 for cmsg_level, cmsg_type, cmsg_data
in ancdata:
261 if cmsg_level == socket.SOL_SOCKET
and cmsg_type == SO_TIMESTAMP:
263 ts_real = sec + usec * 1e-6
268 can_id, can_dlc, can_data = struct.unpack(self.
FRAME_FORMAT, packet_raw)
272 if ts_real
and not ts_mono:
275 frame =
CANFrame(can_id & CAN_EFF_MASK, can_data[0:can_dlc], bool(can_id & CAN_EFF_FLAG),
276 ts_monotonic=ts_mono, ts_real=ts_real)
280 def send(self, message_id, message, extended=False):