Skip to content

Diagnostics: UDS & DoIP

TL;DR

UDS (Unified Diagnostic Services, ISO 14229) is the protocol every workshop scan tool speaks: read trouble codes, live data, flash firmware, run routines. Common services: ReadDTC (0x19), ReadDataByIdentifier (0x22), RoutineControl (0x31), RequestDownload (0x34). DoIP (Diagnostics over IP, ISO 13400) carries UDS over automotive Ethernet, replacing K-Line and CAN-based ISO-TP diagnostics on modern architectures. DTCs (Diagnostic Trouble Codes) are standardized fault records. A P-code in the glove box manual is a UDS concept. When you run adb shell dumpsys car_service, you’re doing the software developer’s version of the same job: asking the vehicle stack what’s wrong.

The technician plugs a scan tool into OBD-II. You SSH into QNX and grep slog2. Different tools, same question: “What’s broken, and can I fix it?” UDS is the language the industry agreed on for that conversation.

UDS defines a client/server model: the tester (scan tool, factory rig, your script) sends service requests; the ECU (or gateway) responds with data or negative response codes (NRC).

Concept Meaning
Tester External diagnostic client (ODIS, CANoe, custom Python script)
ECU / Server Any node exposing diagnostic services (gateway, cluster, ADAS ECU)
SID Service Identifier (first byte of every request, e.g., 0x22 = ReadDataByIdentifier)
DID Data Identifier (which data item to read, e.g., 0xF190 = VIN)
NRC Negative Response Code (why the request failed, e.g., 0x33 = SecurityAccessDenied)
Session Diagnostic mode: Default, Programming, Extended (controls which services are allowed)

Legacy transport was ISO-TP over CAN (8-byte frames, multi-frame segmentation). Modern centralized/zonal architectures use DoIP (next section), but the UDS services are identical regardless of transport.

Service SID Purpose Workshop Example Your Platform Equivalent
ReadDTCInformation 0x19 Read stored/pending trouble codes “Check engine light — what’s the code?” Gateway DTC snapshot via factory tool
ReadDataByIdentifier 0x22 Read live or stored data by DID Read VIN, battery voltage, software version Reading VHAL property or QNX config
WriteDataByIdentifier 0x2E Write calibration/config data Provisioning, variant coding Writing persistent config (often SecurityAccess-protected)
RoutineControl 0x31 Start/stop/request results of test routines Headlight aim routine, sensor calibration Factory test mode trigger
RequestDownload 0x34 Begin firmware download (flash programming) ECU reflash during recall OTA is different path, but factory flash uses this
TransferData 0x36 Send firmware data blocks Continuation of flash
RequestTransferExit 0x37 Finish firmware download End of flash session
SecurityAccess 0x27 Seed-key authentication for protected services Unlock ECU for writing Cybersecurity gate (Module 9.2)
ECUReset 0x11 Hard/soft/key-off reset “Clear adaptations and reboot ECU” adb reboot / QNX process restart

Sub-functions filter what you get:

Sub-function What It Returns
reportNumberOfDTCByStatusMask Count of stored codes matching status mask
reportDTCByStatusMask List of DTCs with status (test failed, pending, confirmed)
reportDTCSnapshotRecordByDTCNumber Freeze-frame data captured when fault occurred
reportDTCExtendedDataRecordByDTCNumber Extended fault context (occurrence count, aging)

Send: [0x22] [DID high] [DID low] → Receive: [0x62] [DID] [data bytes...]

Common DIDs (manufacturer-specific ranges apply):

DID Typical Content
0xF190 VIN
0xF181 Application software identification
0xF187 Spare part number
0x010C Engine RPM (powertrain ECUs)

RoutineControl (0x31): Built-In Test Routines

Section titled “RoutineControl (0x31): Built-In Test Routines”

Three sub-functions: startRoutine, stopRoutine, requestRoutineResults. Factory lines run these for camera calibration, speaker test, leak test. A failed routine often sets a DTC.

Kicks off the programming session sequence: RequestDownload → TransferData (repeated) → RequestTransferExit → ECUReset. Protected by SecurityAccess and Programming Session. This is how workshop tools reflash ECUs. Distinct from cloud OTA, but same integrity concerns (signing, rollback).

Mental Model

UDS is a restaurant order system. The SID is the menu category (appetizers = read data, entrees = routines, dessert = clear DTCs). The DID is the specific dish. NRC 0x33 is “kitchen locked — show your staff badge” (SecurityAccess). DoIP is switching from shouting orders through a mail slot (CAN ISO-TP) to calling on a dedicated phone line (Ethernet) — same menu, better bandwidth.

DoIP (ISO 13400) wraps UDS payloads in TCP/UDP over automotive Ethernet. Essential when your domain controller aggregates dozens of ECUs behind one diagnostic gateway.

Legacy (CAN ISO-TP) Modern (DoIP)
Physical layer CAN bus (500 kbps–1 Mbps) 100BASE-T1 / 1000BASE-T1 Ethernet
Bandwidth ~7 KB/s effective Megabytes/sec
Addressing CAN ID pairs IP address + logical address (LA)
Routing Direct or via gateway DoIP gateway routes to internal ECUs
Use case Body ECUs, legacy powertrain Cockpit domain controller, zonal gateways, ADAS

DoIP header structure (simplified):

Field Purpose
Protocol version 0x02 (ISO 13400-2:2019)
Payload type Vehicle identification, routing activation, diagnostic message
Logical address Which ECU (e.g., 0x0E00 = gateway, 0x0E80 = instrument cluster)
UDS payload The actual 0x22/0x19/etc. service bytes

