Skip to content

Commit ff2c25f

Browse files
committed
Add PcapngReader
1 parent 20a5073 commit ff2c25f

File tree

4 files changed

+66
-4
lines changed

4 files changed

+66
-4
lines changed

can/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"MessageSync",
4545
"ModifiableCyclicTaskABC",
4646
"Notifier",
47+
"PcapngReader",
4748
"PcapngWriter",
4849
"Printer",
4950
"RedirectReader",
@@ -112,6 +113,7 @@
112113
MessageSync,
113114
MF4Reader,
114115
MF4Writer,
116+
PcapngReader,
115117
PcapngWriter,
116118
Printer,
117119
SizedRotatingLogger,

can/io/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"MF4Reader",
2121
"MF4Writer",
2222
"MessageSync",
23+
"PcapngReader",
2324
"PcapngWriter",
2425
"Printer",
2526
"SizedRotatingLogger",
@@ -53,7 +54,7 @@
5354
from .canutils import CanutilsLogReader, CanutilsLogWriter
5455
from .csv import CSVReader, CSVWriter
5556
from .mf4 import MF4Reader, MF4Writer
56-
from .pcapng import PcapngWriter
57+
from .pcapng import PcapngReader, PcapngWriter
5758
from .printer import Printer
5859
from .sqlite import SqliteReader, SqliteWriter
5960
from .trc import TRCFileVersion, TRCReader, TRCWriter

can/io/pcapng.py

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66
"""
77

88
import logging
9-
from typing import Any, BinaryIO, Dict, Optional, Union
9+
from typing import Any, BinaryIO, Dict, Generator, Optional, Union
1010

1111
from ..message import Message
12-
from ..socketcan_common import CAN_FRAME_HEADER_STRUCT_BE, build_can_frame
12+
from ..socketcan_common import (
13+
CAN_FRAME_HEADER_STRUCT_BE,
14+
build_can_frame,
15+
parse_can_frame,
16+
)
1317
from ..typechecking import Channel, StringPathLike
14-
from .generic import BinaryIOMessageWriter
18+
from .generic import BinaryIOMessageReader, BinaryIOMessageWriter
1519

1620
logger = logging.getLogger("can.io.pcapng")
1721

@@ -108,3 +112,56 @@ def on_message_received(self, msg: Message) -> None:
108112
endianness=">", # big
109113
)
110114
)
115+
116+
117+
class PcapngReader(BinaryIOMessageReader):
118+
"""
119+
Iterator of CAN messages from a Pcapng File.
120+
"""
121+
122+
file: BinaryIO
123+
124+
def __init__(
125+
self,
126+
file: Union[StringPathLike, BinaryIO],
127+
**kwargs: Any,
128+
) -> None:
129+
"""
130+
:param file: a path-like object or as file-like object to read from
131+
If this is a file-like object, is has to opened in binary
132+
read mode, not text read mode.
133+
"""
134+
135+
if pcapng is None:
136+
raise NotImplementedError(
137+
"The python-pcapng package was not found. Install python-can with "
138+
"the optional dependency [pcapng] to use the PcapngReader."
139+
)
140+
141+
super().__init__(file, mode="rb")
142+
self._scanner = pcapng.FileScanner(self.file)
143+
144+
def __iter__(self) -> Generator[Message, None, None]:
145+
for block in self._scanner:
146+
if isinstance(block, blocks.EnhancedPacket):
147+
idn: blocks.InterfaceDescription = block.interface
148+
# We only care about the CAN packets
149+
if idn.link_type != LINKTYPE_CAN_SOCKETCAN:
150+
logger.debug(
151+
"Skipping non-CAN packet, link type: %s", idn.link_type
152+
)
153+
continue
154+
155+
msg = parse_can_frame(
156+
block.packet_data, structure=CAN_FRAME_HEADER_STRUCT_BE
157+
)
158+
159+
timestamp64 = (block.timestamp_high << 32) + block.timestamp_low
160+
msg.timestamp = timestamp64 * idn.timestamp_resolution
161+
162+
if "if_name" in idn.options:
163+
msg.channel = idn.options["if_name"]
164+
else:
165+
msg.channel = block.interface_id
166+
167+
yield msg

can/io/player.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from .csv import CSVReader
2828
from .generic import BinaryIOMessageReader, MessageReader
2929
from .mf4 import MF4Reader
30+
from .pcapng import PcapngReader
3031
from .sqlite import SqliteReader
3132
from .trc import TRCReader
3233

@@ -39,6 +40,7 @@
3940
".db": SqliteReader,
4041
".log": CanutilsLogReader,
4142
".mf4": MF4Reader,
43+
".pcapng": PcapngReader,
4244
".trc": TRCReader,
4345
}
4446

0 commit comments

Comments
 (0)