pyxcp 0.25.2__cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.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 (151) 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 +83 -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-x86_64-linux-gnu.so +0 -0
  30. pyxcp/cpp_ext/cpp_ext.cpython-311-x86_64-linux-gnu.so +0 -0
  31. pyxcp/cpp_ext/cpp_ext.cpython-312-x86_64-linux-gnu.so +0 -0
  32. pyxcp/cpp_ext/cpp_ext.cpython-313-x86_64-linux-gnu.so +0 -0
  33. pyxcp/cpp_ext/daqlist.hpp +374 -0
  34. pyxcp/cpp_ext/event.hpp +67 -0
  35. pyxcp/cpp_ext/extension_wrapper.cpp +131 -0
  36. pyxcp/cpp_ext/framing.hpp +360 -0
  37. pyxcp/cpp_ext/helper.hpp +280 -0
  38. pyxcp/cpp_ext/mcobject.hpp +248 -0
  39. pyxcp/cpp_ext/sxi_framing.hpp +332 -0
  40. pyxcp/cpp_ext/tsqueue.hpp +46 -0
  41. pyxcp/daq_stim/__init__.py +306 -0
  42. pyxcp/daq_stim/optimize/__init__.py +67 -0
  43. pyxcp/daq_stim/optimize/binpacking.py +41 -0
  44. pyxcp/daq_stim/scheduler.cpp +62 -0
  45. pyxcp/daq_stim/scheduler.hpp +75 -0
  46. pyxcp/daq_stim/stim.cpp +13 -0
  47. pyxcp/daq_stim/stim.cpython-310-x86_64-linux-gnu.so +0 -0
  48. pyxcp/daq_stim/stim.cpython-311-x86_64-linux-gnu.so +0 -0
  49. pyxcp/daq_stim/stim.cpython-312-x86_64-linux-gnu.so +0 -0
  50. pyxcp/daq_stim/stim.cpython-313-x86_64-linux-gnu.so +0 -0
  51. pyxcp/daq_stim/stim.hpp +604 -0
  52. pyxcp/daq_stim/stim_wrapper.cpp +50 -0
  53. pyxcp/dllif.py +100 -0
  54. pyxcp/errormatrix.py +878 -0
  55. pyxcp/examples/conf_can.toml +19 -0
  56. pyxcp/examples/conf_can_user.toml +16 -0
  57. pyxcp/examples/conf_can_vector.json +11 -0
  58. pyxcp/examples/conf_can_vector.toml +11 -0
  59. pyxcp/examples/conf_eth.toml +9 -0
  60. pyxcp/examples/conf_nixnet.json +20 -0
  61. pyxcp/examples/conf_socket_can.toml +12 -0
  62. pyxcp/examples/run_daq.py +165 -0
  63. pyxcp/examples/xcp_policy.py +60 -0
  64. pyxcp/examples/xcp_read_benchmark.py +38 -0
  65. pyxcp/examples/xcp_skel.py +48 -0
  66. pyxcp/examples/xcp_unlock.py +38 -0
  67. pyxcp/examples/xcp_user_supplied_driver.py +43 -0
  68. pyxcp/examples/xcphello.py +79 -0
  69. pyxcp/examples/xcphello_recorder.py +107 -0
  70. pyxcp/master/__init__.py +10 -0
  71. pyxcp/master/errorhandler.py +677 -0
  72. pyxcp/master/master.py +2645 -0
  73. pyxcp/py.typed +0 -0
  74. pyxcp/recorder/.idea/.gitignore +8 -0
  75. pyxcp/recorder/.idea/misc.xml +4 -0
  76. pyxcp/recorder/.idea/modules.xml +8 -0
  77. pyxcp/recorder/.idea/recorder.iml +6 -0
  78. pyxcp/recorder/.idea/sonarlint/issuestore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +7 -0
  79. pyxcp/recorder/.idea/sonarlint/issuestore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
  80. pyxcp/recorder/.idea/sonarlint/issuestore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
  81. pyxcp/recorder/.idea/sonarlint/issuestore/index.pb +7 -0
  82. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +0 -0
  83. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
  84. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
  85. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/index.pb +7 -0
  86. pyxcp/recorder/.idea/vcs.xml +10 -0
  87. pyxcp/recorder/__init__.py +96 -0
  88. pyxcp/recorder/build_clang.cmd +1 -0
  89. pyxcp/recorder/build_clang.sh +2 -0
  90. pyxcp/recorder/build_gcc.cmd +1 -0
  91. pyxcp/recorder/build_gcc.sh +2 -0
  92. pyxcp/recorder/build_gcc_arm.sh +2 -0
  93. pyxcp/recorder/converter/__init__.py +445 -0
  94. pyxcp/recorder/lz4.c +2829 -0
  95. pyxcp/recorder/lz4.h +879 -0
  96. pyxcp/recorder/lz4hc.c +2041 -0
  97. pyxcp/recorder/lz4hc.h +413 -0
  98. pyxcp/recorder/mio.hpp +1714 -0
  99. pyxcp/recorder/reader.hpp +138 -0
  100. pyxcp/recorder/reco.py +278 -0
  101. pyxcp/recorder/recorder.rst +0 -0
  102. pyxcp/recorder/rekorder.cpp +59 -0
  103. pyxcp/recorder/rekorder.cpython-310-x86_64-linux-gnu.so +0 -0
  104. pyxcp/recorder/rekorder.cpython-311-x86_64-linux-gnu.so +0 -0
  105. pyxcp/recorder/rekorder.cpython-312-x86_64-linux-gnu.so +0 -0
  106. pyxcp/recorder/rekorder.cpython-313-x86_64-linux-gnu.so +0 -0
  107. pyxcp/recorder/rekorder.hpp +274 -0
  108. pyxcp/recorder/setup.py +41 -0
  109. pyxcp/recorder/test_reko.py +34 -0
  110. pyxcp/recorder/unfolder.hpp +1354 -0
  111. pyxcp/recorder/wrap.cpp +184 -0
  112. pyxcp/recorder/writer.hpp +302 -0
  113. pyxcp/scripts/__init__.py +0 -0
  114. pyxcp/scripts/pyxcp_probe_can_drivers.py +20 -0
  115. pyxcp/scripts/xcp_examples.py +64 -0
  116. pyxcp/scripts/xcp_fetch_a2l.py +40 -0
  117. pyxcp/scripts/xcp_id_scanner.py +18 -0
  118. pyxcp/scripts/xcp_info.py +144 -0
  119. pyxcp/scripts/xcp_profile.py +26 -0
  120. pyxcp/scripts/xmraw_converter.py +31 -0
  121. pyxcp/stim/__init__.py +0 -0
  122. pyxcp/tests/test_asam_types.py +24 -0
  123. pyxcp/tests/test_binpacking.py +186 -0
  124. pyxcp/tests/test_can.py +1324 -0
  125. pyxcp/tests/test_checksum.py +95 -0
  126. pyxcp/tests/test_daq.py +193 -0
  127. pyxcp/tests/test_daq_opt.py +426 -0
  128. pyxcp/tests/test_frame_padding.py +156 -0
  129. pyxcp/tests/test_framing.py +262 -0
  130. pyxcp/tests/test_master.py +2116 -0
  131. pyxcp/tests/test_transport.py +177 -0
  132. pyxcp/tests/test_utils.py +30 -0
  133. pyxcp/timing.py +60 -0
  134. pyxcp/transport/__init__.py +13 -0
  135. pyxcp/transport/base.py +484 -0
  136. pyxcp/transport/base_transport.hpp +0 -0
  137. pyxcp/transport/can.py +660 -0
  138. pyxcp/transport/eth.py +254 -0
  139. pyxcp/transport/sxi.py +209 -0
  140. pyxcp/transport/transport_ext.hpp +214 -0
  141. pyxcp/transport/transport_wrapper.cpp +249 -0
  142. pyxcp/transport/usb_transport.py +229 -0
  143. pyxcp/types.py +987 -0
  144. pyxcp/utils.py +127 -0
  145. pyxcp/vector/__init__.py +0 -0
  146. pyxcp/vector/map.py +82 -0
  147. pyxcp-0.25.2.dist-info/METADATA +341 -0
  148. pyxcp-0.25.2.dist-info/RECORD +151 -0
  149. pyxcp-0.25.2.dist-info/WHEEL +6 -0
  150. pyxcp-0.25.2.dist-info/entry_points.txt +9 -0
  151. pyxcp-0.25.2.dist-info/licenses/LICENSE +165 -0
