oscura 0.5.0__py3-none-any.whl → 0.5.1__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 (34) hide show
  1. oscura/__init__.py +1 -1
  2. oscura/analyzers/digital/__init__.py +0 -48
  3. oscura/analyzers/digital/extraction.py +0 -195
  4. oscura/analyzers/protocols/__init__.py +1 -22
  5. oscura/automotive/__init__.py +1 -1
  6. oscura/automotive/dtc/data.json +2763 -0
  7. oscura/export/__init__.py +0 -12
  8. oscura/export/wireshark/README.md +15 -15
  9. oscura/exporters/json_export.py +0 -47
  10. oscura/inference/active_learning/README.md +7 -7
  11. oscura/pipeline/composition.py +10 -2
  12. oscura/reporting/__init__.py +0 -7
  13. oscura/reporting/templates/index.md +13 -13
  14. oscura/schemas/bus_configuration.json +322 -0
  15. oscura/schemas/device_mapping.json +182 -0
  16. oscura/schemas/packet_format.json +418 -0
  17. oscura/schemas/protocol_definition.json +363 -0
  18. oscura/utils/autodetect.py +1 -5
  19. oscura-0.5.1.dist-info/METADATA +583 -0
  20. {oscura-0.5.0.dist-info → oscura-0.5.1.dist-info}/RECORD +23 -28
  21. oscura/analyzers/digital/ic_database.py +0 -498
  22. oscura/analyzers/digital/timing_paths.py +0 -339
  23. oscura/analyzers/digital/vintage.py +0 -377
  24. oscura/analyzers/digital/vintage_result.py +0 -148
  25. oscura/analyzers/protocols/parallel_bus.py +0 -449
  26. oscura/export/wavedrom.py +0 -430
  27. oscura/exporters/vintage_logic_csv.py +0 -247
  28. oscura/reporting/vintage_logic_report.py +0 -523
  29. oscura/visualization/digital_advanced.py +0 -718
  30. oscura/visualization/figure_manager.py +0 -156
  31. oscura-0.5.0.dist-info/METADATA +0 -407
  32. {oscura-0.5.0.dist-info → oscura-0.5.1.dist-info}/WHEEL +0 -0
  33. {oscura-0.5.0.dist-info → oscura-0.5.1.dist-info}/entry_points.txt +0 -0
  34. {oscura-0.5.0.dist-info → oscura-0.5.1.dist-info}/licenses/LICENSE +0 -0
oscura/export/__init__.py CHANGED
@@ -19,19 +19,7 @@ Example:
19
19
 
20
20
  # Import main exports
21
21
  from . import wireshark
22
- from .wavedrom import (
23
- WaveDromBuilder,
24
- WaveDromEdge,
25
- WaveDromSignal,
26
- export_wavedrom,
27
- from_digital_trace,
28
- )
29
22
 
30
23
  __all__ = [
31
- "WaveDromBuilder",
32
- "WaveDromEdge",
33
- "WaveDromSignal",
34
- "export_wavedrom",
35
- "from_digital_trace",
36
24
  "wireshark",
37
25
  ]
