From 452e67cbf4a7898a543ed6e3112150cafaa985f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Jakub=C3=ADk?= Date: Wed, 29 May 2024 10:16:23 +0200 Subject: [PATCH 1/3] Implement configure_acceptance_filters for socketcan --- .../can/media/socketcan/_socketcan.py | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/pycyphal/transport/can/media/socketcan/_socketcan.py b/pycyphal/transport/can/media/socketcan/_socketcan.py index 17d68562..e634d163 100644 --- a/pycyphal/transport/can/media/socketcan/_socketcan.py +++ b/pycyphal/transport/can/media/socketcan/_socketcan.py @@ -123,12 +123,11 @@ def start(self, handler: Media.ReceivedFramesHandler, no_automatic_retransmissio def configure_acceptance_filters(self, configuration: typing.Sequence[FilterConfiguration]) -> None: if self._closed: raise pycyphal.transport.ResourceClosedError(repr(self)) - _logger.info( - "%s FIXME: acceptance filter configuration is not yet implemented; please submit patches! " - "Requested configuration: %s", - self, - ", ".join(map(str, configuration)), - ) + + try: + self._sock.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_FILTER, _pack_filters(configuration)) + except OSError as error: + _logger.error("Setting CAN filters failed: %s", error) async def send(self, frames: typing.Iterable[Envelope], monotonic_deadline: float) -> int: num_sent = 0 @@ -366,3 +365,28 @@ def _make_socket(iface_name: str, can_fd: bool, native_frame_size: int) -> socke raise return s + + +def _pack_filters(configuration: typing.Sequence[FilterConfiguration]) -> bytes: + """Convert a list of filters into a packed structure suitable for setsockopt(). + Inspired by python-can sources. + :param configuration: list of CAN filters + :type configuration: typing.Sequence[FilterConfiguration] + :return: packed structure suitable for setsockopt() + :rtype: bytes + """ + + can_filter_fmt = f"={2 * len(configuration)}I" + filter_data = [] + for can_filter in configuration: + can_id = can_filter.identifier + can_mask = can_filter.mask + if can_filter.format is not None: + # Match on either 11-bit OR 29-bit messages instead of both + can_mask |= _CAN_EFF_FLAG # Not using socket.CAN_EFF_FLAG because it is negative on 32 bit platforms + if can_filter.format == FrameFormat.EXTENDED: + can_id |= _CAN_EFF_FLAG + filter_data.append(can_id) + filter_data.append(can_mask) + + return struct.pack(can_filter_fmt, *filter_data) From b46181156ce2e1121664cfb7206b5ced48c4cd3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Jakub=C3=ADk?= <117373330+tomasjakubik@users.noreply.github.com> Date: Thu, 13 Jun 2024 06:07:14 +0200 Subject: [PATCH 2/3] Ignore missing types in MyPy on Windows Co-authored-by: Pavel Kirienko --- pycyphal/transport/can/media/socketcan/_socketcan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycyphal/transport/can/media/socketcan/_socketcan.py b/pycyphal/transport/can/media/socketcan/_socketcan.py index e634d163..ece360b8 100644 --- a/pycyphal/transport/can/media/socketcan/_socketcan.py +++ b/pycyphal/transport/can/media/socketcan/_socketcan.py @@ -125,7 +125,7 @@ def configure_acceptance_filters(self, configuration: typing.Sequence[FilterConf raise pycyphal.transport.ResourceClosedError(repr(self)) try: - self._sock.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_FILTER, _pack_filters(configuration)) + self._sock.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_FILTER, _pack_filters(configuration)) # type: ignore except OSError as error: _logger.error("Setting CAN filters failed: %s", error) From 660f62517bdcde51c17201e7dfb83ea62eb6cf47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Jakub=C3=ADk?= Date: Thu, 13 Jun 2024 06:18:22 +0200 Subject: [PATCH 3/3] Bump version --- CHANGELOG.rst | 4 ++++ pycyphal/_version.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index bf9938fb..4c3f1119 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,6 +3,10 @@ Changelog ========= +v1.19 +----- +- Implement configure_acceptance_filters for socketcan. + v1.18 ----- - Add FileClient2 which reports errors by raising exceptions. diff --git a/pycyphal/_version.py b/pycyphal/_version.py index 6cea18d8..d84d79d4 100644 --- a/pycyphal/_version.py +++ b/pycyphal/_version.py @@ -1 +1 @@ -__version__ = "1.18.0" +__version__ = "1.19.0"