pyxcp 0.25.1__cp314-cp314-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. pyxcp/__init__.py +20 -0
  2. pyxcp/aml/EtasCANMonitoring.a2l +82 -0
  3. pyxcp/aml/EtasCANMonitoring.aml +67 -0
  4. pyxcp/aml/XCP_Common.aml +408 -0
  5. pyxcp/aml/XCPonCAN.aml +78 -0
  6. pyxcp/aml/XCPonEth.aml +33 -0
  7. pyxcp/aml/XCPonFlx.aml +113 -0
  8. pyxcp/aml/XCPonSxI.aml +66 -0
  9. pyxcp/aml/XCPonUSB.aml +106 -0
  10. pyxcp/aml/ifdata_CAN.a2l +20 -0
  11. pyxcp/aml/ifdata_Eth.a2l +11 -0
  12. pyxcp/aml/ifdata_Flx.a2l +94 -0
  13. pyxcp/aml/ifdata_SxI.a2l +13 -0
  14. pyxcp/aml/ifdata_USB.a2l +81 -0
  15. pyxcp/asam/__init__.py +0 -0
  16. pyxcp/asam/types.py +131 -0
  17. pyxcp/asamkeydll +0 -0
  18. pyxcp/asamkeydll.c +116 -0
  19. pyxcp/asamkeydll.sh +2 -0
  20. pyxcp/checksum.py +732 -0
  21. pyxcp/cmdline.py +84 -0
  22. pyxcp/config/__init__.py +1257 -0
  23. pyxcp/config/legacy.py +120 -0
  24. pyxcp/constants.py +47 -0
  25. pyxcp/cpp_ext/__init__.py +0 -0
  26. pyxcp/cpp_ext/aligned_buffer.hpp +168 -0
  27. pyxcp/cpp_ext/bin.hpp +105 -0
  28. pyxcp/cpp_ext/blockmem.hpp +58 -0
  29. pyxcp/cpp_ext/cpp_ext.cpython-310-darwin.so +0 -0
  30. pyxcp/cpp_ext/cpp_ext.cpython-311-darwin.so +0 -0
  31. pyxcp/cpp_ext/cpp_ext.cpython-312-darwin.so +0 -0
  32. pyxcp/cpp_ext/cpp_ext.cpython-313-darwin.so +0 -0
  33. pyxcp/cpp_ext/cpp_ext.cpython-314-darwin.so +0 -0
  34. pyxcp/cpp_ext/daqlist.hpp +374 -0
  35. pyxcp/cpp_ext/event.hpp +67 -0
  36. pyxcp/cpp_ext/extension_wrapper.cpp +131 -0
  37. pyxcp/cpp_ext/framing.hpp +360 -0
  38. pyxcp/cpp_ext/helper.hpp +280 -0
  39. pyxcp/cpp_ext/mcobject.hpp +248 -0
  40. pyxcp/cpp_ext/sxi_framing.hpp +332 -0
  41. pyxcp/cpp_ext/tsqueue.hpp +46 -0
  42. pyxcp/daq_stim/__init__.py +306 -0
  43. pyxcp/daq_stim/optimize/__init__.py +67 -0
  44. pyxcp/daq_stim/optimize/binpacking.py +41 -0
  45. pyxcp/daq_stim/scheduler.cpp +62 -0
  46. pyxcp/daq_stim/scheduler.hpp +75 -0
  47. pyxcp/daq_stim/stim.cpp +13 -0
  48. pyxcp/daq_stim/stim.cpython-310-darwin.so +0 -0
  49. pyxcp/daq_stim/stim.cpython-311-darwin.so +0 -0
  50. pyxcp/daq_stim/stim.cpython-312-darwin.so +0 -0
  51. pyxcp/daq_stim/stim.cpython-313-darwin.so +0 -0
  52. pyxcp/daq_stim/stim.cpython-314-darwin.so +0 -0
  53. pyxcp/daq_stim/stim.hpp +604 -0
  54. pyxcp/daq_stim/stim_wrapper.cpp +50 -0
  55. pyxcp/dllif.py +100 -0
  56. pyxcp/errormatrix.py +878 -0
  57. pyxcp/examples/conf_can.toml +19 -0
  58. pyxcp/examples/conf_can_user.toml +16 -0
  59. pyxcp/examples/conf_can_vector.json +11 -0
  60. pyxcp/examples/conf_can_vector.toml +11 -0
  61. pyxcp/examples/conf_eth.toml +9 -0
  62. pyxcp/examples/conf_nixnet.json +20 -0
  63. pyxcp/examples/conf_socket_can.toml +12 -0
  64. pyxcp/examples/run_daq.py +165 -0
  65. pyxcp/examples/xcp_policy.py +60 -0
  66. pyxcp/examples/xcp_read_benchmark.py +38 -0
  67. pyxcp/examples/xcp_skel.py +49 -0
  68. pyxcp/examples/xcp_unlock.py +38 -0
  69. pyxcp/examples/xcp_user_supplied_driver.py +44 -0
  70. pyxcp/examples/xcphello.py +78 -0
  71. pyxcp/examples/xcphello_recorder.py +107 -0
  72. pyxcp/master/__init__.py +9 -0
  73. pyxcp/master/errorhandler.py +677 -0
  74. pyxcp/master/master.py +2641 -0
  75. pyxcp/py.typed +0 -0
  76. pyxcp/recorder/.idea/.gitignore +8 -0
  77. pyxcp/recorder/.idea/misc.xml +4 -0
  78. pyxcp/recorder/.idea/modules.xml +8 -0
  79. pyxcp/recorder/.idea/recorder.iml +6 -0
  80. pyxcp/recorder/.idea/sonarlint/issuestore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +7 -0
  81. pyxcp/recorder/.idea/sonarlint/issuestore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
  82. pyxcp/recorder/.idea/sonarlint/issuestore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
  83. pyxcp/recorder/.idea/sonarlint/issuestore/index.pb +7 -0
  84. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +0 -0
  85. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
  86. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
  87. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/index.pb +7 -0
  88. pyxcp/recorder/.idea/vcs.xml +10 -0
  89. pyxcp/recorder/__init__.py +96 -0
  90. pyxcp/recorder/build_clang.cmd +1 -0
  91. pyxcp/recorder/build_clang.sh +2 -0
  92. pyxcp/recorder/build_gcc.cmd +1 -0
  93. pyxcp/recorder/build_gcc.sh +2 -0
  94. pyxcp/recorder/build_gcc_arm.sh +2 -0
  95. pyxcp/recorder/converter/__init__.py +450 -0
  96. pyxcp/recorder/lz4.c +2829 -0
  97. pyxcp/recorder/lz4.h +879 -0
  98. pyxcp/recorder/lz4hc.c +2041 -0
  99. pyxcp/recorder/lz4hc.h +413 -0
  100. pyxcp/recorder/mio.hpp +1714 -0
  101. pyxcp/recorder/reader.hpp +138 -0
  102. pyxcp/recorder/reco.py +277 -0
  103. pyxcp/recorder/recorder.rst +0 -0
  104. pyxcp/recorder/rekorder.cpp +59 -0
  105. pyxcp/recorder/rekorder.cpython-310-darwin.so +0 -0
  106. pyxcp/recorder/rekorder.cpython-311-darwin.so +0 -0
  107. pyxcp/recorder/rekorder.cpython-312-darwin.so +0 -0
  108. pyxcp/recorder/rekorder.cpython-313-darwin.so +0 -0
  109. pyxcp/recorder/rekorder.cpython-314-darwin.so +0 -0
  110. pyxcp/recorder/rekorder.hpp +274 -0
  111. pyxcp/recorder/setup.py +41 -0
  112. pyxcp/recorder/test_reko.py +34 -0
  113. pyxcp/recorder/unfolder.hpp +1354 -0
  114. pyxcp/recorder/wrap.cpp +184 -0
  115. pyxcp/recorder/writer.hpp +302 -0
  116. pyxcp/scripts/__init__.py +0 -0
  117. pyxcp/scripts/pyxcp_probe_can_drivers.py +20 -0
  118. pyxcp/scripts/xcp_examples.py +64 -0
  119. pyxcp/scripts/xcp_fetch_a2l.py +40 -0
  120. pyxcp/scripts/xcp_id_scanner.py +19 -0
  121. pyxcp/scripts/xcp_info.py +144 -0
  122. pyxcp/scripts/xcp_profile.py +27 -0
  123. pyxcp/scripts/xmraw_converter.py +31 -0
  124. pyxcp/stim/__init__.py +0 -0
  125. pyxcp/tests/test_asam_types.py +24 -0
  126. pyxcp/tests/test_binpacking.py +186 -0
  127. pyxcp/tests/test_can.py +1324 -0
  128. pyxcp/tests/test_checksum.py +95 -0
  129. pyxcp/tests/test_daq.py +193 -0
  130. pyxcp/tests/test_daq_opt.py +426 -0
  131. pyxcp/tests/test_frame_padding.py +156 -0
  132. pyxcp/tests/test_framing.py +262 -0
  133. pyxcp/tests/test_master.py +2117 -0
  134. pyxcp/tests/test_transport.py +178 -0
  135. pyxcp/tests/test_utils.py +30 -0
  136. pyxcp/timing.py +60 -0
  137. pyxcp/transport/__init__.py +13 -0
  138. pyxcp/transport/base.py +484 -0
  139. pyxcp/transport/base_transport.hpp +0 -0
  140. pyxcp/transport/can.py +660 -0
  141. pyxcp/transport/eth.py +254 -0
  142. pyxcp/transport/sxi.py +209 -0
  143. pyxcp/transport/transport_ext.hpp +214 -0
  144. pyxcp/transport/transport_wrapper.cpp +249 -0
  145. pyxcp/transport/usb_transport.py +229 -0
  146. pyxcp/types.py +987 -0
  147. pyxcp/utils.py +128 -0
  148. pyxcp/vector/__init__.py +0 -0
  149. pyxcp/vector/map.py +82 -0
  150. pyxcp-0.25.1.dist-info/METADATA +341 -0
  151. pyxcp-0.25.1.dist-info/RECORD +154 -0
  152. pyxcp-0.25.1.dist-info/WHEEL +6 -0
  153. pyxcp-0.25.1.dist-info/entry_points.txt +9 -0
  154. pyxcp-0.25.1.dist-info/licenses/LICENSE +165 -0