Routing Activation is the DoIP handshake. Tester connects to gateway IP (often 169.254.x.x link-local on OBD), sends activation request, gateway assigns diagnostic channel, then UDS flows.

A DTC (Diagnostic Trouble Code) is a standardized fault record stored when a monitor detects a malfunction.

DTC Format Example Meaning
P0128 P = Powertrain Coolant thermostat rationality
B0020 B = Body Occupant classification sensor
C0035 C = Chassis Left front wheel speed sensor
U0100 U = Network Lost communication with ECM

Each DTC has a status byte:

Status Bit Meaning
Test failed Fault currently present
Test failed this cycle Failed since last power cycle
Pending Detected but not yet confirmed
Confirmed Stored after confirmation criteria met
Test not completed since last clear Monitor hasn’t run yet
Warning indicator requested Telltale/MIL should be on

On your platform, a gateway DTC like U0140 (Lost communication with body control module) might appear in the technician’s scan tool while you simultaneously see stale signals in VHAL. Same root cause, two views.

Common Gotcha

Clearing DTCs (UDS 0x14) is not fixing the bug. Workshop “clear codes” resets monitor status. If the fault persists, the DTC returns next drive cycle. When factory asks for a DTC snapshot log, they want the pre-clear freeze frame, not your assurance that you cleared it and drove around the block.

sequenceDiagram
participant Tech as Workshop Tester<br/>(ODIS / CANoe)
participant OBD as OBD-II Port
participant GW as DoIP Gateway<br/>(QNX domain controller)
participant Cluster as Instrument Cluster ECU
participant CAN as CAN / Ethernet Bus
participant BCM as Body Control Module
Tech->>OBD: Ethernet or CAN connection
OBD->>GW: DoIP Routing Activation
GW-->>Tech: Activation OK (logical address assigned)
Tech->>GW: UDS 0x19 ReadDTC (all ECUs via gateway)
GW->>Cluster: Route UDS over internal bus
Cluster-->>GW: DTC U0121 — lost comm with BCM
GW-->>Tech: Aggregated DTC list
Tech->>GW: UDS 0x22 ReadDataByIdentifier (0xF190 VIN)
GW-->>Tech: VIN bytes
Tech->>GW: UDS 0x27 SecurityAccess (seed-key)
GW-->>Tech: Unlock for programming session
Tech->>GW: UDS 0x34 RequestDownload (BCM firmware)
GW->>BCM: Route programming sequence
BCM-->>GW: Transfer ready
Tech->>GW: UDS 0x36 TransferData (blocks...)
GW->>BCM: Flash blocks
Tech->>GW: UDS 0x11 ECUReset
BCM->>BCM: Reboot with new firmware
Where You'll See This

adb shell dumpsys car_service is the software equivalent of a UDS ReadDataByIdentifier session. You’re querying the vehicle abstraction layer for property values, service states, and errors without a physical scan tool.

Terminal window
# What's the vehicle stack reporting? (developer "scan tool")
adb shell dumpsys car_service
# Specific property, like reading a DID
adb shell dumpsys car_service --services VehicleHal
adb shell cmd car_service get-property-value 291504647 # VEHICLE_SPEED example ID
# QNX side equivalent: gateway logs during diagnostic session
slog2info -w | grep -i "uds\|doip\|dtc\|diag"

When a factory issue report says “DTC U0100 during routine 0x0203,” decode it:

  1. U0100: network communication fault (Module 9.2: could be bus-off OR gateway software bug)
  2. Routine 0x0203: look up in OEM diagnostic spec (RoutineControl)
  3. Reproduce: connect CANoe/DoIP tester, run same routine, capture gateway routing logs on QNX

Your bug isn’t “infotainment” if the DTC is set by the gateway ECU during a UDS session. That’s QNX diagnostic stack territory, even if the symptom appears in Android.

UDS Sessions and SecurityAccess

UDS diagnostic sessions gate which services are legal:

Session SID 0x10 Sub Typical Access
Default 0x01 ReadDTC, ReadData (read-only)
Programming 0x02 RequestDownload, TransferData (flash)
Extended 0x03 RoutineControl, WriteData (factory calibration)

Entering Programming or Extended session usually requires SecurityAccess (0x27). ECU sends a seed, tester computes key from OEM algorithm. This is ISO 21434’s diagnostic-layer lock. Leaked seed-key algorithms are a TARA-critical asset. They enable unauthorized reflashing via OBD.

Connect the Dots

Module 1.2 noted CAN IDs aren’t IP addresses. UDS over ISO-TP was the diagnostic answer on CAN. Module 2’s centralized architecture requires DoIP when one gateway serves 70+ logical ECUs. Module 4’s AUTOSAR DCM (Diagnostic Communication Manager) module implements UDS on Classic AUTOSAR ECUs. Module 6.3’s VHAL is the AAOS-side mirror of diagnostic data identifiers. Module 9.2’s OBD-II attack surface is where UDS SecurityAccess protects you.

  1. UDS (ISO 14229): standardized diagnostic services (0x19, 0x22, 0x31, 0x34…).
  2. DoIP (ISO 13400): UDS over automotive Ethernet via gateway routing.
  3. DTCs: P/B/C/U codes with status bytes; freeze frames capture fault context.
  4. SecurityAccess protects write/flash operations (cybersecurity meets diagnostics).
  5. dumpsys car_service is your developer diagnostic console, same intent as a scan tool.

Check Your Understanding

1. What is the primary role of DoIP (ISO 13400) in modern vehicle diagnostics?

2. A workshop tool sends UDS service 0x22 with DID 0xF190. What is it requesting?

3. How does `adb shell dumpsys car_service` relate to UDS diagnostics?