@@ -0,0 +1,2116 @@
1
+ #!/usr/bin/env python
2
+ import selectors
3
+ import struct
4
+ import threading
5
+ import time
6
+ from collections import deque
7
+ from unittest import mock
8
+
9
+ from pyxcp import types
10
+ from pyxcp.master import Master
11
+
12
+
13
+ def create_config():
14
+ # Create a class to simulate the config structure
15
+ class EthConfig:
16
+ def __init__(self):
17
+ self.host = "localhost"
18
+ self.port = 5555
19
+ self.bind_to_address = ""
20
+ self.bind_to_port = 0
21
+ self.protocol = "UDP"
22
+ self.ipv6 = False
23
+ self.tcp_nodelay = False
24
+ self.timeout = 1.0
25
+
26
+ class GeneralConfig:
27
+ def __init__(self):
28
+ self.disable_error_handling = False
29
+ self.stim_support = False
30
+ self.seed_n_key_dll = None
31
+ self.seed_n_key_function = None
32
+ self.seed_n_key_dll_same_bit_width = False
33
+ self.disconnect_response_optional = False
34
+ self.connect_retries = 0 # Disable connect retries for testing
35
+
36
+ class TransportConfig:
37
+ def __init__(self):
38
+ self.create_daq_timestamps = False
39
+ self.alignment = 1
40
+ self.timeout = 1.0
41
+ self.eth = EthConfig()
42
+
43
+ class Config:
44
+ def __init__(self):
45
+ self.general = GeneralConfig()
46
+ self.transport = TransportConfig()
47
+
48
+ return Config()
49
+
50
+
51
+ class MockSocket:
52
+ def __init__(self):
53
+ self.data = bytearray()
54
+ self.ctr = 0
55
+ self.has_data_event = threading.Event()
56
+
57
+ # push frame consisting of header (len + ctr) and packet
58
+ def push_frame(self, frame):
59
+ try:
60
+ self.data.extend(frame)
61
+ except TypeError:
62
+ self.data.extend(bytes.fromhex(frame))
63
+ self.ctr += 1
64
+ self.has_data_event.set() # Signal that data is available
65
+
66
+ # push packet, automatically add header (len + ctr)
67
+ def push_packet(self, data):
68
+ try:
69
+ data = bytes.fromhex(data)
70
+ except TypeError:
71
+ pass
72
+
73
+ header = struct.pack("<HH", len(data), self.ctr)
74
+ self.push_frame(header + data)
75
+
76
+ def recv(self, bufsize):
77
+ r = self.data[:bufsize]
78
+ self.data = self.data[bufsize:]
79
+ if not self.data:
80
+ self.has_data_event.clear() # Signal that no more data is available
81
+ return r
82
+
83
+ def recvfrom(self, bufsize):
84
+ return self.recv(bufsize), ("localhost", 5555)
85
+
86
+ def select(self, timeout):
87
+ if self.data:
88
+ return [(0, selectors.EVENT_READ)]
89
+ else:
90
+ # Wait for data to be available or timeout
91
+ if self.has_data_event.wait(timeout):
92
+ return [(0, selectors.EVENT_READ)]
93
+ return []
94
+
95
+ def connect(self):
96
+ pass
97
+
98
+
99
+ class MockCanInterface: # CanInterfaceBase
100
+ def __init__(self):
101
+ self.data = deque()
102
+ self.receive_callback = None
103
+ self.is_fd = False
104
+
105
+ def init(self, parent, receive_callback):
106
+ self.receive_callback = receive_callback
107
+
108
+ # push packet
109
+ def push_packet(self, data):
110
+ try:
111
+ data = bytes.fromhex(data)
112
+ except TypeError:
113
+ pass
114
+ # no header on CAN
115
+ self.push_frame(data)
116
+
117
+ def push_frame(self, packet):
118
+ self.data.append(packet)
119
+
120
+ def transmit(self, payload: bytes):
121
+ time.sleep(0.001)
122
+ try:
123
+ resp = self.data.popleft()
124
+ if resp:
125
+ self.receive_callback(resp)
126
+ except IndexError:
127
+ pass
128
+
129
+ def close(self):
130
+ pass
131
+
132
+ def connect(self):
133
+ pass
134
+
135
+ def read(self):
136
+ pass
137
+
138
+ def get_timestamp_resolution(self):
139
+ pass
140
+
141
+
142
+ class TestMaster:
143
+ DefaultConnectCmd = bytes([0x02, 0x00, 0x00, 0x00, 0xFF, 0x00])
144
+ # Response format: PID, Resource, CommModeBasic, MaxCto, MaxDto (2 bytes), ProtocolLayerVersion, TransportLayerVersion
145
+ # FF = positive response
146
+ # 1D = Resource (bits: 00011101 - dbg=0, pgm=1, stim=1, daq=1, pad=0, calpag=1)
147
+ # C0 = CommModeBasic (bits: 11000000 - optional=1, slaveBlockMode=1, pad=000, addressGranularity=00 (BYTE), byteOrder=0 (INTEL))
148
+ # FF = MaxCto (255)
149
+ # DC 05 = MaxDto (1500)
150
+ # 01 = ProtocolLayerVersion (1)
151
+ # 01 = TransportLayerVersion (1)
152
+ DefaultConnectResponse = "FF 1D C0 FF DC 05 01 01"
153
+
154
+ @mock.patch("pyxcp.master.master.Master.connect")
155
+ def testConnect(self, mock_connect):
156
+ # Create a response object with the expected values
157
+ from construct import Container
158
+
159
+ # Create nested containers for resource and commModeBasic
160
+ resource = Container(dbg=False, pgm=True, stim=True, daq=True, calpag=True)
161
+
162
+ commModeBasic = Container(
163
+ optional=True, slaveBlockMode=True, addressGranularity=types.AddressGranularity.BYTE, byteOrder=types.ByteOrder.INTEL
164
+ )
165
+
166
+ # Create the main response container
167
+ response = Container(
168
+ resource=resource, commModeBasic=commModeBasic, maxCto=255, maxDto=1500, protocolLayerVersion=1, transportLayerVersion=1
169
+ )
170
+
171
+ # Set up the mock to return the response
172
+ mock_connect.return_value = response
173
+
174
+ # Create the Master instance
175
+ xm = Master("eth", config=create_config())
176
+
177
+ try:
178
+ # Call the connect method
179
+ res = xm.connect()
180
+
181
+ # Verify the mock was called
182
+ mock_connect.assert_called_once()
183
+
184
+ # Verify the response properties
185
+ assert res.maxCto == 255
186
+ assert res.maxDto == 1500
187
+ assert res.protocolLayerVersion == 1
188
+ assert res.transportLayerVersion == 1
189
+ assert res.resource.pgm is True
190
+ assert res.resource.stim is True
191
+ assert res.resource.daq is True
192
+ assert res.resource.calpag is True
193
+ assert res.commModeBasic.optional is True
194
+ assert res.commModeBasic.slaveBlockMode is True
195
+ assert res.commModeBasic.addressGranularity == types.AddressGranularity.BYTE
196
+ assert res.commModeBasic.byteOrder == types.ByteOrder.INTEL
197
+
198
+ # Note: We can't verify the slave properties were updated correctly
199
+ # because we're mocking the connect method, which would normally update them
200
+ finally:
201
+ # Clean up
202
+ xm.close()
203
+
204
+ @mock.patch("pyxcp.transport.eth.socket.socket")
205
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
206
+ def testDisconnect(self, mock_selector, mock_socket):
207
+ ms = MockSocket()
208
+
209
+ mock_socket.return_value.recv.side_effect = ms.recv
210
+ mock_selector.return_value.select.side_effect = ms.select
211
+
212
+ with Master("eth", config=create_config()) as xm:
213
+ ms.push_packet(self.DefaultConnectResponse)
214
+ res = xm.connect()
215
+
216
+ ms.push_frame("01 00 01 00 FF")
217
+ res = xm.disconnect()
218
+
219
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x01, 0x00, 0xFE]))
220
+ assert res == b""
221
+
222
+ @mock.patch("pyxcp.transport.eth.socket.socket")
223
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
224
+ def testGetStatus(self, mock_selector, mock_socket):
225
+ ms = MockSocket()
226
+
227
+ mock_socket.return_value.recv.side_effect = ms.recv
228
+ mock_selector.return_value.select.side_effect = ms.select
229
+
230
+ with Master("eth", config=create_config()) as xm:
231
+ ms.push_packet(self.DefaultConnectResponse)
232
+ res = xm.connect()
233
+
234
+ ms.push_packet("FF 00 1D 00 00")
235
+ res = xm.getStatus()
236
+
237
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x01, 0x00, 0xFD]))
238
+
239
+ assert res.sessionConfiguration == 0
240
+ assert res.sessionStatus.resume is False
241
+ assert res.sessionStatus.daqRunning is False
242
+ assert res.sessionStatus.clearDaqRequest is False
243
+ assert res.sessionStatus.storeDaqRequest is False
244
+ assert res.sessionStatus.storeCalRequest is False
245
+ assert res.resourceProtectionStatus.pgm is True
246
+ assert res.resourceProtectionStatus.stim is True
247
+ assert res.resourceProtectionStatus.daq is True
248
+ assert res.resourceProtectionStatus.calpag is True
249
+
250
+ @mock.patch("pyxcp.transport.eth.socket.socket")
251
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
252
+ def testSync(self, mock_selector, mock_socket):
253
+ ms = MockSocket()
254
+
255
+ mock_socket.return_value.recv.side_effect = ms.recv
256
+ mock_selector.return_value.select.side_effect = ms.select
257
+
258
+ with Master("eth", config=create_config()) as xm:
259
+ ms.push_packet(self.DefaultConnectResponse)
260
+ res = xm.connect()
261
+
262
+ ms.push_packet("FF 00")
263
+ res = xm.synch()
264
+
265
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x01, 0x00, 0xFC]))
266
+
267
+ assert len(res) == 1
268
+
269
+ @mock.patch("pyxcp.transport.eth.socket.socket")
270
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
271
+ def testGetCommModeInfo(self, mock_selector, mock_socket):
272
+ ms = MockSocket()
273
+
274
+ mock_socket.return_value.recv.side_effect = ms.recv
275
+ mock_selector.return_value.select.side_effect = ms.select
276
+
277
+ with Master("eth", config=create_config()) as xm:
278
+ ms.push_packet(self.DefaultConnectResponse)
279
+ res = xm.connect()
280
+
281
+ ms.push_packet("FF 00 01 FF 02 00 00 19")
282
+ res = xm.getCommModeInfo()
283
+
284
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x01, 0x00, 0xFB]))
285
+
286
+ assert res.commModeOptional.interleavedMode is False
287
+ assert res.commModeOptional.masterBlockMode is True
288
+ assert res.maxBs == 2
289
+ assert res.minSt == 0
290
+ assert res.queueSize == 0
291
+ assert res.xcpDriverVersionNumber == 25
292
+
293
+ @mock.patch("pyxcp.transport.eth.socket.socket")
294
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
295
+ def testGetId(self, mock_selector, mock_socket):
296
+ ms = MockSocket()
297
+
298
+ mock_socket.return_value.recv.side_effect = ms.recv
299
+ mock_selector.return_value.select.side_effect = ms.select
300
+
301
+ with Master("eth", config=create_config()) as xm:
302
+ ms.push_packet(self.DefaultConnectResponse)
303
+ res = xm.connect()
304
+
305
+ ms.push_packet("FF 00 01 FF 06 00 00 00")
306
+ gid = xm.getId(0x01)
307
+
308
+ ms.push_packet("FF 58 43 50 73 69 6D")
309
+ res = xm.upload(gid.length)
310
+
311
+ # Assert the getId command was sent correctly
312
+ mock_socket.return_value.send.assert_any_call(bytes([0x02, 0x00, 0x01, 0x00, 0xFA, 0x01]))
313
+ # Assert the upload command was sent correctly
314
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x01, 0x00, 0xF5]))
315
+
316
+ assert gid.mode == 0
317
+ assert gid.length == 6
318
+ assert res == b"XCPsim"
319
+
320
+ @mock.patch("pyxcp.transport.eth.socket.socket")
321
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
322
+ def testConnect2(self, mock_selector, mock_socket):
323
+ ms = MockSocket()
324
+
325
+ mock_socket.return_value.recv.side_effect = ms.recv
326
+ mock_selector.return_value.select.side_effect = ms.select
327
+
328
+ with Master("eth", config=create_config()) as xm:
329
+ ms.push_packet(self.DefaultConnectResponse)
330
+
331
+ res = xm.connect()
332
+
333
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
334
+
335
+ assert res.maxCto == 255
336
+ assert res.maxDto == 1500
337
+ assert res.protocolLayerVersion == 1
338
+ assert res.transportLayerVersion == 1
339
+ assert res.resource.dbg is True
340
+ assert res.resource.pgm is True
341
+ assert res.resource.stim is True
342
+ assert res.resource.daq is True
343
+ assert res.resource.calpag is True
344
+ assert res.commModeBasic.optional is True
345
+ assert res.commModeBasic.slaveBlockMode is True
346
+ assert res.commModeBasic.addressGranularity == types.AddressGranularity.BYTE
347
+ assert res.commModeBasic.byteOrder == types.ByteOrder.INTEL
348
+
349
+ assert xm.slaveProperties.byteOrder == res.commModeBasic.byteOrder
350
+ assert xm.slaveProperties.maxCto == res.maxCto
351
+ assert xm.slaveProperties.maxDto == res.maxDto
352
+
353
+ ms.push_frame("06 00 01 00 FF 00 01 05 01 04")
354
+
355
+ res = xm.getVersion()
356
+
357
+ mock_socket.return_value.send.assert_called_with(bytes([0x02, 0x00, 0x01, 0x00, 0xC0, 0x00]))
358
+
359
+ assert res.protocolMajor == 1
360
+ assert res.protocolMinor == 5
361
+ assert res.transportMajor == 1
362
+ assert res.transportMinor == 4
363
+
364
+ @mock.patch("pyxcp.transport.eth.socket.socket")
365
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
366
+ def testDisconnect2(self, mock_selector, mock_socket):
367
+ ms = MockSocket()
368
+
369
+ mock_socket.return_value.recv.side_effect = ms.recv
370
+ mock_selector.return_value.select.side_effect = ms.select
371
+
372
+ with Master("eth", config=create_config()) as xm:
373
+ ms.push_packet(self.DefaultConnectResponse)
374
+
375
+ res = xm.connect()
376
+
377
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
378
+
379
+ ms.push_frame("01 00 01 00 FF")
380
+
381
+ res = xm.disconnect()
382
+
383
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x01, 0x00, 0xFE]))
384
+
385
+ assert res == b""
386
+
387
+ @mock.patch("pyxcp.transport.eth.socket.socket")
388
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
389
+ def testGetStatus2(self, mock_selector, mock_socket):
390
+ ms = MockSocket()
391
+
392
+ mock_socket.return_value.recv.side_effect = ms.recv
393
+ mock_selector.return_value.select.side_effect = ms.select
394
+
395
+ with Master("eth", config=create_config()) as xm:
396
+ ms.push_packet(self.DefaultConnectResponse)
397
+
398
+ res = xm.connect()
399
+
400
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
401
+
402
+ ms.push_packet("FF 09 1D 00 34 12")
403
+
404
+ res = xm.getStatus()
405
+
406
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x01, 0x00, 0xFD]))
407
+
408
+ assert res.sessionStatus.storeCalRequest is True
409
+ assert res.sessionStatus.storeDaqRequest is False
410
+ assert res.sessionStatus.clearDaqRequest is True
411
+ assert res.sessionStatus.daqRunning is False
412
+ assert res.sessionStatus.resume is False
413
+ assert res.resourceProtectionStatus.pgm is True
414
+ assert res.resourceProtectionStatus.stim is True
415
+ assert res.resourceProtectionStatus.daq is True
416
+ assert res.resourceProtectionStatus.calpag is True
417
+ assert res.sessionConfiguration == 0x1234
418
+
419
+ @mock.patch("pyxcp.transport.eth.socket.socket")
420
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
421
+ def testSynch(self, mock_selector, mock_socket):
422
+ ms = MockSocket()
423
+
424
+ mock_socket.return_value.recv.side_effect = ms.recv
425
+ mock_selector.return_value.select.side_effect = ms.select
426
+
427
+ with Master("eth", config=create_config()) as xm:
428
+ ms.push_packet(self.DefaultConnectResponse)
429
+
430
+ res = xm.connect()
431
+
432
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
433
+
434
+ ms.push_frame([0x02, 0x00, 0x01, 0x00, 0xFE, 0x00])
435
+
436
+ res = xm.synch()
437
+
438
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x01, 0x00, 0xFC]))
439
+
440
+ assert res == b"\x00"
441
+
442
+ @mock.patch("pyxcp.transport.eth.socket.socket")
443
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
444
+ def testGetCommModeInfo2(self, mock_selector, mock_socket):
445
+ ms = MockSocket()
446
+
447
+ mock_socket.return_value.recv.side_effect = ms.recv
448
+ mock_selector.return_value.select.side_effect = ms.select
449
+
450
+ with Master("eth", config=create_config()) as xm:
451
+ ms.push_packet(self.DefaultConnectResponse)
452
+
453
+ res = xm.connect()
454
+
455
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
456
+
457
+ ms.push_packet("FF 00 01 FF 02 00 00 19")
458
+
459
+ res = xm.getCommModeInfo()
460
+
461
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x01, 0x00, 0xFB]))
462
+
463
+ assert res.commModeOptional.interleavedMode is False
464
+ assert res.commModeOptional.masterBlockMode is True
465
+ assert res.maxBs == 2
466
+ assert res.minSt == 0
467
+ assert res.queueSize == 0
468
+ assert res.xcpDriverVersionNumber == 25
469
+
470
+ @mock.patch("pyxcp.transport.eth.socket.socket")
471
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
472
+ def testGetId2(self, mock_selector, mock_socket):
473
+ ms = MockSocket()
474
+
475
+ mock_socket.return_value.recv.side_effect = ms.recv
476
+ mock_selector.return_value.select.side_effect = ms.select
477
+
478
+ with Master("eth", config=create_config()) as xm:
479
+ ms.push_packet(self.DefaultConnectResponse)
480
+
481
+ res = xm.connect()
482
+
483
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
484
+
485
+ ms.push_frame([0x08, 0x00, 0x01, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00])
486
+
487
+ gid = xm.getId(0x01)
488
+
489
+ mock_socket.return_value.send.assert_called_with(bytes([0x02, 0x00, 0x01, 0x00, 0xFA, 0x01]))
490
+
491
+ assert gid.mode == 0
492
+ assert gid.length == 6
493
+
494
+ ms.push_frame([0x07, 0x00, 0x02, 0x00, 0xFF, 0x58, 0x43, 0x50, 0x73, 0x69, 0x6D])
495
+
496
+ res = xm.upload(gid.length)
497
+
498
+ mock_socket.return_value.send.assert_called_with(bytes([0x02, 0x00, 0x02, 0x00, 0xF5, 0x06]))
499
+
500
+ assert res == b"XCPsim"
501
+
502
+ ms.push_frame(
503
+ [
504
+ 0x0E,
505
+ 0x00,
506
+ 0x03,
507
+ 0x00,
508
+ 0xFF,
509
+ 0x01,
510
+ 0x00,
511
+ 0x00,
512
+ 0x06,
513
+ 0x00,
514
+ 0x00,
515
+ 0x00,
516
+ 0x58,
517
+ 0x43,
518
+ 0x50,
519
+ 0x73,
520
+ 0x69,
521
+ 0x6D,
522
+ ]
523
+ )
524
+
525
+ gid = xm.getId(0x01)
526
+
527
+ mock_socket.return_value.send.assert_called_with(bytes([0x02, 0x00, 0x03, 0x00, 0xFA, 0x01]))
528
+
529
+ assert gid.mode == 1
530
+ assert gid.length == 6
531
+ assert gid.identification == list(b"XCPsim")
532
+
533
+ @mock.patch("pyxcp.transport.eth.socket.socket")
534
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
535
+ def testSetRequest(self, mock_selector, mock_socket):
536
+ ms = MockSocket()
537
+
538
+ mock_socket.return_value.recv.side_effect = ms.recv
539
+ mock_selector.return_value.select.side_effect = ms.select
540
+
541
+ with Master("eth", config=create_config()) as xm:
542
+ ms.push_packet(self.DefaultConnectResponse)
543
+
544
+ res = xm.connect()
545
+
546
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
547
+
548
+ ms.push_frame([0x01, 0x00, 0x01, 0x00, 0xFF])
549
+
550
+ res = xm.setRequest(0x15, 0x1234)
551
+
552
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x01, 0x00, 0xF9, 0x15, 0x12, 0x34]))
553
+
554
+ assert res == b""
555
+
556
+ @mock.patch("pyxcp.transport.eth.socket.socket")
557
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
558
+ def testGetSeed(self, mock_selector, mock_socket):
559
+ ms = MockSocket()
560
+
561
+ mock_socket.return_value.recv.side_effect = ms.recv
562
+ mock_selector.return_value.select.side_effect = ms.select
563
+
564
+ with Master("eth", config=create_config()) as xm:
565
+ ms.push_packet(self.DefaultConnectResponse)
566
+
567
+ res = xm.connect()
568
+
569
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
570
+
571
+ ms.push_packet("FF 04 12 34 56 78")
572
+
573
+ res = xm.getSeed(0x00, 0x00)
574
+
575
+ mock_socket.return_value.send.assert_called_with(bytes([0x03, 0x00, 0x01, 0x00, 0xF8, 0x00, 0x00]))
576
+
577
+ assert res.length == 4
578
+ assert res.seed == list(b"\x12\x34\x56\x78")
579
+
580
+ @mock.patch("pyxcp.transport.eth.socket.socket")
581
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
582
+ def testUnlock(self, mock_selector, mock_socket):
583
+ ms = MockSocket()
584
+
585
+ mock_socket.return_value.recv.side_effect = ms.recv
586
+ mock_selector.return_value.select.side_effect = ms.select
587
+
588
+ with Master("eth", config=create_config()) as xm:
589
+ ms.push_packet(self.DefaultConnectResponse)
590
+
591
+ res = xm.connect()
592
+
593
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
594
+
595
+ ms.push_packet("FF 10")
596
+
597
+ res = xm.unlock(0x04, [0x12, 0x34, 0x56, 0x78])
598
+
599
+ mock_socket.return_value.send.assert_called_with(bytes([0x06, 0x00, 0x01, 0x00, 0xF7, 0x04, 0x12, 0x34, 0x56, 0x78]))
600
+
601
+ assert res.calpag is False
602
+ assert res.daq is False
603
+ assert res.stim is False
604
+ assert res.pgm is True
605
+
606
+ @mock.patch("pyxcp.transport.eth.socket.socket")
607
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
608
+ def testSetMta(self, mock_selector, mock_socket):
609
+ ms = MockSocket()
610
+
611
+ mock_socket.return_value.recv.side_effect = ms.recv
612
+ mock_selector.return_value.select.side_effect = ms.select
613
+
614
+ with Master("eth", config=create_config()) as xm:
615
+ ms.push_packet(self.DefaultConnectResponse)
616
+
617
+ res = xm.connect()
618
+
619
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
620
+
621
+ ms.push_frame("01 00 01 00 FF")
622
+
623
+ res = xm.setMta(0x12345678, 0x55)
624
+
625
+ mock_socket.return_value.send.assert_called_with(
626
+ bytes(
627
+ [
628
+ 0x08,
629
+ 0x00,
630
+ 0x01,
631
+ 0x00,
632
+ 0xF6,
633
+ 0x00,
634
+ 0x00,
635
+ 0x55,
636
+ 0x78,
637
+ 0x56,
638
+ 0x34,
639
+ 0x12,
640
+ ]
641
+ )
642
+ )
643
+
644
+ assert res == b""
645
+
646
+ @mock.patch("pyxcp.transport.eth.socket.socket")
647
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
648
+ def testUpload(self, mock_selector, mock_socket):
649
+ ms = MockSocket()
650
+
651
+ mock_socket.return_value.recv.side_effect = ms.recv
652
+ mock_selector.return_value.select.side_effect = ms.select
653
+
654
+ with Master("eth", config=create_config()) as xm:
655
+ ms.push_packet(self.DefaultConnectResponse)
656
+
657
+ res = xm.connect()
658
+
659
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
660
+
661
+ ms.push_frame(
662
+ [
663
+ 0x09,
664
+ 0x00,
665
+ 0x01,
666
+ 0x00,
667
+ 0xFF,
668
+ 0x01,
669
+ 0x02,
670
+ 0x03,
671
+ 0x04,
672
+ 0x05,
673
+ 0x06,
674
+ 0x07,
675
+ 0x08,
676
+ ]
677
+ )
678
+
679
+ res = xm.upload(8)
680
+
681
+ mock_socket.return_value.send.assert_called_with(bytes([0x02, 0x00, 0x01, 0x00, 0xF5, 0x08]))
682
+
683
+ assert res == b"\x01\x02\x03\x04\x05\x06\x07\x08"
684
+
685
+ @mock.patch("pyxcp.transport.eth.socket.socket")
686
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
687
+ def testShortUpload(self, mock_selector, mock_socket):
688
+ ms = MockSocket()
689
+
690
+ mock_socket.return_value.recv.side_effect = ms.recv
691
+ mock_selector.return_value.select.side_effect = ms.select
692
+
693
+ with Master("eth", config=create_config()) as xm:
694
+ ms.push_packet(self.DefaultConnectResponse)
695
+
696
+ res = xm.connect()
697
+
698
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
699
+
700
+ ms.push_frame("09 00 01 00 FF 01 02 03 04 05 06 07 08")
701
+
702
+ res = xm.shortUpload(8, 0xCAFEBABE, 1)
703
+
704
+ mock_socket.return_value.send.assert_called_with(
705
+ bytes(
706
+ [
707
+ 0x08,
708
+ 0x00,
709
+ 0x01,
710
+ 0x00,
711
+ 0xF4,
712
+ 0x08,
713
+ 0x00,
714
+ 0x01,
715
+ 0xBE,
716
+ 0xBA,
717
+ 0xFE,
718
+ 0xCA,
719
+ ]
720
+ )
721
+ )
722
+
723
+ assert res == b"\x01\x02\x03\x04\x05\x06\x07\x08"
724
+
725
+ @mock.patch("pyxcp.transport.eth.socket.socket")
726
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
727
+ def testBuildChecksum(self, mock_selector, mock_socket):
728
+ ms = MockSocket()
729
+
730
+ mock_socket.return_value.recv.side_effect = ms.recv
731
+ mock_selector.return_value.select.side_effect = ms.select
732
+
733
+ with Master("eth", config=create_config()) as xm:
734
+ ms.push_packet(self.DefaultConnectResponse)
735
+
736
+ res = xm.connect()
737
+
738
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
739
+
740
+ ms.push_frame("08 00 01 00 FF 09 00 00 04 05 06 07")
741
+
742
+ res = xm.buildChecksum(1024)
743
+
744
+ mock_socket.return_value.send.assert_called_with(
745
+ bytes(
746
+ [
747
+ 0x08,
748
+ 0x00,
749
+ 0x01,
750
+ 0x00,
751
+ 0xF3,
752
+ 0x00,
753
+ 0x00,
754
+ 0x00,
755
+ 0x00,
756
+ 0x04,
757
+ 0x00,
758
+ 0x00,
759
+ ]
760
+ )
761
+ )
762
+
763
+ assert res.checksumType == types.BuildChecksumResponse.checksumType.XCP_CRC_32
764
+ assert res.checksum == 0x07060504
765
+
766
+ @mock.patch("pyxcp.transport.eth.socket.socket")
767
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
768
+ def testTransportLayerCmd(self, mock_selector, mock_socket):
769
+ ms = MockSocket()
770
+
771
+ mock_socket.return_value.recv.side_effect = ms.recv
772
+ mock_selector.return_value.select.side_effect = ms.select
773
+
774
+ with Master("eth", config=create_config()) as xm:
775
+ ms.push_packet(self.DefaultConnectResponse)
776
+
777
+ res = xm.connect()
778
+
779
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
780
+
781
+ ms.push_frame([0x03, 0x00, 0x01, 0x00, 0xFF, 0xAA, 0xBB])
782
+
783
+ data = [0xBE, 0xEF]
784
+ res = xm.transportLayerCmd(0x55, data)
785
+
786
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x01, 0x00, 0xF2, 0x55, 0xBE, 0xEF]))
787
+
788
+ assert res == b"\xaa\xbb"
789
+
790
+ @mock.patch("pyxcp.transport.eth.socket.socket")
791
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
792
+ def testUserCmd(self, mock_selector, mock_socket):
793
+ ms = MockSocket()
794
+
795
+ mock_socket.return_value.recv.side_effect = ms.recv
796
+ mock_selector.return_value.select.side_effect = ms.select
797
+
798
+ with Master("eth", config=create_config()) as xm:
799
+ ms.push_packet(self.DefaultConnectResponse)
800
+
801
+ res = xm.connect()
802
+
803
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
804
+
805
+ ms.push_frame([0x03, 0x00, 0x01, 0x00, 0xFF, 0xAA, 0xBB])
806
+
807
+ data = [0xBE, 0xEF]
808
+ res = xm.userCmd(0x55, data)
809
+
810
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x01, 0x00, 0xF1, 0x55, 0xBE, 0xEF]))
811
+
812
+ assert res == b"\xaa\xbb"
813
+
814
+ @mock.patch("pyxcp.transport.eth.socket.socket")
815
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
816
+ def testGetVersion(self, mock_selector, mock_socket):
817
+ ms = MockSocket()
818
+
819
+ mock_socket.return_value.recv.side_effect = ms.recv
820
+ mock_selector.return_value.select.side_effect = ms.select
821
+
822
+ with Master("eth", config=create_config()) as xm:
823
+ ms.push_packet(self.DefaultConnectResponse)
824
+
825
+ res = xm.connect()
826
+
827
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
828
+
829
+ ms.push_packet("FF 00 01 05 01 04")
830
+
831
+ res = xm.getVersion()
832
+
833
+ mock_socket.return_value.send.assert_called_with(bytes([0x02, 0x00, 0x01, 0x00, 0xC0, 0x00]))
834
+
835
+ assert res.protocolMajor == 1
836
+ assert res.protocolMinor == 5
837
+ assert res.transportMajor == 1
838
+ assert res.transportMinor == 4
839
+
840
+ @mock.patch("pyxcp.transport.eth.socket.socket")
841
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
842
+ def testDownload(self, mock_selector, mock_socket):
843
+ ms = MockSocket()
844
+
845
+ mock_socket.return_value.recv.side_effect = ms.recv
846
+ mock_selector.return_value.select.side_effect = ms.select
847
+
848
+ with Master("eth", config=create_config()) as xm:
849
+ ms.push_packet(self.DefaultConnectResponse)
850
+
851
+ res = xm.connect()
852
+
853
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
854
+
855
+ ms.push_frame([0x01, 0x00, 0x01, 0x00, 0xFF])
856
+
857
+ data = [0xCA, 0xFE, 0xBA, 0xBE]
858
+ res = xm.download(data)
859
+
860
+ mock_socket.return_value.send.assert_called_with(bytes([0x06, 0x00, 0x01, 0x00, 0xF0, 0x04, 0xCA, 0xFE, 0xBA, 0xBE]))
861
+
862
+ assert res == b""
863
+
864
+ def testDownloadBlock(self):
865
+ conf = {
866
+ "CAN_ID_MASTER": 1,
867
+ "CAN_ID_SLAVE": 2,
868
+ "CAN_DRIVER": "MockCanInterface",
869
+ "CAN_USE_DEFAULT_LISTENER": False,
870
+ }
871
+ with Master("can", config=conf) as xm:
872
+ mock_caninterface = xm.transport.can_interface
873
+ mock_caninterface.push_packet(self.DefaultConnectResponse)
874
+ xm.connect()
875
+
876
+ data = bytes([i for i in range(14)])
877
+ # Downloading 14 bytes in block mode:
878
+ # command code n payload...
879
+ # testing -> DOWNLOAD: 0xF0, 14, 0, 1, 2, 3, 4, 5
880
+ # DOWNLOAD_NEXT: 0xEF, 8, 6, 7, 8, 9, 10,11
881
+ # DOWNLOAD_NEXT: 0xEF, 2, 12,13
882
+ # DOWNLOAD service with block mode, this is the first DOWNLOAD packet of a block, no response
883
+ # is expected from the slave device:
884
+ res = xm.download(data=data, blockModeLength=len(data))
885
+ assert res is None
886
+
887
+ # DOWNLOAD service with normal mode, normal response expected
888
+ mock_caninterface.push_packet("FF")
889
+ res = xm.download(data=data, blockModeLength=None)
890
+ assert res == b""
891
+
892
+ @mock.patch("pyxcp.transport.eth.socket.socket")
893
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
894
+ def testDownloadNext(self, mock_selector, mock_socket):
895
+ ms = MockSocket()
896
+
897
+ mock_socket.return_value.recv.side_effect = ms.recv
898
+ mock_selector.return_value.select.side_effect = ms.select
899
+
900
+ with Master("eth", config=create_config()) as xm:
901
+ ms.push_packet(self.DefaultConnectResponse)
902
+
903
+ res = xm.connect()
904
+
905
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
906
+
907
+ ms.push_frame([0x01, 0x00, 0x01, 0x00, 0xFF])
908
+
909
+ data = [0xCA, 0xFE, 0xBA, 0xBE]
910
+ remaining_block_length = 42
911
+ res = xm.downloadNext(data, remainingBlockLength=remaining_block_length)
912
+
913
+ mock_socket.return_value.send.assert_called_with(
914
+ bytes(
915
+ [
916
+ 0x06,
917
+ 0x00,
918
+ 0x01,
919
+ 0x00,
920
+ 0xEF,
921
+ remaining_block_length,
922
+ 0xCA,
923
+ 0xFE,
924
+ 0xBA,
925
+ 0xBE,
926
+ ]
927
+ )
928
+ )
929
+
930
+ # no response shall be expected if it is not the last DOWNLOAD_NEXT packet of a block
931
+ assert res is None
932
+
933
+ def testDownloadNextBlock(self):
934
+ conf = {
935
+ "CAN_ID_MASTER": 1,
936
+ "CAN_ID_SLAVE": 2,
937
+ "CAN_DRIVER": "MockCanInterface",
938
+ "CAN_USE_DEFAULT_LISTENER": False,
939
+ }
940
+ with Master("can", config=conf) as xm:
941
+ mock_caninterface = xm.transport.can_interface
942
+ mock_caninterface.push_packet(self.DefaultConnectResponse)
943
+ xm.connect()
944
+
945
+ data = bytes([i for i in range(14)])
946
+ # Downloading 14 bytes in block mode:
947
+ # command code n payload...
948
+ # DOWNLOAD: 0xF0, 14, 0, 1, 2, 3, 4, 5
949
+ # testing -> DOWNLOAD_NEXT: 0xEF, 8, 6, 7, 8, 9, 10,11
950
+ # testing -> DOWNLOAD_NEXT: 0xEF, 2, 12,13
951
+
952
+ # This is the first DOWNLOAD_NEXT packet of a block, no response is expected from the slave device.
953
+ res = xm.downloadNext(data=data, remainingBlockLength=8, last=False)
954
+ assert res is None
955
+
956
+ # This is the last DOWNLOAD_NEXT packet of a block, positive response is expected from the slave device.
957
+ mock_caninterface.push_packet("FF")
958
+ res = xm.downloadNext(data=data, remainingBlockLength=2, last=True)
959
+ assert res == b""
960
+
961
+ @mock.patch("pyxcp.transport.eth.socket.socket")
962
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
963
+ def testDownloadMax(self, mock_selector, mock_socket):
964
+ ms = MockSocket()
965
+
966
+ mock_socket.return_value.recv.side_effect = ms.recv
967
+ mock_selector.return_value.select.side_effect = ms.select
968
+
969
+ with Master("eth", config=create_config()) as xm:
970
+ ms.push_packet(self.DefaultConnectResponse)
971
+
972
+ res = xm.connect()
973
+
974
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
975
+
976
+ ms.push_frame([0x01, 0x00, 0x01, 0x00, 0xFF])
977
+
978
+ data = [0xCA, 0xFE, 0xBA, 0xBE]
979
+ res = xm.downloadMax(data)
980
+
981
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x01, 0x00, 0xEE, 0xCA, 0xFE, 0xBA, 0xBE]))
982
+
983
+ assert res == b""
984
+
985
+ @mock.patch("pyxcp.transport.eth.socket.socket")
986
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
987
+ def testShortDownload(self, mock_selector, mock_socket):
988
+ ms = MockSocket()
989
+
990
+ mock_socket.return_value.recv.side_effect = ms.recv
991
+ mock_selector.return_value.select.side_effect = ms.select
992
+
993
+ with Master("eth", config=create_config()) as xm:
994
+ ms.push_packet(self.DefaultConnectResponse)
995
+
996
+ res = xm.connect()
997
+
998
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
999
+
1000
+ ms.push_frame("01 00 01 00 FF")
1001
+
1002
+ data = [0xCA, 0xFE, 0xBA, 0xBE]
1003
+ res = xm.shortDownload(0x12345678, 0x55, data)
1004
+
1005
+ mock_socket.return_value.send.assert_called_with(
1006
+ bytes(
1007
+ [
1008
+ 0x0C,
1009
+ 0x00,
1010
+ 0x01,
1011
+ 0x00,
1012
+ 0xED,
1013
+ 0x04,
1014
+ 0x00,
1015
+ 0x55,
1016
+ 0x78,
1017
+ 0x56,
1018
+ 0x34,
1019
+ 0x12,
1020
+ 0xCA,
1021
+ 0xFE,
1022
+ 0xBA,
1023
+ 0xBE,
1024
+ ]
1025
+ )
1026
+ )
1027
+
1028
+ assert res == b""
1029
+
1030
+ @mock.patch("pyxcp.transport.eth.socket.socket")
1031
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
1032
+ def testModifyBits(self, mock_selector, mock_socket):
1033
+ ms = MockSocket()
1034
+
1035
+ mock_socket.return_value.recv.side_effect = ms.recv
1036
+ mock_selector.return_value.select.side_effect = ms.select
1037
+
1038
+ with Master("eth", config=create_config()) as xm:
1039
+ ms.push_packet(self.DefaultConnectResponse)
1040
+
1041
+ res = xm.connect()
1042
+
1043
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
1044
+
1045
+ ms.push_frame("01 00 01 00 ff")
1046
+
1047
+ res = xm.modifyBits(0xFF, 0x1234, 0xABCD)
1048
+
1049
+ mock_socket.return_value.send.assert_called_with(bytes([0x06, 0x00, 0x01, 0x00, 0xEC, 0xFF, 0x34, 0x12, 0xCD, 0xAB]))
1050
+
1051
+ assert res == b""
1052
+
1053
+ @mock.patch("pyxcp.transport.eth.socket.socket")
1054
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
1055
+ def testPagCommands(self, mock_selector, mock_socket):
1056
+ ms = MockSocket()
1057
+
1058
+ mock_socket.return_value.recv.side_effect = ms.recv
1059
+ mock_selector.return_value.select.side_effect = ms.select
1060
+
1061
+ with Master("eth", config=create_config()) as xm:
1062
+ ms.push_packet(self.DefaultConnectResponse)
1063
+
1064
+ res = xm.connect()
1065
+
1066
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
1067
+
1068
+ ms.push_packet("FF")
1069
+
1070
+ res = xm.setCalPage(0x03, 0x12, 0x34)
1071
+
1072
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x01, 0x00, 0xEB, 0x03, 0x12, 0x34]))
1073
+
1074
+ assert res == b""
1075
+
1076
+ ms.push_packet("FF 00 00 55")
1077
+
1078
+ res = xm.getCalPage(0x02, 0x44)
1079
+
1080
+ mock_socket.return_value.send.assert_called_with(bytes([0x03, 0x00, 0x02, 0x00, 0xEA, 0x02, 0x44]))
1081
+
1082
+ assert res == 0x55
1083
+
1084
+ ms.push_packet("FF 10 01")
1085
+
1086
+ res = xm.getPagProcessorInfo()
1087
+
1088
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x03, 0x00, 0xE9]))
1089
+
1090
+ assert res.maxSegments == 16
1091
+ assert res.pagProperties == 0x01
1092
+
1093
+ ms.push_packet("FF 00 00 00 78 56 34 12")
1094
+
1095
+ res = xm.getSegmentInfo(0, 5, 1, 0)
1096
+
1097
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x04, 0x00, 0xE8, 0x00, 0x05, 0x01, 0x00]))
1098
+
1099
+ assert res.basicInfo == 0x12345678
1100
+
1101
+ ms.push_packet("FF aa bb cc 78 56")
1102
+
1103
+ res = xm.getSegmentInfo(1, 5, 0, 0)
1104
+
1105
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x05, 0x00, 0xE8, 0x01, 0x05, 0x00, 0x00]))
1106
+
1107
+ assert res.maxPages == 0xAA
1108
+ assert res.addressExtension == 0xBB
1109
+ assert res.maxMapping == 0xCC
1110
+ assert res.compressionMethod == 0x78
1111
+ assert res.encryptionMethod == 0x56
1112
+
1113
+ ms.push_packet("FF 00 00 00 78 56 34 12")
1114
+
1115
+ res = xm.getSegmentInfo(2, 5, 1, 3)
1116
+
1117
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x06, 0x00, 0xE8, 0x02, 0x05, 0x01, 0x03]))
1118
+
1119
+ assert res.mappingInfo == 0x12345678
1120
+
1121
+ ms.push_packet("FF 3F 55")
1122
+
1123
+ res = xm.getPageInfo(0x12, 0x34)
1124
+
1125
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x07, 0x00, 0xE7, 0x00, 0x12, 0x34]))
1126
+
1127
+ assert res[0].xcpWriteAccessWithEcu
1128
+ assert res[1] == 0x55
1129
+
1130
+ ms.push_packet("FF")
1131
+
1132
+ res = xm.setSegmentMode(0x01, 0x23)
1133
+
1134
+ mock_socket.return_value.send.assert_called_with(bytes([0x03, 0x00, 0x08, 0x00, 0xE6, 0x01, 0x23]))
1135
+
1136
+ assert res == b""
1137
+
1138
+ ms.push_packet("FF 00 01")
1139
+
1140
+ res = xm.getSegmentMode(0x23)
1141
+
1142
+ mock_socket.return_value.send.assert_called_with(bytes([0x03, 0x00, 0x09, 0x00, 0xE5, 0x00, 0x23]))
1143
+
1144
+ assert res == 0x01
1145
+
1146
+ ms.push_packet("FF")
1147
+
1148
+ res = xm.copyCalPage(0x12, 0x34, 0x56, 0x78)
1149
+
1150
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x0A, 0x00, 0xE4, 0x12, 0x34, 0x56, 0x78]))
1151
+
1152
+ assert res == b""
1153
+
1154
+ @mock.patch("pyxcp.transport.eth.socket.socket")
1155
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
1156
+ def testDaqCommands(self, mock_selector, mock_socket):
1157
+ ms = MockSocket()
1158
+
1159
+ mock_socket.return_value.recv.side_effect = ms.recv
1160
+ mock_selector.return_value.select.side_effect = ms.select
1161
+
1162
+ with Master("eth", config=create_config()) as xm:
1163
+ ms.push_packet(self.DefaultConnectResponse)
1164
+
1165
+ res = xm.connect()
1166
+
1167
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
1168
+
1169
+ ms.push_frame([0x01, 0x00, 0x01, 0x00, 0xFF])
1170
+
1171
+ res = xm.setDaqPtr(2, 3, 4)
1172
+
1173
+ mock_socket.return_value.send.assert_called_with(bytes([0x06, 0x00, 0x01, 0x00, 0xE2, 0x00, 0x02, 0x00, 0x03, 0x04]))
1174
+
1175
+ assert res == b""
1176
+
1177
+ ms.push_frame([0x01, 0x00, 0x02, 0x00, 0xFF])
1178
+
1179
+ res = xm.writeDaq(31, 15, 1, 0x12345678)
1180
+
1181
+ mock_socket.return_value.send.assert_called_with(
1182
+ bytes(
1183
+ [
1184
+ 0x08,
1185
+ 0x00,
1186
+ 0x02,
1187
+ 0x00,
1188
+ 0xE1,
1189
+ 0x1F,
1190
+ 0x0F,
1191
+ 0x01,
1192
+ 0x78,
1193
+ 0x56,
1194
+ 0x34,
1195
+ 0x12,
1196
+ ]
1197
+ )
1198
+ )
1199
+
1200
+ assert res == b""
1201
+
1202
+ ms.push_frame([0x01, 0x00, 0x03, 0x00, 0xFF])
1203
+
1204
+ res = xm.setDaqListMode(0x3B, 256, 512, 1, 0xFF)
1205
+
1206
+ mock_socket.return_value.send.assert_called_with(
1207
+ bytes(
1208
+ [
1209
+ 0x08,
1210
+ 0x00,
1211
+ 0x03,
1212
+ 0x00,
1213
+ 0xE0,
1214
+ 0x3B,
1215
+ 0x00,
1216
+ 0x01,
1217
+ 0x00,
1218
+ 0x02,
1219
+ 0x01,
1220
+ 0xFF,
1221
+ ]
1222
+ )
1223
+ )
1224
+
1225
+ assert res == b""
1226
+
1227
+ ms.push_frame([0x02, 0x00, 0x04, 0x00, 0xFF, 0x00])
1228
+
1229
+ res = xm.startStopDaqList(1, 512)
1230
+
1231
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x04, 0x00, 0xDE, 0x01, 0x00, 0x02]))
1232
+
1233
+ assert res.firstPid == 0
1234
+
1235
+ ms.push_frame([0x01, 0x00, 0x05, 0x00, 0xFF])
1236
+
1237
+ res = xm.startStopSynch(3)
1238
+
1239
+ mock_socket.return_value.send.assert_called_with(bytes([0x02, 0x00, 0x05, 0x00, 0xDD, 0x03]))
1240
+
1241
+ assert res == b""
1242
+
1243
+ ms.push_packet("FF")
1244
+
1245
+ res = xm.writeDaqMultiple(
1246
+ [
1247
+ dict(bitOffset=1, size=2, address=3, addressExt=4),
1248
+ dict(bitOffset=5, size=6, address=0x12345678, addressExt=7),
1249
+ ]
1250
+ )
1251
+
1252
+ mock_socket.return_value.send.assert_called_with(
1253
+ bytes(
1254
+ [
1255
+ 0x12,
1256
+ 0x00,
1257
+ 0x06,
1258
+ 0x00,
1259
+ 0xC7,
1260
+ 0x02,
1261
+ 0x01,
1262
+ 0x02,
1263
+ 0x03,
1264
+ 0x00,
1265
+ 0x00,
1266
+ 0x00,
1267
+ 0x04,
1268
+ 0x00,
1269
+ 0x05,
1270
+ 0x06,
1271
+ 0x78,
1272
+ 0x56,
1273
+ 0x34,
1274
+ 0x12,
1275
+ 0x07,
1276
+ 0x00,
1277
+ ]
1278
+ )
1279
+ )
1280
+
1281
+ assert res == b""
1282
+
1283
+ ms.push_frame("08 00 07 00 FF 1F 03 04 78 56 34 12")
1284
+
1285
+ res = xm.readDaq()
1286
+
1287
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x07, 0x00, 0xDB]))
1288
+
1289
+ assert res.bitOffset == 31
1290
+ assert res.sizeofDaqElement == 3
1291
+ assert res.adressExtension == 4
1292
+ assert res.address == 0x12345678
1293
+
1294
+ ms.push_frame("08 00 08 00 FF 00 03 04 78 56 34 12")
1295
+
1296
+ res = xm.getDaqClock()
1297
+
1298
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x08, 0x00, 0xDC]))
1299
+
1300
+ # todo: assert res.triggerInfo ==
1301
+ # todo: assert res.payloadFmt ==
1302
+ # todo: assert res.timestamp == 0x12345678
1303
+ assert res == 0x12345678
1304
+
1305
+ ms.push_frame("08 00 09 00 FF 55 00 01 34 12 22 03")
1306
+
1307
+ res = xm.getDaqProcessorInfo()
1308
+
1309
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x09, 0x00, 0xDA]))
1310
+
1311
+ assert res.daqProperties.overloadMsb is True
1312
+ assert res.daqProperties.bitStimSupported is False
1313
+ assert res.maxDaq == 256
1314
+ assert res.maxEventChannel == 0x1234
1315
+ assert res.minDaq == 0x22
1316
+ assert res.daqKeyByte.Optimisation_Type == "OM_ODT_TYPE_64"
1317
+
1318
+ ms.push_frame("08 00 0A 00 FF 12 34 56 78 AA 34 12")
1319
+
1320
+ res = xm.getDaqResolutionInfo()
1321
+
1322
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x0A, 0x00, 0xD9]))
1323
+
1324
+ assert res.granularityOdtEntrySizeDaq == 0x12
1325
+ assert res.maxOdtEntrySizeDaq == 0x34
1326
+ assert res.granularityOdtEntrySizeStim == 0x56
1327
+ assert res.maxOdtEntrySizeStim == 0x78
1328
+ assert res.timestampMode.size == "S2"
1329
+ assert res.timestampMode.fixed is True
1330
+ assert res.timestampMode.unit == "DAQ_TIMESTAMP_UNIT_1PS"
1331
+ assert res.timestampTicks == 0x1234
1332
+
1333
+ ms.push_frame("08 00 0B 00 FF AA 00 00 34 12 56 78")
1334
+
1335
+ res = xm.getDaqListMode(256)
1336
+
1337
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x0B, 0x00, 0xDF, 0x00, 0x00, 0x01]))
1338
+
1339
+ assert res.currentMode.resume is True
1340
+ assert res.currentMode.selected is False
1341
+ assert res.currentEventChannel == 0x1234
1342
+ assert res.currentPrescaler == 0x56
1343
+ assert res.currentPriority == 0x78
1344
+
1345
+ ms.push_frame("07 00 0C 00 FF 48 EE 05 06 07 FF")
1346
+
1347
+ res = xm.getDaqEventInfo(256)
1348
+
1349
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x0C, 0x00, 0xD7, 0x00, 0x00, 0x01]))
1350
+
1351
+ assert res.daqEventProperties.consistency == "CONSISTENCY_DAQ"
1352
+ assert res.daqEventProperties.stim is True
1353
+ assert res.daqEventProperties.daq is False
1354
+ assert res.maxDaqList == 0xEE
1355
+ assert res.eventChannelNameLength == 0x05
1356
+ assert res.eventChannelTimeCycle == 0x06
1357
+ assert res.eventChannelTimeUnit == "EVENT_CHANNEL_TIME_UNIT_10MS"
1358
+ assert res.eventChannelPriority == 0xFF
1359
+
1360
+ ms.push_packet("FF AA 34 12 02")
1361
+
1362
+ res = xm.dtoCtrProperties(0x05, 0x1234, 0x5678, 0x02)
1363
+
1364
+ mock_socket.return_value.send.assert_called_with(
1365
+ bytes([0x07, 0x00, 0x0D, 0x00, 0xC5, 0x05, 0x34, 0x12, 0x78, 0x56, 0x02])
1366
+ )
1367
+
1368
+ assert res.properties.evtCtrPresent is True
1369
+ assert res.properties.relatedEventFixed is False
1370
+ assert res.relatedEventChannel == 0x1234
1371
+ assert res.mode.stimMode is True
1372
+ assert res.mode.daqMode is False
1373
+
1374
+ ms.push_frame([0x01, 0x00, 0x0E, 0x00, 0xFF])
1375
+
1376
+ res = xm.clearDaqList(256)
1377
+
1378
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x0E, 0x00, 0xE3, 0x00, 0x00, 0x01]))
1379
+
1380
+ assert res == b""
1381
+
1382
+ ms.push_frame("06 00 0F 00 FF 15 10 20 34 12")
1383
+
1384
+ res = xm.getDaqListInfo(256)
1385
+
1386
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x0F, 0x00, 0xD8, 0x00, 0x00, 0x01]))
1387
+
1388
+ assert res.daqListProperties.packed is True
1389
+ assert res.daqListProperties.eventFixed is False
1390
+ assert res.maxOdt == 0x10
1391
+ assert res.maxOdt == 0x10
1392
+ assert res.maxOdtEntries == 0x20
1393
+ assert res.fixedEvent == 0x1234
1394
+
1395
+ ms.push_frame([0x01, 0x00, 0x10, 0x00, 0xFF])
1396
+
1397
+ res = xm.freeDaq()
1398
+
1399
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x10, 0x00, 0xD6]))
1400
+
1401
+ assert res == b""
1402
+
1403
+ ms.push_frame([0x01, 0x00, 0x11, 0x00, 0xFF])
1404
+
1405
+ res = xm.allocDaq(258)
1406
+
1407
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x11, 0x00, 0xD5, 0x00, 0x02, 0x01]))
1408
+
1409
+ assert res == b""
1410
+
1411
+ ms.push_frame([0x01, 0x00, 0x12, 0x00, 0xFF])
1412
+
1413
+ res = xm.allocOdt(258, 3)
1414
+
1415
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x12, 0x00, 0xD4, 0x00, 0x02, 0x01, 0x03]))
1416
+
1417
+ assert res == b""
1418
+
1419
+ ms.push_frame([0x01, 0x00, 0x13, 0x00, 0xFF])
1420
+
1421
+ res = xm.allocOdtEntry(258, 3, 4)
1422
+
1423
+ mock_socket.return_value.send.assert_called_with(bytes([0x06, 0x00, 0x13, 0x00, 0xD3, 0x00, 0x02, 0x01, 0x03, 0x04]))
1424
+
1425
+ assert res == b""
1426
+
1427
+ ms.push_frame([0x01, 0x00, 0x14, 0x00, 0xFF])
1428
+
1429
+ res = xm.setDaqPackedMode(258, 0)
1430
+
1431
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x14, 0x00, 0xC0, 0x01, 0x02, 0x01, 0x00]))
1432
+
1433
+ assert res == b""
1434
+
1435
+ ms.push_frame([0x03, 0x00, 0x15, 0x00, 0xFF, 0x00, 0x00])
1436
+
1437
+ res = xm.getDaqPackedMode(258)
1438
+
1439
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x15, 0x00, 0xC0, 0x02, 0x02, 0x01]))
1440
+
1441
+ assert res.daqPackedMode == types.DaqPackedMode.NONE
1442
+ assert res.dpmTimestampMode is None
1443
+
1444
+ ms.push_frame([0x01, 0x00, 0x16, 0x00, 0xFF])
1445
+
1446
+ res = xm.setDaqPackedMode(258, 2, 0b01, 0x1234)
1447
+
1448
+ mock_socket.return_value.send.assert_called_with(
1449
+ bytes(
1450
+ [
1451
+ 0x08,
1452
+ 0x00,
1453
+ 0x16,
1454
+ 0x00,
1455
+ 0xC0,
1456
+ 0x01,
1457
+ 0x02,
1458
+ 0x01,
1459
+ 0x02,
1460
+ 0x01,
1461
+ 0x34,
1462
+ 0x12,
1463
+ ]
1464
+ )
1465
+ )
1466
+
1467
+ assert res == b""
1468
+
1469
+ ms.push_frame("06 00 17 00 FF 00 02 01 34 12")
1470
+
1471
+ res = xm.getDaqPackedMode(258)
1472
+
1473
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x17, 0x00, 0xC0, 0x02, 0x02, 0x01]))
1474
+
1475
+ assert res.daqPackedMode == "EVENT_GROUPED"
1476
+ assert res.dpmTimestampMode == 0x01
1477
+ assert res.dpmSampleCount == 0x1234
1478
+
1479
+ @mock.patch("pyxcp.transport.eth.socket.socket")
1480
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
1481
+ def testPgmCommands(self, mock_selector, mock_socket):
1482
+ ms = MockSocket()
1483
+
1484
+ mock_socket.return_value.recv.side_effect = ms.recv
1485
+ mock_selector.return_value.select.side_effect = ms.select
1486
+
1487
+ with Master("eth", config=create_config()) as xm:
1488
+ ms.push_packet(self.DefaultConnectResponse)
1489
+
1490
+ res = xm.connect()
1491
+
1492
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
1493
+
1494
+ ms.push_packet(b"\xff\x00\x01\x08\x2a\xff\x55")
1495
+
1496
+ res = xm.programStart()
1497
+
1498
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x01, 0x00, 0xD2]))
1499
+
1500
+ assert res.commModePgm.masterBlockMode is True
1501
+ assert res.commModePgm.interleavedMode is False
1502
+ assert res.commModePgm.slaveBlockMode is False
1503
+ assert res.maxCtoPgm == 8
1504
+ assert res.maxBsPgm == 0x2A
1505
+ assert res.minStPgm == 0xFF
1506
+ assert res.queueSizePgm == 0x55
1507
+
1508
+ ms.push_packet("FF")
1509
+
1510
+ res = xm.programClear(0x00, 0xA0000100)
1511
+
1512
+ mock_socket.return_value.send.assert_called_with(
1513
+ bytes(
1514
+ [
1515
+ 0x08,
1516
+ 0x00,
1517
+ 0x02,
1518
+ 0x00,
1519
+ 0xD1,
1520
+ 0x00,
1521
+ 0x00,
1522
+ 0x00,
1523
+ 0x00,
1524
+ 0x01,
1525
+ 0x00,
1526
+ 0xA0,
1527
+ ]
1528
+ )
1529
+ )
1530
+
1531
+ assert res == b""
1532
+
1533
+ ms.push_packet("FF")
1534
+
1535
+ res = xm.program([0x01, 0x02, 0x03, 0x04], blockLength=4, last=True)
1536
+
1537
+ mock_socket.return_value.send.assert_called_with(bytes([0x06, 0x00, 0x03, 0x00, 0xD0, 0x04, 0x01, 0x02, 0x03, 0x04]))
1538
+
1539
+ assert res == b""
1540
+
1541
+ ms.push_packet("FF")
1542
+
1543
+ res = xm.programReset()
1544
+
1545
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x04, 0x00, 0xCF]))
1546
+
1547
+ assert res == b""
1548
+
1549
+ ms.push_packet("FF AA BB")
1550
+
1551
+ res = xm.getPgmProcessorInfo()
1552
+
1553
+ mock_socket.return_value.send.assert_called_with(bytes([0x01, 0x00, 0x05, 0x00, 0xCE]))
1554
+
1555
+ assert res.pgmProperties.nonSeqPgmRequired is True
1556
+ assert res.pgmProperties.nonSeqPgmSupported is False
1557
+ assert res.maxSector == 0xBB
1558
+
1559
+ ms.push_packet("FF AA BB CC 78 56 34 12")
1560
+
1561
+ res = xm.getSectorInfo(0, 0x12)
1562
+
1563
+ mock_socket.return_value.send.assert_called_with(bytes([0x03, 0x00, 0x06, 0x00, 0xCD, 0, 0x12]))
1564
+
1565
+ assert res.clearSequenceNumber == 0xAA
1566
+ assert res.programSequenceNumber == 0xBB
1567
+ assert res.programmingMethod == 0xCC
1568
+ assert res.sectorInfo == 0x12345678
1569
+
1570
+ ms.push_packet("FF AA")
1571
+
1572
+ res = xm.getSectorInfo(2, 0x12)
1573
+
1574
+ mock_socket.return_value.send.assert_called_with(bytes([0x03, 0x00, 0x07, 0x00, 0xCD, 2, 0x12]))
1575
+
1576
+ assert res.sectorNameLength == 0xAA
1577
+
1578
+ ms.push_packet("FF")
1579
+
1580
+ res = xm.programPrepare(0x1234)
1581
+
1582
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x08, 0x00, 0xCC, 0x00, 0x34, 0x12]))
1583
+
1584
+ assert res == b""
1585
+
1586
+ ms.push_packet("FF")
1587
+
1588
+ res = xm.programFormat(0x81, 0x82, 0x83, 0x01)
1589
+
1590
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x09, 0x00, 0xCB, 0x81, 0x82, 0x83, 0x01]))
1591
+
1592
+ assert res == b""
1593
+
1594
+ ms.push_packet("FF")
1595
+
1596
+ res = xm.programNext([0x01, 0x02, 0x03, 0x04], remainingBlockLength=4, last=True)
1597
+
1598
+ mock_socket.return_value.send.assert_called_with(bytes([0x06, 0x00, 0x0A, 0x00, 0xCA, 0x04, 0x01, 0x02, 0x03, 0x04]))
1599
+
1600
+ assert res == b""
1601
+
1602
+ ms.push_packet("FF")
1603
+
1604
+ res = xm.programMax([0x01, 0x02, 0x03, 0x04])
1605
+
1606
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x0B, 0x00, 0xC9, 0x01, 0x02, 0x03, 0x04]))
1607
+
1608
+ assert res == b""
1609
+
1610
+ ms.push_packet("FF")
1611
+
1612
+ res = xm.programVerify(0x01, 0x0004, 0xCAFEBABE)
1613
+
1614
+ mock_socket.return_value.send.assert_called_with(
1615
+ bytes(
1616
+ [
1617
+ 0x08,
1618
+ 0x00,
1619
+ 0x0C,
1620
+ 0x00,
1621
+ 0xC8,
1622
+ 0x01,
1623
+ 0x04,
1624
+ 0x00,
1625
+ 0xBE,
1626
+ 0xBA,
1627
+ 0xFE,
1628
+ 0xCA,
1629
+ ]
1630
+ )
1631
+ )
1632
+
1633
+ assert res == b""
1634
+
1635
+ @mock.patch("pyxcp.transport.eth.socket.socket")
1636
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
1637
+ def testDbgCommands(self, mock_selector, mock_socket):
1638
+ ms = MockSocket()
1639
+
1640
+ mock_socket.return_value.recv.side_effect = ms.recv
1641
+ mock_selector.return_value.select.side_effect = ms.select
1642
+
1643
+ with Master("eth", config=create_config()) as xm:
1644
+ ms.push_packet(self.DefaultConnectResponse)
1645
+ res = xm.connect()
1646
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
1647
+
1648
+ ms.push_packet(b"\xff\x01\x00\x02\x03\xff\xfe\xca")
1649
+ res = xm.dbgAttach()
1650
+ mock_socket.return_value.send.assert_called_with(bytes([0x03, 0x00, 0x01, 0x00, 0xC0, 0xFC, 0x00]))
1651
+
1652
+ assert res.major == 1
1653
+ assert res.minor == 0
1654
+ assert res.timeout1 == 2
1655
+ assert res.timeout7 == 3
1656
+ assert res.maxCtoDbg == 0xCAFE
1657
+
1658
+ ms.push_packet(b"\xff\x04\xfe\xca\xef\xbe\xad\xde")
1659
+ res = xm.dbgGetVendorInfo()
1660
+ mock_socket.return_value.send.assert_called_with(bytes([0x03, 0x00, 0x02, 0x00, 0xC0, 0xFC, 0x01]))
1661
+
1662
+ assert res.length == 4
1663
+ assert res.vendorId == 0xCAFE
1664
+ assert res.vendorInfo == list(b"\xef\xbe\xad\xde")
1665
+
1666
+ ms.push_packet(b"\xff\xff\x04\x02\x01\x03")
1667
+ res = xm.dbgGetModeInfo()
1668
+ mock_socket.return_value.send.assert_called_with(bytes([0x03, 0x00, 0x03, 0x00, 0xC0, 0xFC, 0x02]))
1669
+
1670
+ assert res.maxHwIoPins == 4
1671
+ assert res.dialect == 2
1672
+ assert res.feature == 1
1673
+ assert res.serviceLevel == 3
1674
+
1675
+ ms.push_packet(b"\xff\xff\xff\xff\xbe\xba\xfe\xca")
1676
+ res = xm.dbgGetJtagId()
1677
+ mock_socket.return_value.send.assert_called_with(bytes([0x03, 0x00, 0x04, 0x00, 0xC0, 0xFC, 0x03]))
1678
+
1679
+ assert res.jtagId == 0xCAFEBABE
1680
+
1681
+ ms.push_packet(b"\xff")
1682
+ res = xm.dbgHaltAfterReset()
1683
+ mock_socket.return_value.send.assert_called_with(bytes([0x03, 0x00, 0x05, 0x00, 0xC0, 0xFC, 0x04]))
1684
+
1685
+ assert res == b""
1686
+
1687
+ ms.push_packet(b"\xff\x02\x01\x03\x01\x02\x02\x03\x02\x02")
1688
+ res = xm.dbgGetHwioInfo(0)
1689
+ mock_socket.return_value.send.assert_called_with(bytes([0x04, 0x00, 0x06, 0x00, 0xC0, 0xFC, 0x05, 0x00]))
1690
+
1691
+ assert res.num == 2
1692
+ assert res.pins[0].index == 1
1693
+ assert res.pins[0].mode == 3
1694
+ assert res.pins[0].pinClass == 1
1695
+ assert res.pins[0].state == 2
1696
+ assert res.pins[1].index == 2
1697
+ assert res.pins[1].mode == 3
1698
+ assert res.pins[1].pinClass == 2
1699
+ assert res.pins[1].state == 2
1700
+
1701
+ ms.push_packet(b"\xff")
1702
+ res = xm.dbgSetHwioEvent(0, 1)
1703
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x07, 0x00, 0xC0, 0xFC, 0x06, 0x00, 0x01]))
1704
+
1705
+ assert res == b""
1706
+
1707
+ ms.push_packet(b"\xff\x01\x00")
1708
+ res = xm.dbgHwioControl([[1, 2, 0], [2, 0, 0]])
1709
+ mock_socket.return_value.send.assert_called_with(
1710
+ bytes(
1711
+ [
1712
+ 0x0C,
1713
+ 0x00,
1714
+ 0x08,
1715
+ 0x00,
1716
+ 0xC0,
1717
+ 0xFC,
1718
+ 0x07,
1719
+ 0x02,
1720
+ 0x01,
1721
+ 0x02,
1722
+ 0x00,
1723
+ 0x00,
1724
+ 0x02,
1725
+ 0x00,
1726
+ 0x00,
1727
+ 0x00,
1728
+ ]
1729
+ )
1730
+ )
1731
+
1732
+ assert res[0] == 1
1733
+ assert res[1] == 0
1734
+
1735
+ ms.push_packet(b"\xff")
1736
+ res = xm.dbgExclusiveTargetAccess(1, 0)
1737
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x09, 0x00, 0xC0, 0xFC, 0x08, 0x01, 0x00]))
1738
+
1739
+ assert res == b""
1740
+
1741
+ ms.push_packet(b"\xff\xff\x02\x00\x01\x04\x03\x02\x01\x00\x02\xca\xfe\xba\xbe")
1742
+ res = xm.dbgSequenceMultiple(0x3, 0)
1743
+ mock_socket.return_value.send.assert_called_with(bytes([0x06, 0x00, 0x0A, 0x00, 0xC0, 0xFC, 0x09, 0x03, 0x00, 0x00]))
1744
+
1745
+ assert res.num == 2
1746
+ assert res.results[0].status == 0
1747
+ assert res.results[0].repeat == 1
1748
+ assert res.results[0].tdo == 0x04030201
1749
+ assert res.results[1].status == 0
1750
+ assert res.results[1].repeat == 2
1751
+ assert res.results[1].tdo == 0xCAFEBABE
1752
+
1753
+ ms.push_packet(b"\xff\x02\x08\xaa\x10\xaa\x55")
1754
+ res = xm.dbgLlt(0, 1)
1755
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x0B, 0x00, 0xC0, 0xFC, 0x0A, 0x00, 0x01]))
1756
+
1757
+ assert res.num == 2
1758
+ assert res.results[0].length == 8
1759
+ assert res.results[0].data == list(b"\xaa")
1760
+ assert res.results[1].length == 16
1761
+ assert res.results[1].data == list(b"\xaa\x55")
1762
+
1763
+ ms.push_packet(b"\xff\xff\xff\xff\x0d\xf0\xad\xba")
1764
+ res = xm.dbgReadModifyWrite(1, 4, 0xCAFEBABE, 0xFFFFFFFF, 0xDEADBEEF)
1765
+ mock_socket.return_value.send.assert_called_with(
1766
+ bytes(
1767
+ [
1768
+ 0x18,
1769
+ 0x00,
1770
+ 0x0C,
1771
+ 0x00,
1772
+ 0xC0,
1773
+ 0xFC,
1774
+ 0x0B,
1775
+ 0x00,
1776
+ 0x01,
1777
+ 0x04,
1778
+ 0x00,
1779
+ 0x00,
1780
+ 0xBE,
1781
+ 0xBA,
1782
+ 0xFE,
1783
+ 0xCA,
1784
+ 0x00,
1785
+ 0x00,
1786
+ 0x00,
1787
+ 0x00,
1788
+ 0xFF,
1789
+ 0xFF,
1790
+ 0xFF,
1791
+ 0xFF,
1792
+ 0xEF,
1793
+ 0xBE,
1794
+ 0xAD,
1795
+ 0xDE,
1796
+ ]
1797
+ )
1798
+ )
1799
+
1800
+ assert res.value == 0xBAADF00D
1801
+
1802
+ ms.push_packet(b"\xff")
1803
+ res = xm.dbgWrite(1, 4, 0xAAAA0001, [0xDDDD0001, 0xDDDD0002])
1804
+ mock_socket.return_value.send.assert_called_with(
1805
+ bytes(
1806
+ [
1807
+ 0x18,
1808
+ 0x00,
1809
+ 0x0D,
1810
+ 0x00,
1811
+ 0xC0,
1812
+ 0xFC,
1813
+ 0x0C,
1814
+ 0x00,
1815
+ 0x01,
1816
+ 0x04,
1817
+ 0x02,
1818
+ 0x00,
1819
+ 0x01,
1820
+ 0x00,
1821
+ 0xAA,
1822
+ 0xAA,
1823
+ 0x00,
1824
+ 0x00,
1825
+ 0x00,
1826
+ 0x00,
1827
+ 0x01,
1828
+ 0x00,
1829
+ 0xDD,
1830
+ 0xDD,
1831
+ 0x02,
1832
+ 0x00,
1833
+ 0xDD,
1834
+ 0xDD,
1835
+ ]
1836
+ )
1837
+ )
1838
+
1839
+ assert res == b""
1840
+
1841
+ ms.push_packet(b"\xff")
1842
+ res = xm.dbgWriteNext(2, [0xDDDD0003, 0xDDDD0004])
1843
+ mock_socket.return_value.send.assert_called_with(
1844
+ bytes(
1845
+ [
1846
+ 0x10,
1847
+ 0x00,
1848
+ 0x0E,
1849
+ 0x00,
1850
+ 0xC0,
1851
+ 0xFC,
1852
+ 0x0D,
1853
+ 0x00,
1854
+ 0x02,
1855
+ 0x00,
1856
+ 0x00,
1857
+ 0x00,
1858
+ 0x03,
1859
+ 0x00,
1860
+ 0xDD,
1861
+ 0xDD,
1862
+ 0x04,
1863
+ 0x00,
1864
+ 0xDD,
1865
+ 0xDD,
1866
+ ]
1867
+ )
1868
+ )
1869
+
1870
+ assert res == b""
1871
+
1872
+ ms.push_packet(b"\xff")
1873
+ res = xm.dbgWriteCan1(1, 0xAAAA0001)
1874
+ mock_socket.return_value.send.assert_called_with(
1875
+ bytes(
1876
+ [
1877
+ 0x08,
1878
+ 0x00,
1879
+ 0x0F,
1880
+ 0x00,
1881
+ 0xC0,
1882
+ 0xFC,
1883
+ 0x0E,
1884
+ 0x01,
1885
+ 0x01,
1886
+ 0x00,
1887
+ 0xAA,
1888
+ 0xAA,
1889
+ ]
1890
+ )
1891
+ )
1892
+
1893
+ assert res == b""
1894
+
1895
+ ms.push_packet(b"\xff")
1896
+ res = xm.dbgWriteCan2(4, 2)
1897
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x10, 0x00, 0xC0, 0xFC, 0x0F, 0x04, 0x02]))
1898
+
1899
+ assert res == b""
1900
+
1901
+ ms.push_packet(b"\xff")
1902
+ res = xm.dbgWriteCanNext(1, [0xCAFEBABE])
1903
+ mock_socket.return_value.send.assert_called_with(
1904
+ bytes(
1905
+ [
1906
+ 0x08,
1907
+ 0x00,
1908
+ 0x11,
1909
+ 0x00,
1910
+ 0xC0,
1911
+ 0xFC,
1912
+ 0x10,
1913
+ 0x01,
1914
+ 0xBE,
1915
+ 0xBA,
1916
+ 0xFE,
1917
+ 0xCA,
1918
+ ]
1919
+ )
1920
+ )
1921
+
1922
+ assert res == b""
1923
+
1924
+ ms.push_packet(b"\xff\xff\xff\xff\x01\x00\xdd\xdd\x02\x00\xdd\xdd")
1925
+ res = xm.dbgRead(1, 4, 2, 0xAAAA0001)
1926
+ mock_socket.return_value.send.assert_called_with(
1927
+ bytes(
1928
+ [
1929
+ 0x10,
1930
+ 0x00,
1931
+ 0x12,
1932
+ 0x00,
1933
+ 0xC0,
1934
+ 0xFC,
1935
+ 0x11,
1936
+ 0x00,
1937
+ 0x01,
1938
+ 0x04,
1939
+ 0x02,
1940
+ 0x00,
1941
+ 0x01,
1942
+ 0x00,
1943
+ 0xAA,
1944
+ 0xAA,
1945
+ 0x00,
1946
+ 0x00,
1947
+ 0x00,
1948
+ 0x00,
1949
+ ]
1950
+ )
1951
+ )
1952
+
1953
+ assert res.data[0] == 0xDDDD0001
1954
+ assert res.data[1] == 0xDDDD0002
1955
+
1956
+ ms.push_packet(b"\xff")
1957
+ res = xm.dbgReadCan1(1, 0xAAAA0001)
1958
+ mock_socket.return_value.send.assert_called_with(
1959
+ bytes(
1960
+ [
1961
+ 0x08,
1962
+ 0x00,
1963
+ 0x13,
1964
+ 0x00,
1965
+ 0xC0,
1966
+ 0xFC,
1967
+ 0x12,
1968
+ 0x01,
1969
+ 0x01,
1970
+ 0x00,
1971
+ 0xAA,
1972
+ 0xAA,
1973
+ ]
1974
+ )
1975
+ )
1976
+
1977
+ assert res == b""
1978
+
1979
+ ms.push_packet(b"\xff")
1980
+ res = xm.dbgReadCan2(4, 2)
1981
+ mock_socket.return_value.send.assert_called_with(bytes([0x05, 0x00, 0x14, 0x00, 0xC0, 0xFC, 0x13, 0x04, 0x02]))
1982
+
1983
+ assert res == b""
1984
+
1985
+ ms.push_packet(
1986
+ "FF 01 00 00 D0 00 00 00 07 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 00"
1987
+ " 06 00 00 00 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 07 00 00 00 00 00 02 01 00 00"
1988
+ "00 00 00 00 00 00 01 00 00 00 00 00 05 00 01 00 00 00 00 00 03 01 00 00 00 00 00 00 00 00 02 00 00 00 "
1989
+ "00 00 05 00 04 00 00 00 00 00 04 02 00 00 00 00 00 00 00 00 02 00 00 00 00 00 05 00 04 00 00 00 00 00 "
1990
+ "00 00 01 00 00 00 00 00 05 00 05 00 00 00 00 00 05 02 00 00 00 00 00 00 00 00 02 00 00 00 00 00 05 00 "
1991
+ "04 00 00 00 00 00 00 00 02 00 00 00 00 00 05 00 05 00 00 00 00 00 06 01 00 00 00 00 00 00 00 00 04 00 "
1992
+ "00 00 00 00 05 00 05 00 00 00 00 00"
1993
+ )
1994
+ res = xm.dbgGetTriDescTbl()
1995
+ mock_socket.return_value.send.assert_called_with(
1996
+ bytes(
1997
+ [
1998
+ 0x08,
1999
+ 0x00,
2000
+ 0x15,
2001
+ 0x00,
2002
+ 0xC0,
2003
+ 0xFC,
2004
+ 0x14,
2005
+ 0x00,
2006
+ 0x00,
2007
+ 0x00,
2008
+ 0x00,
2009
+ 0x00,
2010
+ ]
2011
+ )
2012
+ )
2013
+
2014
+ assert res.mode == 1
2015
+ assert res.length == 208
2016
+ assert res.table.tri_cnt == 7
2017
+ assert res.table.tris[0].tri == 0
2018
+ assert res.table.tris[0].trad_cnt == 1
2019
+ assert res.table.tris[0].trads[0].trai == 0x0
2020
+ assert res.table.tris[0].trads[0].trdt == 0x5
2021
+ assert res.table.tris[0].trads[0].trat == 0x6
2022
+ assert res.table.tris[1].tri == 1
2023
+ assert res.table.tris[1].trad_cnt == 1
2024
+ assert res.table.tris[1].trads[0].trai == 0x0
2025
+ assert res.table.tris[1].trads[0].trdt == 0x5
2026
+ assert res.table.tris[1].trads[0].trat == 0x7
2027
+ assert res.table.tris[2].tri == 2
2028
+ assert res.table.tris[2].trad_cnt == 1
2029
+ assert res.table.tris[2].trads[0].trai == 0x10000
2030
+ assert res.table.tris[2].trads[0].trdt == 0x5
2031
+ assert res.table.tris[2].trads[0].trat == 0x1
2032
+ assert res.table.tris[3].tri == 3
2033
+ assert res.table.tris[3].trad_cnt == 1
2034
+ assert res.table.tris[3].trads[0].trai == 0x20000
2035
+ assert res.table.tris[3].trads[0].trdt == 0x5
2036
+ assert res.table.tris[3].trads[0].trat == 0x4
2037
+ assert res.table.tris[4].tri == 4
2038
+ assert res.table.tris[4].trad_cnt == 2
2039
+ assert res.table.tris[4].trads[0].trai == 0x20000
2040
+ assert res.table.tris[4].trads[0].trdt == 0x5
2041
+ assert res.table.tris[4].trads[0].trat == 0x4
2042
+ assert res.table.tris[4].trads[1].trai == 0x10000
2043
+ assert res.table.tris[4].trads[1].trdt == 0x5
2044
+ assert res.table.tris[4].trads[1].trat == 0x5
2045
+ assert res.table.tris[5].tri == 5
2046
+ assert res.table.tris[5].trad_cnt == 2
2047
+ assert res.table.tris[5].trads[0].trai == 0x20000
2048
+ assert res.table.tris[5].trads[0].trdt == 0x5
2049
+ assert res.table.tris[5].trads[0].trat == 0x4
2050
+ assert res.table.tris[5].trads[1].trai == 0x20000
2051
+ assert res.table.tris[5].trads[1].trdt == 0x5
2052
+ assert res.table.tris[5].trads[1].trat == 0x5
2053
+ assert res.table.tris[6].tri == 6
2054
+ assert res.table.tris[6].trad_cnt == 1
2055
+ assert res.table.tris[6].trads[0].trai == 0x40000
2056
+ assert res.table.tris[6].trads[0].trdt == 0x5
2057
+ assert res.table.tris[6].trads[0].trat == 0x5
2058
+
2059
+ ms.push_packet("FF 00 0F 00 81 00 0A 34 00 00 00 00 00 00 00 00 00 C2 03")
2060
+ res = xm.dbgLlbt([0x01, 0x00, 0x05, 0x34, 0x00, 0x26, 0x25, 0xA0, 0xDC, 0x03])
2061
+ mock_socket.return_value.send.assert_called_with(
2062
+ bytes(
2063
+ [
2064
+ 0x10,
2065
+ 0x00,
2066
+ 0x16,
2067
+ 0x00,
2068
+ 0xC0,
2069
+ 0xFC,
2070
+ 0x15,
2071
+ 0x00,
2072
+ 0x0A,
2073
+ 0x00,
2074
+ 0x01,
2075
+ 0x00,
2076
+ 0x05,
2077
+ 0x34,
2078
+ 0x00,
2079
+ 0x26,
2080
+ 0x25,
2081
+ 0xA0,
2082
+ 0xDC,
2083
+ 0x03,
2084
+ ]
2085
+ )
2086
+ )
2087
+
2088
+ assert res.length == 15
2089
+ assert res.data == list(b"\x81\x00\x0a\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc2\x03")
2090
+
2091
+ @mock.patch("pyxcp.transport.eth.socket.socket")
2092
+ @mock.patch("pyxcp.transport.eth.selectors.DefaultSelector")
2093
+ def testTimeCorrelationProperties(self, mock_selector, mock_socket):
2094
+ ms = MockSocket()
2095
+
2096
+ mock_socket.return_value.recv.side_effect = ms.recv
2097
+ mock_selector.return_value.select.side_effect = ms.select
2098
+
2099
+ with Master("eth", config=create_config()) as xm:
2100
+ ms.push_packet(self.DefaultConnectResponse)
2101
+
2102
+ res = xm.connect()
2103
+
2104
+ mock_socket.return_value.send.assert_called_with(self.DefaultConnectCmd)
2105
+
2106
+ ms.push_packet("FF 15 25 01 1F 00 78 56")
2107
+
2108
+ res = xm.timeCorrelationProperties(0x15, 0x01, 0x1234)
2109
+
2110
+ mock_socket.return_value.send.assert_called_with(bytes([0x06, 0x00, 0x01, 0x00, 0xC6, 0x15, 0x01, 0x00, 0x34, 0x12]))
2111
+
2112
+ assert res.slaveConfig == 0x15
2113
+ assert res.observableClocks == 0x25
2114
+ assert res.syncState == 0x01
2115
+ assert res.clockInfo == 0x1F
2116
+ assert res.clusterId == 0x5678