@@ -64,21 +64,21 @@ Then reload Lua plugins in Wireshark: **Analyze > Reload Lua Plugins** (Ctrl+Shi
64
64
 
65
65
  ## Supported Field Types
66
66
 
67
- |Oscura Type|Wireshark Type|Size|Notes|
68
- |---|---|---|---|
69
- |`uint8`|`ProtoField.uint8`|1 byte|Unsigned 8-bit integer|
70
- |`uint16`|`ProtoField.uint16`|2 bytes|Unsigned 16-bit integer|
71
- |`uint32`|`ProtoField.uint32`|4 bytes|Unsigned 32-bit integer|
72
- |`uint64`|`ProtoField.uint64`|8 bytes|Unsigned 64-bit integer|
73
- |`int8`|`ProtoField.int8`|1 byte|Signed 8-bit integer|
74
- |`int16`|`ProtoField.int16`|2 bytes|Signed 16-bit integer|
75
- |`int32`|`ProtoField.int32`|4 bytes|Signed 32-bit integer|
76
- |`int64`|`ProtoField.int64`|8 bytes|Signed 64-bit integer|
77
- |`float32`|`ProtoField.float`|4 bytes|IEEE 754 single precision|
78
- |`float64`|`ProtoField.double`|8 bytes|IEEE 754 double precision|
79
- |`bool`|`ProtoField.bool`|1 byte|Boolean value|
80
- |`bytes`|`ProtoField.bytes`|Variable|Raw byte array|
81
- |`string`|`ProtoField.string`|Variable|Text string|
67
+ | Oscura Type | Wireshark Type | Size | Notes |
68
+ | ----------- | ------------------- | -------- | ------------------------- |
69
+ | `uint8` | `ProtoField.uint8` | 1 byte | Unsigned 8-bit integer |
70
+ | `uint16` | `ProtoField.uint16` | 2 bytes | Unsigned 16-bit integer |
71
+ | `uint32` | `ProtoField.uint32` | 4 bytes | Unsigned 32-bit integer |
72
+ | `uint64` | `ProtoField.uint64` | 8 bytes | Unsigned 64-bit integer |
73
+ | `int8` | `ProtoField.int8` | 1 byte | Signed 8-bit integer |
74
+ | `int16` | `ProtoField.int16` | 2 bytes | Signed 16-bit integer |
75
+ | `int32` | `ProtoField.int32` | 4 bytes | Signed 32-bit integer |
76
+ | `int64` | `ProtoField.int64` | 8 bytes | Signed 64-bit integer |
77
+ | `float32` | `ProtoField.float` | 4 bytes | IEEE 754 single precision |
78
+ | `float64` | `ProtoField.double` | 8 bytes | IEEE 754 double precision |
79
+ | `bool` | `ProtoField.bool` | 1 byte | Boolean value |
80
+ | `bytes` | `ProtoField.bytes` | Variable | Raw byte array |
81
+ | `string` | `ProtoField.string` | Variable | Text string |
82
82
 
83
83
  ## Display Bases
84
84
 
@@ -263,52 +263,6 @@ def export_protocol_decode(
263
263
  json.dump(output, f, cls=OscuraJSONEncoder)
264
264
 
265
265
 
266
- def export_vintage_logic_json(
267
- result: Any,
268
- path: str | Path,
269
- *,
270
- indent: int = 2,
271
- include_metadata: bool = True,
272
- ) -> None:
273
- """Export vintage logic analysis results to JSON.
274
-
275
- Convenience function for exporting VintageLogicAnalysisResult objects.
276
- The dataclass is automatically serialized to JSON with all nested objects.
277
-
278
- Args:
279
- result: VintageLogicAnalysisResult object.
280
- path: Output JSON file path.
281
- indent: Indentation level for pretty printing (default: 2).
282
- include_metadata: Include export metadata (default: True).
283
-
284
- Example:
285
- >>> from oscura.analyzers.digital.vintage import analyze_vintage_logic
286
- >>> result = analyze_vintage_logic(traces)
287
- >>> export_vintage_logic_json(result, "analysis_results.json")
288
- """
289
- path = Path(path)
290
-
291
- output: dict[str, Any] = {}
292
-
293
- if include_metadata:
294
- output["_metadata"] = {
295
- "format": "oscura_vintage_logic",
296
- "version": "1.0",
297
- "exported_at": datetime.now().isoformat(),
298
- "analysis_timestamp": result.timestamp.isoformat(),
299
- }
300
-
301
- output["analysis_result"] = result
302
-
303
- # Sanitize to handle inf/nan
304
- from oscura.reporting.output import _sanitize_for_serialization
305
-
306
- output = _sanitize_for_serialization(output)
307
-
308
- with open(path, "w") as f:
309
- json.dump(output, f, cls=OscuraJSONEncoder, indent=indent)
310
-
311
-
312
266
  def load_json(path: str | Path) -> dict[str, Any]:
313
267
  """Load JSON data file.
314
268
 
@@ -333,6 +287,5 @@ __all__ = [
333
287
  "export_json",
334
288
  "export_measurements",
335
289
  "export_protocol_decode",
336
- "export_vintage_logic_json",
337
290
  "load_json",
338
291
  ]
@@ -140,13 +140,13 @@ Information and Computation, 75(2), 87-106.
140
140
 
141
141
  ## Comparison with RPNI
142
142
 
143
- |Feature|L\* (Active)|RPNI (Passive)|
144
- |---|---|---|---|---|---|---|
145
- |Learning type|Active (queries oracle)|Passive (fixed dataset)|
146
- |Minimal DFA|Yes|No (may have extra states)|
147
- |Negative examples|Not required|Optional|
148
- |Live learning|Yes|No|
149
- |Query complexity|O(|Q|²|Σ|)|N/A|## See Also
143
+ | Feature | L\* (Active) | RPNI (Passive) |
144
+ | ----------------- | ----------------------- | -------------------------- | --- | --- | --- | --- | ----------- |
145
+ | Learning type | Active (queries oracle) | Passive (fixed dataset) |
146
+ | Minimal DFA | Yes | No (may have extra states) |
147
+ | Negative examples | Not required | Optional |
148
+ | Live learning | Yes | No |
149
+ | Query complexity | O( | Q | ² | Σ | ) | N/A | ## See Also |
150
150
 
151
151
  - `oscura.inference.state_machine`: RPNI passive learning
152
152
  - `examples/lstar_demo.py`: Complete usage examples
@@ -60,8 +60,16 @@ def compose(*funcs: TraceFunc) -> TraceFunc:
60
60
  # Apply functions in reverse order (right to left)
61
61
  return reduce(lambda val, func: func(val), reversed(funcs), x)
62
62
 
63
- # Preserve function metadata
64
- composed.__name__ = "compose(" + ", ".join(f.__name__ for f in funcs) + ")"
63
+ # Preserve function metadata (handle functools.partial which lacks __name__)
64
+ func_names = []
65
+ for f in funcs:
66
+ if hasattr(f, "__name__"):
67
+ func_names.append(f.__name__)
68
+ elif hasattr(f, "func"): # functools.partial
69
+ func_names.append(f.func.__name__)
70
+ else:
71
+ func_names.append(repr(f))
72
+ composed.__name__ = "compose(" + ", ".join(func_names) + ")"
65
73
  composed.__doc__ = f"Composition of {len(funcs)} functions"
66
74
 
67
75
  return composed
@@ -138,10 +138,6 @@ from oscura.reporting.template_system import (
138
138
  list_templates,
139
139
  load_template,
140
140
  )
141
- from oscura.reporting.vintage_logic_report import (
142
- VintageLogicReport,
143
- generate_vintage_logic_report,
144
- )
145
141
 
146
142
  __all__ = [
147
143
  # Comprehensive Analysis Report API (CAR-001 through CAR-007)
@@ -191,8 +187,6 @@ __all__ = [
191
187
  "TemplateEngine",
192
188
  "TemplateSection",
193
189
  "UnsupportedFormatError",
194
- # Vintage Logic Reporting
195
- "VintageLogicReport",
196
190
  "VisualEmphasis",
197
191
  "aggregate_batch_measurements",
198
192
  "analyze",
@@ -241,7 +235,6 @@ __all__ = [
241
235
  "generate_presentation_from_report",
242
236
  "generate_report",
243
237
  "generate_summary",
244
- "generate_vintage_logic_report",
245
238
  "get_available_analyses",
246
239
  "get_axis_scaling",
247
240
  "list_templates",
@@ -2,22 +2,22 @@
2
2
 
3
3
  ## Report Metadata
4
4
 
5
- |Field|Value|
6
- |---|---|
7
- |**Input File**|{{input_name}}|
8
- |**File Size**|{{input_size}}|
9
- |**Input Type**|{{input_type}}|
10
- |**Generated**|{{timestamp}}|
11
- |**Analysis Duration**|{{duration}}|
5
+ | Field | Value |
6
+ | --------------------- | -------------- |
7
+ | **Input File** | {{input_name}} |
8
+ | **File Size** | {{input_size}} |
9
+ | **Input Type** | {{input_type}} |
10
+ | **Generated** | {{timestamp}} |
11
+ | **Analysis Duration** | {{duration}} |
12
12
 
13
13
  ## Analysis Summary
14
14
 
15
- |Metric|Count|
16
- |---|---|
17
- |Total Analyses|{{total_analyses}}|
18
- |Successful|{{successful}}|
19
- |Failed|{{failed}}|
20
- |Analysis Domains|{{domains_count}}|
15
+ | Metric | Count |
16
+ | ---------------- | ------------------ |
17
+ | Total Analyses | {{total_analyses}} |
18
+ | Successful | {{successful}} |
19
+ | Failed | {{failed}} |
20
+ | Analysis Domains | {{domains_count}} |
21
21
 
22
22
  {{#if has_errors}}
23
23
 
@@ -0,0 +1,322 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://oscura.io/schemas/bus_configuration.json",
4
+ "title": "Bus Configuration Schema",
5
+ "description": "Schema for validating parallel bus configurations for multi-bit protocols (CFG-001).",
6
+ "type": "object",
7
+ "required": ["name", "settings"],
8
+ "additionalProperties": true,
9
+ "properties": {
10
+ "name": {
11
+ "type": "string",
12
+ "description": "Bus configuration identifier",
13
+ "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$",
14
+ "minLength": 1
15
+ },
16
+ "version": {
17
+ "type": "string",
18
+ "description": "Configuration version",
19
+ "pattern": "^\\d+\\.\\d+$"
20
+ },
21
+ "description": {
22
+ "type": "string",
23
+ "description": "Human-readable description"
24
+ },
25
+ "settings": {
26
+ "type": "object",
27
+ "description": "Global bus settings",
28
+ "properties": {
29
+ "active_low": {
30
+ "type": "boolean",
31
+ "description": "Signals are active-low (inverted)"
32
+ },
33
+ "sample_on": {
34
+ "type": "string",
35
+ "enum": ["rising", "falling", "both"],
36
+ "description": "Sample on clock/timing pulse edge"
37
+ },
38
+ "bit_numbering": {
39
+ "type": "string",
40
+ "enum": ["lsb_0", "msb_0"],
41
+ "description": "Bit numbering convention"
42
+ }
43
+ },
44
+ "additionalProperties": false
45
+ },
46
+ "data_bus": {
47
+ "type": "object",
48
+ "description": "Data bus definition",
49
+ "required": ["name", "width", "bits"],
50
+ "properties": {
51
+ "name": {
52
+ "type": "string",
53
+ "description": "Bus name",
54
+ "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$"
55
+ },
56
+ "width": {
57
+ "type": "integer",
58
+ "minimum": 1,
59
+ "maximum": 128,
60
+ "description": "Bus width in bits"
61
+ },
62
+ "description": {
63
+ "type": "string",
64
+ "description": "Bus description"
65
+ },
66
+ "active_low": {
67
+ "type": "boolean",
68
+ "description": "Override global active_low setting"
69
+ },
70
+ "bits": {
71
+ "type": "array",
72
+ "description": "Bit mappings from channel to position",
73
+ "minItems": 1,
74
+ "items": {
75
+ "type": "object",
76
+ "required": ["channel", "bit"],
77
+ "properties": {
78
+ "channel": {
79
+ "type": "integer",
80
+ "minimum": 0,
81
+ "description": "Source channel index"
82
+ },
83
+ "bit": {
84
+ "type": "integer",
85
+ "minimum": 0,
86
+ "description": "Bit position in bus"
87
+ },
88
+ "name": {
89
+ "type": "string",
90
+ "description": "Signal name",
91
+ "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$"
92
+ }
93
+ },
94
+ "additionalProperties": false
95
+ }
96
+ }
97
+ },
98
+ "additionalProperties": false
99
+ },
100
+ "address_bus": {
101
+ "type": "object",
102
+ "description": "Address bus definition",
103
+ "required": ["name", "width", "bits"],
104
+ "properties": {
105
+ "name": {
106
+ "type": "string",
107
+ "description": "Bus name",
108
+ "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$"
109
+ },
110
+ "width": {
111
+ "type": "integer",
112
+ "minimum": 1,
113
+ "maximum": 128,
114
+ "description": "Bus width in bits"
115
+ },
116
+ "description": {
117
+ "type": "string",
118
+ "description": "Bus description"
119
+ },
120
+ "active_low": {
121
+ "type": "boolean",
122
+ "description": "Override global active_low setting"
123
+ },
124
+ "bits": {
125
+ "type": "array",
126
+ "description": "Bit mappings from channel to position",
127
+ "minItems": 1,
128
+ "items": {
129
+ "type": "object",
130
+ "required": ["channel", "bit"],
131
+ "properties": {
132
+ "channel": {
133
+ "type": "integer",
134
+ "minimum": 0,
135
+ "description": "Source channel index"
136
+ },
137
+ "bit": {
138
+ "type": "integer",
139
+ "minimum": 0,
140
+ "description": "Bit position in bus"
141
+ },
142
+ "name": {
143
+ "type": "string",
144
+ "description": "Signal name",
145
+ "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$"
146
+ }
147
+ },
148
+ "additionalProperties": false
149
+ }
150
+ }
151
+ },
152
+ "additionalProperties": false
153
+ },
154
+ "control_signals": {
155
+ "type": "array",
156
+ "description": "Control signal definitions",
157
+ "items": {
158
+ "type": "object",
159
+ "required": ["name", "channel"],
160
+ "properties": {
161
+ "name": {
162
+ "type": "string",
163
+ "description": "Signal name",
164
+ "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$"
165
+ },
166
+ "channel": {
167
+ "type": "integer",
168
+ "minimum": 0,
169
+ "description": "Source channel index"
170
+ },
171
+ "active_low": {
172
+ "type": "boolean",
173
+ "description": "Signal is active-low"
174
+ },
175
+ "description": {
176
+ "type": "string",
177
+ "description": "Signal description"
178
+ },
179
+ "short_name": {
180
+ "type": "string",
181
+ "description": "Short name/abbreviation",
182
+ "maxLength": 8
183
+ }
184
+ },
185
+ "additionalProperties": false
186
+ }
187
+ },
188
+ "timing": {
189
+ "type": "object",
190
+ "description": "Timing constraints and validation",
191
+ "properties": {
192
+ "clock_period_ns": {
193
+ "type": "number",
194
+ "exclusiveMinimum": 0,
195
+ "description": "Clock period in nanoseconds"
196
+ },
197
+ "setup_time_ns": {
198
+ "type": "number",
199
+ "minimum": 0,
200
+ "description": "Setup time requirement in nanoseconds"
201
+ },
202
+ "hold_time_ns": {
203
+ "type": "number",
204
+ "minimum": 0,
205
+ "description": "Hold time requirement in nanoseconds"
206
+ },
207
+ "pulse_width_ns": {
208
+ "type": "object",
209
+ "description": "Pulse width requirements by signal type",
210
+ "additionalProperties": {
211
+ "type": "number",
212
+ "minimum": 0
213
+ }
214
+ }
215
+ },
216
+ "additionalProperties": false
217
+ },
218
+ "transactions": {
219
+ "type": "object",
220
+ "description": "Transaction decoding rules",
221
+ "properties": {
222
+ "types": {
223
+ "type": "array",
224
+ "description": "Transaction type definitions",
225
+ "items": {
226
+ "type": "object",
227
+ "required": ["name", "conditions"],
228
+ "properties": {
229
+ "name": {
230
+ "type": "string",
231
+ "description": "Transaction type name",
232
+ "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$"
233
+ },
234
+ "conditions": {
235
+ "type": "object",
236
+ "description": "Signal conditions for this transaction",
237
+ "additionalProperties": {
238
+ "type": "boolean"
239
+ }
240
+ },
241
+ "sample_on": {
242
+ "type": "string",
243
+ "description": "Control signal to sample on"
244
+ },
245
+ "capture": {
246
+ "type": "object",
247
+ "description": "Buses/signals to capture",
248
+ "additionalProperties": {
249
+ "type": "string"
250
+ }
251
+ }
252
+ },
253
+ "additionalProperties": false
254
+ }
255
+ }
256
+ },
257
+ "additionalProperties": false
258
+ },
259
+ "instruction_decode": {
260
+ "type": "object",
261
+ "description": "Instruction decoding (if data contains opcodes)",
262
+ "properties": {
263
+ "enabled": {
264
+ "type": "boolean",
265
+ "description": "Enable instruction decoding"
266
+ },
267
+ "opcode_bits": {
268
+ "type": "array",
269
+ "description": "Bit range for opcode [start, end]",
270
+ "items": { "type": "integer", "minimum": 0 },
271
+ "minItems": 2,
272
+ "maxItems": 2
273
+ },
274
+ "opcodes": {
275
+ "type": "object",
276
+ "description": "Opcode to instruction mappings (keys can be integers or binary/hex strings)",
277
+ "additionalProperties": {
278
+ "type": "object",
279
+ "required": ["name"],
280
+ "properties": {
281
+ "name": {
282
+ "type": "string",
283
+ "description": "Instruction mnemonic"
284
+ },
285
+ "description": {
286
+ "type": "string",
287
+ "description": "Instruction description"
288
+ }
289
+ },
290
+ "additionalProperties": false
291
+ }
292
+ }
293
+ },
294
+ "additionalProperties": false
295
+ },
296
+ "output": {
297
+ "type": "object",
298
+ "description": "Output formatting options",
299
+ "properties": {
300
+ "format": {
301
+ "type": "string",
302
+ "enum": ["raw", "transaction", "annotated"],
303
+ "description": "Output format type"
304
+ },
305
+ "timestamp_format": {
306
+ "type": "string",
307
+ "enum": ["absolute", "relative_us", "relative_ns", "sample_index"],
308
+ "description": "Timestamp format"
309
+ },
310
+ "include_raw_values": {
311
+ "type": "boolean",
312
+ "description": "Include raw values in output"
313
+ },
314
+ "hex_format": {
315
+ "type": "boolean",
316
+ "description": "Display values in hexadecimal"
317
+ }
318
+ },
319
+ "additionalProperties": false
320
+ }
321
+ }
322
+ }