Skip to Content
UDS Simulator 2.0 Released
DocsLearnCore UDS Services

Core UDS Services

Module 3 of 5 · 3 lessons · ~75 min · ← Back to Learning Hub


Lesson 1: SID 0x10 — Diagnostic Session Control

Purpose

Controls which diagnostic session the ECU operates in. Different sessions enable different levels of diagnostic access and functionality. Every diagnostic sequence begins here.

Session Types

0x01 — Default Session

  • Normal vehicle operation mode
  • Limited diagnostics: read DTCs, read basic data
  • No security access required
  • Active at vehicle power-up

0x02 — Programming Session

  • ECU software updates and calibration data writing
  • Enables memory write and flash download (SID 0x34/0x36)
  • Typically requires security access (SID 0x27) first
  • Not available during normal driving (conditionsNotCorrect)

0x03 — Extended Diagnostic Session

  • Full diagnostic access: all read/write operations, routine control, actuator tests
  • Requires Tester Present (0x3E) to maintain
  • Most common session for dealer diagnostics

0x04 — Safety System Diagnostic Session

  • Safety-critical ECU access (airbags, ABS, ESC)
  • Manufacturer-specific availability

Request and Response Format

Request:

10 [Session Type]

Positive Response:

50 [Session Type] [P2 High] [P2 Low] [P2* High] [P2* Low]

Examples:

OperationRequestResponse
Enter Extended Session10 0350 03 00 32 01 F4
Return to Default10 0150 01 00 32 01 F4
Enter Programming10 0250 02 00 32 01 F4

Session State Machine

Power-up [Default Session 0x01] ↕ 10 03 / 10 01 [Extended Session 0x03] ↕ 10 02 / ECU reset [Programming Session 0x02]

Any session returns to Default after S3 timeout (5 seconds of inactivity).

Negative Response Codes

NRCTrigger
0x12Sub-function not supported (session type unknown)
0x22conditionsNotCorrect — e.g. requesting Programming session while driving
0x7FserviceNotSupportedInActiveSession

Common Use Cases

  1. Dealer Diagnostics: 10 03 → enter Extended → perform diagnostics → 10 01 return to Default
  2. ECU Reprogramming: 10 02 → enter Programming → Security Access → erase → flash → checksum → 11 01 reset
  3. End of Diagnostics: Always return to Default when complete

Best Practices

  • Always return to Default Session (10 01) when diagnostics are complete
  • Monitor S3 timeout — send Tester Present (3E 80) if operation takes longer than 2–3 seconds
  • Check the P2/P2* values in the session response to set your client timeouts correctly

Lesson 2: SID 0x27 — Security Access

Purpose

Implements challenge-response authentication to prevent unauthorized access to protected ECU operations. Required before flash programming, critical calibration writes, or access to sensitive vehicle data.

Why Security Matters

Without Security Access, any tool connected to the OBD-II port could reprogram an ECU or disable safety systems. The seed-key mechanism ensures only authorized tools with the correct algorithm can unlock protected operations.

Authentication Flow

Step 1 — Request Seed: Client → 27 01 ECU → 67 01 [4-byte seed] (random value, different each time) Step 2 — Calculate Key: Client computes: key = f(seed, secret_constant) Step 3 — Send Key: Client → 27 02 [4-byte key] ECU → 67 02 (access granted)

Security Levels

Odd sub-functions request a seed; the matching even sub-function sends the key:

Seed RequestKey SendTypical Use
27 0127 02Level 1 — extended diagnostics
27 0327 04Level 2 — ECU reprogramming
27 0527 06Level 3 — calibration/supplier

Already Unlocked

If the ECU is already unlocked at the requested level, it returns a seed of all zeros:

27 01 → 67 01 00 00 00 00

In this case, send a key of all zeros to confirm:

27 02 00 00 00 00 → 67 02

Seed-Key Algorithms

The algorithm is manufacturer-specific and kept confidential. Common approaches:

  • XOR with a proprietary constant (simple, less secure)
  • CRC32-based transformation
  • AES encryption using a hardware-stored secret key
  • Combination of seed + VIN + ECU serial number

Example for learning only (never use in production):

