tdl-xoa-driver 1.0.0__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.
- tdl_xoa_driver-1.0.0.dist-info/LICENSE +202 -0
- tdl_xoa_driver-1.0.0.dist-info/METADATA +177 -0
- tdl_xoa_driver-1.0.0.dist-info/RECORD +325 -0
- tdl_xoa_driver-1.0.0.dist-info/WHEEL +5 -0
- tdl_xoa_driver-1.0.0.dist-info/top_level.txt +1 -0
- xoa_driver/__init__.py +2 -0
- xoa_driver/enums.py +399 -0
- xoa_driver/exceptions.py +77 -0
- xoa_driver/functions/__init__.py +0 -0
- xoa_driver/functions/anlt.py +744 -0
- xoa_driver/functions/anlt_ll_debug.py +429 -0
- xoa_driver/functions/cli.py +581 -0
- xoa_driver/functions/exceptions.py +72 -0
- xoa_driver/functions/headers.py +608 -0
- xoa_driver/functions/mgmt.py +515 -0
- xoa_driver/functions/tools.py +256 -0
- xoa_driver/hlfuncs.py +18 -0
- xoa_driver/internals/__init__.py +0 -0
- xoa_driver/internals/commands/__init__.py +31 -0
- xoa_driver/internals/commands/c_commands.py +2041 -0
- xoa_driver/internals/commands/enums.py +3289 -0
- xoa_driver/internals/commands/m4_commands.py +700 -0
- xoa_driver/internals/commands/m4e_commands.py +107 -0
- xoa_driver/internals/commands/m_commands.py +1875 -0
- xoa_driver/internals/commands/p4_commands.py +2221 -0
- xoa_driver/internals/commands/p4e_commands.py +160 -0
- xoa_driver/internals/commands/p4g_commands.py +7253 -0
- xoa_driver/internals/commands/p_commands.py +6000 -0
- xoa_driver/internals/commands/pc_commands.py +335 -0
- xoa_driver/internals/commands/pd_commands.py +355 -0
- xoa_driver/internals/commands/pe_commands.py +1018 -0
- xoa_driver/internals/commands/pec_commands.py +265 -0
- xoa_driver/internals/commands/ped_commands.py +1034 -0
- xoa_driver/internals/commands/pef_commands.py +2216 -0
- xoa_driver/internals/commands/pf_commands.py +379 -0
- xoa_driver/internals/commands/pl1_commands.py +1588 -0
- xoa_driver/internals/commands/pl_commands.py +178 -0
- xoa_driver/internals/commands/pm_commands.py +256 -0
- xoa_driver/internals/commands/pp_commands.py +2341 -0
- xoa_driver/internals/commands/pr_commands.py +812 -0
- xoa_driver/internals/commands/ps_commands.py +2311 -0
- xoa_driver/internals/commands/pt_commands.py +370 -0
- xoa_driver/internals/commands/px_commands.py +303 -0
- xoa_driver/internals/commands/subtypes.py +86 -0
- xoa_driver/internals/core/__init__.py +0 -0
- xoa_driver/internals/core/builders.py +39 -0
- xoa_driver/internals/core/exceptions.py +69 -0
- xoa_driver/internals/core/funcs.py +81 -0
- xoa_driver/internals/core/funcs.pyi +1072 -0
- xoa_driver/internals/core/interfaces.py +47 -0
- xoa_driver/internals/core/token.py +44 -0
- xoa_driver/internals/core/transporter/__init__.py +0 -0
- xoa_driver/internals/core/transporter/_processor.py +83 -0
- xoa_driver/internals/core/transporter/_publisher.py +101 -0
- xoa_driver/internals/core/transporter/_request_id_counter.py +28 -0
- xoa_driver/internals/core/transporter/_stream.py +99 -0
- xoa_driver/internals/core/transporter/_typings.py +43 -0
- xoa_driver/internals/core/transporter/exceptions.py +44 -0
- xoa_driver/internals/core/transporter/handler.py +127 -0
- xoa_driver/internals/core/transporter/logger/__init__.py +10 -0
- xoa_driver/internals/core/transporter/logger/__logger.py +94 -0
- xoa_driver/internals/core/transporter/logger/__state_off.py +32 -0
- xoa_driver/internals/core/transporter/logger/__state_on_default.py +70 -0
- xoa_driver/internals/core/transporter/logger/__state_on_loguru.py +51 -0
- xoa_driver/internals/core/transporter/logger/__state_on_user.py +48 -0
- xoa_driver/internals/core/transporter/protocol/__init__.py +0 -0
- xoa_driver/internals/core/transporter/protocol/_constants.py +77 -0
- xoa_driver/internals/core/transporter/protocol/_utils.py +59 -0
- xoa_driver/internals/core/transporter/protocol/exceptions.py +271 -0
- xoa_driver/internals/core/transporter/protocol/payload/__init__.py +70 -0
- xoa_driver/internals/core/transporter/protocol/payload/base_struct.py +283 -0
- xoa_driver/internals/core/transporter/protocol/payload/descriptor.py +119 -0
- xoa_driver/internals/core/transporter/protocol/payload/exceptions.py +20 -0
- xoa_driver/internals/core/transporter/protocol/payload/field.py +296 -0
- xoa_driver/internals/core/transporter/protocol/payload/types.py +173 -0
- xoa_driver/internals/core/transporter/protocol/payload/utils.py +53 -0
- xoa_driver/internals/core/transporter/protocol/struct_header.py +123 -0
- xoa_driver/internals/core/transporter/protocol/struct_request.py +65 -0
- xoa_driver/internals/core/transporter/protocol/struct_response.py +89 -0
- xoa_driver/internals/core/transporter/registry.py +43 -0
- xoa_driver/internals/exceptions/__init__.py +9 -0
- xoa_driver/internals/exceptions/modules.py +13 -0
- xoa_driver/internals/exceptions/testers.py +21 -0
- xoa_driver/internals/hli_v1/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/base_index.py +39 -0
- xoa_driver/internals/hli_v1/indices/connection_group/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/connection_group/cg.py +186 -0
- xoa_driver/internals/hli_v1/indices/connection_group/histogram.py +78 -0
- xoa_driver/internals/hli_v1/indices/connection_group/l2.py +94 -0
- xoa_driver/internals/hli_v1/indices/connection_group/l3.py +130 -0
- xoa_driver/internals/hli_v1/indices/connection_group/raw.py +200 -0
- xoa_driver/internals/hli_v1/indices/connection_group/replay.py +109 -0
- xoa_driver/internals/hli_v1/indices/connection_group/tcp.py +314 -0
- xoa_driver/internals/hli_v1/indices/connection_group/tls.py +198 -0
- xoa_driver/internals/hli_v1/indices/connection_group/udp.py +133 -0
- xoa_driver/internals/hli_v1/indices/connection_group/user_state.py +28 -0
- xoa_driver/internals/hli_v1/indices/filter/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/filter/base_filter.py +65 -0
- xoa_driver/internals/hli_v1/indices/filter/genuine_filter.py +20 -0
- xoa_driver/internals/hli_v1/indices/length_term.py +49 -0
- xoa_driver/internals/hli_v1/indices/macsecscs/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/macsecscs/base_macsecsc.py +224 -0
- xoa_driver/internals/hli_v1/indices/macsecscs/genuine_macsecsc.py +72 -0
- xoa_driver/internals/hli_v1/indices/match_term.py +64 -0
- xoa_driver/internals/hli_v1/indices/port_dataset.py +72 -0
- xoa_driver/internals/hli_v1/indices/streams/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/streams/base_stream.py +405 -0
- xoa_driver/internals/hli_v1/indices/streams/genuine_stream.py +64 -0
- xoa_driver/internals/hli_v1/modules/__init__.py +0 -0
- xoa_driver/internals/hli_v1/modules/__interfaces.py +21 -0
- xoa_driver/internals/hli_v1/modules/base_module.py +138 -0
- xoa_driver/internals/hli_v1/modules/module_chimera.py +366 -0
- xoa_driver/internals/hli_v1/modules/module_l23ve.py +73 -0
- xoa_driver/internals/hli_v1/modules/module_l47.py +397 -0
- xoa_driver/internals/hli_v1/modules/module_l47ve.py +9 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/__init__.py +0 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_combi.py +83 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_d.py +75 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_e.py +85 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_f.py +145 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_g.py +84 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_h.py +40 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_i.py +25 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_j.py +25 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_k.py +39 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_l.py +55 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_l1.py +800 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_m.py +25 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_n.py +40 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/module_l23_base.py +383 -0
- xoa_driver/internals/hli_v1/ports/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/base_port.py +125 -0
- xoa_driver/internals/hli_v1/ports/port_l23/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_capture.py +70 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_l23.py +527 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_l23_genuine.py +229 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_reception_statistics.py +231 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_transceiver.py +117 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_transmission_statistics.py +131 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/filter_definition/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/filter_definition/_utils.py +15 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/filter_definition/general.py +396 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/filter_definition/shadow.py +104 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/filter_definition/working.py +36 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/pe_custom_distribution.py +125 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/pe_distribution.py +174 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/port_chimera.py +119 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/port_emulation.py +244 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/reception_statistics.py +24 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/transmission_statistics.py +24 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_combi.py +37 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_d.py +51 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_e.py +107 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_f.py +151 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_g.py +77 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_h.py +67 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_i.py +84 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_j.py +68 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_k.py +73 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_l.py +82 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_l1.py +166 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_m.py +29 -0
- xoa_driver/internals/hli_v1/ports/port_l23/fault_jkl.py +24 -0
- xoa_driver/internals/hli_v1/ports/port_l23/freya_l1.py +722 -0
- xoa_driver/internals/hli_v1/ports/port_l23/pcs_pma_ghijkl.py +369 -0
- xoa_driver/internals/hli_v1/ports/port_l23/pcs_pma_ijkl_chimera.py +60 -0
- xoa_driver/internals/hli_v1/ports/port_l23/pcs_pma_l.py +78 -0
- xoa_driver/internals/hli_v1/ports/port_l23/port_l23ve.py +101 -0
- xoa_driver/internals/hli_v1/ports/port_l47/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/port_l47/counters.py +174 -0
- xoa_driver/internals/hli_v1/ports/port_l47/main.py +228 -0
- xoa_driver/internals/hli_v1/ports/port_l47/packet_engine.py +31 -0
- xoa_driver/internals/hli_v1/revisions.py +11 -0
- xoa_driver/internals/hli_v1/testers/__init__.py +0 -0
- xoa_driver/internals/hli_v1/testers/_base_tester.py +259 -0
- xoa_driver/internals/hli_v1/testers/genuine/__init__.py +0 -0
- xoa_driver/internals/hli_v1/testers/genuine/l_23/__init__.py +0 -0
- xoa_driver/internals/hli_v1/testers/genuine/l_23/health.py +16 -0
- xoa_driver/internals/hli_v1/testers/genuine/l_23/rest_api.py +38 -0
- xoa_driver/internals/hli_v1/testers/genuine/l_23/time_keeper.py +57 -0
- xoa_driver/internals/hli_v1/testers/genuine/l_23/upload_file.py +29 -0
- xoa_driver/internals/hli_v1/testers/genuine/management_interface.py +42 -0
- xoa_driver/internals/hli_v1/testers/l23_tester.py +196 -0
- xoa_driver/internals/hli_v1/testers/l23ve_tester.py +114 -0
- xoa_driver/internals/hli_v1/testers/l47_tester.py +106 -0
- xoa_driver/internals/hli_v1/testers/l47ve_tester.py +54 -0
- xoa_driver/internals/hli_v2/__init__.py +0 -0
- xoa_driver/internals/hli_v2/indices/__init__.py +0 -0
- xoa_driver/internals/hli_v2/indices/base_index.py +39 -0
- xoa_driver/internals/hli_v2/indices/connection_group/__init__.py +0 -0
- xoa_driver/internals/hli_v2/indices/connection_group/cg.py +115 -0
- xoa_driver/internals/hli_v2/indices/connection_group/histogram.py +59 -0
- xoa_driver/internals/hli_v2/indices/connection_group/l2.py +71 -0
- xoa_driver/internals/hli_v2/indices/connection_group/l3.py +96 -0
- xoa_driver/internals/hli_v2/indices/connection_group/raw.py +148 -0
- xoa_driver/internals/hli_v2/indices/connection_group/replay.py +89 -0
- xoa_driver/internals/hli_v2/indices/connection_group/tcp.py +261 -0
- xoa_driver/internals/hli_v2/indices/connection_group/tls.py +166 -0
- xoa_driver/internals/hli_v2/indices/connection_group/udp.py +112 -0
- xoa_driver/internals/hli_v2/indices/connection_group/user_state.py +25 -0
- xoa_driver/internals/hli_v2/indices/filter/__init__.py +0 -0
- xoa_driver/internals/hli_v2/indices/filter/base_filter.py +50 -0
- xoa_driver/internals/hli_v2/indices/filter/genuine_filter.py +17 -0
- xoa_driver/internals/hli_v2/indices/length_term.py +44 -0
- xoa_driver/internals/hli_v2/indices/match_term.py +49 -0
- xoa_driver/internals/hli_v2/indices/port_dataset.py +53 -0
- xoa_driver/internals/hli_v2/indices/streams/__init__.py +0 -0
- xoa_driver/internals/hli_v2/indices/streams/base_stream.py +234 -0
- xoa_driver/internals/hli_v2/indices/streams/genuine_stream.py +32 -0
- xoa_driver/internals/hli_v2/modules/__init__.py +0 -0
- xoa_driver/internals/hli_v2/modules/__interfaces.py +21 -0
- xoa_driver/internals/hli_v2/modules/base_module.py +125 -0
- xoa_driver/internals/hli_v2/modules/module_chimera.py +358 -0
- xoa_driver/internals/hli_v2/modules/module_l23ve.py +58 -0
- xoa_driver/internals/hli_v2/modules/module_l47.py +230 -0
- xoa_driver/internals/hli_v2/modules/module_l47ve.py +8 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/__init__.py +0 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_combi.py +73 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_d.py +75 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_e.py +85 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_f.py +144 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_g.py +84 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_h.py +40 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_i.py +25 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_j.py +25 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_k.py +39 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_l.py +55 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_l1.py +797 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_m.py +25 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_n.py +40 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/module_l23_base.py +339 -0
- xoa_driver/internals/hli_v2/ports/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/base_port.py +105 -0
- xoa_driver/internals/hli_v2/ports/port_l23/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_capture.py +64 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_l23.py +441 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_l23_genuine.py +172 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_reception_statistics.py +156 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_transceiver.py +117 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_transmission_statistics.py +59 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/filter_definition/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/filter_definition/_utils.py +15 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/filter_definition/general.py +340 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/filter_definition/shadow.py +99 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/filter_definition/working.py +36 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/pe_custom_distribution.py +116 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/pe_distribution.py +102 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/port_chimera.py +113 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/port_emulation.py +420 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/reception_statistics.py +22 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/transmission_statistics.py +22 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_combi.py +36 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_d.py +49 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_e.py +96 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_f.py +144 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_g.py +77 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_h.py +60 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_i.py +66 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_j.py +53 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_k.py +58 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_l.py +67 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_l1.py +149 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_m.py +28 -0
- xoa_driver/internals/hli_v2/ports/port_l23/fault_jkl.py +22 -0
- xoa_driver/internals/hli_v2/ports/port_l23/pcs_pma_ghijkl.py +342 -0
- xoa_driver/internals/hli_v2/ports/port_l23/pcs_pma_ijkl_chimera.py +50 -0
- xoa_driver/internals/hli_v2/ports/port_l23/pcs_pma_l.py +65 -0
- xoa_driver/internals/hli_v2/ports/port_l23/port_l23ve.py +81 -0
- xoa_driver/internals/hli_v2/ports/port_l47/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/port_l47/counters.py +146 -0
- xoa_driver/internals/hli_v2/ports/port_l47/main.py +137 -0
- xoa_driver/internals/hli_v2/ports/port_l47/packet_engine.py +20 -0
- xoa_driver/internals/hli_v2/revisions.py +11 -0
- xoa_driver/internals/hli_v2/testers/__init__.py +0 -0
- xoa_driver/internals/hli_v2/testers/_base_tester.py +207 -0
- xoa_driver/internals/hli_v2/testers/genuine/__init__.py +0 -0
- xoa_driver/internals/hli_v2/testers/genuine/l_23/__init__.py +0 -0
- xoa_driver/internals/hli_v2/testers/genuine/l_23/health.py +16 -0
- xoa_driver/internals/hli_v2/testers/genuine/l_23/rest_api.py +34 -0
- xoa_driver/internals/hli_v2/testers/genuine/l_23/time_keeper.py +50 -0
- xoa_driver/internals/hli_v2/testers/genuine/l_23/upload_file.py +26 -0
- xoa_driver/internals/hli_v2/testers/genuine/management_interface.py +38 -0
- xoa_driver/internals/hli_v2/testers/l23_tester.py +159 -0
- xoa_driver/internals/hli_v2/testers/l23ve_tester.py +98 -0
- xoa_driver/internals/hli_v2/testers/l47_tester.py +95 -0
- xoa_driver/internals/hli_v2/testers/l47ve_tester.py +50 -0
- xoa_driver/internals/state_storage/__init__.py +0 -0
- xoa_driver/internals/state_storage/_speed_detector.py +121 -0
- xoa_driver/internals/state_storage/modules_state.py +128 -0
- xoa_driver/internals/state_storage/ports_state.py +154 -0
- xoa_driver/internals/state_storage/testers_state.py +104 -0
- xoa_driver/internals/utils/__init__.py +0 -0
- xoa_driver/internals/utils/attributes.py +33 -0
- xoa_driver/internals/utils/cap_id.py +63 -0
- xoa_driver/internals/utils/con_traffic_light.py +88 -0
- xoa_driver/internals/utils/indices/__init__.py +0 -0
- xoa_driver/internals/utils/indices/_interfaces.py +26 -0
- xoa_driver/internals/utils/indices/header_modifier_manager.py +56 -0
- xoa_driver/internals/utils/indices/index_manager.py +95 -0
- xoa_driver/internals/utils/indices/observer.py +17 -0
- xoa_driver/internals/utils/kind.py +19 -0
- xoa_driver/internals/utils/managers/__init__.py +0 -0
- xoa_driver/internals/utils/managers/abc.py +44 -0
- xoa_driver/internals/utils/managers/exceptions.py +22 -0
- xoa_driver/internals/utils/managers/modules_manager.py +118 -0
- xoa_driver/internals/utils/managers/ports_manager.py +116 -0
- xoa_driver/internals/utils/rev_tool.py +21 -0
- xoa_driver/internals/utils/session.py +117 -0
- xoa_driver/internals/warn.py +32 -0
- xoa_driver/lli.py +15 -0
- xoa_driver/misc.py +57 -0
- xoa_driver/modules.py +448 -0
- xoa_driver/ports.py +332 -0
- xoa_driver/testers.py +37 -0
- xoa_driver/utils.py +12 -0
- xoa_driver/v2/__init__.py +11 -0
- xoa_driver/v2/misc.py +77 -0
- xoa_driver/v2/modules.py +308 -0
- xoa_driver/v2/ports.py +232 -0
- xoa_driver/v2/testers.py +24 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Type
|
|
3
|
+
from ._constants import CommandStatus
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class XmpStatusException(Exception):
|
|
7
|
+
__slots__ = ("err_code", "msg", "cmd",)
|
|
8
|
+
|
|
9
|
+
err_code: CommandStatus | None
|
|
10
|
+
msg: str
|
|
11
|
+
cmd: str
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class XmpNoConnectionError(XmpStatusException):
|
|
15
|
+
"""Chassis has no available connection slots (NOCONNECTIONS)"""
|
|
16
|
+
def __init__(self, cmd) -> None:
|
|
17
|
+
self.err_code = CommandStatus.NOCONNECTIONS
|
|
18
|
+
self.msg = f"Chassis has no available connection slots ({self.err_code.name})"
|
|
19
|
+
self.cmd = cmd
|
|
20
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class XmpNoLoggedOnError(XmpStatusException):
|
|
24
|
+
"""No command can be submitted before logon (NOTLOGGEDON)"""
|
|
25
|
+
def __init__(self, cmd) -> None:
|
|
26
|
+
self.err_code = CommandStatus.NOTLOGGEDON
|
|
27
|
+
self.msg = f"No command can be submitted before logon ({self.err_code.name})"
|
|
28
|
+
self.cmd = cmd
|
|
29
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class XmpNotReservedError(XmpStatusException):
|
|
33
|
+
"""Command cannot be set because resource not reserved (NOTRESERVED)"""
|
|
34
|
+
def __init__(self, cmd) -> None:
|
|
35
|
+
self.err_code = CommandStatus.NOTRESERVED
|
|
36
|
+
self.msg = f"Command cannot be set because resource not reserved ({self.err_code.name})"
|
|
37
|
+
self.cmd = cmd
|
|
38
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class XmpNotWritableError(XmpStatusException):
|
|
42
|
+
"""Command cannot be set because it is not in a writable state (NOTWRITABLE)"""
|
|
43
|
+
def __init__(self, cmd) -> None:
|
|
44
|
+
self.err_code = CommandStatus.NOTWRITABLE
|
|
45
|
+
self.msg = f"Command cannot be set because it is not in a writable state ({self.err_code.name})"
|
|
46
|
+
self.cmd = cmd
|
|
47
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class XmpNotReadableError(XmpStatusException):
|
|
51
|
+
"""Command is write-only (NOTREADABLE)"""
|
|
52
|
+
def __init__(self, cmd) -> None:
|
|
53
|
+
self.err_code = CommandStatus.NOTREADABLE
|
|
54
|
+
self.msg = f"Command is write-only ({self.err_code.name})"
|
|
55
|
+
self.cmd = cmd
|
|
56
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class XmpNotValidError(XmpStatusException):
|
|
60
|
+
"""Operation not valid in current state (NOTVALID)"""
|
|
61
|
+
def __init__(self, cmd) -> None:
|
|
62
|
+
self.err_code = CommandStatus.NOTVALID
|
|
63
|
+
self.msg = f"Operation not valid in current state ({self.err_code.name})"
|
|
64
|
+
self.cmd = cmd
|
|
65
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class XmpBadHeaderError(XmpStatusException):
|
|
69
|
+
"""Invalid magic word (BADHEADER)"""
|
|
70
|
+
def __init__(self, cmd) -> None:
|
|
71
|
+
self.err_code = CommandStatus.BADHEADER
|
|
72
|
+
self.msg = f"Invalid magic word ({self.err_code.name})"
|
|
73
|
+
self.cmd = cmd
|
|
74
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class XmpBadCommandError(XmpStatusException):
|
|
78
|
+
"""Invalid command (BADCOMMAND)"""
|
|
79
|
+
def __init__(self, cmd) -> None:
|
|
80
|
+
self.err_code = CommandStatus.BADCOMMAND
|
|
81
|
+
self.msg = f"Invalid command ({self.err_code.name})"
|
|
82
|
+
self.cmd = cmd
|
|
83
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class XmpBadParameterError(XmpStatusException):
|
|
87
|
+
"""Invalid command code (BADPARAMETER)"""
|
|
88
|
+
def __init__(self, cmd) -> None:
|
|
89
|
+
self.err_code = CommandStatus.BADPARAMETER
|
|
90
|
+
self.msg = f"Invalid command code ({self.err_code.name})"
|
|
91
|
+
self.cmd = cmd
|
|
92
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class XmpBadModuleError(XmpStatusException):
|
|
96
|
+
"""Bad module index (BADMODULE)"""
|
|
97
|
+
def __init__(self, cmd) -> None:
|
|
98
|
+
self.err_code = CommandStatus.BADMODULE
|
|
99
|
+
self.msg = f"Bad module index ({self.err_code.name})"
|
|
100
|
+
self.cmd = cmd
|
|
101
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class XmpBadPortError(XmpStatusException):
|
|
105
|
+
"""Bad port index (BADPORT)"""
|
|
106
|
+
def __init__(self, cmd) -> None:
|
|
107
|
+
self.err_code = CommandStatus.BADPORT
|
|
108
|
+
self.msg = f"Bad port index ({self.err_code.name})"
|
|
109
|
+
self.cmd = cmd
|
|
110
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class XmpBadIndexError(XmpStatusException):
|
|
114
|
+
"""Bad index (BADINDEX)"""
|
|
115
|
+
def __init__(self, cmd) -> None:
|
|
116
|
+
self.err_code = CommandStatus.BADINDEX
|
|
117
|
+
self.msg = f"Bad index ({self.err_code.name})"
|
|
118
|
+
self.cmd = cmd
|
|
119
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class XmpBadSizeError(XmpStatusException):
|
|
123
|
+
"""Invalid data size (BADSIZE)"""
|
|
124
|
+
def __init__(self, cmd) -> None:
|
|
125
|
+
self.err_code = CommandStatus.BADSIZE
|
|
126
|
+
self.msg = f"Invalid data size ({self.err_code.name})"
|
|
127
|
+
self.cmd = cmd
|
|
128
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class XmpBadValueError(XmpStatusException):
|
|
132
|
+
"""Invalid data value (BADVALUE)"""
|
|
133
|
+
def __init__(self, cmd) -> None:
|
|
134
|
+
self.err_code = CommandStatus.BADVALUE
|
|
135
|
+
self.msg = f"Invalid data value ({self.err_code.name})"
|
|
136
|
+
self.cmd = cmd
|
|
137
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class XmpFailedError(XmpStatusException):
|
|
141
|
+
"""Failed to perform operation (FAILED)"""
|
|
142
|
+
def __init__(self, cmd) -> None:
|
|
143
|
+
self.err_code = CommandStatus.FAILED
|
|
144
|
+
self.msg = f"Failed to perform operation ({self.err_code.name})"
|
|
145
|
+
self.cmd = cmd
|
|
146
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class XmpMemoryFailureError(XmpStatusException):
|
|
150
|
+
"""Failed to allocate memory (MEMORYFAILURE)"""
|
|
151
|
+
def __init__(self, cmd) -> None:
|
|
152
|
+
self.err_code = CommandStatus.MEMORYFAILURE
|
|
153
|
+
self.msg = f"Failed to allocate memory ({self.err_code.name})"
|
|
154
|
+
self.cmd = cmd
|
|
155
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class XmpNoPeLicenseError(XmpStatusException):
|
|
159
|
+
"""o free PE license (NOLICPE)"""
|
|
160
|
+
def __init__(self, cmd) -> None:
|
|
161
|
+
self.err_code = CommandStatus.NOLICPE
|
|
162
|
+
self.msg = f"No free PE license ({self.err_code.name})"
|
|
163
|
+
self.cmd = cmd
|
|
164
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class XmpNoFreePortLicenseError(XmpStatusException):
|
|
168
|
+
"""No free Port license (NOLICPORT)"""
|
|
169
|
+
def __init__(self, cmd) -> None:
|
|
170
|
+
self.err_code = CommandStatus.NOLICPORT
|
|
171
|
+
self.msg = f"No free Port license ({self.err_code.name})"
|
|
172
|
+
self.cmd = cmd
|
|
173
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class XmpNotSupportedError(XmpStatusException):
|
|
177
|
+
"""Command not supported (NOTSUPPORTED)"""
|
|
178
|
+
def __init__(self, cmd) -> None:
|
|
179
|
+
self.err_code = CommandStatus.NOTSUPPORTED
|
|
180
|
+
self.msg = f"Command not supported ({self.err_code.name})"
|
|
181
|
+
self.cmd = cmd
|
|
182
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class XmpPendingError(XmpStatusException):
|
|
186
|
+
"""Status return will wait until command has been execute (PENDING)"""
|
|
187
|
+
def __init__(self, cmd) -> None:
|
|
188
|
+
self.err_code = CommandStatus.PENDING
|
|
189
|
+
self.msg = f"Pending status reply until command has been executed ({self.err_code.name})"
|
|
190
|
+
self.cmd = cmd
|
|
191
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class XmpModuleOperationNotSupportedByChassisError(XmpStatusException):
|
|
195
|
+
"""Module not supported by chassis (MODULE_OPERATION_NOT_SUPPORTED_BY_CHASSIS)"""
|
|
196
|
+
def __init__(self, cmd) -> None:
|
|
197
|
+
self.err_code = CommandStatus.MODULE_OPERATION_NOT_SUPPORTED_BY_CHASSIS
|
|
198
|
+
self.msg = f"Module not supported by chassis ({self.err_code.name})"
|
|
199
|
+
self.cmd = cmd
|
|
200
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class XmpXlsFailedError(XmpStatusException):
|
|
204
|
+
"""Could not establish connection to Xena License Server (XLSFAILED)"""
|
|
205
|
+
def __init__(self, cmd) -> None:
|
|
206
|
+
self.err_code = CommandStatus.XLSFAILED
|
|
207
|
+
self.msg = f"Could not establish connection to Xena License Server ({self.err_code.name})"
|
|
208
|
+
self.cmd = cmd
|
|
209
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
class XmpXlsDeniedError(XmpStatusException):
|
|
213
|
+
"""Request for resource rejected by Xena License Server (XLSDENIED)"""
|
|
214
|
+
def __init__(self, cmd) -> None:
|
|
215
|
+
self.err_code = CommandStatus.XLSDENIED
|
|
216
|
+
self.msg = f"Request for resource rejected by Xena License Server ({self.err_code.name})"
|
|
217
|
+
self.cmd = cmd
|
|
218
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class XmpXlsInvalidError(XmpStatusException):
|
|
222
|
+
"""Trying to run Valkyrie VE with VulcanVE-300 resource (XLSINVALID)"""
|
|
223
|
+
def __init__(self, cmd) -> None:
|
|
224
|
+
self.err_code = CommandStatus.XLSINVALID
|
|
225
|
+
self.msg = f"Trying to run Valkyrie VE with VulcanVE-300 resource ({self.err_code.name})"
|
|
226
|
+
self.cmd = cmd
|
|
227
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class XmpUnknownError(XmpStatusException):
|
|
231
|
+
"""Unknown XOA status (None)"""
|
|
232
|
+
def __init__(self, cmd) -> None:
|
|
233
|
+
self.err_code = None
|
|
234
|
+
self.msg = f"Unknown XOA status (None)"
|
|
235
|
+
self.cmd = cmd
|
|
236
|
+
super().__init__(f"{self.cmd}: {self.msg}")
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
__EXCEPTIONS_MAP = {
|
|
240
|
+
CommandStatus.NOCONNECTIONS: XmpNoConnectionError,
|
|
241
|
+
CommandStatus.NOTLOGGEDON: XmpNoLoggedOnError,
|
|
242
|
+
CommandStatus.NOTRESERVED: XmpNotReservedError,
|
|
243
|
+
CommandStatus.NOTWRITABLE: XmpNotWritableError,
|
|
244
|
+
CommandStatus.NOTREADABLE: XmpNotReadableError,
|
|
245
|
+
CommandStatus.NOTVALID: XmpNotValidError,
|
|
246
|
+
CommandStatus.BADHEADER: XmpBadHeaderError,
|
|
247
|
+
CommandStatus.BADCOMMAND: XmpBadCommandError,
|
|
248
|
+
CommandStatus.BADPARAMETER: XmpBadParameterError,
|
|
249
|
+
CommandStatus.BADMODULE: XmpBadModuleError,
|
|
250
|
+
CommandStatus.BADPORT: XmpBadPortError,
|
|
251
|
+
CommandStatus.BADINDEX: XmpBadIndexError,
|
|
252
|
+
CommandStatus.BADSIZE: XmpBadSizeError,
|
|
253
|
+
CommandStatus.BADVALUE: XmpBadValueError,
|
|
254
|
+
CommandStatus.FAILED: XmpFailedError,
|
|
255
|
+
CommandStatus.MEMORYFAILURE: XmpMemoryFailureError,
|
|
256
|
+
CommandStatus.NOLICPE: XmpNoPeLicenseError,
|
|
257
|
+
CommandStatus.NOLICPORT: XmpNoFreePortLicenseError,
|
|
258
|
+
CommandStatus.NOTSUPPORTED: XmpNotSupportedError,
|
|
259
|
+
CommandStatus.PENDING: XmpPendingError,
|
|
260
|
+
CommandStatus.MODULE_OPERATION_NOT_SUPPORTED_BY_CHASSIS: XmpModuleOperationNotSupportedByChassisError,
|
|
261
|
+
CommandStatus.XLSFAILED: XmpXlsFailedError,
|
|
262
|
+
CommandStatus.XLSDENIED: XmpXlsDeniedError,
|
|
263
|
+
CommandStatus.XLSINVALID: XmpXlsInvalidError
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def get_status_error(cmd_status: CommandStatus | None) -> Type[XmpStatusException]:
|
|
268
|
+
global __EXCEPTIONS_MAP
|
|
269
|
+
if cmd_status is None:
|
|
270
|
+
return XmpUnknownError
|
|
271
|
+
return __EXCEPTIONS_MAP.get(cmd_status, XmpUnknownError)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from .field import field
|
|
2
|
+
from .base_struct import (
|
|
3
|
+
RequestBodyStruct,
|
|
4
|
+
ResponseBodyStruct,
|
|
5
|
+
)
|
|
6
|
+
from .types import (
|
|
7
|
+
XmpByte,
|
|
8
|
+
XmpHex,
|
|
9
|
+
XmpInt,
|
|
10
|
+
XmpIPv4Address,
|
|
11
|
+
XmpIPv6Address,
|
|
12
|
+
XmpLong,
|
|
13
|
+
XmpMacAddress,
|
|
14
|
+
XmpSequence,
|
|
15
|
+
XmpShort,
|
|
16
|
+
XmpStr,
|
|
17
|
+
Hex
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
__all__ = (
|
|
21
|
+
"field",
|
|
22
|
+
"RequestBodyStruct",
|
|
23
|
+
"ResponseBodyStruct",
|
|
24
|
+
"XmpByte",
|
|
25
|
+
"XmpHex",
|
|
26
|
+
"XmpInt",
|
|
27
|
+
"XmpIPv4Address",
|
|
28
|
+
"XmpIPv6Address",
|
|
29
|
+
"XmpLong",
|
|
30
|
+
"XmpMacAddress",
|
|
31
|
+
"XmpSequence",
|
|
32
|
+
"XmpShort",
|
|
33
|
+
"XmpStr",
|
|
34
|
+
"Hex",
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
"""
|
|
39
|
+
Commands with non fixed size attributes will work slower
|
|
40
|
+
|
|
41
|
+
!!!NOT PERMITED STRUCTURES!!!
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# 2 strings with undefined size in one packet, seporated or not with other attributes
|
|
45
|
+
|
|
46
|
+
class BadClass1:
|
|
47
|
+
attr1: str = field(XmpStr())
|
|
48
|
+
attr2: str = field(XmpStr())
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# Strings and arrays with undefined size
|
|
52
|
+
|
|
53
|
+
class BadClass2:
|
|
54
|
+
attr1: str = field(XmpStr())
|
|
55
|
+
attr2: list[int] = field(XmpSequence(XmpInt()))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# List of strings
|
|
59
|
+
|
|
60
|
+
class BadClass3:
|
|
61
|
+
attr1: list[str] = field(XmpSequence(XmpStr()))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# Multiple lists of unfixed sizes
|
|
65
|
+
|
|
66
|
+
class BadClass3:
|
|
67
|
+
attr1: list[int] = field(XmpSequence(XmpInt()))
|
|
68
|
+
attr2: list[int] = field(XmpSequence(XmpInt()))
|
|
69
|
+
|
|
70
|
+
"""
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from functools import (
|
|
3
|
+
cached_property,
|
|
4
|
+
partial,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
from io import BytesIO
|
|
8
|
+
from typing import (
|
|
9
|
+
Any,
|
|
10
|
+
ClassVar,
|
|
11
|
+
Generator,
|
|
12
|
+
Iterator,
|
|
13
|
+
NamedTuple,
|
|
14
|
+
Type,
|
|
15
|
+
cast,
|
|
16
|
+
)
|
|
17
|
+
from typing_extensions import (
|
|
18
|
+
Self,
|
|
19
|
+
dataclass_transform,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
from . import utils
|
|
23
|
+
from .field import (
|
|
24
|
+
FieldSpecs,
|
|
25
|
+
field,
|
|
26
|
+
)
|
|
27
|
+
from .descriptor import (
|
|
28
|
+
ResponseFieldDescr,
|
|
29
|
+
RequestFieldDescr
|
|
30
|
+
)
|
|
31
|
+
from .exceptions import (
|
|
32
|
+
FieldDeclarationError,
|
|
33
|
+
FirmwareVersionError,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
RESPONSE_CLS_NAME = "ResponseBodyStruct"
|
|
38
|
+
SKIP_CLASSES = (
|
|
39
|
+
"RequestBodyStruct",
|
|
40
|
+
RESPONSE_CLS_NAME,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class CellInfo(NamedTuple):
|
|
45
|
+
fmt: str
|
|
46
|
+
offset: int
|
|
47
|
+
bsize: int | None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class Cell:
|
|
51
|
+
__slots__ = (
|
|
52
|
+
"name",
|
|
53
|
+
"spec",
|
|
54
|
+
"_prev",
|
|
55
|
+
"_next"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
def __init__(self, name: str, spec: FieldSpecs) -> None:
|
|
59
|
+
self.name = name
|
|
60
|
+
self.spec = spec
|
|
61
|
+
|
|
62
|
+
self._prev: Cell | None = None
|
|
63
|
+
self._next: Cell | None = None
|
|
64
|
+
|
|
65
|
+
def info(self, buff: memoryview | None = None, offset: int = 0) -> CellInfo:
|
|
66
|
+
bsize = self.spec.calc_bsize(buff, offset)
|
|
67
|
+
fmt = self.spec.format(bsize)
|
|
68
|
+
return CellInfo(fmt, offset, bsize)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def is_dynamic(self) -> bool:
|
|
72
|
+
return self.spec.is_dynamic
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class Order:
|
|
76
|
+
__slots__ = (
|
|
77
|
+
"__start",
|
|
78
|
+
"__head",
|
|
79
|
+
"__head_idx",
|
|
80
|
+
"__stencil",
|
|
81
|
+
"__dict__",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def __init__(self) -> None:
|
|
85
|
+
self.__start: Cell | None = None
|
|
86
|
+
self.__head: Cell | None = None
|
|
87
|
+
self.__head_idx: int = -1
|
|
88
|
+
self.__stencil: tuple[tuple[str, int], ...] = ()
|
|
89
|
+
|
|
90
|
+
def __iter__(self):
|
|
91
|
+
temp = self.__start
|
|
92
|
+
while temp is not None:
|
|
93
|
+
yield temp
|
|
94
|
+
temp = temp._next
|
|
95
|
+
|
|
96
|
+
def __reversed__(self):
|
|
97
|
+
temp = self.__head
|
|
98
|
+
while temp is not None:
|
|
99
|
+
yield temp
|
|
100
|
+
temp = temp._prev
|
|
101
|
+
|
|
102
|
+
@cached_property
|
|
103
|
+
def is_dynamic(self) -> bool:
|
|
104
|
+
"""Computed only once, Determinate if structure is contain types with dynamic lenght or not"""
|
|
105
|
+
return any(c.is_dynamic for c in self)
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def field_names(self) -> Iterator[str]:
|
|
109
|
+
"""Get iterator of ordered fields names"""
|
|
110
|
+
return iter(itm.name for itm in self)
|
|
111
|
+
|
|
112
|
+
def append(self, name: str, data: FieldSpecs) -> int:
|
|
113
|
+
"""Append field structure"""
|
|
114
|
+
self.__head_idx += 1
|
|
115
|
+
c = Cell(name, data)
|
|
116
|
+
if not self.__start:
|
|
117
|
+
self.__start = c
|
|
118
|
+
if self.__head:
|
|
119
|
+
self.__head._next = c
|
|
120
|
+
c._prev = self.__head
|
|
121
|
+
self.__head = c
|
|
122
|
+
return self.__head_idx
|
|
123
|
+
|
|
124
|
+
def bake(self) -> None:
|
|
125
|
+
"""Bake tuple of the offsets for static length structures, at the defenition time."""
|
|
126
|
+
if self.is_dynamic:
|
|
127
|
+
return None
|
|
128
|
+
self.__stencil = tuple(self.__construct_stencil(None))
|
|
129
|
+
|
|
130
|
+
def get_stencil(self, buffer: memoryview) -> tuple[tuple[str, int], ...]:
|
|
131
|
+
"""Get offsets for the instance. If struct is static get baked offsets, otherwise compute them for the individual instance"""
|
|
132
|
+
if self.is_dynamic:
|
|
133
|
+
return tuple(self.__construct_stencil(buffer))
|
|
134
|
+
return self.__stencil
|
|
135
|
+
|
|
136
|
+
def __construct_stencil(self, buffer: memoryview | None) -> Generator[tuple[str, int], None, None]:
|
|
137
|
+
"""An private method for construct stencils items."""
|
|
138
|
+
current_node = self.__start
|
|
139
|
+
cumulative_sum = 0
|
|
140
|
+
|
|
141
|
+
while current_node is not None:
|
|
142
|
+
info_tuple = current_node.info(buffer, cumulative_sum)
|
|
143
|
+
yield (info_tuple.fmt, cumulative_sum)
|
|
144
|
+
cumulative_sum += info_tuple.bsize or 0
|
|
145
|
+
current_node = current_node._next
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class OrderedMeta(type):
|
|
149
|
+
def __new__(cls: Type[Self], clsname: str, bases: tuple[Type], clsdict: dict[str, Any]) -> Self:
|
|
150
|
+
if clsname not in SKIP_CLASSES:
|
|
151
|
+
is_response = any(iter(cls_.__name__ == RESPONSE_CLS_NAME for cls_ in bases))
|
|
152
|
+
annotations = utils.resolve_annotations(
|
|
153
|
+
clsdict.get('__annotations__', {}),
|
|
154
|
+
clsdict.get('__module__', None)
|
|
155
|
+
)
|
|
156
|
+
clsdict = cls._prepare_order(
|
|
157
|
+
annotations=annotations,
|
|
158
|
+
clsdict=clsdict,
|
|
159
|
+
is_response=is_response
|
|
160
|
+
)
|
|
161
|
+
return super().__new__(cls, clsname, bases, clsdict)
|
|
162
|
+
|
|
163
|
+
@classmethod
|
|
164
|
+
def __prepare__(cls, clsname: str, bases: tuple) -> dict[str, Any]:
|
|
165
|
+
return dict()
|
|
166
|
+
|
|
167
|
+
@staticmethod
|
|
168
|
+
def _prepare_order(annotations: dict[str, Any], clsdict: dict[str, Any], is_response: bool) -> dict[str, Any]:
|
|
169
|
+
clsdict["_order"] = order = Order()
|
|
170
|
+
for field_name, client_type in annotations.items():
|
|
171
|
+
field_specs = clsdict.get(field_name, None)
|
|
172
|
+
if not isinstance(field_specs, FieldSpecs):
|
|
173
|
+
raise FieldDeclarationError(field_name)
|
|
174
|
+
position_idx = order.append(field_name, field_specs)
|
|
175
|
+
descriptor = ResponseFieldDescr if is_response else RequestFieldDescr
|
|
176
|
+
clsdict[field_name] = descriptor(
|
|
177
|
+
idx=position_idx,
|
|
178
|
+
specs=field_specs,
|
|
179
|
+
user_type=client_type,
|
|
180
|
+
)
|
|
181
|
+
order.bake()
|
|
182
|
+
return clsdict
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@dataclass_transform(kw_only_default=True, field_descriptors=(field, FieldSpecs,)) # type: ignore[Pylance, false positive]
|
|
186
|
+
class RequestBodyStruct(metaclass=OrderedMeta):
|
|
187
|
+
"""Request Body class"""
|
|
188
|
+
|
|
189
|
+
__slots__ = ("_buffer", "_order", "__stored", "__nbytes")
|
|
190
|
+
|
|
191
|
+
def __init__(self, **kwargs) -> None:
|
|
192
|
+
self._buffer = BytesIO()
|
|
193
|
+
for name in cast(Order, self._order).field_names:
|
|
194
|
+
if name not in kwargs:
|
|
195
|
+
raise AttributeError(f"[{name}] is required!")
|
|
196
|
+
setattr(self, name, kwargs[name])
|
|
197
|
+
self.__stored = kwargs
|
|
198
|
+
self.__nbytes = self._buffer.getbuffer().nbytes
|
|
199
|
+
padding = bytes(4 - (self.__nbytes % 4) if self.__nbytes % 4 else 0)
|
|
200
|
+
self._buffer.write(padding)
|
|
201
|
+
|
|
202
|
+
def __repr__(self) -> str:
|
|
203
|
+
cls_name = f"{self.__class__.__qualname__}"
|
|
204
|
+
vals = ", ".join(
|
|
205
|
+
f"{n}={v!r}" for n, v in self.__stored.items()
|
|
206
|
+
)
|
|
207
|
+
return f"{cls_name}({vals})"
|
|
208
|
+
|
|
209
|
+
def nbytes(self) -> int:
|
|
210
|
+
"""Return number of byffer bytes"""
|
|
211
|
+
return self.__nbytes
|
|
212
|
+
|
|
213
|
+
def nbytes_with_padding(self) -> int:
|
|
214
|
+
return self._buffer.getbuffer().nbytes
|
|
215
|
+
|
|
216
|
+
def to_dict(self) -> dict[str, Any]:
|
|
217
|
+
"""Get Dict representation of the object"""
|
|
218
|
+
return self.__stored
|
|
219
|
+
|
|
220
|
+
def to_hex(self) -> str:
|
|
221
|
+
"""Get buffer as hex string"""
|
|
222
|
+
return self.to_bytes().hex()
|
|
223
|
+
|
|
224
|
+
def to_bytes(self) -> bytes:
|
|
225
|
+
"""Get buffer as bytes"""
|
|
226
|
+
return self._buffer.getvalue()
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def get_val(inst: object, fn: str) -> Any:
|
|
230
|
+
"""
|
|
231
|
+
An helper method for get a value fro mobject and in case if FirmwareVersionError swap the value as not supported.
|
|
232
|
+
|
|
233
|
+
IMPORTANT: only used in conversion to tuple, dict
|
|
234
|
+
"""
|
|
235
|
+
# TODO: Allow to skip not supported values for tuple and dict
|
|
236
|
+
try:
|
|
237
|
+
val = getattr(inst, fn)
|
|
238
|
+
except FirmwareVersionError:
|
|
239
|
+
return "NOT_SUPORTED_BY_FIRMWARE"
|
|
240
|
+
else:
|
|
241
|
+
return val
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class ResponseBodyStruct(metaclass=OrderedMeta):
|
|
245
|
+
"""Response Body class"""
|
|
246
|
+
|
|
247
|
+
__slots__ = ("_buffer", "_order", "_stencil")
|
|
248
|
+
_order: ClassVar[Order]
|
|
249
|
+
|
|
250
|
+
def __init__(self, packet_body: bytes | bytearray | memoryview) -> None:
|
|
251
|
+
self._buffer = memoryview(packet_body).toreadonly()
|
|
252
|
+
self._stencil = self._order.get_stencil(self._buffer)
|
|
253
|
+
|
|
254
|
+
def __repr__(self) -> str:
|
|
255
|
+
cls_name = self.__class__.__qualname__
|
|
256
|
+
vals = ", ".join(
|
|
257
|
+
f"{n}={v!r}" for n, v in self.to_dict().items()
|
|
258
|
+
)
|
|
259
|
+
return f"{cls_name}({vals})"
|
|
260
|
+
|
|
261
|
+
def nbytes(self) -> int:
|
|
262
|
+
"""Return number of byffer bytes"""
|
|
263
|
+
return self._buffer.nbytes
|
|
264
|
+
|
|
265
|
+
def to_tuple(self) -> tuple:
|
|
266
|
+
"""Get py values as tuple"""
|
|
267
|
+
get_val_ = partial(get_val, self)
|
|
268
|
+
return tuple(map(get_val_, self._order.field_names))
|
|
269
|
+
|
|
270
|
+
def to_dict(self) -> dict[str, Any]:
|
|
271
|
+
"""Get Dict representation of the object"""
|
|
272
|
+
return {
|
|
273
|
+
name: get_val(self, name)
|
|
274
|
+
for name in self._order.field_names
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
def to_hex(self) -> str:
|
|
278
|
+
"""Get buffer as hex string"""
|
|
279
|
+
return self._buffer.hex()
|
|
280
|
+
|
|
281
|
+
def to_bytes(self) -> bytes:
|
|
282
|
+
"""Get buffer as bytes"""
|
|
283
|
+
return self._buffer.tobytes()
|