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,600 @@
1
+
2
+ import typing as t
3
+
4
+ class CMDBaseReply:
5
+ def __init__(self, reply: t.Dict[str, t.Any]):
6
+ self.cdb_io_status: int = reply.get("cdb_io_status", 0)
7
+ """integer, indicates the CDB IO status.
8
+
9
+ * 0: Idle, transceiver is not processing a CDB command.
10
+ * 1: Finished, transceiver has finished processing a CDB command. It is ready to accept a new CDB command.
11
+ * 2: Timeout, transceiver has timed out while processing a CDB command. It is ready to accept a new CDB command.
12
+ * 3: In progress: transceiver is currently processing a CDB command. It is not ready to accept a new CDB command.
13
+ """
14
+ self.cdb_status: int = reply['cdb_status']
15
+ """
16
+ integer, provides the status of the most recently triggered CDB command.
17
+
18
+ In Progress
19
+
20
+ * ``10 000001b``: Busy capturing command
21
+ * ``10 000010b``: Busy checking/validating command
22
+ * ``10 000011b``: Busy executing command
23
+
24
+ On Success
25
+
26
+ * ``00 000001b``: Success
27
+
28
+ On Failure
29
+
30
+ * ``01 000000b``: Failed, no specific failure
31
+ * ``01 000101b``: CdbChkCode error
32
+
33
+ """
34
+ self.cdb_cmd_complete_flag: bool = reply["cdb_cmd_complete_flag"]
35
+ """
36
+ Latched Flag to indicate completion of a CDB command for CDB instance.
37
+
38
+ Set by module when the CDB command is complete.
39
+
40
+ """
41
+
42
+ class CMD0000hQueryStatusReply(CMDBaseReply):
43
+ """REPLY message of CMD 0000h Query Status
44
+ """
45
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
46
+ super().__init__(reply)
47
+ self.status: int = reply['status']
48
+ """integer
49
+
50
+ * ``0000 0000b``: Module Boot Up.
51
+ * ``0000 0001b``: Host Password Accepted.
52
+ * ``1xxx xxxxb``: Module Password accepted.
53
+ * Bits ‘x’ may contain custom information.
54
+ """
55
+
56
+ class CMD0001hEnterPasswordReply(CMDBaseReply):
57
+ """REPLY message of CMD 0001h Enter Password
58
+ """
59
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
60
+ super().__init__(reply)
61
+
62
+ class CMD0002hChangePasswordReply(CMDBaseReply):
63
+ """REPLY message of CMD 0002h Change Password
64
+ """
65
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
66
+ super().__init__(reply)
67
+
68
+ class CMD0004hAbortProcessingReply(CMDBaseReply):
69
+ """REPLY message of CMD 0004h Abort Processing
70
+ """
71
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
72
+ super().__init__(reply)
73
+
74
+ class CMD0040hModuleFeaturesReply(CMDBaseReply):
75
+ """REPLY message of CMD 0040h Module Features
76
+ """
77
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
78
+ super().__init__(reply)
79
+
80
+ # Parse cmd_support_mask as a list of integers
81
+ self.cmd_support = reply["cmd_support_mask"]
82
+
83
+ self.max_completion_time: int = reply["max_completion_time"]
84
+ """integer, U16 Maximum CDB command execution time in ms, of all supported CDB commands
85
+ """
86
+
87
+ class CMD0041hFirmwareManagementFeaturesReply(CMDBaseReply):
88
+ """REPLY message of CMD 0041h Firmware Management Features
89
+ """
90
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
91
+ super().__init__(reply)
92
+
93
+ feature_support_mask: int = reply["feature_support_mask"]
94
+
95
+ self.abort_cmd: int = (feature_support_mask >> 0) & 0x01
96
+ """
97
+ * 0b = CMD 0102h (Abort) Not Supported
98
+ * 1b = CMD 0102h (Abort) Supported
99
+
100
+ """
101
+ self.copy_cmd: int = (feature_support_mask >> 1) & 0x01
102
+ """
103
+ * 0b = CMD 0108h (Copy image) Not Supported
104
+ * 1b = CMD 0108h (Copy image) Supported
105
+
106
+ """
107
+ self.skipping_erased_blocks: int = (feature_support_mask >> 2) & 0x01
108
+ """
109
+ * 0b = Skipping erased blocks Not Supported
110
+ * 1b = Skipping erased blocks Supported
111
+
112
+ """
113
+ self.max_duration_coding: int = (feature_support_mask >> 3) & 0x01
114
+ """
115
+ * 0b = max duration multiplier M is 1
116
+ * 1b = max duration multiplier M is 10
117
+
118
+ This bit encodes a multiplier value M which governs the interpretation of values found in the U16 array of advertised max durations in Bytes 144-153 of this message: These advertised values are multiplied by M.
119
+
120
+ """
121
+ self.image_readback: int = (feature_support_mask >> 7) & 0x01
122
+ """
123
+ * 0b = Full Image Readback Not Supported
124
+ * 1b = Full Image Readback Supported
125
+
126
+ """
127
+ self.start_cmd_payload_size: int = reply["start_cmd_payload_size"]
128
+ """integer, This defines the number of bytes that the host must extract from the beginning of the vendor-delivered binary firmware image file and send to the module in CMD 0101h (Start)
129
+ """
130
+ self.erased_byte: int = reply["erased_byte"]
131
+ """integer, This is the value representing an erased byte. The purpose of advertising this byte is to optionally reduce download time by allowing the host to skip sending blocks of the image containing ErasedByte values only.
132
+ """
133
+ self.read_write_length_ext: int = reply["read_write_length_ext"]
134
+ """integer, specifies the allowable additional number of byte octets in a READ or a WRITE, specifically for Firmware Management Commands (IDs 0100h-01FFh) as follows:
135
+
136
+ EPL: For accessing the multi-page EPL field, the allowable length extension is i byte octets (8 bytes).
137
+
138
+ LPL: For accessing the LPL field on page 9Fh, the allowable length extension is min(i, 15) byte octets.
139
+
140
+ This leads to the maximum length of a READ or a WRITE
141
+
142
+ Value Maximum Number of Bytes (EPL)
143
+
144
+ * 0: 8 bytes (no extension of general length limit)
145
+ * i: 8 * (1+i) bytes (0 ≤ i ≤ 255)
146
+ * 255: 8 * 256 = 2048 bytes
147
+
148
+ Value Maximum Number of Bytes (LPL)
149
+
150
+ * 0: 8 bytes (no extension of general length limit)
151
+ * i: 8 * (1+i) bytes (0 ≤ i ≤ 15)
152
+ * i: 8 * 16 = 128 bytes (16 ≤ i ≤ 256)
153
+
154
+ """
155
+ self.write_mechanism: int = reply['write_mechanism']
156
+ """integer, Firmware update supported mechanism
157
+
158
+ * 00h: None Supported.
159
+ * 01h: Write to LPL supported.
160
+ * 10h: Write to EPL supported.
161
+ * 11h: Both Write to LPL and EPL supported.
162
+
163
+ """
164
+ self.read_mechanism: int = reply['read_mechanism']
165
+ """integer, Firmware read / readback support mechanism.
166
+
167
+ * 00h: None Supported.
168
+ * 01h: Read via LPL supported.
169
+ * 10h: Read via EPL supported.
170
+ * 11h: Both Read via LPL and EPL supported.
171
+
172
+ """
173
+ self.hitless_restart: int = reply["hitless_restart"]
174
+ """integer
175
+
176
+ * 0: CMD Run Image causes a reset. Traffic is affected.
177
+ * 1: CMD Run Image may reset but module will do its best to maintain traffic and management states. Data path functions are not reset.
178
+
179
+ """
180
+ self.max_duration_start: int = reply["max_duration_start"]
181
+ """integer, U16 Maximum time in M ms for a CDB Start command to complete execution
182
+ """
183
+ self.max_duration_abort: int = reply["max_duration_abort"]
184
+ """integer, U16 Maximum time in M ms for a CDB Abort command to complete execution
185
+ """
186
+ self.max_duration_write: int = reply["max_duration_write"]
187
+ """integer, U16 Maximum time in M ms for a CDB Write command to complete execution
188
+ """
189
+ self.max_duration_complete: int = reply["max_duration_complete"]
190
+ """integer, U16 Maximum time in M ms for a CDB Complete command to complete execution
191
+ """
192
+ self.max_duration_copy: int = reply["max_duration_copy"]
193
+ """integer, U16 Maximum time in M ms for a CDB Copy command to complete execution
194
+ """
195
+
196
+ class CMD0044hSecFeaturesAndCapabilitiesReply(CMDBaseReply):
197
+ """REPLY message of CMD 0044h Security Features and Capabilities
198
+ """
199
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
200
+ super().__init__(reply)
201
+
202
+ # Parse cmd_support_mask as a list of integers
203
+ self.cmd_support = reply["cmd_support_mask"]
204
+
205
+ """
206
+ CMD 0400h-04FFh support.
207
+
208
+ Each integer represents a mask. If an integer is set, the corresponding command is supported
209
+
210
+ * D0: CMD 0400h is supported.
211
+ * ..
212
+ * D255: CMD 04FFh is supported
213
+
214
+ """
215
+
216
+ self.num_certificates: int = reply["num_certificates"]
217
+ """integer, Number of public certificates the host may obtain from the module.
218
+
219
+ The device must contain a single leaf certificate and it may optionally contain one or more intermediate certificates optionally followed by a root certificate. For X.509 certificates, intermediate certificates are not self-signed, and the root cert is self-signed.
220
+
221
+ ``num_certificates <= 4``
222
+
223
+ """
224
+
225
+ self.cert_chain_supported: int = reply["cert_chain_supported"]
226
+ """integer
227
+
228
+ * 0: Certificate chain is not supported. Module contains leaf certificate instance i = 0 only.
229
+ * 1: Module supports certificate chain and host must specify the instance when downloading a certificate.
230
+
231
+ Instance i = 0 is the start of the chain, i.e. the leaf certificate, and any instance i+1 is another certificate used to sign the certificate instance i, where ``i < num_certificates <= 4``
232
+
233
+ """
234
+
235
+ self.certificate_format: int = reply["certificate_format"]
236
+ """integer
237
+
238
+ * 0: Not supported.
239
+ * 1: **Custom**.
240
+ * 2: X509v3 DER encoding.
241
+ * 3-255: Reserved.
242
+
243
+ """
244
+
245
+ self.certificate_length_1: int = reply["certificate_length_1"]
246
+ """integer, Length of leaf certificate i = 0.
247
+ """
248
+ self.certificate_length_2: int = reply["certificate_length_2"]
249
+ """integer, Length of certificate i = 1 or 0 when not supported.
250
+ """
251
+ self.certificate_length_3: int = reply["certificate_length_3"]
252
+ """integer, Length of certificate i = 2 or 0 when not supported.
253
+ """
254
+ self.certificate_length_4: int = reply["certificate_length_4"]
255
+ """integer, Length of certificate i = 3 or 0 when not supported.
256
+ """
257
+ self.digest_length: int = reply["digest_length"]
258
+ """integer, Required message hash digest length (in bytes)
259
+
260
+ * 0: Not supported.
261
+ * 1: 28 bytes (SHA224).
262
+ * 2: 32 bytes (SHA256).
263
+ * 3: 48 bytes (SHA384).
264
+ * 4: 64 bytes (SHA512).
265
+ * 5-255: **Reserved**.
266
+
267
+ """
268
+
269
+ self.signature_time: int = reply["signature_time"]
270
+ """integer, Maximum time (in milliseconds) for signature generation.
271
+ """
272
+
273
+ self.signature_length: int = reply["signature_length"]
274
+ """integer, Length (in bytes) of the encoded/padded (if applicable) digest signature
275
+ """
276
+
277
+ self.signature_format: int = reply["signature_format"]
278
+ """integer
279
+ * 0: Not supported.
280
+ * 1: **Custom, vendor specific encoding**.
281
+ * 2: Raw binary byte stream.
282
+ * 3: DER encoding.
283
+ * 4: ECDSA (R,S) integer pair, integers prefixed with length.
284
+ * 5-255: Reserved.
285
+
286
+ """
287
+
288
+ self.signature_pad_scheme: int = reply["signature_pad_scheme"]
289
+ """integer
290
+
291
+ * 0: None.
292
+ * 1: **Custom**.
293
+ * 2: PKCS#1 v1.5.
294
+ * 3: OAEP.
295
+ * 4: PSS.
296
+ * 5-255: Reserved
297
+
298
+ """
299
+
300
+ class CMD0045hExternallyDefinedFeaturesReply(CMDBaseReply):
301
+ """REPLY message of CMD 0045h Externally Defined Features
302
+ """
303
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
304
+ super().__init__(reply)
305
+
306
+ self.supplement_support: int = reply['supplement_support']
307
+ """Bit 0 = 0/1: CMIS-VCS not supported/supported
308
+ """
309
+
310
+ class CMD0050hGetApplicationAttributesReply(CMDBaseReply):
311
+ """REPLY message of CMD 0050h Get Application Attributes
312
+ """
313
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
314
+ super().__init__(reply)
315
+
316
+ self.application_number: int = reply["application_number"]
317
+ """integer, U16 Application number.
318
+
319
+ * 15-8: reserved (0).
320
+ * 7-4: NADBlockIndex (0-15) or 0.
321
+ * 3-0: AppSelCode (1-15).
322
+
323
+ """
324
+
325
+ self.max_module_power: int = reply["max_module_power"]
326
+ """integer, U16: Worst case module power dissipation when this Application is instantiated homogeneously as often as possible in parallel (when applicable) with worst case configuration options.
327
+
328
+ Unit: 0.25 W.
329
+
330
+ """
331
+
332
+ self.prog_output_power_min: int = reply["prog_output_power_min"]
333
+ """integer, S16: Minimum Programmable Output Power, Unit: 0.01 dBm.
334
+ """
335
+ self.prog_output_power_max: int = reply["prog_output_power_max"]
336
+ """integer, S16: Maximum Programmable Output Power, Unit: 0.01 dBm.
337
+ """
338
+ self.pre_fec_ber_threshold: float = reply["pre_fec_ber_threshold"]
339
+ """float, F16: Pre FEC BER VDM high alarm threshold.
340
+ """
341
+ self.rx_los_optical_power_threshold: int = reply["rx_los_optical_power_threshold"]
342
+ """integer, S16: Optical power threshold for RxLOS alarm. Unit: 0.01dBm.
343
+ """
344
+ self.rx_power_high_alarm_threshold: int = reply["rx_power_high_alarm_threshold"]
345
+ """integer, U16: OpticalPowerRxHighAlarmThreshold. Unit: 0.1uW.
346
+ """
347
+ self.rx_power_low_alarm_threshold: int = reply["rx_power_low_alarm_threshold"]
348
+ """integer, U16: OpticalPowerRxLowAlarmThreshold. Unit: 0.1uW.
349
+ """
350
+ self.rx_power_high_warning_threshold: int = reply["rx_power_high_warning_threshold"]
351
+ """integer, U16: OpticalPowerRxHighWarningThreshold.Unit: 0.1uW.
352
+ """
353
+ self.rx_power_low_warning_threshold: int = reply["rx_power_low_warning_threshold"]
354
+ """integer, U16: OpticalPowerRxLowWarningThreshold. Unit: 0.1uW.
355
+ """
356
+
357
+ class CMD0051hGetInterfaceCodeDescriptionReply(CMDBaseReply):
358
+ """REPLY message of CMD 0051h Get Interface Code Description
359
+ """
360
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
361
+ super().__init__(reply)
362
+
363
+ self.interface_id: int = reply['interface_id']
364
+ """integer, U16: HostInterfaceID or MediaInterfaceID. 15-8: reserved (0). 7-0: InterfaceID
365
+ """
366
+ self.interface_location: int = reply['interface_location']
367
+ """integer, 0: media side. 1: host side.
368
+ """
369
+ self.interfacre_name: str = reply["interfacre_name"]
370
+ """string, 16-byte long ACII string. Name of the interface.
371
+ """
372
+ self.interfacre_description: str = reply["interfacre_description"]
373
+ """string, 48-byte long ACII string. Description of the interface.
374
+ """
375
+ self.interfacre_data_rate: float = reply["interfacre_data_rate"]
376
+ """float, F16: Application Bit Rate in Gb/s
377
+ """
378
+ self.interfacre_lane_count: int = reply["interfacre_lane_count"]
379
+ """integer, U16: Number of parallel lanes.
380
+ """
381
+ self.lane_signaling_rate: float = reply["lane_signaling_rate"]
382
+ """float, F16: Lane Signaling Rate in GBd.
383
+ """
384
+ self.modulation: str = reply["modulation"]
385
+ """string, 16-byte long ACII string. Lane Modulation Format.
386
+ """
387
+ self.bits_per_symbol: int = reply["bits_per_symbol"]
388
+ """ integer, U16: Bits per Symbol.
389
+ """
390
+
391
+ class CMD0100hGetFirmwareInfoReply(CMDBaseReply):
392
+ """REPLY message of CMD 0100h Get Firmware Info
393
+ """
394
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
395
+ super().__init__(reply)
396
+
397
+ self.firmware_status: int = reply["firmware_status"]
398
+ """
399
+ integer, Firmware Status.
400
+
401
+ Bitmask to indicate FW Status.
402
+
403
+ * Image in Bank A:
404
+ * Bit 0: Operational Status
405
+ * Bit 1: Administrative Status
406
+ * Bit 2: Validity Status
407
+ * Bit 3: Reserved
408
+
409
+ * Image in Bank B:
410
+ * Bit 4: Operational Status
411
+ * Bit 5: Administrative Status
412
+ * Bit 6: Validity Status
413
+ * Bit 7: Reserved
414
+
415
+ * Encoding as follows:
416
+ * Operational Status: 1 = running, 0 = not running
417
+ * Administrative Status: 1=committed, 0=uncommitted
418
+ * Validity Status: 1 = invalid, 0 = valid
419
+
420
+ """
421
+ self.image_information: int = reply["image_information"]
422
+ """
423
+ integer, Image Information.
424
+
425
+ * Bit 0: Firmware image A information
426
+ * Bit 1: Firmware image B information
427
+ * Bit 2: Factory or Boot image information
428
+
429
+ """
430
+ self.image_a_major: int = reply["image_a_major"]
431
+ """integer, Image A firmware major revision.
432
+ """
433
+ self.image_a_minor: int = reply["image_a_minor"]
434
+ """integer, Image A firmware minor revision.
435
+ """
436
+ self.image_a_build: int = reply["image_a_build"]
437
+ """integer, Image A firmware build number.
438
+ """
439
+ self.image_a_extra_string: str = reply["image_a_extra_string"]
440
+ """string, Image A additional information (32-byte long ASCII string).
441
+ """
442
+ self.image_b_major: int = reply["image_b_major"]
443
+ """integer, Image B firmware major revision.
444
+ """
445
+ self.image_b_minor: int = reply["image_b_minor"]
446
+ """integer, Image B firmware minor revision.
447
+ """
448
+ self.image_b_build: int = reply["image_b_build"]
449
+ """integer, Image B firmware build number.
450
+ """
451
+ self.image_b_extra_string: str = reply["image_b_extra_string"]
452
+ """string, Image B additional information (32-byte long ASCII string).
453
+ """
454
+ self.factory_boot_major: int = reply["factory_boot_major"]
455
+ """integer, Factory or Boot firmware major revision.
456
+ """
457
+ self.factory_boot_minor: int = reply["factory_boot_minor"]
458
+ """integer, Factory or Boot firmware minor revision.
459
+ """
460
+ self.factory_boot_build: int = reply["factory_boot_build"]
461
+ """integer, Factory or Boot firmware build number.
462
+ """
463
+ self.factory_boot_extra_string: int = reply["factory_boot_extra_string"]
464
+ """string, Factory or Boot additional information (32-byte long ASCII string).
465
+ """
466
+
467
+ class CMD0101hStartFirmwareDownloadReply(CMDBaseReply):
468
+ """REPLY message of CMD 0101h Start Firmware Download
469
+ """
470
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
471
+ super().__init__(reply)
472
+
473
+ class CMD0102hAbortFirmwareDownloadReply(CMDBaseReply):
474
+ """REPLY message of CMD 0102h Abort Firmware Download
475
+ """
476
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
477
+ super().__init__(reply)
478
+
479
+ class CMD0103hWriteFirmwareBlockLPLReply(CMDBaseReply):
480
+ """REPLY message of CMD 0103h Write Firmware Block LPL
481
+ """
482
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
483
+ super().__init__(reply)
484
+
485
+ class CMD0104hWriteFirmwareBlockEPLReply(CMDBaseReply):
486
+ """REPLY message of CMD 0104h Write Firmware Block EPL
487
+ """
488
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
489
+ super().__init__(reply)
490
+
491
+ class CMD0105hReadFirmwareBlockLPLReply(CMDBaseReply):
492
+ """REPLY message of CMD 0105h Read Firmware Block LPL
493
+ """
494
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
495
+ super().__init__(reply)
496
+ self.base_address_block: int = reply["base_address_block"]
497
+ """hex string, Base address of the data block within the firmware image.
498
+ """
499
+ self.image_data = reply["image_data"]
500
+ """hex string, Up to 116 bytes.
501
+ """
502
+
503
+ class CMD0106hReadFirmwareBlockEPLReply(CMDBaseReply):
504
+ """REPLY message of CMD 0106h Read Firmware Block EPL
505
+ """
506
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
507
+ super().__init__(reply)
508
+ self.image_data = reply["image_data"]
509
+ """Up to 2048 Bytes. Actual Length specified in RPLLength
510
+ """
511
+
512
+ class CMD0107hCompleteFirmwareDownloadReply(CMDBaseReply):
513
+ """REPLY message of CMD 0107h Complete Firmware Download
514
+ """
515
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
516
+ super().__init__(reply)
517
+
518
+ class CMD0108hCopyFirmwareImageReply(CMDBaseReply):
519
+ """REPLY message of CMD 0108h Copy Firmware Image
520
+ """
521
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
522
+ super().__init__(reply)
523
+ self.length: int = reply["length"]
524
+ """integer, number of bytes copied.
525
+ """
526
+ self.copy_direction: int = reply['copy_direction']
527
+ """int, copy direction.
528
+
529
+ * ``0xAB``, Copy Image A into Image B
530
+ * ``0xBA``,Copy Image B into Image A
531
+
532
+ """
533
+ self.copy_status: int = reply['copy_status']
534
+ """int, copy status.
535
+
536
+ * ``0x00``, Copy Successful
537
+ * ``0x01``, Copy Failed
538
+
539
+ """
540
+
541
+ class CMD0109hRunFirmwareImageReply(CMDBaseReply):
542
+ """REPLY message of CMD 0109h Run Firmware Image
543
+ """
544
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
545
+ super().__init__(reply)
546
+
547
+ class CMD010AhCommitFirmwareImageReply(CMDBaseReply):
548
+ """REPLY message of CMD 010Ah Commit Firmware Image
549
+ """
550
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
551
+ super().__init__(reply)
552
+
553
+ class CustomCMDReply():
554
+ """Defines the custom reply to receiver for the CDB instance.
555
+ """
556
+ def __init__(self, reply: t.Dict[str, t.Any]) -> None:
557
+ self.cdb_io_status: int = reply["reply_status"]["cdb_io_status"]
558
+ """integer, indicates the CDB IO status.
559
+
560
+ * 0: Idle, transceiver is not processing a CDB command.
561
+ * 1: Finished, transceiver has finished processing a CDB command. It is ready to accept a new CDB command.
562
+ * 2: Timeout, transceiver has timed out while processing a CDB command. It is ready to accept a new CDB command.
563
+ * 3: In progress: transceiver is currently processing a CDB command. It is not ready to accept a new CDB command.
564
+
565
+ """
566
+
567
+ self.cdb_cmd_complete_flag: bool = reply["reply_status"]["cdb_cmd_complete_flag"]
568
+ """Integer, REPLY Status.CdbCmdCompleteFlag.
569
+
570
+ Indicates whether the CDB command is complete.
571
+
572
+ """
573
+
574
+ self.cdb_status: int = reply["reply_status"]["cdb_status"]
575
+ """Integer, REPLY Status.CdbStatus.
576
+
577
+ Provides the status of the most recently triggered CDB command.
578
+
579
+ """
580
+
581
+ self.rpl_length: int = reply["reply_header"]["rpl_length"]
582
+ """integer, REPLY Header.RPLLength.
583
+
584
+ Length of the reply data.
585
+
586
+ """
587
+
588
+ self.rpl_check_code: int = reply["reply_header"]["rpl_check_code"]
589
+ """integer, REPLY Header.RPLChkCode.
590
+
591
+ Check code for the reply data.
592
+
593
+ """
594
+
595
+ self.data = reply["reply_data"]["data"]
596
+ """hex string, REPLY Data.Data
597
+
598
+ The actual data to be sent in the reply.
599
+
600
+ """
@@ -0,0 +1,49 @@
1
+ from __future__ import annotations
2
+ from ._utils import *
3
+ from ._constants import *
4
+
5
+ def get_cdb_coarse_status(cdb_status: int) -> CdbCommandCoarseStatus:
6
+ """Convert CDB status to CDB command coarse status
7
+
8
+ :param cdb_status: CDB status
9
+ :type cdb_status: int
10
+ :raises ValueError: value error if CDB status is invalid
11
+ :return: CDB command coarse status
12
+ :rtype: CdbCommandCoarseStatus
13
+ """
14
+ if cdb_status & 0x80 == 0x80:
15
+ return CdbCommandCoarseStatus.IN_PROGRESS
16
+ elif cdb_status & 0xC0 == 0x40:
17
+ return CdbCommandCoarseStatus.FAILED
18
+ elif cdb_status & 0x01 == 0x01:
19
+ return CdbCommandCoarseStatus.SUCCESS
20
+ elif cdb_status == 0x00:
21
+ return CdbCommandCoarseStatus.NA
22
+ else:
23
+ raise ValueError(f"Invalid CDB status: {cdb_status}")
24
+
25
+
26
+ def check_erased_byte(data_block: str, erased_byte: str) -> bool:
27
+ """Check erased byte against data block
28
+
29
+ :param data_block: data block hex string
30
+ :type data_block: str
31
+ :param erased_byte: erased byte hex string
32
+ :type erased_byte: str
33
+ :return: True if data block matches erased byte pattern, False otherwise
34
+ :rtype: bool
35
+ """
36
+ data_block = data_block.lower().lstrip("0x")
37
+ erased_byte = erased_byte.lower().lstrip("0x")
38
+
39
+ # Edge case: erased byte must be non-zero
40
+ if not erased_byte:
41
+ return False
42
+
43
+ # Length of data block must be a multiple of length of erased byte
44
+ if len(data_block) % len(erased_byte) != 0:
45
+ return False
46
+
47
+ # Repeat erased byte to match length of data block and compare
48
+ multiplier = len(data_block) // len(erased_byte)
49
+ return data_block == erased_byte * multiplier