function calculateKey(seed) { // Simple XOR — DO NOT USE IN REAL IMPLEMENTATIONS return seed ^ 0x12345678; }

Anti-Brute-Force Protections

  • Failed attempts increment a counter
  • After N failures (typically 2–5), NRC 0x36 (exceededNumberOfAttempts) is returned
  • After that, NRC 0x37 (requiredTimeDelayNotExpired) blocks further attempts
  • The delay period is typically 10 seconds to several minutes
  • Some ECUs require a power cycle to reset the counter

Negative Response Codes

NRCMeaningResolution
0x22conditionsNotCorrectMust be in Extended/Programming session first
0x24requestSequenceErrorYou sent key without requesting seed first
0x35invalidKeyKey calculation is wrong — check algorithm
0x36exceededNumberOfAttemptsToo many failures — trigger delay
0x37requiredTimeDelayNotExpiredWait the full delay before retrying

Best Practices

  • Always request seed before sending key — never skip
  • Protect seed-key algorithms as trade secrets
  • Limit retry attempts in your client to avoid triggering ECU lockout
  • Log all security access events for audit trails
  • Security unlock persists for the active diagnostic session only

Lesson 3: SID 0x19 — Read DTC Information

Purpose

Retrieves Diagnostic Trouble Codes (DTCs) and their associated data from ECU memory. This is the primary service for fault diagnosis — you’ll use it in nearly every diagnostic session.

DTC Format

A DTC (Diagnostic Trouble Code) is 3 bytes:

[High Byte] [Middle Byte] [Low Byte] Example: 04 20 01 → P0420 (Catalytic Converter Efficiency)

DTC Category Prefixes (from high byte):

RangeCategoryDescription
0x00–0x3FP (Powertrain)Engine, transmission, fuel system
0x40–0x7FC (Chassis)ABS, steering, suspension
0x80–0xBFB (Body)Airbags, windows, lighting
0xC0–0xFFU (Network)CAN bus, gateway, ECU communication

DTC Status Byte

Every DTC has an 8-bit status byte:

BitNameMeaning
0testFailedCurrently failing
1testFailedThisOperationCycleFailed this ignition cycle
2pendingDTCDetected but not yet confirmed
3confirmedDTCMature fault — seen across multiple cycles
4testNotCompletedSinceLastClearNot retested since last clear
5testFailedSinceLastClearHas failed at least once since clear
6testNotCompletedThisOperationCycleNot yet tested this cycle
7warningIndicatorRequestedMIL / warning lamp is on

Sub-Functions

0x01 — reportNumberOfDTCByStatusMask

Count DTCs matching a status mask (does not return DTC values, just count):

Request: 19 01 FF Response: 59 01 FF 01 00 05 ↑ ↑──┘ format count = 5 DTCs

0x02 — reportDTCByStatusMask

List all DTCs matching the mask:

Request: 19 02 08 (confirmed DTCs only — bit 3) Response: 59 02 08 [DTC1 3-bytes] [status] [DTC2 3-bytes] [status] ...

0x04 — reportDTCSnapshotRecordByDTCNumber

Get freeze frame data captured when the DTC was set:

Request: 19 04 [DTC 3-bytes] FF (FF = all records) Response: 59 04 [DTC] [status] [record#] [freeze frame data...]

0x06 — reportDTCExtDataRecordByDTCNumber

Get extended counters, aging data, and healing progress:

Request: 19 06 [DTC 3-bytes] FF Response: 59 06 [DTC] [status] [record#] [extended data...]

0x0A — reportSupportedDTCs

List all DTCs the ECU is capable of detecting:

Request: 19 0A Response: 59 0A [availability mask] [DTC1] [DTC2] ...

Status Mask Reference

MaskUse Case
0x01Currently failing tests
0x04Pending DTCs
0x08Confirmed DTCs
0x09Confirmed or currently failing
0x80Warning lamp active
0xFFAll DTCs regardless of status

Negative Response Codes

NRCTrigger
0x12Sub-function not supported
0x31requestOutOfRange — invalid DTC or record number

Key Takeaways

  • DTC = 3 bytes; status byte = 8 flags describing the fault’s lifecycle
  • Sub-function 0x02 with mask 0x08 is the most common: “read confirmed DTCs”
  • Sub-function 0x0A shows what the ECU can detect (all possible DTCs)
  • Freeze frames (0x04) capture the exact conditions when a fault was first logged
  • Use status mask 0xFF to see all DTCs in any state

Next Steps

Continue to Practical Testing to see how these services work together in a real DTC diagnosis workflow.