tdl-xoa-driver 1.4.0__py3-none-any.whl → 1.5.0b1__py3-none-any.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 (46) hide show
  1. {tdl_xoa_driver-1.4.0.dist-info → tdl_xoa_driver-1.5.0b1.dist-info}/METADATA +2 -2
  2. {tdl_xoa_driver-1.4.0.dist-info → tdl_xoa_driver-1.5.0b1.dist-info}/RECORD +45 -33
  3. xoa_driver/__init__.py +2 -2
  4. xoa_driver/enums.py +2 -0
  5. xoa_driver/exceptions.py +2 -0
  6. xoa_driver/functions/anlt.py +2 -0
  7. xoa_driver/functions/anlt_ll_debug.py +2 -0
  8. xoa_driver/functions/cli/__init__.py +21 -0
  9. xoa_driver/functions/cli/_cli_manager.py +541 -0
  10. xoa_driver/functions/cli/_config_block.py +334 -0
  11. xoa_driver/functions/cli/_socket_driver.py +111 -0
  12. xoa_driver/functions/cli/port_config.py +107 -0
  13. xoa_driver/functions/cli/test_case_config.py +172 -0
  14. xoa_driver/functions/cmis/__init__.py +8 -0
  15. xoa_driver/functions/cmis/_constants.py +25 -0
  16. xoa_driver/functions/cmis/_replies.py +600 -0
  17. xoa_driver/functions/cmis/_utils.py +49 -0
  18. xoa_driver/functions/cmis/cdb.py +1266 -0
  19. xoa_driver/functions/exceptions.py +2 -0
  20. xoa_driver/functions/headers.py +2 -0
  21. xoa_driver/functions/mgmt.py +42 -19
  22. xoa_driver/functions/tools.py +9 -3
  23. xoa_driver/hlfuncs.py +6 -2
  24. xoa_driver/internals/commands/c_commands.py +6 -10
  25. xoa_driver/internals/commands/enums.py +25 -1
  26. xoa_driver/internals/commands/pr_commands.py +17 -16
  27. xoa_driver/internals/commands/px_commands.py +54 -54
  28. xoa_driver/internals/core/transporter/logger/__state_on_user.py +1 -1
  29. xoa_driver/internals/exceptions/modules.py +4 -3
  30. xoa_driver/internals/hli/modules/modules_l23/family_edun.py +82 -0
  31. xoa_driver/internals/hli/modules/modules_l23/family_g.py +1 -1
  32. xoa_driver/internals/hli/modules/modules_l23/family_l1.py +19 -0
  33. xoa_driver/internals/hli/ports/port_l23/family_edun.py +82 -0
  34. xoa_driver/internals/hli/ports/port_l23/family_l1.py +6 -0
  35. xoa_driver/internals/state_storage/modules_state.py +20 -0
  36. xoa_driver/internals/state_storage/testers_state.py +10 -0
  37. xoa_driver/lli.py +1 -0
  38. xoa_driver/misc.py +1 -0
  39. xoa_driver/modules.py +22 -0
  40. xoa_driver/ports.py +22 -0
  41. xoa_driver/testers.py +2 -0
  42. xoa_driver/utils.py +2 -0
  43. xoa_driver/functions/cli.py +0 -581
  44. {tdl_xoa_driver-1.4.0.dist-info → tdl_xoa_driver-1.5.0b1.dist-info}/WHEEL +0 -0
  45. {tdl_xoa_driver-1.4.0.dist-info → tdl_xoa_driver-1.5.0b1.dist-info}/licenses/LICENSE +0 -0
  46. {tdl_xoa_driver-1.4.0.dist-info → tdl_xoa_driver-1.5.0b1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1266 @@
1
+ """The cmis cdb high-level function module."""
2
+
3
+ from __future__ import annotations
4
+ import asyncio
5
+ from dataclasses import dataclass
6
+ from typing import (TYPE_CHECKING, Callable, Awaitable, Dict)
7
+ from ._utils import *
8
+ from ._constants import *
9
+ from ._replies import *
10
+ import time
11
+ # from contextlib import suppress
12
+ from xoa_driver import exceptions
13
+
14
+ if TYPE_CHECKING:
15
+ from xoa_driver.ports import GenericL23Port
16
+
17
+
18
+ # CMD 0000h: Query Status
19
+
20
+ async def cmd_0000h_query_status_cmd(port: GenericL23Port, cdb_instance: int, response_delay: int) -> None:
21
+ """Send CMD 0000h Query Status
22
+
23
+ :param port: the port object to send the command to
24
+ :type port: GenericL23Port
25
+ :param cdb_instance: CDB instance number.
26
+
27
+ * 0 = CBD Instance 1
28
+ * 1 = CDB Instance 2
29
+
30
+ :type cdb_instance: int
31
+ :param response_delay: Programmable delay in ms for module responding to this command. A value of 0 asks for module response as fast as possible.
32
+ :type response_delay: int
33
+ """
34
+
35
+ cmd_data = {
36
+ "response_delay": response_delay
37
+ }
38
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0000h_query_status.set(cmd_data=cmd_data)
39
+
40
+ async def cmd_0000h_query_status_reply(port: GenericL23Port, cdb_instance: int) -> CMD0000hQueryStatusReply:
41
+ """Read the module response to CMD 0000h Query Status
42
+
43
+ :param port: the port object to read the response from
44
+ :type port: GenericL23Port
45
+ :param cdb_instance: CDB instance number.
46
+
47
+ * 0 = CBD Instance 1
48
+ * 1 = CDB Instance 2
49
+
50
+ :type cdb_instance: int
51
+ :return: REPLY of CMD 0000h Query Status
52
+ :rtype: CMD0000hQueryStatusReply
53
+ """
54
+ while True:
55
+ try:
56
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0000h_query_status.get()
57
+ return CMD0000hQueryStatusReply(resp.reply)
58
+ except exceptions.XmpPendingError:
59
+ time.sleep(0.1)
60
+
61
+ # CMD 0001h: Enter Password
62
+
63
+ async def cmd_0001h_enter_password_cmd(port: GenericL23Port, cdb_instance: int, password: bytearray) -> None:
64
+ """Send CMD 0001h Enter Password
65
+
66
+ :param port: the port object to send the command to
67
+ :type port: GenericL23Port
68
+
69
+ :param cdb_instance: CDB instance number.
70
+
71
+ * 0 = CBD Instance 1
72
+ * 1 = CDB Instance 2
73
+
74
+ :type cdb_instance: int
75
+ :param password: password to be entered
76
+ :type password: int
77
+ """
78
+
79
+ cmd_data = {
80
+ "password": password
81
+ }
82
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0001h_enter_password.set(cmd_data=cmd_data)
83
+
84
+ async def cmd_0001h_enter_password_reply(port: GenericL23Port, cdb_instance: int) -> CMD0001hEnterPasswordReply:
85
+ """Read the module response to CMD 0001h Enter Password
86
+
87
+ :param port: the port object to read the response from
88
+ :type port: GenericL23Port
89
+ :param cdb_instance: CDB instance number.
90
+
91
+ * 0 = CBD Instance 1
92
+ * 1 = CDB Instance 2
93
+
94
+ :type cdb_instance: int
95
+ :return: REPLY of CMD 0001h Enter Password
96
+ :rtype: CMD0001hEnterPasswordReply
97
+ """
98
+ while True:
99
+ try:
100
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0001h_enter_password.get()
101
+ return CMD0001hEnterPasswordReply(resp.reply)
102
+ except exceptions.XmpPendingError:
103
+ time.sleep(0.1)
104
+
105
+
106
+ # CMD 0002h: Change Password
107
+
108
+ async def cmd_0002h_change_password_cmd(port: GenericL23Port, cdb_instance: int, new_password: bytearray) -> None:
109
+ """Send CMD 0002h Change Password
110
+
111
+ :param port: the port object to send the command to
112
+ :type port: GenericL23Port
113
+ :param cdb_instance: CDB instance number.
114
+
115
+ * 0 = CBD Instance 1
116
+ * 1 = CDB Instance 2
117
+
118
+ :type cdb_instance: int
119
+ :param new_password: new password to be entered
120
+ :type new_password: int
121
+ """
122
+ cmd_data = {
123
+ "new_password": new_password
124
+ }
125
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0002h_change_password.set(cmd_data=cmd_data)
126
+
127
+ async def cmd_0002h_change_password_reply(port: GenericL23Port, cdb_instance: int) -> CMD0002hChangePasswordReply:
128
+ """Read the module response to CMD 0002h Change Password
129
+
130
+ :param port: the port object to read the response from
131
+ :type port: GenericL23Port
132
+ :param cdb_instance: CDB instance number.
133
+
134
+ * 0 = CBD Instance 1
135
+ * 1 = CDB Instance 2
136
+
137
+ :type cdb_instance: int
138
+ :return: REPLY of CMD 0002h Change Password
139
+ :rtype: CMD0002hChangePasswordReply
140
+ """
141
+ while True:
142
+ try:
143
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0002h_change_password.get()
144
+ return CMD0002hChangePasswordReply(resp.reply)
145
+ except exceptions.XmpPendingError:
146
+ time.sleep(0.1)
147
+
148
+
149
+ # CMD 0004h: Abort Processing
150
+
151
+ async def cmd_0004h_abort_processing_cmd(port: GenericL23Port, cdb_instance: int) -> None:
152
+ """Send CMD 0004h Abort Processing
153
+
154
+ :param port: the port object to send the command to
155
+ :type port: GenericL23Port
156
+ :param cdb_instance: CDB instance number.
157
+
158
+ * 0 = CBD Instance 1
159
+ * 1 = CDB Instance 2
160
+
161
+ :type cdb_instance: int
162
+ """
163
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0004h_abort_processing.set()
164
+
165
+ async def cmd_0004h_abort_processing_reply(port: GenericL23Port, cdb_instance: int) -> CMD0004hAbortProcessingReply:
166
+ """Read the module response to CMD 0004h Abort Processing
167
+
168
+ :param port: the port object to read the response from
169
+ :type port: GenericL23Port
170
+ :param cdb_instance: CDB instance number.
171
+
172
+ * 0 = CBD Instance 1
173
+ * 1 = CDB Instance 2
174
+
175
+ :type cdb_instance: int
176
+ :return: REPLY of CMD 0004h Abort Processing
177
+ :rtype: CMD0004hAbortProcessingReply
178
+ """
179
+ while True:
180
+ try:
181
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0004h_abort_processing.get()
182
+ return CMD0004hAbortProcessingReply(resp.reply)
183
+ except exceptions.XmpPendingError:
184
+ time.sleep(0.1)
185
+
186
+
187
+ # CMD 0040h: Module Features
188
+
189
+ async def cmd_0040h_module_features_cmd(port: GenericL23Port, cdb_instance: int) -> None:
190
+ """Send CMD 0040h Module Features
191
+
192
+ :param port: the port object to send the command to
193
+ :type port: GenericL23Port
194
+ :param cdb_instance: CDB instance number.
195
+
196
+ * 0 = CBD Instance 1
197
+ * 1 = CDB Instance 2
198
+
199
+ :type cdb_instance: int
200
+ """
201
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0040h_module_features.set()
202
+
203
+ async def cmd_0040h_module_features_reply(port: GenericL23Port, cdb_instance: int) -> CMD0040hModuleFeaturesReply:
204
+ """Read the module response to CMD 0040h Module Features
205
+
206
+ :param port: the port object to read the response from
207
+ :type port: GenericL23Port
208
+ :param cdb_instance: CDB instance number.
209
+
210
+ * 0 = CBD Instance 1
211
+ * 1 = CDB Instance 2
212
+
213
+ :type cdb_instance: int
214
+ :return: REPLY of CMD 0040h Module Features
215
+ :rtype: CMD0040hModuleFeaturesReply
216
+ """
217
+ while True:
218
+ try:
219
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0040h_module_features.get()
220
+ return CMD0040hModuleFeaturesReply(resp.reply)
221
+ except exceptions.XmpPendingError:
222
+ time.sleep(0.1)
223
+
224
+
225
+ # CMD 0041h: Firmware Management Features
226
+
227
+ async def cmd_0041h_fw_mgmt_features_cmd(port: GenericL23Port, cdb_instance: int) -> None:
228
+ """Send CMD 0041h Firmware Management Features
229
+
230
+ :param port: the port object to send the command to
231
+ :type port: GenericL23Port
232
+ :param cdb_instance: CDB instance number.
233
+
234
+ * 0 = CBD Instance 1
235
+ * 1 = CDB Instance 2
236
+
237
+ :type cdb_instance: int
238
+ """
239
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0041h_fw_mgmt_features.set()
240
+
241
+ async def cmd_0041h_fw_mgmt_features_reply(port: GenericL23Port, cdb_instance: int) -> CMD0041hFirmwareManagementFeaturesReply:
242
+ """Read the module response to CMD 0041h Firmware Management Features
243
+
244
+ :param port: the port object to read the response from
245
+ :type port: GenericL23Port
246
+ :param cdb_instance: CDB instance number.
247
+
248
+ * 0 = CBD Instance 1
249
+ * 1 = CDB Instance 2
250
+
251
+ :type cdb_instance: int
252
+ :return: REPLY of CMD 0041h Firmware Management Features
253
+ :rtype: CMD0041hFirmwareManagementFeaturesReply
254
+ """
255
+ while True:
256
+ try:
257
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0041h_fw_mgmt_features.get()
258
+ return CMD0041hFirmwareManagementFeaturesReply(resp.reply)
259
+ except exceptions.XmpPendingError:
260
+ time.sleep(0.1)
261
+
262
+
263
+ # CMD 0044h: Security Features and Capabilities
264
+
265
+ async def cmd_0044h_sec_feat_capabilities_cmd(port: GenericL23Port, cdb_instance: int) -> None:
266
+ """Send CMD 0044h Security Features and Capabilities
267
+
268
+ :param port: the port object to send the command to
269
+ :type port: GenericL23Port
270
+ :param cdb_instance: CDB instance number.
271
+
272
+ * 0 = CBD Instance 1
273
+ * 1 = CDB Instance 2
274
+
275
+ :type cdb_instance: int
276
+ """
277
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0044h_sec_feat_capabilities.set()
278
+
279
+ async def cmd_0044h_sec_feat_and_capabilities_reply(port: GenericL23Port, cdb_instance: int) -> CMD0044hSecFeaturesAndCapabilitiesReply:
280
+ """Read the module response to CMD 0044h Security Features and Capabilities
281
+
282
+ :param port: the port object to read the response from
283
+ :type port: GenericL23Port
284
+ :param cdb_instance: CDB instance number.
285
+
286
+ * 0 = CBD Instance 1
287
+ * 1 = CDB Instance 2
288
+
289
+ :type cdb_instance: int
290
+ :return: REPLY of CMD 0044h Security Features and Capabilities
291
+ :rtype: CMD0044hSecFeaturesAndCapabilitiesReply
292
+ """
293
+ while True:
294
+ try:
295
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0044h_sec_feat_capabilities.get()
296
+ return CMD0044hSecFeaturesAndCapabilitiesReply(resp.reply)
297
+ except exceptions.XmpPendingError:
298
+ time.sleep(0.1)
299
+
300
+ # CMD 0045h: Externally Defined Features
301
+
302
+ async def cmd_0045h_externally_defined_features_cmd(port: GenericL23Port, cdb_instance: int) -> None:
303
+ """Send CMD 0045h Externally Defined Features
304
+
305
+ :param port: the port object to send the command to
306
+ :type port: GenericL23Port
307
+ :param cdb_instance: CDB instance number.
308
+
309
+ * 0 = CBD Instance 1
310
+ * 1 = CDB Instance 2
311
+
312
+ :type cdb_instance: int
313
+ """
314
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0045h_external_features.set()
315
+
316
+ async def cmd_0045h_externally_defined_features_reply(port: GenericL23Port, cdb_instance: int) -> CMD0045hExternallyDefinedFeaturesReply:
317
+ """Read the module response to CMD 0045h Externally Defined Features
318
+
319
+ :param port: the port object to read the response from
320
+ :type port: GenericL23Port
321
+ :param cdb_instance: CDB instance number.
322
+
323
+ * 0 = CBD Instance 1
324
+ * 1 = CDB Instance 2
325
+
326
+ :type cdb_instance: int
327
+ :return: REPLY of CMD 0045h Externally Defined Features
328
+ :rtype: CMD0045hExternallyDefinedFeaturesReply
329
+ """
330
+ while True:
331
+ try:
332
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0045h_external_features.get()
333
+ return CMD0045hExternallyDefinedFeaturesReply(resp.reply)
334
+ except exceptions.XmpPendingError:
335
+ time.sleep(0.1)
336
+
337
+ # CMD 0050h: Get Application Attributes
338
+
339
+ async def cmd_0050h_get_application_attributes_cmd(port: GenericL23Port, cdb_instance: int, application_number: int) -> None:
340
+ """Send CMD 0050h Get Application Attributes
341
+
342
+ :param port: the port object to send the command to
343
+ :type port: GenericL23Port
344
+ :param cdb_instance: CDB instance number.
345
+
346
+ * 0 = CBD Instance 1
347
+ * 1 = CDB Instance 2
348
+
349
+ :type cdb_instance: int
350
+ :param application_number: U16 Application number. 15-8: reserved (0). 7-4: NADBlockIndex (0-15) or 0. 3-0: AppSelCode (1-15)
351
+ :type application_number: int
352
+ """
353
+ cmd_data = {
354
+ "application_number": application_number
355
+ }
356
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0050h_get_app_attributes.set(cmd_data=cmd_data)
357
+
358
+ async def cmd_0050h_get_application_attributes_reply(port: GenericL23Port, cdb_instance: int) -> CMD0050hGetApplicationAttributesReply:
359
+ """Read the module response to CMD 0050h Get Application Attributes
360
+
361
+ :param port: the port object to read the response from
362
+ :type port: GenericL23Port
363
+ :param cdb_instance: CDB instance number.
364
+
365
+ * 0 = CBD Instance 1
366
+ * 1 = CDB Instance 2
367
+
368
+ :type cdb_instance: int
369
+ :return: REPLY of CMD 0050h Get Application Attributes
370
+ :rtype: CMD0050hGetApplicationAttributesReply
371
+ """
372
+ while True:
373
+ try:
374
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0050h_get_app_attributes.get()
375
+ return CMD0050hGetApplicationAttributesReply(resp.reply)
376
+ except exceptions.XmpPendingError:
377
+ time.sleep(0.1)
378
+
379
+
380
+ # CMD 0051h: Get Interface Code Description
381
+
382
+ async def cmd_0051h_get_interface_code_description_cmd(port: GenericL23Port, cdb_instance: int, interface_id: int, interface_location: int) -> None:
383
+ """Send CMD 0051h Get Interface Code Description
384
+
385
+ :param port: the port object to send the command to
386
+ :type port: GenericL23Port
387
+ :param cdb_instance: CDB instance number.
388
+
389
+ * 0 = CBD Instance 1
390
+ * 1 = CDB Instance 2
391
+
392
+ :type cdb_instance: int
393
+ :param interface_id: HostInterfaceID or MediaInterfaceID. 15-8: reserved (0). 7-0: InterfaceID
394
+ :type interface_id: hex str
395
+ :param interface_location: 0: Media side. 1: Host side
396
+ :type interface_location: int
397
+ """
398
+ cmd_data = {
399
+ "interface_id": interface_id,
400
+ "interface_location": interface_location
401
+ }
402
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0051h_get_if_code_descr.set(cmd_data=cmd_data)
403
+
404
+ async def cmd_0051h_get_interface_code_description_reply(port: GenericL23Port, cdb_instance: int) -> CMD0051hGetInterfaceCodeDescriptionReply:
405
+ """Read the module response to CMD 0051h Get Interface Code Description
406
+
407
+ :param port: the port object to read the response from
408
+ :type port: GenericL23Port
409
+ :param cdb_instance: CDB instance number.
410
+
411
+ * 0 = CBD Instance 1
412
+ * 1 = CDB Instance 2
413
+
414
+ :type cdb_instance: int
415
+ :return: REPLY of CMD 0051h Get Interface Code Description
416
+ :rtype: CMD0051hGetInterfaceCodeDescriptionReply
417
+ """
418
+ while True:
419
+ try:
420
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0051h_get_if_code_descr.get()
421
+ return CMD0051hGetInterfaceCodeDescriptionReply(resp.reply)
422
+ except exceptions.XmpPendingError:
423
+ time.sleep(0.1)
424
+
425
+
426
+ # CMD 0100h: Get Firmware Info
427
+
428
+ async def cmd_0100h_get_firmware_info_cmd(port: GenericL23Port, cdb_instance: int) -> None:
429
+ """Send CMD 0100h Get Firmware Info
430
+
431
+ :param port: the port object to send the command to
432
+ :type port: GenericL23Port
433
+ :param cdb_instance: CDB instance number.
434
+
435
+ * 0 = CBD Instance 1
436
+ * 1 = CDB Instance 2
437
+
438
+ :type cdb_instance: int
439
+ """
440
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0100h_get_firmware_info.set()
441
+
442
+ async def cmd_0100h_get_firmware_info_reply(port: GenericL23Port, cdb_instance: int) -> CMD0100hGetFirmwareInfoReply:
443
+ """Read the module response to CMD 0100h Get Firmware Info
444
+
445
+ :param port: the port object to read the response from
446
+ :type port: GenericL23Port
447
+ :param cdb_instance: CDB instance number.
448
+
449
+ * 0 = CBD Instance 1
450
+ * 1 = CDB Instance 2
451
+
452
+ :type cdb_instance: int
453
+ :return: REPLY of CMD 0100h Get Firmware Info
454
+ :rtype: CMD0100hGetFirmwareInfoReply
455
+ """
456
+ while True:
457
+ try:
458
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0100h_get_firmware_info.get()
459
+ return CMD0100hGetFirmwareInfoReply(resp.reply)
460
+ except exceptions.XmpPendingError:
461
+ time.sleep(0.1)
462
+
463
+
464
+ # CMD 0101h: Start Firmware Download
465
+
466
+ async def cmd_0101h_start_firmware_download_cmd(port: GenericL23Port, cdb_instance: int, image_size: int, vendor_data: str) -> None:
467
+ """Send CMD 0101h Start Firmware Download
468
+
469
+ :param port: the port object to send the command to
470
+ :type port: GenericL23Port
471
+ :param cdb_instance: CDB instance number.
472
+
473
+ * 0 = CBD Instance 1
474
+ * 1 = CDB Instance 2
475
+
476
+ :type cdb_instance: int
477
+ :param image_size: U32 Size of firmware image to download into the module. This should be the file size including the LPL bytes sent as vendor data in this message.
478
+ :type image_size: int
479
+ :param vendor_data: U8 Array of vendor specific data to be sent to the module. This data is sent as part of the firmware download message. The size of this data is included in the image_size parameter
480
+ :type vendor_data: hex str
481
+ """
482
+ cmd_data = {
483
+ "image_size": image_size,
484
+ "vendor_data": vendor_data
485
+ }
486
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0101h_start_firmware_download.set(cmd_data=cmd_data)
487
+
488
+ async def cmd_0101h_start_firmware_download_reply(port: GenericL23Port, cdb_instance: int) -> CMD0101hStartFirmwareDownloadReply:
489
+ """Read the module response to CMD 0101h Start Firmware Download
490
+
491
+ :param port: the port object to read the response from
492
+ :type port: GenericL23Port
493
+ :param cdb_instance: CDB instance number.
494
+
495
+ * 0 = CBD Instance 1
496
+ * 1 = CDB Instance 2
497
+
498
+ :type cdb_instance: int
499
+ :return: REPLY of CMD 0101h Start Firmware Download
500
+ :rtype: CMD0101hStartFirmwareDownloadReply
501
+ """
502
+ while True:
503
+ try:
504
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0101h_start_firmware_download.get()
505
+ return CMD0101hStartFirmwareDownloadReply(resp.reply)
506
+ except exceptions.XmpPendingError:
507
+ time.sleep(0.1)
508
+
509
+
510
+ # CMD 0102h: Abort Firmware Download
511
+
512
+ async def cmd_0102h_abort_firmware_download_cmd(port: GenericL23Port, cdb_instance: int) -> None:
513
+ """Send CMD 0102h Abort Firmware Download
514
+
515
+ :param port: the port object to send the command to
516
+ :type port: GenericL23Port
517
+ :param cdb_instance: CDB instance number.
518
+
519
+ * 0 = CBD Instance 1
520
+ * 1 = CDB Instance 2
521
+
522
+ :type cdb_instance: int
523
+ """
524
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0102h_abort_firmware_download.set()
525
+
526
+ async def cmd_0102h_abort_firmware_download_reply(port: GenericL23Port, cdb_instance: int) -> CMD0102hAbortFirmwareDownloadReply:
527
+ """Read the module response to CMD 0102h Abort Firmware Download
528
+
529
+ :param port: the port object to read the response from
530
+ :type port: GenericL23Port
531
+ :param cdb_instance: CDB instance number.
532
+
533
+ * 0 = CBD Instance 1
534
+ * 1 = CDB Instance 2
535
+
536
+ :type cdb_instance: int
537
+ :return: REPLY of CMD 0102h Abort Firmware Download
538
+ :rtype: CMD0102hAbortFirmwareDownloadReply
539
+ """
540
+ while True:
541
+ try:
542
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0102h_abort_firmware_download.get()
543
+ return CMD0102hAbortFirmwareDownloadReply(resp.reply)
544
+ except exceptions.XmpPendingError:
545
+ time.sleep(0.1)
546
+
547
+
548
+ # CMD 0103h: Write Firmware Block LPL
549
+
550
+ async def cmd_0103h_write_firmware_block_lpl_cmd(port: GenericL23Port, cdb_instance: int, block_address: int, firmware_block: bytes) -> None:
551
+ """Send CMD 0103h Write Firmware Block LPL
552
+
553
+ :param port: the port object to send the command to
554
+ :type port: GenericL23Port
555
+ :param cdb_instance: CDB instance number.
556
+
557
+ * 0 = CBD Instance 1
558
+ * 1 = CDB Instance 2
559
+
560
+ :type cdb_instance: int
561
+ :param block_address: U32 Starting byte address of this block of data within the supplied image file minus the size of the “Start Command Payload Size”.
562
+ :type block_address: int
563
+ :param firmware_block: U8[116] One block of the firmware image. The actually needed length may be shorter than the available FirmwareBlock field size. This actual length of the block is defined in Byte 132 (LPLLength)
564
+ :type firmware_block: bytes
565
+ """
566
+ cmd_data = {
567
+ "block_address": block_address,
568
+ "firmware_block": "0x" + bytes.hex(firmware_block).upper()
569
+ }
570
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0103h_write_firmware_block_lpl.set(cmd_data=cmd_data)
571
+
572
+ async def cmd_0103h_write_firmware_block_lpl_reply(port: GenericL23Port, cdb_instance: int) -> CMD0103hWriteFirmwareBlockLPLReply:
573
+ """Read the module response to CMD 0103h Write Firmware Block LPL
574
+
575
+ :param port: the port object to read the response from
576
+ :type port: GenericL23Port
577
+ :param cdb_instance: CDB instance number.
578
+
579
+ * 0 = CBD Instance 1
580
+ * 1 = CDB Instance 2
581
+
582
+ :type cdb_instance: int
583
+ :return: REPLY of CMD 0103h Write Firmware Block LPL
584
+ :rtype: CMD0103hWriteFirmwareBlockLPLReply
585
+ """
586
+ while True:
587
+ try:
588
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0103h_write_firmware_block_lpl.get()
589
+ return CMD0103hWriteFirmwareBlockLPLReply(resp.reply)
590
+ except exceptions.XmpPendingError:
591
+ time.sleep(0.1)
592
+
593
+
594
+ # CMD 0104h: Write Firmware Block EPL
595
+
596
+ async def cmd_0104h_write_firmware_block_epl_cmd(port: GenericL23Port, cdb_instance: int, block_address: int, firmware_block: bytes) -> None:
597
+ """Send CMD 0104h Write Firmware Block EPL
598
+
599
+ :param port: the port object to send the command to
600
+ :type port: GenericL23Port
601
+ :param cdb_instance: CDB instance number.
602
+
603
+ * 0 = CBD Instance 1
604
+ * 1 = CDB Instance 2
605
+
606
+ :type cdb_instance: int
607
+ :param block_address: U32 Starting byte address of this block of data within the supplied image file minus the size of the “Start Command Payload Size”.
608
+ :type block_address: int
609
+ :param firmware_block: Up to 2048 Bytes. Actual Length specified in EPLLength
610
+ :type firmware_block: hex str
611
+ """
612
+
613
+ cmd_data = {
614
+ "block_address": block_address,
615
+ "firmware_block": "0x" + bytes.hex(firmware_block).upper()
616
+ }
617
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0104h_write_firmware_block_epl.set(cmd_data=cmd_data)
618
+
619
+ async def cmd_0104h_write_firmware_block_epl_reply(port: GenericL23Port, cdb_instance: int) -> CMD0104hWriteFirmwareBlockEPLReply:
620
+ """Read the module response to CMD 0104h Write Firmware Block EPL
621
+
622
+ :param port: the port object to read the response from
623
+ :type port: GenericL23Port
624
+ :param cdb_instance: CDB instance number.
625
+
626
+ * 0 = CBD Instance 1
627
+ * 1 = CDB Instance 2
628
+
629
+ :type cdb_instance: int
630
+ :return: REPLY of CMD 0104h Write Firmware Block EPL
631
+ :rtype: CMD0104hWriteFirmwareBlockEPLReply
632
+ """
633
+ while True:
634
+ try:
635
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0104h_write_firmware_block_epl.get()
636
+ return CMD0104hWriteFirmwareBlockEPLReply(resp.reply)
637
+ except exceptions.XmpPendingError:
638
+ time.sleep(0.1)
639
+
640
+
641
+ # CMD 0105h: Read Firmware Block LPL
642
+
643
+ async def cmd_0105h_read_firmware_block_lpl_cmd(port: GenericL23Port, cdb_instance: int, block_address: int, length: int) -> None:
644
+ """Send CMD 0105h Read Firmware Block LPL
645
+
646
+ :param port: the port object to send the command to
647
+ :type port: GenericL23Port
648
+ :param cdb_instance: CDB instance number.
649
+
650
+ * 0 = CBD Instance 1
651
+ * 1 = CDB Instance 2
652
+
653
+ :type cdb_instance: int
654
+ :param block_address: U32 Starting byte address of this block of data within the supplied image file minus the size of the size of the “Start Command Payload Size”.
655
+ :type block_address: int
656
+ :param length: U16 Number of bytes to read back to the LPL in this command, starting at the indicated address.
657
+ :type length: int
658
+ """
659
+ cmd_data = {
660
+ "block_address": block_address,
661
+ "length": length
662
+ }
663
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0105h_read_firmware_block_lpl.set(cmd_data=cmd_data)
664
+
665
+ async def cmd_0105h_read_firmware_block_lpl_reply(port: GenericL23Port, cdb_instance: int) -> CMD0105hReadFirmwareBlockLPLReply:
666
+ """Read the module response to CMD 0105h Read Firmware Block LPL
667
+
668
+ :param port: the port object to read the response from
669
+ :type port: GenericL23Port
670
+ :param cdb_instance: CDB instance number.
671
+
672
+ * 0 = CBD Instance 1
673
+ * 1 = CDB Instance 2
674
+
675
+ :type cdb_instance: int
676
+ :param block_address: U32 Starting byte address of this block of data within the supplied image file minus the size of the size of the “Start Command Payload Size”.
677
+ :type block_address: int
678
+ :param length: U16 Number of bytes to read back to the LPL in this command, starting at the indicated address
679
+ :type length: int
680
+ :return: REPLY of CMD 0105h Read Firmware Block LPL
681
+ :rtype: CMD0105hReadFirmwareBlockLPLReply
682
+ """
683
+ while True:
684
+ try:
685
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0105h_read_firmware_block_lpl.get()
686
+ return CMD0105hReadFirmwareBlockLPLReply(resp.reply)
687
+ except exceptions.XmpPendingError:
688
+ time.sleep(0.1)
689
+
690
+
691
+ # CMD 0106h: Read Firmware Block EPL
692
+
693
+ async def cmd_0106h_read_firmware_block_epl_cmd(port: GenericL23Port, cdb_instance: int, block_address: int, length: int) -> None:
694
+ """Send CMD 0106h Read Firmware Block EPL
695
+
696
+ :param port: the port object to send the command to
697
+ :type port: GenericL23Port
698
+ :param cdb_instance: CDB instance number.
699
+
700
+ * 0 = CBD Instance 1
701
+ * 1 = CDB Instance 2
702
+
703
+ :type cdb_instance: int
704
+ :param block_address: U32 Starting byte address of this block of data within the supplied image file minus the size of the size of the “Start Command Payload Size”
705
+ :type block_address: int
706
+ :param length: U16 Number of bytes to read back to the EPL in this command, starting at the indicated address.
707
+ :type length: int
708
+ """
709
+ cmd_data = {
710
+ "block_address": block_address,
711
+ "length": length
712
+ }
713
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0106h_read_firmware_block_epl.set(cmd_data=cmd_data)
714
+
715
+ async def cmd_0106h_read_firmware_block_epl_reply(port: GenericL23Port, cdb_instance: int) -> CMD0106hReadFirmwareBlockEPLReply:
716
+ """Read the module response to CMD 0106h Read Firmware Block EPL
717
+
718
+ :param port: the port object to read the response from
719
+ :type port: GenericL23Port
720
+ :param cdb_instance: CDB instance number.
721
+
722
+ * 0 = CBD Instance 1
723
+ * 1 = CDB Instance 2
724
+
725
+ :type cdb_instance: int
726
+ :param block_address: U32 Starting byte address of this block of data within the supplied image file minus the size of the size of the “Start Command Payload Size”
727
+ :type block_address: int
728
+ :param length: U16 Number of bytes to read back to the EPL in this command, starting at the indicated address.
729
+ :type length: int
730
+ :return: REPLY of CMD 0106h Read Firmware Block EPL
731
+ :rtype: CMD0106hReadFirmwareBlockEPLReply
732
+ """
733
+ while True:
734
+ try:
735
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0106h_read_firmware_block_epl.get()
736
+ return CMD0106hReadFirmwareBlockEPLReply(resp.reply)
737
+ except exceptions.XmpPendingError:
738
+ time.sleep(0.1)
739
+
740
+
741
+ # CMD 0107h: Complete Firmware Download
742
+
743
+ async def cmd_0107h_complete_firmware_download_cmd(port: GenericL23Port, cdb_instance: int) -> None:
744
+ """Send CMD 0107h Complete Firmware Download
745
+
746
+ :param port: the port object to send the command to
747
+ :type port: GenericL23Port
748
+ :param cdb_instance: CDB instance number.
749
+
750
+ * 0 = CBD Instance 1
751
+ * 1 = CDB Instance 2
752
+
753
+ :type cdb_instance: int
754
+ """
755
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0107h_complete_firmware_download.set()
756
+
757
+ async def cmd_0107h_complete_firmware_download_reply(port: GenericL23Port, cdb_instance: int) -> CMD0107hCompleteFirmwareDownloadReply:
758
+ """Read the module response to CMD 0107h Complete Firmware Download
759
+
760
+ :param port: the port object to read the response from
761
+ :type port: GenericL23Port
762
+ :param cdb_instance: CDB instance number.
763
+
764
+ * 0 = CBD Instance 1
765
+ * 1 = CDB Instance 2
766
+
767
+ :type cdb_instance: int
768
+ :return: REPLY of CMD 0107h Complete Firmware Download
769
+ :rtype: CMD0107hCompleteFirmwareDownloadReply
770
+ """
771
+ while True:
772
+ try:
773
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0107h_complete_firmware_download.get()
774
+ return CMD0107hCompleteFirmwareDownloadReply(resp.reply)
775
+ except exceptions.XmpPendingError:
776
+ time.sleep(0.1)
777
+
778
+
779
+ # CMD 0108h: Copy Firmware Image
780
+
781
+ async def cmd_0108h_copy_firmware_image_cmd(port: GenericL23Port, cdb_instance: int, copy_direction: int) -> None:
782
+ """Send CMD 0108h Copy Firmware Image
783
+
784
+ :param port: the port object to send the command to
785
+ :type port: GenericL23Port
786
+ :param cdb_instance: CDB instance number.
787
+
788
+ * 0 = CBD Instance 1
789
+ * 1 = CDB Instance 2
790
+
791
+ :type cdb_instance: int
792
+ :param copy_direction: copy direction.
793
+
794
+ * ``0xAB``, Copy Image A into Image B
795
+ * ``0xBA``,Copy Image B into Image A
796
+
797
+ :type copy_direction: hex str
798
+ """
799
+ cmd_data = {
800
+ "copy_direction": copy_direction
801
+ }
802
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0108h_copy_firmware_image.set(cmd_data=cmd_data)
803
+
804
+ async def cmd_0108h_copy_firmware_image_reply(port: GenericL23Port, cdb_instance: int) -> CMD0108hCopyFirmwareImageReply:
805
+ """Read the module response to CMD 0108h Copy Firmware Image
806
+
807
+ :param port: the port object to read the response from
808
+ :type port: GenericL23Port
809
+ :param cdb_instance: CDB instance number.
810
+
811
+ * 0 = CBD Instance 1
812
+ * 1 = CDB Instance 2
813
+
814
+ :type cdb_instance: int
815
+ :return: REPLY of CMD 0108h Copy Firmware Image
816
+ :rtype: CMD0108CopyFirmwareImageReply
817
+ """
818
+ while True:
819
+ try:
820
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0108h_copy_firmware_image.get()
821
+ return CMD0108hCopyFirmwareImageReply(resp.reply)
822
+ except exceptions.XmpPendingError:
823
+ time.sleep(0.1)
824
+
825
+
826
+ # CMD 0109h: Run Firmware Image
827
+
828
+ async def cmd_0109h_run_firmware_image_cmd(port: GenericL23Port, cdb_instance: int, image_to_run: int, delay_to_reset: int) -> None:
829
+ """Send CMD 0109h Run Firmware Image
830
+
831
+ :param port: the port object to send the command to
832
+ :type port: GenericL23Port
833
+ :param cdb_instance: CDB instance number.
834
+
835
+ * 0 = CBD Instance 1
836
+ * 1 = CDB Instance 2
837
+
838
+ :type cdb_instance: int
839
+ :param image_to_run: integer, index of the image to run.
840
+
841
+ * 0 = Traffic affecting Reset to Inactive Image.
842
+ * 1 = Attempt Hitless Reset to Inactive Image
843
+ * 2 = Traffic affecting Reset to Running Image.
844
+ * 3 = Attempt Hitless Reset to Running Image
845
+
846
+ :type image_to_run: int
847
+ :param delay_to_reset: integer, Indicates the delay in ms after receiving this command before a reset will occur, starting from the time the CDB complete Flag is set.
848
+ :type delay_to_reset: int
849
+ """
850
+ cmd_data = {
851
+ "image_to_run": image_to_run,
852
+ "delay_to_reset": delay_to_reset
853
+ }
854
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_0109h_run_firmware_image.set(cmd_data=cmd_data)
855
+
856
+ async def cmd_0109h_run_firmware_image_reply(port: GenericL23Port, cdb_instance: int) -> CMD0109hRunFirmwareImageReply:
857
+ """Read the module response to CMD 0109h Run Firmware Image
858
+
859
+ :param port: the port object to read the response from
860
+ :type port: GenericL23Port
861
+ :param cdb_instance: CDB instance number.
862
+
863
+ * 0 = CBD Instance 1
864
+ * 1 = CDB Instance 2
865
+
866
+ :type cdb_instance: int
867
+ :return: REPLY of CMD 0109h Run Firmware Image
868
+ :rtype: CMD0109RunFirmwareImageReply
869
+ """
870
+ while True:
871
+ try:
872
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_0109h_run_firmware_image.get()
873
+ return CMD0109hRunFirmwareImageReply(resp.reply)
874
+ except exceptions.XmpPendingError:
875
+ time.sleep(0.1)
876
+
877
+
878
+ # CMD 010Ah: Commit Firmware Image
879
+
880
+ async def cmd_010ah_commit_firmware_image_cmd(port: GenericL23Port, cdb_instance: int) -> None:
881
+ """Send CMD 010Ah Commit Firmware Image
882
+
883
+ :param port: the port object to send the command to
884
+ :type port: GenericL23Port
885
+ :param cdb_instance: CDB instance number.
886
+
887
+ * 0 = CBD Instance 1
888
+ * 1 = CDB Instance 2
889
+
890
+ :type cdb_instance: int
891
+ """
892
+ await port.transceiver.cmis.cdb(cdb_instance).cmd_010ah_commit_firmware_image.set()
893
+
894
+ async def cmd_010ah_commit_firmware_image_reply(port: GenericL23Port, cdb_instance: int) -> CMD010AhCommitFirmwareImageReply:
895
+ """Read the module response to CMD 010Ah Commit Firmware Image
896
+
897
+ :param port: the port object to read the response from
898
+ :type port: GenericL23Port
899
+ :param cdb_instance: CDB instance number.
900
+
901
+ * 0 = CBD Instance 1
902
+ * 1 = CDB Instance 2
903
+
904
+ :type cdb_instance: int
905
+ :return: REPLY of CMD 010Ah Commit Firmware Image
906
+ :rtype: CMD010AhCommitFirmwareImageReply
907
+ """
908
+ while True:
909
+ try:
910
+ resp = await port.transceiver.cmis.cdb(cdb_instance).cmd_010ah_commit_firmware_image.get()
911
+ return CMD010AhCommitFirmwareImageReply(resp.reply)
912
+ except exceptions.XmpPendingError:
913
+ time.sleep(0.1)
914
+
915
+
916
+ # CMD 8000h-FFFFh: Custom Command
917
+
918
+ async def cmd_custom_cmd_reply(port: GenericL23Port, cdb_instance: int) -> CustomCMDReply:
919
+ """Read the module response to CMD 8000h-FFFFh Custom Command
920
+
921
+ :param port: the port object to read the response from
922
+ :type port: GenericL23Port
923
+ :param cdb_instance: CDB instance number.
924
+
925
+ * 0 = CBD Instance 1
926
+ * 1 = CDB Instance 2
927
+
928
+ :type cdb_instance: int
929
+ :return: REPLY of CMD 8000h-FFFFh Custom Command
930
+ :rtype: CustomCMDReply
931
+ """
932
+ while True:
933
+ try:
934
+ resp = await port.transceiver.cmis.cdb(cdb_instance).custom_cmd.get()
935
+ return CustomCMDReply(resp.reply)
936
+ except exceptions.XmpPendingError:
937
+ time.sleep(0.1)
938
+
939
+ async def cmd_custom_cmd_request(port: GenericL23Port, cdb_instance: int, cmd_id: str, epl_length: int, lpl_length: int, rpl_length: int, rpl_check_code: int, data: str) -> None:
940
+ """Send CMD 8000h-FFFFh Custom Command
941
+
942
+ :param port: the port object to send the command to
943
+ :type port: GenericL23Port
944
+ :param cdb_instance: CDB instance number.
945
+
946
+ * 0 = CBD Instance 1
947
+ * 1 = CDB Instance 2
948
+
949
+ :type cdb_instance: int
950
+ :param cmd_id: ``CMD Header.CMDID``. Command ID.
951
+ :type cmd_id: hex str
952
+
953
+ :param epl_length: ``CMD Header.EPLLength``. Length of the EPL.
954
+ :type epl_length: int
955
+
956
+ :param lpl_length: ``CMD Header.LPLLength``. Length of the LPL.
957
+ :type lpl_length: int
958
+
959
+ :param rpl_length: ``CMD Header.RPLLength``. Length of the RPL (optional).
960
+ :type rpl_length: int
961
+
962
+ :param rpl_check_code: ``CMD Header.RPLChkCode``. Check code for the RPL. (optional)
963
+ :type rpl_check_code: int
964
+
965
+ :param data: ``CMD Data.Data``. The data to be sent in the command.
966
+ :type data: hex str
967
+ """
968
+ cmd = {
969
+ "cmd_header": {
970
+ "cmd_id": cmd_id,
971
+ "epl_length": epl_length,
972
+ "lpl_length": lpl_length,
973
+ "rpl_length": rpl_length,
974
+ "rpl_check_code": rpl_check_code
975
+ },
976
+ "cmd_data": {
977
+ "data": data
978
+ }
979
+ }
980
+ await port.transceiver.cmis.cdb(cdb_instance).custom_cmd.set(cmd=cmd)
981
+
982
+ async def cdb_instances_supported_reply(port: GenericL23Port) -> int:
983
+ resp = await port.transceiver.cmis.cdb_instances_supported.get()
984
+ return resp.reply["cdb_instances_supported"]
985
+
986
+
987
+ async def firmware_download_procedure(port: GenericL23Port, cdb_instance: int, firmware_file: str, use_epl_write: bool, use_abort_for_failure: bool) -> bool:
988
+ """Specified in **OIF-CMIS-05.3**
989
+
990
+ Start transceiver firmware update on the specified port.
991
+
992
+ The host begins by reading module capabilities using CMD 0041h: (Firmware Management Features).
993
+
994
+ The host then reads (and possibly converts to binary format) the vendor specific and vendor provided firmware download file into a contiguous addressable byte array defined as the binary download image.
995
+
996
+ To start the firmware download, the host sends the download image header consisting of the first StartCmdPayloadSize bytes from the download image using CMD 0101h: (Start Firmware Download). This header instructs the module in a vendor specific way about the full or partial download content to be expected.
997
+
998
+ Before the module updates an image bank in a download procedure the module ensures that the bank is marked as empty or corrupt until the download has eventually finished successfully.
999
+
1000
+ When CMD 0101h: was successful, the module is ready to accept data from the host using the advertised method, either CMD 0103h: (Write Firmware Block LPL) or CMD 0104h: (Write Firmware Block EPL). These command differ only in the allowed size of a download image block, which: is advertised for the EPL variant.
1001
+
1002
+ The host zero-initializes a variable containing the address of the next data block to be sent or received in subsequent Write Firmware Block or Read Firmware Block commands, respectively.
1003
+
1004
+ In a loop the host then reads subsequent bytes of the download image in blocks not exceeding the allowed block site and sends it using CMD 0103h: or 0104h.
1005
+
1006
+ :param port: the port object to send the command to
1007
+ :type port: GenericL23Port
1008
+ :param cdb_instance: the CDB instance number.
1009
+ :type cdb_instance: int
1010
+ :param firmware_file: the module firmware filename
1011
+ :type firmware_file: str
1012
+ :param use_epl_write: should the procedure use EPL write mechanism for data block write.
1013
+ :type use_epl_write: bool
1014
+ :param use_abort_for_failure: should the procedure use CMD 0102h Abort Firmware Download to abort the firmware download on failure.
1015
+ :type use_abort_for_failure: bool
1016
+ """
1017
+ cdb_instances_supported = await cdb_instances_supported_reply(port)
1018
+ # Check if the specified CDB instance is supported
1019
+ if cdb_instance >= cdb_instances_supported:
1020
+ print(f"CDB instance {cdb_instance} is not supported. Only {cdb_instances_supported} CDB instances are supported.")
1021
+ return False
1022
+
1023
+ # Log the start of the firmware update
1024
+ print(f"Starting firmware update on {port}")
1025
+
1026
+ # Read capabilities (CMD 0041h)
1027
+ # Read size of START_LPL, erase byte
1028
+ reply_obj = await cmd_0041h_fw_mgmt_features_reply(port, cdb_instance)
1029
+ firmware_header_size = reply_obj.start_cmd_payload_size
1030
+
1031
+ # Determine the write mechanism
1032
+ write_mechanism = reply_obj.write_mechanism
1033
+ if write_mechanism == WriteMechanism.NONE_SUPPORTED:
1034
+ print("Write Mechanism is not supported. Unable to proceed with firmware update.")
1035
+ return False
1036
+ elif write_mechanism == WriteMechanism.LPL_ONLY:
1037
+ print("Only CMD 0103h Write Firmware Block LPL is supported. Will use LPL write mechanism.")
1038
+ use_epl_write = False
1039
+ elif write_mechanism == WriteMechanism.EPL_ONLY:
1040
+ print("Only CMD 0104h Write Firmware Block EPL is supported. Will use EPL write mechanism.")
1041
+ use_epl_write = True
1042
+ else:
1043
+ print(("Both CMD 0103h and CMD 0104h are supported. Will use the preferred write mechanism."))
1044
+
1045
+ # Read the erased byte value
1046
+ erased_byte = reply_obj.erased_byte
1047
+ if reply_obj.abort_cmd == 0 and use_abort_for_failure:
1048
+ use_abort_for_failure = False
1049
+ print("CMD 0102h Abort Firmware Download is not supported by the module. Will use CMD 0107h Complete Firmware Download instead.")
1050
+
1051
+ # Start the data block write loop
1052
+ return await _write_data_block_loop(port, cdb_instance, firmware_file, firmware_header_size, erased_byte, use_epl_write, use_abort_for_failure)
1053
+
1054
+
1055
+ ##################
1056
+ # Helper functions
1057
+ ##################
1058
+
1059
+ async def _write_data_block_loop(port: GenericL23Port, cdb_instance: int, firmware_filename: str, firmware_header_size: int, erased_byte: int, use_epl_write: bool, use_abort_for_failure: bool) -> bool:
1060
+ """Write data block loop
1061
+
1062
+ :param port: the port object
1063
+ :type port: GenericL23Port
1064
+ :param cdb_instance: CDB instance number.
1065
+ :type cdb_instance: int
1066
+ :param firmware_filename: module firmware filename
1067
+ :type firmware_filename: str
1068
+ :param firmware_header_size: firmware header size
1069
+ :type firmware_header_size: int
1070
+ :param erased_byte: value of the erased byte to check against
1071
+ :type erased_byte: int
1072
+ :param use_epl_write: should the procedure use EPL write mechanism for data block write.
1073
+ :type use_epl_write: bool
1074
+ :param use_abort_for_failure: should the procedure use CMD 0102h Abort Firmware Download to abort the firmware download on failure.
1075
+ :type use_abort_for_failure: bool
1076
+ """
1077
+ if use_epl_write:
1078
+ write_func_map = {
1079
+ "block_size": 2048,
1080
+ "write_cmd_func": cmd_0104h_write_firmware_block_epl_cmd,
1081
+ "write_reply_func": cmd_0104h_write_firmware_block_epl_reply,
1082
+ "description": "CMD 0104h: (Write Firmware Block EPL)"
1083
+ }
1084
+ else:
1085
+ write_func_map = {
1086
+ "block_size": 116,
1087
+ "write_cmd_func": cmd_0103h_write_firmware_block_lpl_cmd,
1088
+ "write_reply_func": cmd_0103h_write_firmware_block_lpl_reply,
1089
+ "description": "CMD 0103h: (Write Firmware Block LPL)"
1090
+ }
1091
+
1092
+ with open(firmware_filename, "rb") as f:
1093
+ # Read the header data
1094
+ firmware_header_data = "0x" + f.read(firmware_header_size).hex()
1095
+
1096
+ # Send the header data using CMD 0101h: (Start Firmware Download), and wait for completion
1097
+ await cmd_0101h_start_firmware_download_cmd(port, cdb_instance, firmware_header_size, firmware_header_data)
1098
+ while True:
1099
+ reply = await cmd_0101h_start_firmware_download_reply(port, cdb_instance)
1100
+ if reply.cdb_io_status == 1 or reply.cdb_io_status == 2:
1101
+ break
1102
+ await asyncio.sleep(0.1)
1103
+
1104
+ if reply.cdb_io_status != 1 or reply.cdb_status != 1:
1105
+ print(f"CMD 0101h: (Start Firmware Download) failed. cdb_io_status={reply.cdb_io_status}, cdb_status={reply.cdb_status}")
1106
+ await _abort_firmware_download(port, cdb_instance, use_abort_for_failure)
1107
+ return False
1108
+
1109
+ addr = 0
1110
+ while True:
1111
+ # Read a block of firmware data
1112
+ data_block = f.read(write_func_map["block_size"])
1113
+ if not data_block:
1114
+ print("EOF. No more data to read.")
1115
+ break
1116
+ data_block_len = len(data_block)
1117
+ data_block_hex = "0x" + data_block.hex()
1118
+ erased_byte_hex = f"0x{erased_byte:02X}"
1119
+ if check_erased_byte(data_block_hex, erased_byte_hex):
1120
+ addr += data_block_len
1121
+ continue
1122
+ else:
1123
+ # Send the data block
1124
+ await write_func_map["write_cmd_func"](port, cdb_instance, addr, data_block)
1125
+
1126
+ # Wait for completion by polling cdb_io_status
1127
+ while True:
1128
+ reply = await write_func_map["write_reply_func"](port, cdb_instance)
1129
+ if reply.cdb_io_status == 1 or reply.cdb_io_status == 2:
1130
+ break
1131
+ await asyncio.sleep(0.1)
1132
+
1133
+ if reply.cdb_io_status != 1 or reply.cdb_status != 1:
1134
+ print(f"{write_func_map['description']} failed. cdb_io_status={reply.cdb_io_status}, cdb_status={reply.cdb_status}")
1135
+ await _abort_firmware_download(port, cdb_instance, use_abort_for_failure)
1136
+ return False
1137
+ else:
1138
+ addr += data_block_len
1139
+ continue
1140
+
1141
+ # Send CMD 0107h: (Complete Firmware Download) to complete the firmware download
1142
+ await cmd_0107h_complete_firmware_download_cmd(port, cdb_instance)
1143
+ while True:
1144
+ reply = await cmd_0107h_complete_firmware_download_reply(port, cdb_instance)
1145
+ if reply.cdb_io_status == 1 or reply.cdb_io_status == 2:
1146
+ break
1147
+ await asyncio.sleep(0.1)
1148
+
1149
+ if reply.cdb_io_status != 1 or reply.cdb_status != 1:
1150
+ print(f"CMD 0107h: (Complete Firmware Download) failed. cdb_io_status={reply.cdb_io_status}, cdb_status={reply.cdb_status}")
1151
+ print("Firmware Update Failed.")
1152
+ return False
1153
+
1154
+ print("Firmware Update Successful.")
1155
+ return True
1156
+
1157
+
1158
+ async def _abort_firmware_download(port: GenericL23Port, cdb_instance: int, use_abort_for_failure: bool) -> None:
1159
+ """Abort firmware download
1160
+
1161
+ :param port: the port object
1162
+ :type port: GenericL23Port
1163
+ :param cdb_instance: the CDB instance number
1164
+ :type cdb_instance: int
1165
+ :param use_abort_for_failure: should the procedure use CMD 0102h Abort Firmware Download to abort the firmware download on failure.
1166
+ :type use_abort_for_failure: bool
1167
+ """
1168
+ if use_abort_for_failure:
1169
+ # Send CMD 0102h: (Abort Firmware Download) to abort the firmware download
1170
+ await cmd_0102h_abort_firmware_download_cmd(port, cdb_instance)
1171
+ while True:
1172
+ reply = await cmd_0102h_abort_firmware_download_reply(port, cdb_instance)
1173
+ if reply.cdb_io_status == 1 or reply.cdb_io_status == 2:
1174
+ break
1175
+ await asyncio.sleep(0.1)
1176
+
1177
+ if reply.cdb_io_status != 1 or reply.cdb_status != 1:
1178
+ print("CMD 0102h: (Abort Firmware Download) failed.")
1179
+ else:
1180
+ print("CMD 0102h: (Abort Firmware Download) successful.")
1181
+ else:
1182
+ # Send CMD 0107h: (Complete Firmware Download) to complete the firmware download
1183
+ await cmd_0107h_complete_firmware_download_cmd(port, cdb_instance)
1184
+ while True:
1185
+ reply = await cmd_0107h_complete_firmware_download_reply(port, cdb_instance)
1186
+ if reply.cdb_io_status == 1 or reply.cdb_io_status == 2:
1187
+ break
1188
+ await asyncio.sleep(0.1)
1189
+
1190
+ if reply.cdb_io_status != 1 or reply.cdb_status != 1:
1191
+ print("CMD 0107h: (Complete Firmware Download) failed.")
1192
+ else:
1193
+ print("CMD 0107h: (Complete Firmware Download) successful.")
1194
+
1195
+ print("Firmware Update Failed.")
1196
+
1197
+
1198
+ __all__ = (
1199
+ "cmd_0000h_query_status_cmd",
1200
+ "cmd_0000h_query_status_reply",
1201
+ "cmd_0001h_enter_password_cmd",
1202
+ "cmd_0001h_enter_password_reply",
1203
+ "cmd_0002h_change_password_cmd",
1204
+ "cmd_0002h_change_password_reply",
1205
+ "cmd_0004h_abort_processing_cmd",
1206
+ "cmd_0004h_abort_processing_reply",
1207
+ "cmd_0040h_module_features_cmd",
1208
+ "cmd_0040h_module_features_reply",
1209
+ "cmd_0041h_fw_mgmt_features_cmd",
1210
+ "cmd_0041h_fw_mgmt_features_reply",
1211
+ "cmd_0044h_sec_feat_and_capabilities_reply",
1212
+ "cmd_0044h_sec_feat_capabilities_cmd",
1213
+ "cmd_0045h_externally_defined_features_cmd",
1214
+ "cmd_0045h_externally_defined_features_reply",
1215
+ "cmd_0050h_get_application_attributes_cmd",
1216
+ "cmd_0050h_get_application_attributes_reply",
1217
+ "cmd_0051h_get_interface_code_description_cmd",
1218
+ "cmd_0051h_get_interface_code_description_reply",
1219
+ "cmd_0100h_get_firmware_info_cmd",
1220
+ "cmd_0100h_get_firmware_info_reply",
1221
+ "cmd_0101h_start_firmware_download_cmd",
1222
+ "cmd_0101h_start_firmware_download_reply",
1223
+ "cmd_0102h_abort_firmware_download_cmd",
1224
+ "cmd_0102h_abort_firmware_download_reply",
1225
+ "cmd_0103h_write_firmware_block_lpl_cmd",
1226
+ "cmd_0103h_write_firmware_block_lpl_reply",
1227
+ "cmd_0104h_write_firmware_block_epl_cmd",
1228
+ "cmd_0104h_write_firmware_block_epl_reply",
1229
+ "cmd_0105h_read_firmware_block_lpl_cmd",
1230
+ "cmd_0105h_read_firmware_block_lpl_reply",
1231
+ "cmd_0106h_read_firmware_block_epl_cmd",
1232
+ "cmd_0106h_read_firmware_block_epl_reply",
1233
+ "cmd_0107h_complete_firmware_download_cmd",
1234
+ "cmd_0107h_complete_firmware_download_reply",
1235
+ "cmd_0108h_copy_firmware_image_cmd",
1236
+ "cmd_0108h_copy_firmware_image_reply",
1237
+ "cmd_0109h_run_firmware_image_cmd",
1238
+ "cmd_0109h_run_firmware_image_reply",
1239
+ "cmd_010ah_commit_firmware_image_cmd",
1240
+ "cmd_010ah_commit_firmware_image_reply",
1241
+ "cmd_custom_cmd_reply",
1242
+ "cmd_custom_cmd_request",
1243
+ "CMD0000hQueryStatusReply",
1244
+ "CMD0001hEnterPasswordReply",
1245
+ "CMD0002hChangePasswordReply",
1246
+ "CMD0004hAbortProcessingReply",
1247
+ "CMD0040hModuleFeaturesReply",
1248
+ "CMD0041hFirmwareManagementFeaturesReply",
1249
+ "CMD0044hSecFeaturesAndCapabilitiesReply",
1250
+ "CMD0045hExternallyDefinedFeaturesReply",
1251
+ "CMD0050hGetApplicationAttributesReply",
1252
+ "CMD0051hGetInterfaceCodeDescriptionReply",
1253
+ "CMD0100hGetFirmwareInfoReply",
1254
+ "CMD0101hStartFirmwareDownloadReply",
1255
+ "CMD0102hAbortFirmwareDownloadReply",
1256
+ "CMD0103hWriteFirmwareBlockLPLReply",
1257
+ "CMD0104hWriteFirmwareBlockEPLReply",
1258
+ "CMD0105hReadFirmwareBlockLPLReply",
1259
+ "CMD0106hReadFirmwareBlockEPLReply",
1260
+ "CMD0107hCompleteFirmwareDownloadReply",
1261
+ "CMD0108hCopyFirmwareImageReply",
1262
+ "CMD0109hRunFirmwareImageReply",
1263
+ "CMD010AhCommitFirmwareImageReply",
1264
+ "CustomCMDReply",
1265
+ "firmware_download_procedure",
1266
+ )