@@ -0,0 +1,178 @@
1
+ from unittest import mock
2
+
3
+ import pytest
4
+ import serial
5
+ from can.bus import BusABC
6
+
7
+ import pyxcp.transport.base as tr
8
+ import pyxcp.transport.can as can_transport
9
+
10
+
11
+ def create_mock_serial():
12
+ """Create a mock serial port for testing."""
13
+ mock_serial = mock.MagicMock(spec=serial.Serial)
14
+ mock_serial.portstr = "MOCK_PORT"
15
+ mock_serial.in_waiting = 0
16
+ mock_serial.read.return_value = b""
17
+ mock_serial.is_open = True
18
+ return mock_serial
19
+
20
+
21
+ def create_mock_can_interface():
22
+ """Create a mock CAN interface for testing."""
23
+ mock_can = mock.MagicMock(spec=BusABC)
24
+ mock_can.filters = []
25
+ mock_can.state = "ACTIVE"
26
+ mock_can.recv.return_value = None
27
+ return mock_can
28
+
29
+
30
+ # Mock CAN interface configuration class
31
+ class MockCanInterfaceConfig:
32
+ OPTIONAL_BASE_PARAMS = []
33
+ CAN_PARAM_MAP = {}
34
+
35
+ @classmethod
36
+ def class_own_traits(cls):
37
+ return {}
38
+
39
+
40
+ def create_config():
41
+ # Create a class to simulate the config structure
42
+ class EthConfig:
43
+ def __init__(self):
44
+ self.host = "localhost"
45
+ self.port = 5555
46
+ self.bind_to_address = ""
47
+ self.bind_to_port = 0
48
+ self.protocol = "UDP"
49
+ self.ipv6 = False
50
+ self.tcp_nodelay = False
51
+
52
+ class SxiConfig:
53
+ def __init__(self):
54
+ self.port = "MOCK_PORT" # This won't be used with the mock
55
+ self.bitrate = 115200
56
+ self.bytesize = 8
57
+ self.parity = "N"
58
+ self.stopbits = 1
59
+ self.mode = "NORMAL"
60
+ self.header_format = "HEADER_LEN_BYTE"
61
+ self.tail_format = ""
62
+ self.framing = 0
63
+ self.esc_sync = 0
64
+ self.esc_esc = 0
65
+
66
+ class CanConfig:
67
+ def __init__(self):
68
+ self.can_id_master = 1
69
+ self.can_id_slave = 2
70
+ self.interface = "MockCanInterface"
71
+ self.channel = "vcan0"
72
+ self.use_default_listener = False # Don't start the listener
73
+ self.fd = False
74
+ self.max_dlc_required = False
75
+ self.padding_value = 0
76
+ self.timeout = 1.0
77
+ self.daq_identifier = [] # Empty list for DAQ identifiers
78
+
79
+ # Add the MockCanInterface attribute
80
+ self.MockCanInterface = MockCanInterfaceConfig()
81
+
82
+ # Special flag for testing
83
+ self.testing = True
84
+
85
+ class Config:
86
+ def __init__(self):
87
+ # Set attributes directly on the class for BaseTransport.load_config
88
+ self.eth = EthConfig()
89
+ self.sxi = SxiConfig()
90
+ self.can = CanConfig()
91
+
92
+ # Set attributes for BaseTransport.__init__
93
+ self.create_daq_timestamps = False
94
+ self.alignment = 1
95
+ self.timeout = 1.0
96
+
97
+ return Config()
98
+
99
+
100
+ @mock.patch("pyxcp.transport.can.detect_available_configs")
101
+ @mock.patch("pyxcp.transport.can.CAN_INTERFACE_MAP")
102
+ def test_factory_works(mock_can_interface_map, mock_detect_configs):
103
+ # Mock the detect_available_configs function to return an empty list
104
+ mock_detect_configs.return_value = []
105
+
106
+ # Mock the CAN_INTERFACE_MAP to return an instance of our MockCanInterfaceConfig for any key
107
+ mock_can_interface_map.__getitem__.return_value = MockCanInterfaceConfig()
108
+
109
+ config = create_config()
110
+ mock_serial_port = create_mock_serial()
111
+ mock_can_interface = create_mock_can_interface()
112
+
113
+ # Test ETH transport
114
+ assert isinstance(tr.create_transport("eth", config=config), tr.BaseTransport)
115
+
116
+ # Test SXI transport with mock serial port
117
+ assert isinstance(tr.create_transport("sxi", config=config, transport_layer_interface=mock_serial_port), tr.BaseTransport)
118
+
119
+ # Test CAN transport with mock CAN interface
120
+ # assert isinstance(
121
+ # tr.create_transport("can", config=config, transport_layer_interface=mock_can_interface),
122
+ # tr.BaseTransport,
123
+ # )
124
+
125
+
126
+ @mock.patch("pyxcp.transport.can.detect_available_configs")
127
+ @mock.patch("pyxcp.transport.can.CAN_INTERFACE_MAP")
128
+ def test_factory_works_case_insensitive(mock_can_interface_map, mock_detect_configs):
129
+ # Mock the detect_available_configs function to return an empty list
130
+ mock_detect_configs.return_value = []
131
+
132
+ # Mock the CAN_INTERFACE_MAP to return an instance of our MockCanInterfaceConfig for any key
133
+ mock_can_interface_map.__getitem__.return_value = MockCanInterfaceConfig()
134
+
135
+ config = create_config()
136
+ mock_serial_port = create_mock_serial()
137
+ mock_can_interface = create_mock_can_interface()
138
+
139
+ # Test ETH transport with uppercase name
140
+ assert isinstance(tr.create_transport("ETH", config=config), tr.BaseTransport)
141
+
142
+ # Test SXI transport with uppercase name and mock serial port
143
+ assert isinstance(tr.create_transport("SXI", config=config, transport_layer_interface=mock_serial_port), tr.BaseTransport)
144
+
145
+ # Test CAN transport with uppercase name and mock CAN interface
146
+ # assert isinstance(
147
+ # tr.create_transport("CAN", config=config, transport_layer_interface=mock_can_interface),
148
+ # tr.BaseTransport,
149
+ # )
150
+
151
+
152
+ def test_factory_invalid_transport_name_raises():
153
+ with pytest.raises(ValueError):
154
+ tr.create_transport("xCp")
155
+
156
+
157
+ def test_transport_names():
158
+ transports = tr.available_transports()
159
+
160
+ assert "can" in transports
161
+ assert "eth" in transports
162
+ assert "sxi" in transports
163
+
164
+
165
+ def test_transport_names_are_lower_case_only():
166
+ transports = tr.available_transports()
167
+
168
+ assert "CAN" not in transports
169
+ assert "ETH" not in transports
170
+ assert "SXI" not in transports
171
+
172
+
173
+ def test_transport_classes():
174
+ transports = tr.available_transports()
175
+
176
+ assert issubclass(transports.get("can"), tr.BaseTransport)
177
+ assert issubclass(transports.get("eth"), tr.BaseTransport)
178
+ assert issubclass(transports.get("sxi"), tr.BaseTransport)
@@ -0,0 +1,30 @@
1
+ from sys import version_info
2
+
3
+ from pyxcp.utils import PYTHON_VERSION, flatten, getPythonVersion, hexDump, slicer
4
+
5
+
6
+ def test_hexdump(capsys):
7
+ print(hexDump(range(16)), end="")
8
+ captured = capsys.readouterr()
9
+ assert captured.out == "[00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f]"
10
+
11
+
12
+ def test_slicer1():
13
+ res = slicer([1, 2, 3, 4, 5, 6, 7, 8], 4)
14
+ assert res == [[1, 2, 3, 4], [5, 6, 7, 8]]
15
+
16
+
17
+ def test_slicer2():
18
+ res = slicer(["10", "20", "30", "40", "50", "60", "70", "80"], 4, tuple)
19
+ assert res == [("10", "20", "30", "40"), ("50", "60", "70", "80")]
20
+
21
+
22
+ def test_flatten1():
23
+ res = flatten([[1, 2, 3, 4], [5, 6, 7, 8]])
24
+ assert res == [1, 2, 3, 4, 5, 6, 7, 8]
25
+
26
+
27
+ def test_version():
28
+ assert getPythonVersion() == version_info
29
+ assert PYTHON_VERSION == version_info
30
+ assert getPythonVersion() == PYTHON_VERSION
pyxcp/timing.py ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env python
2
+ import time
3
+
4
+
5
+ class Timing:
6
+ T_US = 1000 * 1000
7
+ T_MS = 1000
8
+ T_S = 1
9
+
10
+ UNIT_MAP = {
11
+ T_US: "uS",
12
+ T_MS: "mS",
13
+ T_S: "S",
14
+ }
15
+ FMT = "min: {0:2.3f} {4}\nmax: {1:2.3f} {4}\n" "avg: {2:2.3f} {4}\nlast: {3:2.3f} {4}"
16
+
17
+ def __init__(self, unit=T_MS, record=False):
18
+ self.min = None
19
+ self.max = None
20
+ self.avg = None
21
+ self._previous = None
22
+ self.unit = unit
23
+ self._record = record
24
+ self._values = []
25
+
26
+ def start(self):
27
+ self._start = time.perf_counter()
28
+
29
+ def stop(self):
30
+ self._stop = time.perf_counter()
31
+ elapsed = self._stop - self._start
32
+ if self._record:
33
+ self._values.append(elapsed)
34
+ if self._previous:
35
+ self.min = min(self._previous, elapsed)
36
+ self.max = max(self._previous, elapsed)
37
+ self.avg = (self._previous + elapsed) / 2
38
+ else:
39
+ self.min = self.max = self.avg = elapsed
40
+ self._previous = elapsed
41
+
42
+ def __str__(self):
43
+ unitName = Timing.UNIT_MAP.get(self.unit, "??")
44
+ self.min = 0 if self.min is None else self.min
45
+ self.max = 0 if self.max is None else self.max
46
+ self.avg = 0 if self.avg is None else self.avg
47
+ self._previous = 0 if self._previous is None else self._previous
48
+ return Timing.FMT.format(
49
+ self.min * self.unit,
50
+ self.max * self.unit,
51
+ self.avg * self.unit,
52
+ self._previous * self.unit,
53
+ unitName,
54
+ )
55
+
56
+ __repr__ = __str__
57
+
58
+ @property
59
+ def values(self):
60
+ return self._values
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env python
2
+ # from .transport_ext import (
3
+ # FrameAcquisitionPolicy, # noqa: F401
4
+ # FrameRecorderPolicy, # noqa: F401
5
+ # LegacyFrameAcquisitionPolicy, # noqa: F401
6
+ # NoOpPolicy, # noqa: F401
7
+ # StdoutPolicy, # noqa: F401
8
+ # )
9
+
10
+ from .can import Can # noqa: F401
11
+ from .eth import Eth # noqa: F401
12
+ from .sxi import SxI # noqa: F401
13
+ from .usb_transport import Usb # noqa: F401