Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions python/fusion_engine_client/applications/p1_capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from ..utils.socket_timestamping import (enable_socket_timestamping,
HW_TIMESTAMPING_HELP,
log_timestamped_data_offset,
parse_timestamps_from_ancdata,
recv,
TIMESTAMP_FILE_ENDING,)
from ..utils.transport_utils import *
from ..utils.trace import HighlightFormatter, BrokenPipeStreamHandler
Expand Down Expand Up @@ -206,8 +206,7 @@ def _print_status(now):
if isinstance(transport, socket.socket):
ready = select.select([transport], [], [], read_timeout_sec)
if ready[0]:
received_data, ancdata, _, _ = transport.recvmsg(1024, 1024)
kernel_ts, _, hw_ts = parse_timestamps_from_ancdata(ancdata)
received_data, kernel_ts, hw_ts = recv(transport, 1024)
else:
received_data = []
# If this is a serial port, we set the read timeout above.
Expand Down
53 changes: 44 additions & 9 deletions python/fusion_engine_client/utils/socket_timestamping.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import socket
import struct
import sys
from typing import BinaryIO, Optional, TypeAlias
from typing import BinaryIO, Optional, Tuple, TypeAlias


_CMSG: TypeAlias = tuple[int, int, bytes]
Expand Down Expand Up @@ -102,16 +102,51 @@ def parse_timestamps_from_ancdata(ancdata: list[_CMSG]) -> tuple[Optional[float]
return tuple(timestamps)


def enable_socket_timestamping(sock: socket.socket, enable_sw_timestamp: bool, enable_hw_timestamp: bool):
if enable_sw_timestamp or enable_hw_timestamp:
flags = 0
if enable_sw_timestamp:
flags |= SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE
def enable_socket_timestamping(sock: socket.socket, enable_sw_timestamp: bool, enable_hw_timestamp: bool) -> bool:
'''!
Enable kernel-level hardware or software timestamping of incoming socket data.

if enable_hw_timestamp:
flags |= SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE
@param sock The socket to be used.
@param enable_sw_timestamp Set to `True` to enable software timestamping in the kernel.
@param enable_hw_timestamp Set to `True` to enable hardware timestamping by the network interface.

sock.setsockopt(socket.SOL_SOCKET, SO_TIMESTAMPING, flags)
@return `True` if timestamping is supported on the host OS.
'''
if sys.platform == "linux":
if enable_sw_timestamp or enable_hw_timestamp:
flags = 0
if enable_sw_timestamp:
flags |= SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE

if enable_hw_timestamp:
flags |= SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE

sock.setsockopt(socket.SOL_SOCKET, SO_TIMESTAMPING, flags)
return True
else:
return False


def recv(sock: socket.socket, buffer_size: int) -> Tuple[bytes, Optional[float], Optional[float]]:
'''!
Receive data from the specified socket and capture timestamps, if enabled.

@param sock The socket to be used.
@param buffer_size The maximum number of bytes to read.

@return A tuple containing:
- The bytes read from the socket
- The kernel timestamp, if enabled
- The hardware timestamp, if enabled
'''
if sys.platform == "linux":
received_data, ancdata, _, _ = sock.recvmsg(buffer_size, 1024)
kernel_ts, _, hw_ts = parse_timestamps_from_ancdata(ancdata)
else:
received_data = sock.recv(buffer_size)
kernel_ts = None
hw_ts = None
return received_data, kernel_ts, hw_ts


def log_timestamped_data_offset(fd: BinaryIO, timestamp_ns: int, byte_offset: int):
Expand Down
Loading