oscura 0.5.0__py3-none-any.whl → 0.6.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.
- oscura/__init__.py +169 -167
- oscura/analyzers/__init__.py +3 -0
- oscura/analyzers/classification.py +659 -0
- oscura/analyzers/digital/__init__.py +0 -48
- oscura/analyzers/digital/edges.py +325 -65
- oscura/analyzers/digital/extraction.py +0 -195
- oscura/analyzers/digital/quality.py +293 -166
- oscura/analyzers/digital/timing.py +260 -115
- oscura/analyzers/digital/timing_numba.py +334 -0
- oscura/analyzers/entropy.py +605 -0
- oscura/analyzers/eye/diagram.py +176 -109
- oscura/analyzers/eye/metrics.py +5 -5
- oscura/analyzers/jitter/__init__.py +6 -4
- oscura/analyzers/jitter/ber.py +52 -52
- oscura/analyzers/jitter/classification.py +156 -0
- oscura/analyzers/jitter/decomposition.py +163 -113
- oscura/analyzers/jitter/spectrum.py +80 -64
- oscura/analyzers/ml/__init__.py +39 -0
- oscura/analyzers/ml/features.py +600 -0
- oscura/analyzers/ml/signal_classifier.py +604 -0
- oscura/analyzers/packet/daq.py +246 -158
- oscura/analyzers/packet/parser.py +12 -1
- oscura/analyzers/packet/payload.py +50 -2110
- oscura/analyzers/packet/payload_analysis.py +361 -181
- oscura/analyzers/packet/payload_patterns.py +133 -70
- oscura/analyzers/packet/stream.py +84 -23
- oscura/analyzers/patterns/__init__.py +26 -5
- oscura/analyzers/patterns/anomaly_detection.py +908 -0
- oscura/analyzers/patterns/clustering.py +169 -108
- oscura/analyzers/patterns/clustering_optimized.py +227 -0
- oscura/analyzers/patterns/discovery.py +1 -1
- oscura/analyzers/patterns/matching.py +581 -197
- oscura/analyzers/patterns/pattern_mining.py +778 -0
- oscura/analyzers/patterns/periodic.py +121 -38
- oscura/analyzers/patterns/sequences.py +175 -78
- oscura/analyzers/power/conduction.py +1 -1
- oscura/analyzers/power/soa.py +6 -6
- oscura/analyzers/power/switching.py +250 -110
- oscura/analyzers/protocol/__init__.py +17 -1
- oscura/analyzers/protocols/__init__.py +1 -22
- oscura/analyzers/protocols/base.py +6 -6
- oscura/analyzers/protocols/ble/__init__.py +38 -0
- oscura/analyzers/protocols/ble/analyzer.py +809 -0
- oscura/analyzers/protocols/ble/uuids.py +288 -0
- oscura/analyzers/protocols/can.py +257 -127
- oscura/analyzers/protocols/can_fd.py +107 -80
- oscura/analyzers/protocols/flexray.py +139 -80
- oscura/analyzers/protocols/hdlc.py +93 -58
- oscura/analyzers/protocols/i2c.py +247 -106
- oscura/analyzers/protocols/i2s.py +138 -86
- oscura/analyzers/protocols/industrial/__init__.py +40 -0
- oscura/analyzers/protocols/industrial/bacnet/__init__.py +33 -0
- oscura/analyzers/protocols/industrial/bacnet/analyzer.py +708 -0
- oscura/analyzers/protocols/industrial/bacnet/encoding.py +412 -0
- oscura/analyzers/protocols/industrial/bacnet/services.py +622 -0
- oscura/analyzers/protocols/industrial/ethercat/__init__.py +30 -0
- oscura/analyzers/protocols/industrial/ethercat/analyzer.py +474 -0
- oscura/analyzers/protocols/industrial/ethercat/mailbox.py +339 -0
- oscura/analyzers/protocols/industrial/ethercat/topology.py +166 -0
- oscura/analyzers/protocols/industrial/modbus/__init__.py +31 -0
- oscura/analyzers/protocols/industrial/modbus/analyzer.py +525 -0
- oscura/analyzers/protocols/industrial/modbus/crc.py +79 -0
- oscura/analyzers/protocols/industrial/modbus/functions.py +436 -0
- oscura/analyzers/protocols/industrial/opcua/__init__.py +21 -0
- oscura/analyzers/protocols/industrial/opcua/analyzer.py +552 -0
- oscura/analyzers/protocols/industrial/opcua/datatypes.py +446 -0
- oscura/analyzers/protocols/industrial/opcua/services.py +264 -0
- oscura/analyzers/protocols/industrial/profinet/__init__.py +23 -0
- oscura/analyzers/protocols/industrial/profinet/analyzer.py +441 -0
- oscura/analyzers/protocols/industrial/profinet/dcp.py +263 -0
- oscura/analyzers/protocols/industrial/profinet/ptcp.py +200 -0
- oscura/analyzers/protocols/jtag.py +180 -98
- oscura/analyzers/protocols/lin.py +219 -114
- oscura/analyzers/protocols/manchester.py +4 -4
- oscura/analyzers/protocols/onewire.py +253 -149
- oscura/analyzers/protocols/parallel_bus/__init__.py +20 -0
- oscura/analyzers/protocols/parallel_bus/centronics.py +92 -0
- oscura/analyzers/protocols/parallel_bus/gpib.py +137 -0
- oscura/analyzers/protocols/spi.py +192 -95
- oscura/analyzers/protocols/swd.py +321 -167
- oscura/analyzers/protocols/uart.py +267 -125
- oscura/analyzers/protocols/usb.py +235 -131
- oscura/analyzers/side_channel/power.py +17 -12
- oscura/analyzers/signal/__init__.py +15 -0
- oscura/analyzers/signal/timing_analysis.py +1086 -0
- oscura/analyzers/signal_integrity/__init__.py +4 -1
- oscura/analyzers/signal_integrity/sparams.py +2 -19
- oscura/analyzers/spectral/chunked.py +129 -60
- oscura/analyzers/spectral/chunked_fft.py +300 -94
- oscura/analyzers/spectral/chunked_wavelet.py +100 -80
- oscura/analyzers/statistical/checksum.py +376 -217
- oscura/analyzers/statistical/classification.py +229 -107
- oscura/analyzers/statistical/entropy.py +78 -53
- oscura/analyzers/statistics/correlation.py +407 -211
- oscura/analyzers/statistics/outliers.py +2 -2
- oscura/analyzers/statistics/streaming.py +30 -5
- oscura/analyzers/validation.py +216 -101
- oscura/analyzers/waveform/measurements.py +9 -0
- oscura/analyzers/waveform/measurements_with_uncertainty.py +31 -15
- oscura/analyzers/waveform/spectral.py +500 -228
- oscura/api/__init__.py +31 -5
- oscura/api/dsl/__init__.py +582 -0
- oscura/{dsl → api/dsl}/commands.py +43 -76
- oscura/{dsl → api/dsl}/interpreter.py +26 -51
- oscura/{dsl → api/dsl}/parser.py +107 -77
- oscura/{dsl → api/dsl}/repl.py +2 -2
- oscura/api/dsl.py +1 -1
- oscura/{integrations → api/integrations}/__init__.py +1 -1
- oscura/{integrations → api/integrations}/llm.py +201 -102
- oscura/api/operators.py +3 -3
- oscura/api/optimization.py +144 -30
- oscura/api/rest_server.py +921 -0
- oscura/api/server/__init__.py +17 -0
- oscura/api/server/dashboard.py +850 -0
- oscura/api/server/static/README.md +34 -0
- oscura/api/server/templates/base.html +181 -0
- oscura/api/server/templates/export.html +120 -0
- oscura/api/server/templates/home.html +284 -0
- oscura/api/server/templates/protocols.html +58 -0
- oscura/api/server/templates/reports.html +43 -0
- oscura/api/server/templates/session_detail.html +89 -0
- oscura/api/server/templates/sessions.html +83 -0
- oscura/api/server/templates/waveforms.html +73 -0
- oscura/automotive/__init__.py +8 -1
- oscura/automotive/can/__init__.py +10 -0
- oscura/automotive/can/checksum.py +3 -1
- oscura/automotive/can/dbc_generator.py +590 -0
- oscura/automotive/can/message_wrapper.py +121 -74
- oscura/automotive/can/patterns.py +98 -21
- oscura/automotive/can/session.py +292 -56
- oscura/automotive/can/state_machine.py +6 -3
- oscura/automotive/can/stimulus_response.py +97 -75
- oscura/automotive/dbc/__init__.py +10 -2
- oscura/automotive/dbc/generator.py +84 -56
- oscura/automotive/dbc/parser.py +6 -6
- oscura/automotive/dtc/data.json +2763 -0
- oscura/automotive/dtc/database.py +2 -2
- oscura/automotive/flexray/__init__.py +31 -0
- oscura/automotive/flexray/analyzer.py +504 -0
- oscura/automotive/flexray/crc.py +185 -0
- oscura/automotive/flexray/fibex.py +449 -0
- oscura/automotive/j1939/__init__.py +45 -8
- oscura/automotive/j1939/analyzer.py +605 -0
- oscura/automotive/j1939/spns.py +326 -0
- oscura/automotive/j1939/transport.py +306 -0
- oscura/automotive/lin/__init__.py +47 -0
- oscura/automotive/lin/analyzer.py +612 -0
- oscura/automotive/loaders/blf.py +13 -2
- oscura/automotive/loaders/csv_can.py +143 -72
- oscura/automotive/loaders/dispatcher.py +50 -2
- oscura/automotive/loaders/mdf.py +86 -45
- oscura/automotive/loaders/pcap.py +111 -61
- oscura/automotive/uds/__init__.py +4 -0
- oscura/automotive/uds/analyzer.py +725 -0
- oscura/automotive/uds/decoder.py +140 -58
- oscura/automotive/uds/models.py +7 -1
- oscura/automotive/visualization.py +1 -1
- oscura/cli/analyze.py +348 -0
- oscura/cli/batch.py +142 -122
- oscura/cli/benchmark.py +275 -0
- oscura/cli/characterize.py +137 -82
- oscura/cli/compare.py +224 -131
- oscura/cli/completion.py +250 -0
- oscura/cli/config_cmd.py +361 -0
- oscura/cli/decode.py +164 -87
- oscura/cli/export.py +286 -0
- oscura/cli/main.py +115 -31
- oscura/{onboarding → cli/onboarding}/__init__.py +3 -3
- oscura/{onboarding → cli/onboarding}/help.py +80 -58
- oscura/{onboarding → cli/onboarding}/tutorials.py +97 -72
- oscura/{onboarding → cli/onboarding}/wizard.py +55 -36
- oscura/cli/progress.py +147 -0
- oscura/cli/shell.py +157 -135
- oscura/cli/validate_cmd.py +204 -0
- oscura/cli/visualize.py +158 -0
- oscura/convenience.py +125 -79
- oscura/core/__init__.py +4 -2
- oscura/core/backend_selector.py +3 -3
- oscura/core/cache.py +126 -15
- oscura/core/cancellation.py +1 -1
- oscura/{config → core/config}/__init__.py +20 -11
- oscura/{config → core/config}/defaults.py +1 -1
- oscura/{config → core/config}/loader.py +7 -5
- oscura/{config → core/config}/memory.py +5 -5
- oscura/{config → core/config}/migration.py +1 -1
- oscura/{config → core/config}/pipeline.py +99 -23
- oscura/{config → core/config}/preferences.py +1 -1
- oscura/{config → core/config}/protocol.py +3 -3
- oscura/{config → core/config}/schema.py +426 -272
- oscura/{config → core/config}/settings.py +1 -1
- oscura/{config → core/config}/thresholds.py +195 -153
- oscura/core/correlation.py +5 -6
- oscura/core/cross_domain.py +0 -2
- oscura/core/debug.py +9 -5
- oscura/{extensibility → core/extensibility}/docs.py +158 -70
- oscura/{extensibility → core/extensibility}/extensions.py +160 -76
- oscura/{extensibility → core/extensibility}/logging.py +1 -1
- oscura/{extensibility → core/extensibility}/measurements.py +1 -1
- oscura/{extensibility → core/extensibility}/plugins.py +1 -1
- oscura/{extensibility → core/extensibility}/templates.py +73 -3
- oscura/{extensibility → core/extensibility}/validation.py +1 -1
- oscura/core/gpu_backend.py +11 -7
- oscura/core/log_query.py +101 -11
- oscura/core/logging.py +126 -54
- oscura/core/logging_advanced.py +5 -5
- oscura/core/memory_limits.py +108 -70
- oscura/core/memory_monitor.py +2 -2
- oscura/core/memory_progress.py +7 -7
- oscura/core/memory_warnings.py +1 -1
- oscura/core/numba_backend.py +13 -13
- oscura/{plugins → core/plugins}/__init__.py +9 -9
- oscura/{plugins → core/plugins}/base.py +7 -7
- oscura/{plugins → core/plugins}/cli.py +3 -3
- oscura/{plugins → core/plugins}/discovery.py +186 -106
- oscura/{plugins → core/plugins}/lifecycle.py +1 -1
- oscura/{plugins → core/plugins}/manager.py +7 -7
- oscura/{plugins → core/plugins}/registry.py +3 -3
- oscura/{plugins → core/plugins}/versioning.py +1 -1
- oscura/core/progress.py +16 -1
- oscura/core/provenance.py +8 -2
- oscura/{schemas → core/schemas}/__init__.py +2 -2
- oscura/core/schemas/bus_configuration.json +322 -0
- oscura/core/schemas/device_mapping.json +182 -0
- oscura/core/schemas/packet_format.json +418 -0
- oscura/core/schemas/protocol_definition.json +363 -0
- oscura/core/types.py +4 -0
- oscura/core/uncertainty.py +3 -3
- oscura/correlation/__init__.py +52 -0
- oscura/correlation/multi_protocol.py +811 -0
- oscura/discovery/auto_decoder.py +117 -35
- oscura/discovery/comparison.py +191 -86
- oscura/discovery/quality_validator.py +155 -68
- oscura/discovery/signal_detector.py +196 -79
- oscura/export/__init__.py +18 -20
- oscura/export/kaitai_struct.py +513 -0
- oscura/export/scapy_layer.py +801 -0
- oscura/export/wireshark/README.md +15 -15
- oscura/export/wireshark/generator.py +1 -1
- oscura/export/wireshark/templates/dissector.lua.j2 +2 -2
- oscura/export/wireshark_dissector.py +746 -0
- oscura/guidance/wizard.py +207 -111
- oscura/hardware/__init__.py +19 -0
- oscura/{acquisition → hardware/acquisition}/__init__.py +4 -4
- oscura/{acquisition → hardware/acquisition}/file.py +2 -2
- oscura/{acquisition → hardware/acquisition}/hardware.py +7 -7
- oscura/{acquisition → hardware/acquisition}/saleae.py +15 -12
- oscura/{acquisition → hardware/acquisition}/socketcan.py +1 -1
- oscura/{acquisition → hardware/acquisition}/streaming.py +2 -2
- oscura/{acquisition → hardware/acquisition}/synthetic.py +3 -3
- oscura/{acquisition → hardware/acquisition}/visa.py +33 -11
- oscura/hardware/firmware/__init__.py +29 -0
- oscura/hardware/firmware/pattern_recognition.py +874 -0
- oscura/hardware/hal_detector.py +736 -0
- oscura/hardware/security/__init__.py +37 -0
- oscura/hardware/security/side_channel_detector.py +1126 -0
- oscura/inference/__init__.py +4 -0
- oscura/inference/active_learning/README.md +7 -7
- oscura/inference/active_learning/observation_table.py +4 -1
- oscura/inference/alignment.py +216 -123
- oscura/inference/bayesian.py +113 -33
- oscura/inference/crc_reverse.py +101 -55
- oscura/inference/logic.py +6 -2
- oscura/inference/message_format.py +342 -183
- oscura/inference/protocol.py +95 -44
- oscura/inference/protocol_dsl.py +180 -82
- oscura/inference/signal_intelligence.py +1439 -706
- oscura/inference/spectral.py +99 -57
- oscura/inference/state_machine.py +810 -158
- oscura/inference/stream.py +270 -110
- oscura/iot/__init__.py +34 -0
- oscura/iot/coap/__init__.py +32 -0
- oscura/iot/coap/analyzer.py +668 -0
- oscura/iot/coap/options.py +212 -0
- oscura/iot/lorawan/__init__.py +21 -0
- oscura/iot/lorawan/crypto.py +206 -0
- oscura/iot/lorawan/decoder.py +801 -0
- oscura/iot/lorawan/mac_commands.py +341 -0
- oscura/iot/mqtt/__init__.py +27 -0
- oscura/iot/mqtt/analyzer.py +999 -0
- oscura/iot/mqtt/properties.py +315 -0
- oscura/iot/zigbee/__init__.py +31 -0
- oscura/iot/zigbee/analyzer.py +615 -0
- oscura/iot/zigbee/security.py +153 -0
- oscura/iot/zigbee/zcl.py +349 -0
- oscura/jupyter/display.py +125 -45
- oscura/{exploratory → jupyter/exploratory}/__init__.py +8 -8
- oscura/{exploratory → jupyter/exploratory}/error_recovery.py +298 -141
- oscura/jupyter/exploratory/fuzzy.py +746 -0
- oscura/{exploratory → jupyter/exploratory}/fuzzy_advanced.py +258 -100
- oscura/{exploratory → jupyter/exploratory}/legacy.py +464 -242
- oscura/{exploratory → jupyter/exploratory}/parse.py +167 -145
- oscura/{exploratory → jupyter/exploratory}/recovery.py +119 -87
- oscura/jupyter/exploratory/sync.py +612 -0
- oscura/{exploratory → jupyter/exploratory}/unknown.py +299 -176
- oscura/jupyter/magic.py +4 -4
- oscura/{ui → jupyter/ui}/__init__.py +2 -2
- oscura/{ui → jupyter/ui}/formatters.py +3 -3
- oscura/{ui → jupyter/ui}/progressive_display.py +153 -82
- oscura/loaders/__init__.py +171 -63
- oscura/loaders/binary.py +88 -1
- oscura/loaders/chipwhisperer.py +153 -137
- oscura/loaders/configurable.py +208 -86
- oscura/loaders/csv_loader.py +458 -215
- oscura/loaders/hdf5_loader.py +278 -119
- oscura/loaders/lazy.py +87 -54
- oscura/loaders/mmap_loader.py +1 -1
- oscura/loaders/numpy_loader.py +253 -116
- oscura/loaders/pcap.py +226 -151
- oscura/loaders/rigol.py +110 -49
- oscura/loaders/sigrok.py +201 -78
- oscura/loaders/tdms.py +81 -58
- oscura/loaders/tektronix.py +291 -174
- oscura/loaders/touchstone.py +182 -87
- oscura/loaders/vcd.py +215 -117
- oscura/loaders/wav.py +155 -68
- oscura/reporting/__init__.py +9 -7
- oscura/reporting/analyze.py +352 -146
- oscura/reporting/argument_preparer.py +69 -14
- oscura/reporting/auto_report.py +97 -61
- oscura/reporting/batch.py +131 -58
- oscura/reporting/chart_selection.py +57 -45
- oscura/reporting/comparison.py +63 -17
- oscura/reporting/content/executive.py +76 -24
- oscura/reporting/core_formats/multi_format.py +11 -8
- oscura/reporting/engine.py +312 -158
- oscura/reporting/enhanced_reports.py +949 -0
- oscura/reporting/export.py +86 -43
- oscura/reporting/formatting/numbers.py +69 -42
- oscura/reporting/html.py +139 -58
- oscura/reporting/index.py +137 -65
- oscura/reporting/output.py +158 -67
- oscura/reporting/pdf.py +67 -102
- oscura/reporting/plots.py +191 -112
- oscura/reporting/sections.py +88 -47
- oscura/reporting/standards.py +104 -61
- oscura/reporting/summary_generator.py +75 -55
- oscura/reporting/tables.py +138 -54
- oscura/reporting/templates/enhanced/protocol_re.html +525 -0
- oscura/reporting/templates/index.md +13 -13
- oscura/sessions/__init__.py +14 -23
- oscura/sessions/base.py +3 -3
- oscura/sessions/blackbox.py +106 -10
- oscura/sessions/generic.py +2 -2
- oscura/sessions/legacy.py +783 -0
- oscura/side_channel/__init__.py +63 -0
- oscura/side_channel/dpa.py +1025 -0
- oscura/utils/__init__.py +15 -1
- oscura/utils/autodetect.py +1 -5
- oscura/utils/bitwise.py +118 -0
- oscura/{builders → utils/builders}/__init__.py +1 -1
- oscura/{comparison → utils/comparison}/__init__.py +6 -6
- oscura/{comparison → utils/comparison}/compare.py +202 -101
- oscura/{comparison → utils/comparison}/golden.py +83 -63
- oscura/{comparison → utils/comparison}/limits.py +313 -89
- oscura/{comparison → utils/comparison}/mask.py +151 -45
- oscura/{comparison → utils/comparison}/trace_diff.py +1 -1
- oscura/{comparison → utils/comparison}/visualization.py +147 -89
- oscura/{component → utils/component}/__init__.py +3 -3
- oscura/{component → utils/component}/impedance.py +122 -58
- oscura/{component → utils/component}/reactive.py +165 -168
- oscura/{component → utils/component}/transmission_line.py +3 -3
- oscura/{filtering → utils/filtering}/__init__.py +6 -6
- oscura/{filtering → utils/filtering}/base.py +1 -1
- oscura/{filtering → utils/filtering}/convenience.py +2 -2
- oscura/{filtering → utils/filtering}/design.py +169 -93
- oscura/{filtering → utils/filtering}/filters.py +2 -2
- oscura/{filtering → utils/filtering}/introspection.py +2 -2
- oscura/utils/geometry.py +31 -0
- oscura/utils/imports.py +184 -0
- oscura/utils/lazy.py +1 -1
- oscura/{math → utils/math}/__init__.py +2 -2
- oscura/{math → utils/math}/arithmetic.py +114 -48
- oscura/{math → utils/math}/interpolation.py +139 -106
- oscura/utils/memory.py +129 -66
- oscura/utils/memory_advanced.py +92 -9
- oscura/utils/memory_extensions.py +10 -8
- oscura/{optimization → utils/optimization}/__init__.py +1 -1
- oscura/{optimization → utils/optimization}/search.py +2 -2
- oscura/utils/performance/__init__.py +58 -0
- oscura/utils/performance/caching.py +889 -0
- oscura/utils/performance/lsh_clustering.py +333 -0
- oscura/utils/performance/memory_optimizer.py +699 -0
- oscura/utils/performance/optimizations.py +675 -0
- oscura/utils/performance/parallel.py +654 -0
- oscura/utils/performance/profiling.py +661 -0
- oscura/{pipeline → utils/pipeline}/base.py +1 -1
- oscura/{pipeline → utils/pipeline}/composition.py +11 -3
- oscura/{pipeline → utils/pipeline}/parallel.py +3 -2
- oscura/{pipeline → utils/pipeline}/pipeline.py +1 -1
- oscura/{pipeline → utils/pipeline}/reverse_engineering.py +412 -221
- oscura/{search → utils/search}/__init__.py +3 -3
- oscura/{search → utils/search}/anomaly.py +188 -58
- oscura/utils/search/context.py +294 -0
- oscura/{search → utils/search}/pattern.py +138 -10
- oscura/utils/serial.py +51 -0
- oscura/utils/storage/__init__.py +61 -0
- oscura/utils/storage/database.py +1166 -0
- oscura/{streaming → utils/streaming}/chunked.py +302 -143
- oscura/{streaming → utils/streaming}/progressive.py +1 -1
- oscura/{streaming → utils/streaming}/realtime.py +3 -2
- oscura/{triggering → utils/triggering}/__init__.py +6 -6
- oscura/{triggering → utils/triggering}/base.py +6 -6
- oscura/{triggering → utils/triggering}/edge.py +2 -2
- oscura/{triggering → utils/triggering}/pattern.py +2 -2
- oscura/{triggering → utils/triggering}/pulse.py +115 -74
- oscura/{triggering → utils/triggering}/window.py +2 -2
- oscura/utils/validation.py +32 -0
- oscura/validation/__init__.py +121 -0
- oscura/{compliance → validation/compliance}/__init__.py +5 -5
- oscura/{compliance → validation/compliance}/advanced.py +5 -5
- oscura/{compliance → validation/compliance}/masks.py +1 -1
- oscura/{compliance → validation/compliance}/reporting.py +127 -53
- oscura/{compliance → validation/compliance}/testing.py +114 -52
- oscura/validation/compliance_tests.py +915 -0
- oscura/validation/fuzzer.py +990 -0
- oscura/validation/grammar_tests.py +596 -0
- oscura/validation/grammar_validator.py +904 -0
- oscura/validation/hil_testing.py +977 -0
- oscura/{quality → validation/quality}/__init__.py +4 -4
- oscura/{quality → validation/quality}/ensemble.py +251 -171
- oscura/{quality → validation/quality}/explainer.py +3 -3
- oscura/{quality → validation/quality}/scoring.py +1 -1
- oscura/{quality → validation/quality}/warnings.py +4 -4
- oscura/validation/regression_suite.py +808 -0
- oscura/validation/replay.py +788 -0
- oscura/{testing → validation/testing}/__init__.py +2 -2
- oscura/{testing → validation/testing}/synthetic.py +5 -5
- oscura/visualization/__init__.py +9 -0
- oscura/visualization/accessibility.py +1 -1
- oscura/visualization/annotations.py +64 -67
- oscura/visualization/colors.py +7 -7
- oscura/visualization/digital.py +180 -81
- oscura/visualization/eye.py +236 -85
- oscura/visualization/interactive.py +320 -143
- oscura/visualization/jitter.py +587 -247
- oscura/visualization/layout.py +169 -134
- oscura/visualization/optimization.py +103 -52
- oscura/visualization/palettes.py +1 -1
- oscura/visualization/power.py +427 -211
- oscura/visualization/power_extended.py +626 -297
- oscura/visualization/presets.py +2 -0
- oscura/visualization/protocols.py +495 -181
- oscura/visualization/render.py +79 -63
- oscura/visualization/reverse_engineering.py +171 -124
- oscura/visualization/signal_integrity.py +460 -279
- oscura/visualization/specialized.py +190 -100
- oscura/visualization/spectral.py +670 -255
- oscura/visualization/thumbnails.py +166 -137
- oscura/visualization/waveform.py +150 -63
- oscura/workflows/__init__.py +3 -0
- oscura/{batch → workflows/batch}/__init__.py +5 -5
- oscura/{batch → workflows/batch}/advanced.py +150 -75
- oscura/workflows/batch/aggregate.py +531 -0
- oscura/workflows/batch/analyze.py +236 -0
- oscura/{batch → workflows/batch}/logging.py +2 -2
- oscura/{batch → workflows/batch}/metrics.py +1 -1
- oscura/workflows/complete_re.py +1144 -0
- oscura/workflows/compliance.py +44 -54
- oscura/workflows/digital.py +197 -51
- oscura/workflows/legacy/__init__.py +12 -0
- oscura/{workflow → workflows/legacy}/dag.py +4 -1
- oscura/workflows/multi_trace.py +9 -9
- oscura/workflows/power.py +42 -62
- oscura/workflows/protocol.py +82 -49
- oscura/workflows/reverse_engineering.py +351 -150
- oscura/workflows/signal_integrity.py +157 -82
- oscura-0.6.0.dist-info/METADATA +643 -0
- oscura-0.6.0.dist-info/RECORD +590 -0
- oscura/analyzers/digital/ic_database.py +0 -498
- oscura/analyzers/digital/timing_paths.py +0 -339
- oscura/analyzers/digital/vintage.py +0 -377
- oscura/analyzers/digital/vintage_result.py +0 -148
- oscura/analyzers/protocols/parallel_bus.py +0 -449
- oscura/batch/aggregate.py +0 -300
- oscura/batch/analyze.py +0 -139
- oscura/dsl/__init__.py +0 -73
- oscura/exceptions.py +0 -59
- oscura/exploratory/fuzzy.py +0 -513
- oscura/exploratory/sync.py +0 -384
- oscura/export/wavedrom.py +0 -430
- oscura/exporters/__init__.py +0 -94
- oscura/exporters/csv.py +0 -303
- oscura/exporters/exporters.py +0 -44
- oscura/exporters/hdf5.py +0 -217
- oscura/exporters/html_export.py +0 -701
- oscura/exporters/json_export.py +0 -338
- oscura/exporters/markdown_export.py +0 -367
- oscura/exporters/matlab_export.py +0 -354
- oscura/exporters/npz_export.py +0 -219
- oscura/exporters/spice_export.py +0 -210
- oscura/exporters/vintage_logic_csv.py +0 -247
- oscura/reporting/vintage_logic_report.py +0 -523
- oscura/search/context.py +0 -149
- oscura/session/__init__.py +0 -34
- oscura/session/annotations.py +0 -289
- oscura/session/history.py +0 -313
- oscura/session/session.py +0 -520
- oscura/visualization/digital_advanced.py +0 -718
- oscura/visualization/figure_manager.py +0 -156
- oscura/workflow/__init__.py +0 -13
- oscura-0.5.0.dist-info/METADATA +0 -407
- oscura-0.5.0.dist-info/RECORD +0 -486
- /oscura/core/{config.py → config/legacy.py} +0 -0
- /oscura/{extensibility → core/extensibility}/__init__.py +0 -0
- /oscura/{extensibility → core/extensibility}/registry.py +0 -0
- /oscura/{plugins → core/plugins}/isolation.py +0 -0
- /oscura/{builders → utils/builders}/signal_builder.py +0 -0
- /oscura/{optimization → utils/optimization}/parallel.py +0 -0
- /oscura/{pipeline → utils/pipeline}/__init__.py +0 -0
- /oscura/{streaming → utils/streaming}/__init__.py +0 -0
- {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/WHEEL +0 -0
- {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/entry_points.txt +0 -0
- {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"""Standard BLE UUID mappings for services, characteristics, and descriptors.
|
|
2
|
+
|
|
3
|
+
This module provides mappings for standard Bluetooth SIG-assigned UUIDs
|
|
4
|
+
to human-readable names for GATT services, characteristics, and descriptors.
|
|
5
|
+
|
|
6
|
+
References:
|
|
7
|
+
Assigned Numbers: https://www.bluetooth.com/specifications/assigned-numbers/
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
# Standard GATT Services (16-bit UUIDs)
|
|
13
|
+
# Format: {uuid: name}
|
|
14
|
+
STANDARD_SERVICES: dict[int, str] = {
|
|
15
|
+
# Generic Services
|
|
16
|
+
0x1800: "Generic Access",
|
|
17
|
+
0x1801: "Generic Attribute",
|
|
18
|
+
# Health & Fitness Services
|
|
19
|
+
0x180D: "Heart Rate",
|
|
20
|
+
0x180F: "Battery Service",
|
|
21
|
+
0x1810: "Blood Pressure",
|
|
22
|
+
0x1811: "Alert Notification Service",
|
|
23
|
+
0x1812: "Human Interface Device",
|
|
24
|
+
0x1814: "Running Speed and Cadence",
|
|
25
|
+
0x1816: "Cycling Speed and Cadence",
|
|
26
|
+
0x1818: "Cycling Power",
|
|
27
|
+
0x1819: "Location and Navigation",
|
|
28
|
+
# Device Information
|
|
29
|
+
0x180A: "Device Information",
|
|
30
|
+
# Environmental Sensing
|
|
31
|
+
0x181A: "Environmental Sensing",
|
|
32
|
+
0x181C: "User Data",
|
|
33
|
+
0x181D: "Weight Scale",
|
|
34
|
+
# Automation
|
|
35
|
+
0x1820: "Internet Protocol Support",
|
|
36
|
+
0x1821: "Indoor Positioning",
|
|
37
|
+
0x1822: "Pulse Oximeter",
|
|
38
|
+
0x1823: "HTTP Proxy",
|
|
39
|
+
0x1824: "Transport Discovery",
|
|
40
|
+
0x1825: "Object Transfer",
|
|
41
|
+
# Audio
|
|
42
|
+
0x1826: "Fitness Machine",
|
|
43
|
+
0x1827: "Mesh Provisioning",
|
|
44
|
+
0x1828: "Mesh Proxy",
|
|
45
|
+
# Nordic Services (vendor-specific but common)
|
|
46
|
+
0xFE59: "Nordic UART Service",
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Standard GATT Characteristics (16-bit UUIDs)
|
|
50
|
+
STANDARD_CHARACTERISTICS: dict[int, str] = {
|
|
51
|
+
# Generic Access
|
|
52
|
+
0x2A00: "Device Name",
|
|
53
|
+
0x2A01: "Appearance",
|
|
54
|
+
0x2A02: "Peripheral Privacy Flag",
|
|
55
|
+
0x2A03: "Reconnection Address",
|
|
56
|
+
0x2A04: "Peripheral Preferred Connection Parameters",
|
|
57
|
+
# Generic Attribute
|
|
58
|
+
0x2A05: "Service Changed",
|
|
59
|
+
# Device Information
|
|
60
|
+
0x2A23: "System ID",
|
|
61
|
+
0x2A24: "Model Number String",
|
|
62
|
+
0x2A25: "Serial Number String",
|
|
63
|
+
0x2A26: "Firmware Revision String",
|
|
64
|
+
0x2A27: "Hardware Revision String",
|
|
65
|
+
0x2A28: "Software Revision String",
|
|
66
|
+
0x2A29: "Manufacturer Name String",
|
|
67
|
+
# Battery Service
|
|
68
|
+
0x2A19: "Battery Level",
|
|
69
|
+
# Heart Rate
|
|
70
|
+
0x2A37: "Heart Rate Measurement",
|
|
71
|
+
0x2A38: "Body Sensor Location",
|
|
72
|
+
0x2A39: "Heart Rate Control Point",
|
|
73
|
+
# Blood Pressure
|
|
74
|
+
0x2A35: "Blood Pressure Measurement",
|
|
75
|
+
0x2A36: "Intermediate Cuff Pressure",
|
|
76
|
+
0x2A49: "Blood Pressure Feature",
|
|
77
|
+
# Environmental Sensing
|
|
78
|
+
0x2A6E: "Temperature",
|
|
79
|
+
0x2A6F: "Humidity",
|
|
80
|
+
0x2A76: "UV Index",
|
|
81
|
+
# HID
|
|
82
|
+
0x2A4A: "HID Information",
|
|
83
|
+
0x2A4B: "Report Map",
|
|
84
|
+
0x2A4C: "HID Control Point",
|
|
85
|
+
0x2A4D: "Report",
|
|
86
|
+
0x2A4E: "Protocol Mode",
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# Standard GATT Descriptors (16-bit UUIDs)
|
|
90
|
+
STANDARD_DESCRIPTORS: dict[int, str] = {
|
|
91
|
+
0x2900: "Characteristic Extended Properties",
|
|
92
|
+
0x2901: "Characteristic User Description",
|
|
93
|
+
0x2902: "Client Characteristic Configuration",
|
|
94
|
+
0x2903: "Server Characteristic Configuration",
|
|
95
|
+
0x2904: "Characteristic Presentation Format",
|
|
96
|
+
0x2905: "Characteristic Aggregate Format",
|
|
97
|
+
0x2906: "Valid Range",
|
|
98
|
+
0x2907: "External Report Reference",
|
|
99
|
+
0x2908: "Report Reference",
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
# Advertising Data (AD) Type codes
|
|
103
|
+
AD_TYPES: dict[int, str] = {
|
|
104
|
+
0x01: "Flags",
|
|
105
|
+
0x02: "Incomplete List of 16-bit Service UUIDs",
|
|
106
|
+
0x03: "Complete List of 16-bit Service UUIDs",
|
|
107
|
+
0x04: "Incomplete List of 32-bit Service UUIDs",
|
|
108
|
+
0x05: "Complete List of 32-bit Service UUIDs",
|
|
109
|
+
0x06: "Incomplete List of 128-bit Service UUIDs",
|
|
110
|
+
0x07: "Complete List of 128-bit Service UUIDs",
|
|
111
|
+
0x08: "Shortened Local Name",
|
|
112
|
+
0x09: "Complete Local Name",
|
|
113
|
+
0x0A: "Tx Power Level",
|
|
114
|
+
0x0D: "Class of Device",
|
|
115
|
+
0x0E: "Simple Pairing Hash C",
|
|
116
|
+
0x0F: "Simple Pairing Randomizer R",
|
|
117
|
+
0x10: "Device ID",
|
|
118
|
+
0x11: "Security Manager Out of Band Flags",
|
|
119
|
+
0x12: "Slave Connection Interval Range",
|
|
120
|
+
0x14: "List of 16-bit Service Solicitation UUIDs",
|
|
121
|
+
0x15: "List of 128-bit Service Solicitation UUIDs",
|
|
122
|
+
0x16: "Service Data - 16-bit UUID",
|
|
123
|
+
0x17: "Public Target Address",
|
|
124
|
+
0x18: "Random Target Address",
|
|
125
|
+
0x19: "Appearance",
|
|
126
|
+
0x1A: "Advertising Interval",
|
|
127
|
+
0x1B: "LE Bluetooth Device Address",
|
|
128
|
+
0x1C: "LE Role",
|
|
129
|
+
0x1D: "Simple Pairing Hash C-256",
|
|
130
|
+
0x1E: "Simple Pairing Randomizer R-256",
|
|
131
|
+
0x1F: "List of 32-bit Service Solicitation UUIDs",
|
|
132
|
+
0x20: "Service Data - 32-bit UUID",
|
|
133
|
+
0x21: "Service Data - 128-bit UUID",
|
|
134
|
+
0xFF: "Manufacturer Specific Data",
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def uuid_to_string(uuid_bytes: bytes, short: bool = True) -> str:
|
|
139
|
+
"""Convert UUID bytes to standard string format.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
uuid_bytes: UUID as bytes (2, 4, or 16 bytes).
|
|
143
|
+
short: Use short format for 16/32-bit UUIDs (e.g., "0x180D").
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
UUID string in standard format.
|
|
147
|
+
|
|
148
|
+
Example:
|
|
149
|
+
>>> uuid_to_string(b"\\x0d\\x18") # 16-bit UUID
|
|
150
|
+
'0x180D'
|
|
151
|
+
>>> uuid_to_string(b"\\x00\\x00\\x18\\x0d...", short=False)
|
|
152
|
+
'0000180d-0000-1000-8000-00805f9b34fb'
|
|
153
|
+
"""
|
|
154
|
+
if len(uuid_bytes) == 2:
|
|
155
|
+
# 16-bit UUID
|
|
156
|
+
val = int.from_bytes(uuid_bytes, "little")
|
|
157
|
+
return f"0x{val:04X}" if short else f"{val:08x}-0000-1000-8000-00805f9b34fb"
|
|
158
|
+
elif len(uuid_bytes) == 4:
|
|
159
|
+
# 32-bit UUID (rare)
|
|
160
|
+
val = int.from_bytes(uuid_bytes, "little")
|
|
161
|
+
return f"0x{val:08X}" if short else f"{val:08x}-0000-1000-8000-00805f9b34fb"
|
|
162
|
+
elif len(uuid_bytes) == 16:
|
|
163
|
+
# 128-bit UUID (full)
|
|
164
|
+
# Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
165
|
+
parts = [
|
|
166
|
+
uuid_bytes[0:4][::-1].hex(), # Reverse for little-endian
|
|
167
|
+
uuid_bytes[4:6][::-1].hex(),
|
|
168
|
+
uuid_bytes[6:8][::-1].hex(),
|
|
169
|
+
uuid_bytes[8:10].hex(), # These stay in order
|
|
170
|
+
uuid_bytes[10:16].hex(),
|
|
171
|
+
]
|
|
172
|
+
return "-".join(parts)
|
|
173
|
+
else:
|
|
174
|
+
return uuid_bytes.hex()
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def string_to_uuid_bytes(uuid_str: str) -> bytes:
|
|
178
|
+
"""Convert UUID string to bytes.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
uuid_str: UUID string (e.g., "0x180D" or full format).
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
UUID as bytes.
|
|
185
|
+
|
|
186
|
+
Example:
|
|
187
|
+
>>> string_to_uuid_bytes("0x180D")
|
|
188
|
+
b'\\x0d\\x18'
|
|
189
|
+
"""
|
|
190
|
+
if uuid_str.startswith("0x") or uuid_str.startswith("0X"):
|
|
191
|
+
# Short format
|
|
192
|
+
val = int(uuid_str, 16)
|
|
193
|
+
if val <= 0xFFFF:
|
|
194
|
+
return val.to_bytes(2, "little")
|
|
195
|
+
else:
|
|
196
|
+
return val.to_bytes(4, "little")
|
|
197
|
+
elif "-" in uuid_str:
|
|
198
|
+
# Full format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
199
|
+
uuid_str = uuid_str.replace("-", "")
|
|
200
|
+
if len(uuid_str) != 32:
|
|
201
|
+
raise ValueError(f"Invalid UUID format: {uuid_str}")
|
|
202
|
+
# Convert back to bytes (handle endianness)
|
|
203
|
+
parts = [
|
|
204
|
+
bytes.fromhex(uuid_str[0:8])[::-1], # Reverse for little-endian
|
|
205
|
+
bytes.fromhex(uuid_str[8:12])[::-1],
|
|
206
|
+
bytes.fromhex(uuid_str[12:16])[::-1],
|
|
207
|
+
bytes.fromhex(uuid_str[16:20]), # These stay in order
|
|
208
|
+
bytes.fromhex(uuid_str[20:32]),
|
|
209
|
+
]
|
|
210
|
+
return b"".join(parts)
|
|
211
|
+
else:
|
|
212
|
+
raise ValueError(f"Invalid UUID format: {uuid_str}")
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def get_service_name(uuid: int | str) -> str:
|
|
216
|
+
"""Get standard service name from UUID.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
uuid: Service UUID (16-bit int or string).
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
Service name or "Unknown Service".
|
|
223
|
+
|
|
224
|
+
Example:
|
|
225
|
+
>>> get_service_name(0x180D)
|
|
226
|
+
'Heart Rate'
|
|
227
|
+
"""
|
|
228
|
+
if isinstance(uuid, str):
|
|
229
|
+
if uuid.startswith("0x"):
|
|
230
|
+
uuid = int(uuid, 16)
|
|
231
|
+
else:
|
|
232
|
+
return "Custom Service"
|
|
233
|
+
return STANDARD_SERVICES.get(uuid, "Unknown Service")
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def get_characteristic_name(uuid: int | str) -> str:
|
|
237
|
+
"""Get standard characteristic name from UUID.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
uuid: Characteristic UUID (16-bit int or string).
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
Characteristic name or "Unknown Characteristic".
|
|
244
|
+
|
|
245
|
+
Example:
|
|
246
|
+
>>> get_characteristic_name(0x2A37)
|
|
247
|
+
'Heart Rate Measurement'
|
|
248
|
+
"""
|
|
249
|
+
if isinstance(uuid, str):
|
|
250
|
+
if uuid.startswith("0x"):
|
|
251
|
+
uuid = int(uuid, 16)
|
|
252
|
+
else:
|
|
253
|
+
return "Custom Characteristic"
|
|
254
|
+
return STANDARD_CHARACTERISTICS.get(uuid, "Unknown Characteristic")
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def get_descriptor_name(uuid: int | str) -> str:
|
|
258
|
+
"""Get standard descriptor name from UUID.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
uuid: Descriptor UUID (16-bit int or string).
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
Descriptor name or "Unknown Descriptor".
|
|
265
|
+
|
|
266
|
+
Example:
|
|
267
|
+
>>> get_descriptor_name(0x2902)
|
|
268
|
+
'Client Characteristic Configuration'
|
|
269
|
+
"""
|
|
270
|
+
if isinstance(uuid, str):
|
|
271
|
+
if uuid.startswith("0x"):
|
|
272
|
+
uuid = int(uuid, 16)
|
|
273
|
+
else:
|
|
274
|
+
return "Custom Descriptor"
|
|
275
|
+
return STANDARD_DESCRIPTORS.get(uuid, "Unknown Descriptor")
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
__all__ = [
|
|
279
|
+
"AD_TYPES",
|
|
280
|
+
"STANDARD_CHARACTERISTICS",
|
|
281
|
+
"STANDARD_DESCRIPTORS",
|
|
282
|
+
"STANDARD_SERVICES",
|
|
283
|
+
"get_characteristic_name",
|
|
284
|
+
"get_descriptor_name",
|
|
285
|
+
"get_service_name",
|
|
286
|
+
"string_to_uuid_bytes",
|
|
287
|
+
"uuid_to_string",
|
|
288
|
+
]
|