Protocol deep-dive

KWP2000 vs UDS over DoIP.

E-series BMWs use KWP2000. F/G-series BMWs use UDS over DoIP. Beemuu supports both. This page explains the protocol stack, the framing, the segmentation, and the practical differences for the operator — what to expect from each path, what the failure modes are, and how to read what Beemuu is doing under the hood.

KWP2000 + UDSUpdated August 2026Project-local

The protocol stack

BMW diagnostic communication is layered. Beemuu uses the same model for both KWP2000 and UDS paths:

LayerKWP2000 path (E-series)UDS path (F/G-series)
TransportUSB → serial → FTDI → K+DCAN cable → OBD-II socketUSB / Ethernet → RJ45 → ENET cable → OBD-II socket
PhysicalCAN bus (D-CAN, 500 kbit/s) or K-line (10.4 kbit/s)Automotive Ethernet (100 Mbit/s)
DiscoveryBeemuu probes known module addressesUDP broadcast on port 13400 (still not implemented in project)
SegmentationNot needed (single-frame requests)ISO-TP (CAN path) or DoIP framing (Ethernet path)
Service layerKWP2000 (startDiagnosticSession, readDataByLocalIdentifier, etc.)UDS (DiagnosticSessionControl, ReadDataByIdentifier, etc.)
ApplicationBeemuu’s protocol helpers (read_vin, read_faults, run_service_function)Same Beemuu helpers, different framing

KWP2000 (E-series)

KWP2000 is the older BMW diagnostic protocol. It runs on a single-wire K-line bus or, on later E-series, on the dual K+DCAN cable’s D-CAN pair. Single-frame requests — each request fits in a single CAN frame (8 bytes). No segmentation, no security access gate, smaller data blocks.

The project’s KWP2000 path is in src-tauri/src/protocol/kwp2000.rs. Service identifiers are 1-byte locals (for example, 0x90 for VIN read on E-series DME). The framing is straightforward request-response; the deadline (typically 1 s default, 3 s for slow modules) is the main tuning parameter.

What the operator sees

  • Reads are fast (typically under 100 ms for fault codes).
  • Per-target KWP response deadline is hardware-aware: it scales with the FTDI VCP latency timer. A 1 ms latency timer doesn’t pay a 3 s penalty on a 1 s target.
  • Service functions (CBS reset, etc.) use startDiagnosticSession + startRoutineByLocalIdentifier.

UDS (F/G-series)

UDS is the modern diagnostic protocol standardised as ISO 14229. It runs over CAN with ISO-TP segmentation, or over Ethernet with DoIP framing. UDS adds several features KWP2000 doesn’t have:

  • Larger data blocks via ISO-TP or DoIP segmentation.
  • SecurityAccess (0x27) gates write operations behind a seed/key challenge. CBS reset, battery registration, and any coding operation must pass SecurityAccess first.
  • RoutineControl (0x31) is the standard service for invoking service functions. The DID format is consistent across targets (16-bit), unlike KWP2000’s 1-byte local identifiers.
  • ReadDataByIdentifier (0x22) reads a single DID. The same service reads VIN, fault memory, live-data DIDs.

What the operator sees

  • Reads over DoIP are very fast (typically under 30 ms for fault codes).
  • SecurityAccess can be a barrier: a misconfigured seed/key routine will hang the service function indefinitely.
  • Service functions on F/G-series are larger operations; a CBS reset reads the current state, computes the new state, writes, verifies.

DoIP (transport)

DoIP is the transport that puts UDS over automotive Ethernet. It’s standardised as ISO 13400 and uses UDP for discovery (port 13400) and TCP for the actual diagnostic session.

Beemuu’s DoIP UDP broadcast discovery is still honestly not implemented per the v0.14.4 CLAUDE.md refresh. The project preserves this as an open item rather than overstating. The work is well-scoped and ready to claim — see the roadmap.

What does work in Beemuu today: the UDS-over-DoIP framing once a connection is established. You can plug an ENET cable into a router, set the laptop IP in the 169.254.x.x range, and Beemuu talks UDS directly.

ISO-TP (segmentation)

ISO-TP is the segmentation layer that lets UDS messages longer than 8 bytes be split across multiple CAN frames. The protocol is a simple frame-reassembly scheme:

  • First frame (FF): carries the length and the first 6 bytes.
  • Consecutive frames (CF): carry 7 bytes each, in order.
  • Flow control (FC): the receiver tells the sender how many frames to send before pausing.

Beemuu’s src-tauri/src/transport/isotp.rs handles ISO-TP for UDS-over-CAN. The DoIP path uses a different segmentation scheme on top of UDP, defined as part of ISO 13400.

Timing & deadlines

Both KWP2000 and UDS paths have timing constraints. The v0.13.0 cycle added per-target KWP response deadlines (1 s default, 3 s “slow”) that scale with the FTDI VCP latency timer. The UDS path uses the standard P2 server timer (typically 50 ms) and P2* (typically 5 s for enhanced operations).

The CLAUDE.md invariants (preserved by the v0.14.4 refresh) cover timing-critical rules:

  • Async commands. Any #[tauri::command] that touches serial or network transport must be async fn. Blocking I/O on the main thread freezes the webview.
  • Tester Present keep-alive. Active diagnostic sessions need a 3E 00 / 3E 80 frame every 2000–4000 ms on an async/isolated worker. Beemuu ships this in src-tauri/src/keepalive.rs with a 3000 ms interval.
  • Per-target deadlines. A 1 ms latency timer shouldn’t pay a 3 s penalty on a 1 s target. The deadline is hardware-aware.

In Beemuu

The project’s src-tauri/src/protocol/ module is the protocol dispatch. The protocol::read_vin helper handles both E-series (KWP2000 1A 90) and F/G-series (UDS 22 F1 90) from a single call site. Same pattern for read_faults, read_live_data, and the service functions.

For the operator, the protocol choice is transparent: pick the right cable, Beemuu handles the framing. What you do see is that F/G-series reads are generally faster (DoIP is faster than D-CAN for fault reads), and F/G-series service functions sometimes need SecurityAccess first while E-series doesn’t.

Protocol questions

Why does the E-series use KWP2000 and the F/G-series use UDS?

E-series BMWs were designed before UDS over CAN was standardised. KWP2000 was the BMW-specific protocol at the time. F-series moved to UDS running over DoIP, which supports larger data blocks, ISO-TP segmentation, security access and routine control in one standard.

Does Beemuu support both?

Yes. KWP2000 over K+DCAN for E-series, UDS over DoIP for F/G-series. The protocol module dispatches based on the cable and chassis.

What is ISO-TP?

ISO Transport Layer (ISO 15765-2). The segmentation layer that splits UDS messages longer than 8 bytes across multiple CAN frames.

One tool, two protocols.

Beemuu talks KWP2000 over K+DCAN and UDS over DoIP. Pick the cable, connect, scan.

Download BeemuuGlossary

Last updated: 2026-08-02 ยท Beemuu contributors