diff --git a/artifacts/README.md b/artifacts/README.md new file mode 100644 index 000000000..481e8916b --- /dev/null +++ b/artifacts/README.md @@ -0,0 +1,70 @@ +# Session artifacts + +Unrelated to `normalize.css` itself. These files were produced in a +Claude Code session whose harness pinned the working branch to this +repository; they're the deliverables of that session's work on a +separate project and live here only because this was the one repo +the sandbox could push to. + +## Current state: M1.1 committed (.NET 10 upgrade) + +- `bench-mercedes-m1.1.bundle` — **latest, full history (M0 + M1 + M1.1).** + Three commits: M0 scaffold, M1 DoIP+UDS+DTC work, M1.1 .NET 10 upgrade. + Use this for a fresh import. +- `bench-mercedes-m1-to-m1.1.bundle` — incremental, M1.1 commit only. + Use this if you already pushed M0+M1 to your GitHub repo and just + want to add the upgrade commit. + +### Already pushed M0+M1 to GitHub (your case right now) + +From your local `Bench-mercedes` checkout on your Mac: + +```bash +cd ~/path/to/Bench-mercedes +git pull /path/to/artifacts/bench-mercedes-m1-to-m1.1.bundle main +git push origin main +``` + +Then rerun the build from the repo root: + +```bash +dotnet restore +dotnet build +dotnet test +dotnet run --project src/MercedesDiag.App +``` + +The SDK-version error should be gone — the project now targets +`net10.0` and drops the `global.json` pin, so your installed +`10.0.202` SDK will be picked up automatically. + +### Fresh import (empty Bench-mercedes repo) + +```bash +git clone artifacts/bench-mercedes-m1.1.bundle Bench-mercedes +cd Bench-mercedes +git remote set-url origin https://github.com/rohite1983/Bench-mercedes.git +git push -u origin main +``` + +## Historical + +- `bench-mercedes-m1.bundle` / `bench-mercedes-m1.tar.gz` — M0+M1 + snapshot (pre .NET 10 upgrade). Kept for reference. +- `bench-mercedes-m0-to-m1.bundle` — incremental M1 commit on top + of M0. Kept for reference. +- `bench-mercedes-m0.bundle` / `bench-mercedes-m0.tar.gz` — the + original M0 scaffold. Prefer the M1.1 bundles above. + +## After import: verify on your machine + +```bash +dotnet restore +dotnet build +dotnet test +dotnet run --project src/MercedesDiag.App +``` + +You should see the Avalonia window open with connection fields, +an ECU dropdown, and empty DTC grid. If `dotnet build` fails, paste +the errors into the next session and I'll fix them. diff --git a/artifacts/SESSION_STATE.md b/artifacts/SESSION_STATE.md new file mode 100644 index 000000000..a9d16f55c --- /dev/null +++ b/artifacts/SESSION_STATE.md @@ -0,0 +1,196 @@ +# Session state — resume here next time + +## Where we are — M2.9 shipped (J2534 device auto-discovery via registry) + +- **Scratch repo**: `/tmp/bench-mercedes` (rebuilt each sandbox session + from the latest cumulative bundle — commits are unsigned there, see + signing note at the bottom). +- **Delivery branch on this repo**: `claude/clarify-project-requirements-Qz5IO`. + Each increment lands here as a `bench-mercedes-mX.Y-to-mX.Z.bundle` + in `/artifacts/`. +- **User's real repo**: `https://github.com/rohite1983/Bench-mercedes` + (private) on his Mac at `/Users/mohammedouchrif/Bench-mercedes`. +- **Plan file**: `docs/mercedes-diag-plan.md` on this branch. +- **Hard out-of-scope** (do not drift): anti-theft/VIN-lock write on + head units; redistribution of Mercedes proprietary files; SCN. + +## Milestone timeline shipped so far + +| Commit | Label | What it did | +|---------|--------|-----------------------------------------------------------| +| 31a4bc6 | M0 | Avalonia solution scaffold | +| 7d6da3b | M1 | DoIP transport + UDS services + DTC UI | +| 43edd0b | M1.1 | Upgrade to .NET 10 | +| 6577c0b | M1.2 | Fix NuGet build failures on .NET 10 | +| 571b5b1 | M1.3 | Satisfy .NET 10 IDE style rules in build | +| 2954c03 | M1.4 | Drop unused MercedesDiag.Transport using | +| 8b5b090 | M1.5 | Fix Avalonia 11.2 XAML (no ColumnSpacing/RowSpacing) | +| 1024256 | M2.0 | ISO-TP (ISO 15765-2) channel implementation | +| a1d6bca | M1.6 | Expand ECU catalog + custom target address | +| 713d67e | M2.1 | Fix ISO-TP CS4007 (ReadOnlyMemory across awaits) | +| 7c0b04f | M2.2 | Drop unused Hal using in IsoTpChannelTests | +| 20881c6 | M2.3 | KWP2000 client (ISO 14230) + 11 KWP tests | +| 0495c83 | M2.4 | Adapter + protocol selector UI, transport generalization | +| d290c84 | M2.5 | Adapter auto-probe, ECU bus discovery, named custom, UI polish | +| 033f39e | M2.6 | Real PCAN-USB P/Invoke backend (Windows + Linux) | +| 2210555 | M2.6f | Fix CS0246 missing `using MercedesDiag.Hal` for IDoipAdapter | +| 932e9ba | M2.7 | Auto-detect DoIP vehicle + hide transport details behind Advanced expander | +| 4bfe0f8 | M2.8 | Real J2534 P/Invoke backend (Windows-only) | +| bac8ace | M2.9 | Auto-discover installed J2534 PassThru devices via registry | +| 4b99028 | M2.9f | Drop Microsoft.Win32.Registry pkg (NU1510 — framework now provides it) | + +## What M2.7 added (UI simplification + DoIP auto-discovery) + +- **DoIP vehicle detect** — a 'Detect vehicle' button (visible only for + DoIP transport) calls `DoipDiscovery.DiscoverAsync` which broadcasts + a UDP VehicleIdentificationRequest and waits 3 s for a + VehicleAnnouncement. On success the vehicle IP/port and VIN are + auto-populated into the settings fields; a small `DetectedVin` line + shows under the transport summary. +- **Advanced expander** — all the 'inner plumbing' fields (vehicle IP, + DoIP port, logical tester/ECU addresses, CAN bitrate, PCAN channel, + CAN TX/RX IDs, J2534 DLL path, SDconnect host) moved inside an + `` that starts + collapsed. The default view now shows only: Adapter → Re-probe → + one-line `TransportSummary` → Detect button (DoIP) → Protocol → + Target ECU + Scan bus → Custom target → Connect → VIN. +- **`TransportSummary` computed property** in MainWindowViewModel with + `[NotifyPropertyChangedFor]` on every transport field so the summary + auto-refreshes when the user tweaks Advanced. + +## What M2.9 added (J2534 device auto-discovery) + +- User reported that with Tactrix OpenPort 2.0 installed on the Windows + PC, the app still prompted for a DLL path — which is the wrong UX. + The J2534-04 spec standardises the registry location for PassThru + DLLs, so all compliant vendors (Tactrix, PEAK, DrewTech Mongoose, + Mongoose Plus, CarDAQ, etc.) can be enumerated without user input. +- **`src/MercedesDiag.Hal/J2534/J2534DeviceEnumerator.cs`** — reads + `HKLM\SOFTWARE\PassThruSupport.04.04` in both `RegistryView.Registry64` + and `RegistryView.Registry32` so a 64-bit host still sees the + typically 32-bit-registered vendor DLLs. Returns a list of + `J2534Device(Name, Vendor, DllPath)`. Deduplicated by DLL path. + Platform-gated: returns empty on non-Windows. +- **`MercedesDiag.Hal.csproj`** — adds `Microsoft.Win32.Registry` + 5.0.0 (the ref-only package that exposes RegistryKey on net10.0). +- **`AdapterProbeService.ProbeJ2534`** — now reports e.g. + `2 PassThru device(s) found: Tactrix OpenPort 2.0 J2534, PEAK + PCAN-USB Pro FD`, or a clear install-your-driver message when empty. +- **`MainWindowViewModel`** — `J2534Devices` ObservableCollection, + `SelectedJ2534Device` with a partial `OnSelectedJ2534DeviceChanged` + that auto-sets `J2534DllPath`. `TryBuildSettings` falls back to + the selected device's DLL path if the override field is empty. + Re-probe refreshes both the transport probes and the J2534 device + list, keeping the previous device selected if still present. +- **`MainWindow.axaml`** — when J2534 is the current transport, a + top-level 'Device' dropdown shows installed PassThru devices. + If the registry has no entries, a short hint explains the user + can install a vendor driver or set the DLL manually in Advanced. + The Advanced DLL path field is relabelled '(override)' and + preceded by a hint so users know it's optional. + +## What M2.8 added (J2534 PassThru backend) + +- **`src/MercedesDiag.Hal/J2534/J2534Native.cs`** — J2534 P/Invoke + layer. Because the DLL path is user-supplied at runtime, + `[DllImport("…")]` won't work; instead `J2534Library` loads the DLL + with `NativeLibrary.Load(dllPath)` and binds each PassThru function + via `NativeLibrary.GetExport` + `Marshal.GetDelegateForFunctionPointer` + against `[UnmanagedFunctionPointer(CallingConvention.StdCall)]` + delegates: `PassThruOpen/Close/Connect/Disconnect/ReadMsgs/WriteMsgs/ + StartMsgFilter/StopMsgFilter/Ioctl/GetLastError`. Includes the + `PassThruMsg` struct (4128-byte inline `Data` via ByValArray), + protocol/flag/ioctl/filter-type enums, and + `J2534Errors.Describe(code)` mapping 0x00..0x1A to SAE-spec names. +- **`J2534Adapter.cs`** — replaces the throwing stub with a full + `ICanAdapter`. `OpenAsync` guards Windows-only, loads the DLL, calls + `PassThruOpen` → `PassThruConnect` on `Can` protocol at + `BitrateKbps*1000`, installs a pass-all filter (required before RX + flows), and starts a background pump reading into a bounded + `Channel(2048)` (DropOldest). `SendAsync` maps `CanFrame` + → `PassThruMsg` with the 29-bit TX flag and 4-byte big-endian ID + prefix. `CloseAsync` tears filter → channel → device down in order + and disposes the library. macOS/Linux throw `PlatformNotSupported` + up-front (no free PassThru DLLs outside Windows). + +## Next session — first actions + +User on his Mac (or Windows PC): +``` +cd ~/normalize.css && git pull origin claude/clarify-project-requirements-Qz5IO +cd /Users/mohammedouchrif/Bench-mercedes # (or the clone path on Windows) +git pull ~/normalize.css/artifacts/bench-mercedes-m2.8-to-m2.9.bundle main +git push origin main +dotnet restore && dotnet build && dotnet test +dotnet run --project src/MercedesDiag.App +``` + +(If behind M2.8, pull the previous bundles first in order: +`m2.3-to-m2.4`, `m2.4-to-m2.6`, `m2.6-to-m2.6fix`, +`m2.6fix-to-m2.8`, then this newest one.) + +Expected after pull: +- The top of the sidebar is much cleaner: Adapter → Re-probe → single + monospace `TransportSummary` line → Detect button (DoIP only) → + Protocol → Target ECU → Connect. +- 'Detect vehicle' (DoIP) broadcasts a VIR, populates the vehicle + IP/port and VIN from the car's announcement within ~3 s. +- All IP/port/CAN/PCAN/J2534 fine-tuning lives in the collapsed + 'Advanced (manual overrides)' expander. +- J2534: pointing the Advanced-expander 'J2534 DLL' field at a real + vendor PassThru DLL on Windows (e.g. PEAK, Tactrix OpenPort 2.0, + DrewTech Mongoose) + setting bitrate + IDs now actually opens the + device, connects CAN, installs a pass filter, and sends/receives + frames. macOS shows the J2534 option as unavailable. +- 32 tests still passing (no new unit tests in M2.7/M2.8 — both + benefit most from live hardware integration tests; unit coverage + for platform-gated backends lands later). + +## Next milestone — M3 (live data + YAML coding) + +- `src/MercedesDiag.Coding/Yaml/UserYamlProvider.cs` — user-supplied + YAML coding definitions (`ecuName → did → bit/byte → featureName`). +- Periodic DID polling task with a live graph/gauge view in the UI. +- Coding tree UI (read-only values first; writes land in M4 behind a + mandatory backup). + +## Then — M4 (coding writes) and beyond + +- `CodingWriteSafety` — every `0x2E WriteDataByIdentifier` preceded + by a `0x22` read that gets persisted to a JSON backup file in the + same session; one-click restore. +- Security access framework with pluggable seed/key from user-loaded + DLLs/scripts. +- M5: `.aed` provider. M6: C3/C4 MUX passthrough + partial CBF reader. + +## Open items + +- Sandbox scope for `rohite1983/Bench-mercedes` still not granted, + so the bundle workflow continues. +- `TransportSummary`'s DoIP line falls back to the default IP/port + if Detect was never run — that's intentional; the Detect button + is the auto path and manual fields in Advanced are the fallback. +- No unit tests yet for `AdapterProbeService`, `EcuDiscoveryService`, + `PcanAdapter`, `J2534Adapter`, `DoipDiscovery`. All four gain the + most value from real-hardware integration tests; simulator-backed + unit tests can still be added on demand (e.g. fake `J2534Library`). +- UI language: English only; revisit multi-language in M3/M4. + +## Known caveats still unresolved + +- DoIP response-pending handling loops inside the outer timeout + without bounding pending-count. +- `ReadDtcs` unconditionally enters extended session; some ECUs + reject. Will add default-session fallback once we hit one. +- No security-access UI; API exists, UI lands M4. +- SDconnect remains unimplemented and will stay so until a real + user need surfaces. +- J2534 backend is raw-CAN only (no KWP on K-line, no J1850). Fine + for every Mercedes use case we target (all are CAN or DoIP). + +## Sandbox signing note + +Commits in the scratch repo at `/tmp/bench-mercedes` are unsigned +because the sandbox signing server rejects writes from that path +(`missing source`). Every M0..M2.8 commit follows the same pattern. +Signatures re-apply when the user pushes from his Mac. diff --git a/artifacts/bench-mercedes-m0-to-m1.bundle b/artifacts/bench-mercedes-m0-to-m1.bundle new file mode 100644 index 000000000..e0301062c Binary files /dev/null and b/artifacts/bench-mercedes-m0-to-m1.bundle differ diff --git a/artifacts/bench-mercedes-m0.bundle b/artifacts/bench-mercedes-m0.bundle new file mode 100644 index 000000000..e72957013 Binary files /dev/null and b/artifacts/bench-mercedes-m0.bundle differ diff --git a/artifacts/bench-mercedes-m0.tar.gz b/artifacts/bench-mercedes-m0.tar.gz new file mode 100644 index 000000000..205d227c9 Binary files /dev/null and b/artifacts/bench-mercedes-m0.tar.gz differ diff --git a/artifacts/bench-mercedes-m1-to-m1.1.bundle b/artifacts/bench-mercedes-m1-to-m1.1.bundle new file mode 100644 index 000000000..ba1021170 Binary files /dev/null and b/artifacts/bench-mercedes-m1-to-m1.1.bundle differ diff --git a/artifacts/bench-mercedes-m1.1-to-m1.2.bundle b/artifacts/bench-mercedes-m1.1-to-m1.2.bundle new file mode 100644 index 000000000..2bf85260a Binary files /dev/null and b/artifacts/bench-mercedes-m1.1-to-m1.2.bundle differ diff --git a/artifacts/bench-mercedes-m1.1.bundle b/artifacts/bench-mercedes-m1.1.bundle new file mode 100644 index 000000000..ae7b6f378 Binary files /dev/null and b/artifacts/bench-mercedes-m1.1.bundle differ diff --git a/artifacts/bench-mercedes-m1.2-to-m1.3.bundle b/artifacts/bench-mercedes-m1.2-to-m1.3.bundle new file mode 100644 index 000000000..fc3296800 Binary files /dev/null and b/artifacts/bench-mercedes-m1.2-to-m1.3.bundle differ diff --git a/artifacts/bench-mercedes-m1.3-to-m1.4.bundle b/artifacts/bench-mercedes-m1.3-to-m1.4.bundle new file mode 100644 index 000000000..5a3af13a4 Binary files /dev/null and b/artifacts/bench-mercedes-m1.3-to-m1.4.bundle differ diff --git a/artifacts/bench-mercedes-m1.4-to-m1.5.bundle b/artifacts/bench-mercedes-m1.4-to-m1.5.bundle new file mode 100644 index 000000000..bc1fb64ce Binary files /dev/null and b/artifacts/bench-mercedes-m1.4-to-m1.5.bundle differ diff --git a/artifacts/bench-mercedes-m1.5-to-m2.0.bundle b/artifacts/bench-mercedes-m1.5-to-m2.0.bundle new file mode 100644 index 000000000..61916c37e Binary files /dev/null and b/artifacts/bench-mercedes-m1.5-to-m2.0.bundle differ diff --git a/artifacts/bench-mercedes-m1.6-to-m2.1fix.bundle b/artifacts/bench-mercedes-m1.6-to-m2.1fix.bundle new file mode 100644 index 000000000..08729f1f1 Binary files /dev/null and b/artifacts/bench-mercedes-m1.6-to-m2.1fix.bundle differ diff --git a/artifacts/bench-mercedes-m1.bundle b/artifacts/bench-mercedes-m1.bundle new file mode 100644 index 000000000..0d7d8b8c5 Binary files /dev/null and b/artifacts/bench-mercedes-m1.bundle differ diff --git a/artifacts/bench-mercedes-m1.tar.gz b/artifacts/bench-mercedes-m1.tar.gz new file mode 100644 index 000000000..9d7a19c42 Binary files /dev/null and b/artifacts/bench-mercedes-m1.tar.gz differ diff --git a/artifacts/bench-mercedes-m2.0-to-m1.6.bundle b/artifacts/bench-mercedes-m2.0-to-m1.6.bundle new file mode 100644 index 000000000..c805b333b Binary files /dev/null and b/artifacts/bench-mercedes-m2.0-to-m1.6.bundle differ diff --git a/artifacts/bench-mercedes-m2.10-to-m2.11.bundle b/artifacts/bench-mercedes-m2.10-to-m2.11.bundle new file mode 100644 index 000000000..f9a752c95 Binary files /dev/null and b/artifacts/bench-mercedes-m2.10-to-m2.11.bundle differ diff --git a/artifacts/bench-mercedes-m2.11-to-m2.12.bundle b/artifacts/bench-mercedes-m2.11-to-m2.12.bundle new file mode 100644 index 000000000..307ba4ce7 Binary files /dev/null and b/artifacts/bench-mercedes-m2.11-to-m2.12.bundle differ diff --git a/artifacts/bench-mercedes-m2.12-to-m2.13.bundle b/artifacts/bench-mercedes-m2.12-to-m2.13.bundle new file mode 100644 index 000000000..4fde090fb Binary files /dev/null and b/artifacts/bench-mercedes-m2.12-to-m2.13.bundle differ diff --git a/artifacts/bench-mercedes-m2.13-to-m2.13fix.bundle b/artifacts/bench-mercedes-m2.13-to-m2.13fix.bundle new file mode 100644 index 000000000..76d2cc12d Binary files /dev/null and b/artifacts/bench-mercedes-m2.13-to-m2.13fix.bundle differ diff --git a/artifacts/bench-mercedes-m2.13fix-to-m2.14.bundle b/artifacts/bench-mercedes-m2.13fix-to-m2.14.bundle new file mode 100644 index 000000000..2c8ad6075 Binary files /dev/null and b/artifacts/bench-mercedes-m2.13fix-to-m2.14.bundle differ diff --git a/artifacts/bench-mercedes-m2.14-to-m3.0.bundle b/artifacts/bench-mercedes-m2.14-to-m3.0.bundle new file mode 100644 index 000000000..a019c259a Binary files /dev/null and b/artifacts/bench-mercedes-m2.14-to-m3.0.bundle differ diff --git a/artifacts/bench-mercedes-m2.1fix-to-m2.2fix.bundle b/artifacts/bench-mercedes-m2.1fix-to-m2.2fix.bundle new file mode 100644 index 000000000..6514492bb Binary files /dev/null and b/artifacts/bench-mercedes-m2.1fix-to-m2.2fix.bundle differ diff --git a/artifacts/bench-mercedes-m2.2fix-to-m2.3.bundle b/artifacts/bench-mercedes-m2.2fix-to-m2.3.bundle new file mode 100644 index 000000000..f3d59e6e1 Binary files /dev/null and b/artifacts/bench-mercedes-m2.2fix-to-m2.3.bundle differ diff --git a/artifacts/bench-mercedes-m2.3-to-m2.4.bundle b/artifacts/bench-mercedes-m2.3-to-m2.4.bundle new file mode 100644 index 000000000..1a03a65c3 Binary files /dev/null and b/artifacts/bench-mercedes-m2.3-to-m2.4.bundle differ diff --git a/artifacts/bench-mercedes-m2.4-to-m2.6.bundle b/artifacts/bench-mercedes-m2.4-to-m2.6.bundle new file mode 100644 index 000000000..7f1dbef1c Binary files /dev/null and b/artifacts/bench-mercedes-m2.4-to-m2.6.bundle differ diff --git a/artifacts/bench-mercedes-m2.6-to-m2.6fix.bundle b/artifacts/bench-mercedes-m2.6-to-m2.6fix.bundle new file mode 100644 index 000000000..6184dd093 Binary files /dev/null and b/artifacts/bench-mercedes-m2.6-to-m2.6fix.bundle differ diff --git a/artifacts/bench-mercedes-m2.6fix-to-m2.8.bundle b/artifacts/bench-mercedes-m2.6fix-to-m2.8.bundle new file mode 100644 index 000000000..cd80e6428 Binary files /dev/null and b/artifacts/bench-mercedes-m2.6fix-to-m2.8.bundle differ diff --git a/artifacts/bench-mercedes-m2.8-to-m2.9.bundle b/artifacts/bench-mercedes-m2.8-to-m2.9.bundle new file mode 100644 index 000000000..f469ab907 Binary files /dev/null and b/artifacts/bench-mercedes-m2.8-to-m2.9.bundle differ diff --git a/artifacts/bench-mercedes-m2.9-to-m2.9fix.bundle b/artifacts/bench-mercedes-m2.9-to-m2.9fix.bundle new file mode 100644 index 000000000..1eafab667 Binary files /dev/null and b/artifacts/bench-mercedes-m2.9-to-m2.9fix.bundle differ diff --git a/artifacts/bench-mercedes-m2.9fix-to-m2.10.bundle b/artifacts/bench-mercedes-m2.9fix-to-m2.10.bundle new file mode 100644 index 000000000..fae0dcd50 Binary files /dev/null and b/artifacts/bench-mercedes-m2.9fix-to-m2.10.bundle differ diff --git a/artifacts/bench-mercedes-m3.0-to-m3.1.bundle b/artifacts/bench-mercedes-m3.0-to-m3.1.bundle new file mode 100644 index 000000000..d15ef1d92 Binary files /dev/null and b/artifacts/bench-mercedes-m3.0-to-m3.1.bundle differ diff --git a/artifacts/bench-mercedes-m3.1-to-m4.0.bundle b/artifacts/bench-mercedes-m3.1-to-m4.0.bundle new file mode 100644 index 000000000..3ede9efd4 Binary files /dev/null and b/artifacts/bench-mercedes-m3.1-to-m4.0.bundle differ diff --git a/artifacts/bench-mercedes-m4.0-to-m4.0fix.bundle b/artifacts/bench-mercedes-m4.0-to-m4.0fix.bundle new file mode 100644 index 000000000..f4072f68f Binary files /dev/null and b/artifacts/bench-mercedes-m4.0-to-m4.0fix.bundle differ diff --git a/artifacts/bench-mercedes-m4.0fix-to-m4.1.bundle b/artifacts/bench-mercedes-m4.0fix-to-m4.1.bundle new file mode 100644 index 000000000..c20db8e70 Binary files /dev/null and b/artifacts/bench-mercedes-m4.0fix-to-m4.1.bundle differ diff --git a/artifacts/bench-mercedes-m4.1-to-m4.2.bundle b/artifacts/bench-mercedes-m4.1-to-m4.2.bundle new file mode 100644 index 000000000..6ed59ba73 Binary files /dev/null and b/artifacts/bench-mercedes-m4.1-to-m4.2.bundle differ diff --git a/artifacts/bench-mercedes-m4.2-to-m4.3.bundle b/artifacts/bench-mercedes-m4.2-to-m4.3.bundle new file mode 100644 index 000000000..3fbb8ccab Binary files /dev/null and b/artifacts/bench-mercedes-m4.2-to-m4.3.bundle differ diff --git a/artifacts/bench-mercedes-m4.3-to-m4.4.bundle b/artifacts/bench-mercedes-m4.3-to-m4.4.bundle new file mode 100644 index 000000000..b46c3cec0 Binary files /dev/null and b/artifacts/bench-mercedes-m4.3-to-m4.4.bundle differ diff --git a/artifacts/bench-mercedes-m4.4-to-m4.5.bundle b/artifacts/bench-mercedes-m4.4-to-m4.5.bundle new file mode 100644 index 000000000..3f57b1a74 Binary files /dev/null and b/artifacts/bench-mercedes-m4.4-to-m4.5.bundle differ diff --git a/artifacts/bench-mercedes-m4.5-to-m4.6.bundle b/artifacts/bench-mercedes-m4.5-to-m4.6.bundle new file mode 100644 index 000000000..409fb68bf Binary files /dev/null and b/artifacts/bench-mercedes-m4.5-to-m4.6.bundle differ diff --git a/artifacts/bench-mercedes-m4.6-to-m5prep.bundle b/artifacts/bench-mercedes-m4.6-to-m5prep.bundle new file mode 100644 index 000000000..e051650ff Binary files /dev/null and b/artifacts/bench-mercedes-m4.6-to-m5prep.bundle differ diff --git a/artifacts/bench-mercedes-m5prep-to-m5prepfix.bundle b/artifacts/bench-mercedes-m5prep-to-m5prepfix.bundle new file mode 100644 index 000000000..ac1a01c30 Binary files /dev/null and b/artifacts/bench-mercedes-m5prep-to-m5prepfix.bundle differ diff --git a/docs/mercedes-diag-plan.md b/docs/mercedes-diag-plan.md new file mode 100644 index 000000000..58aeae77f --- /dev/null +++ b/docs/mercedes-diag-plan.md @@ -0,0 +1,221 @@ +# Mercedes Diagnostic & Coding Tool — Personal / Workshop Edition + +> **Note:** This document is unrelated to `normalize.css` itself. It was +> produced in a Claude Code session whose harness pinned the working +> branch to this repository; the content is the clarified requirements +> and architecture for a separate desktop application project the user +> is planning. It lives here only as a durable record of that session's +> deliverable. The actual project, when it starts, belongs in its own +> repository. + +## Context + +The user wants a Windows/macOS desktop application for Mercedes-Benz +diagnostics, variant coding, feature activation/deactivation, and "small +coding" — similar in spirit to MBTools, but scoped as a **personal / +workshop internal tool** for cars the user owns or services with the +owner's consent. Not redistributed, not sold. + +This scope was chosen after an earlier discussion ruled out a commercial +clone, because a commercial product would require redistributing Mercedes +proprietary coding artefacts (SMR-D, CBF, .aed) which are Daimler IP. +Personal/workshop use on the user's own machine with files the user +already has is a very different legal situation and is the path we're +taking. + +### Hard out-of-scope (will not implement, even in personal scope) + +- **Anti-theft / VIN-lock write or reset on Audio20 / COMAND / NTG + head units.** The dominant real-world use is reactivating stolen + units; not building this. +- **Redistributing Mercedes proprietary files** (SMR-D, CBF, .aed, + Xentry databases) inside the application binary or installer. + The app reads files the user already has locally. +- **SCN online coding** (requires Mercedes backend credentials and + cryptographic signatures — not feasible anyway). + +### In scope + +- Diagnostics: read/clear DTCs (with human-readable text where + available), live data / PIDs, freeze-frame, actuator/routine tests, + ECU identification, session & security access (seed/key where the + user has the algorithm). +- Small coding and feature enable/disable via writing Data + Identifiers (DIDs) — driven either by user-supplied maps or by + interpreting SMR-D / CBF / .aed files the user loads locally. +- Service functions (service reset, SBC/EPB, DPF regen where + documented, steering-angle calibration, etc.) on ECUs that accept + standard UDS routine controls. +- Target vehicles: both pre-2015 (K-line / CAN, KWP2000 + UDS) and + 2015+ (DoIP over Ethernet). + +## Tech stack (confirmed) + +- **Language/UI:** C# with **Avalonia UI 11** (cross-platform + Windows/macOS/Linux, native feel, modern MVVM via + CommunityToolkit.Mvvm). Rejected .NET MAUI for desktop because + Avalonia is more mature for Windows+macOS desktop today. +- **Runtime:** .NET 8 LTS. +- **DI / logging:** Microsoft.Extensions.Hosting, Serilog. +- **Testing:** xUnit + FluentAssertions; protocol layers tested with + recorded ISO-TP traces. +- **Packaging:** MSIX (Windows) and `.app` bundle via + `dotnet publish -r osx-arm64/osx-x64` with a notarised DMG. + +## Proposed solution architecture + +Layered, with each layer swappable and unit-testable in isolation. + +``` ++---------------------------------------------+ +| UI (Avalonia, MVVM) | MercedesDiag.App ++---------------------------------------------+ +| Application services (coding engine, | MercedesDiag.Services +| session orchestration, job queue) | ++---------------------------------------------+ +| Diagnostic protocol stack | MercedesDiag.Uds +| - UDS (ISO 14229) | MercedesDiag.Kwp +| - KWP2000 (ISO 14230) | +| - OBD-II mode 01-0A | ++---------------------------------------------+ +| Transport layer | MercedesDiag.Transport +| - ISO-TP (ISO 15765-2) over CAN | +| - DoIP (ISO 13400) over TCP/UDP | +| - K-line framing | ++---------------------------------------------+ +| Hardware abstraction (IAdapter) | MercedesDiag.Hal +| - ENET / DoIP (sockets, no driver) | +| - J2534 (P/Invoke into vendor DLL) | +| - PCAN-Basic (P/Invoke) | +| - SocketCAN (Linux only, future) | +| - ELM327 / STN (serial) - for bring-up | +| - C3/C4 MUX in passthrough mode | ++---------------------------------------------+ +``` + +`IAdapter` exposes a raw frame interface (send/receive 11/29-bit CAN +frames, or DoIP payloads). The ISO-TP / DoIP layer sits above and +presents a request/response API to the protocol stack. The protocol +stack never talks to hardware directly. + +### Coding engine + +A separate `MercedesDiag.Coding` assembly with pluggable +`ICodingProvider` implementations: + +1. **UserYamlProvider** — simplest; user writes YAML describing + `ecuName → did → bit/byte → featureName`. This is the "clean" + provider that needs no proprietary formats and is enough for many + everyday coding tasks. Build this first. +2. **AedProvider** — loads `.aed` files the user already has on disk + and exposes their options as a tree. Reader only; no files shipped. +3. **CbfProvider / SmrdProvider** — later milestones. These are + non-trivial (CBF is essentially a compiled ODX variant with its + own VM for seed/key and conversion functions). Start with a + partial reader for common opcodes; extend as real use demands. + +The UI never hard-codes ECU knowledge — it renders whatever the +coding provider produces. + +## Phased delivery + +**M0 — Project skeleton (1–2 days of work)** +- New git repo (a fresh repo e.g. `mercedes-diag`, *not* this one). +- Avalonia solution with the project layout above, CI building on + Windows + macOS, Serilog wired up, xUnit scaffolding. +- A "Hello ECU" screen that does nothing yet. + +**M1 — Talk to one car over ENET (DoIP)** +- Implement DoIP transport (vehicle identification, routing + activation, diagnostic message). +- Implement minimum UDS: `0x10` DiagnosticSessionControl, `0x22` + ReadDataByIdentifier, `0x27` SecurityAccess (no algorithms yet), + `0x19` ReadDTCInformation, `0x14` ClearDiagnosticInformation, + `0x11` ECUReset, `0x31` RoutineControl. +- UI: ECU list, connect, read identification, read DTCs, clear DTCs. +- Verified on a 2015+ Mercedes via OBD-II ENET cable. + +**M2 — Pre-2015 vehicles over CAN** +- PCAN adapter backend (P/Invoke to `PCANBasic.dll` / `libpcan`). +- ISO-TP implementation (single-frame, first-frame/consecutive-frame, + flow-control). +- KWP2000-on-CAN service mapping (many services are UDS-compatible; + a few like `0x1A` need a KWP-specific path). +- J2534 adapter backend (P/Invoke; Windows only for v1). + +**M3 — Live data & coding (read-only first)** +- Periodic DID polling with a graph/gauge view. +- Coding tree UI driven by `UserYamlProvider`. Read current values + and display them; do *not* write yet. +- Ship a small library of hand-written YAML for a few ECUs the user + confirms on their own cars. + +**M4 — Coding writes** +- `0x2E` WriteDataByIdentifier with a mandatory "confirm + backup" + flow: the app always reads and saves current DID values to a JSON + backup file before any write, and offers one-click restore. +- Security access framework: pluggable seed/key algorithms loaded + from user-supplied DLLs or scripts (not shipped). + +**M5 — .aed support** +- Loader for `.aed` files; render their option tree in the coding UI. +- Parity with the YAML provider on write/backup flow. + +**M6 — C3/C4 passthrough and extras** +- Treat the MUX as a CAN/K-line gateway over its network interface + (no proprietary protocol use). +- Optional SMR-D / CBF partial reader — only if real use demands it. + +## Critical files (to be created in the new repo) + +- `src/MercedesDiag.Hal/IAdapter.cs` — hardware abstraction +- `src/MercedesDiag.Hal/Doip/DoipAdapter.cs` +- `src/MercedesDiag.Hal/Pcan/PcanAdapter.cs` +- `src/MercedesDiag.Hal/J2534/J2534Adapter.cs` +- `src/MercedesDiag.Transport/IsoTp/IsoTpChannel.cs` +- `src/MercedesDiag.Transport/Doip/DoipChannel.cs` +- `src/MercedesDiag.Uds/UdsClient.cs` — high-level UDS service API +- `src/MercedesDiag.Coding/ICodingProvider.cs` +- `src/MercedesDiag.Coding/Yaml/UserYamlProvider.cs` +- `src/MercedesDiag.Coding/Aed/AedProvider.cs` +- `src/MercedesDiag.Services/DiagnosticSession.cs` +- `src/MercedesDiag.Services/CodingWriteSafety.cs` — backup & restore +- `src/MercedesDiag.App/` — Avalonia UI (Views, ViewModels) +- `tests/MercedesDiag.Uds.Tests/` — recorded-trace-driven tests +- `docs/SAFETY.md` — out-of-scope items (anti-theft, SCN) restated + in repo so future contributors / future-you don't drift + +## Libraries / tools to evaluate (not committed yet) + +- **Avalonia.ReactiveUI** vs **CommunityToolkit.Mvvm** — pick one. +- **PCAN-Basic.NET** (Peak official binding) for PCAN. +- **Any-J2534 wrappers**: there is no good open binding; we'll + P/Invoke the vendor DLL directly. +- **SharpPcap** — only if we later want to sniff DoIP on a lab PC. +- **YamlDotNet** — coding definitions. +- **MessagePack** — for backup file format. + +## Verification plan + +- **Unit tests**: ISO-TP, DoIP framing, UDS service encode/decode use + recorded binary traces as fixtures. Run in CI on every PR. +- **Integration tests** behind a `[Trait("Hardware","Real")]` gate, + run manually against a real ECU: connect over ENET, read VIN from + `0x22 0xF1 0x90`, read and clear a pending DTC, write-then-restore + a harmless DID (e.g. a user-configurable welcome string on a + non-critical ECU). +- **Safety test**: every write path must refuse to run unless a + backup file for that ECU's coding was written in the same session. + This is itself unit-tested. +- **Manual end-to-end**: on the user's own test vehicle, reproduce + a known coding change (e.g. enable/disable a convenience feature + the user has documented), verify behaviour, then restore. + +## Open items to resolve before starting M0 + +- Repo location: new GitHub repo name (e.g. `mercedes-diag`) and + visibility (private recommended for personal workshop use). +- Which ENET cable / J2534 device / PCAN model the user actually + has on the bench for M1 testing. +- Whether the user wants the UI in English only or multi-language + from day one (Arabic + French were hinted at).