Skip to content

LibUDS 1.20.0

Latest

Choose a tag to compare

@github-actions github-actions released this 22 Jun 14:11
· 44 commits to develop since this release

UDSLib v1.20.0

Universal Diagnostics Stack for Embedded Systems


What's New

Added

  • ISO-TP configurable frame padding: uds_tp_isotp_set_pad_byte() sets the byte used to fill unused bytes in every transmitted frame (SF, FF, CF, FC). The default is now 0xCC (ISOTP_PAD_BYTE_DEFAULT), the value ISO 15765-2:2016 recommends to minimize stuff-bit insertions on the wire; override per channel (e.g. 0xAA, or 0x00 to restore the previous fill). (#67)
  • ISO-TP physical/functional addressing: a channel can now recognise a functional (broadcast) RX ID via uds_tp_isotp_set_functional_id(); requests are tagged physical/functional and delivered through the new uds_input_sdu_addr() (uds_input_sdu() stays as a physical-default wrapper). Services gate on a new address_mode field in uds_service_entry_t (0 = both). Functional addressing is Single-Frame only, and functionally addressed requests suppress NRC 0x11/0x12/0x7E/0x7F/0x31 per ISO 14229-1. Completes #42.
  • ISO-TP full-duplex mode: uds_tp_isotp_set_mode(iso, ISOTP_FULL_DUPLEX) lets a segmented reception and a segmented transmission proceed simultaneously on the same N_AI; an inbound frame no longer aborts an in-flight multi-frame response. Default remains half-duplex (prior behavior). The ISO-TP context now keeps independent RX/TX state. Scope: one concurrent RX and one TX per channel — two simultaneous transmissions on one N_AI are not supported (single TX connection per N_AI, per ISO 15765-2). (#42)
  • ReadDTCInformation (0x19) — severity, fault-detection counter, and WWH-OBD subfunctions: added reportNumberOfDTCBySeverityMaskRecord (0x07), reportDTCBySeverityMaskRecord (0x08), reportSeverityInformationOfDTC (0x09), reportDTCFaultDetectionCounter (0x14), reportWWHOBDDTCByMaskRecord (0x42), and reportWWHOBDDTCWithPermanentStatus (0x55). The DTC record now carries severity, functional unit, fault-detection counter, aging counter, and functional group; all new subfunctions are formatted by the library from records supplied via the existing fn_dtc_list hook. New config field dtc_severity_availability_mask. (#39)
  • DTC classification helpers (uds/uds_dtc.h): uds_dtc_category() decodes Powertrain/Chassis/Body/Network from a DTC, plus named UDS_DTC_STATUS_*, UDS_DTC_SEVERITY_*, and UDS_DTC_FGID_* constants. (#39)
  • Optional reference DTC store (uds/uds_dtc_store.h): opt-in, application-provides-storage helper that manages DTC instances (register/get/clear), tracks the fault-detection counter and aging (with self-heal), and supplies ready-made fn_dtc_list/fn_dtc_extdata/fn_dtc_clear callbacks. The protocol core does not depend on it. (#39)
  • ReadDTCInformation (0x19) — complete sub-function coverage: added reportFirstTestFailedDTC (0x0B), reportFirstConfirmedDTC (0x0C), reportMostRecentTestFailedDTC (0x0D), reportMostRecentConfirmedDTC (0x0E), and reportDTCWithPermanentStatus (0x15), each formatted by the library from records supplied via the existing fn_dtc_list hook (first/most-recent select by occurrence order; permanent is reported as the confirmed set). The 0x19 sub-function mask now admits every standard sub-function (0x01–0x19) plus 0x42/0x55; the memory-region, by-record-number, emissions-OBD, and user-defined-memory variants (0x03, 0x05, 0x0F–0x13, 0x16–0x19) are routed to the raw fn_dtc_read hook for the application to format rather than rejected with subFunctionNotSupported. (#39)
  • DiagnosticSessionControl (0x10) — safetySystemDiagnosticSession ($04): the fourth standard ISO 14229-1 session type is now accepted (sub-function mask widened to $01–$04) and mapped to a new UDS_SESSION_SAFETY service-gate bit. (#40)
  • Optional session-transition policy hook fn_session_transition_allowed(ctx, from, to): called before 0x10 changes the active session. Returning false rejects the request with NRC 0x22 (conditionsNotCorrect) and leaves the session unchanged. When unset (default), any session may be entered from any session — matching ISO 14229-1, which imposes no transition graph. Lets integrators enforce OEM-specific transition graphs (e.g. extended-before-programming) without baking a non-standard default into the library. (#40)
  • ResponseOnEvent (0x86) — onComparisonOfValues (0x07) completes 0x86 sub-function coverage (8/8). The application reports an observed value via uds_roe_trigger(ctx, 0x07, value) and the library emits when it satisfies the stored comparison. The 0x07 eventTypeRecord is interpreted pragmatically as <comparisonOperator(1)><referenceValue(4)> (operators 0x01 equal / 0x02 greater-than / 0x03 less-than), documented in code as a simplification pending a concrete spec/use-case.
  • ResponseOnEvent persistence helpers uds_roe_serialize() / uds_roe_deserialize(): write/restore the stored 0x86 event definitions to a caller-owned buffer so an application can persist them across a reset using its own NVM. The library stays storage-agnostic (no collision with the fn_nvm_save session/security channel); restored events are inactive until a startResponseOnEvent.
  • Authentication (0x29) — sub-function validation, state, and native handling: a sub-function mask now admits only 0x00–0x08 (else NRC 0x12). deAuthenticate (0x00) and authenticationConfiguration (0x08, returns the new cfg.auth_configuration byte) are handled natively. A new ctx.authenticated flag (set by the application's fn_auth on success) is auto-cleared on deAuthenticate, session change, S3 timeout, and reset — mirroring security_level. The certificate/proof/challenge sub-functions (0x01–0x07) remain delegated to fn_auth (crypto stays in the app/HSM).
  • Authentication-gated services: a new optional cfg.fn_auth_required(ctx, sid) hook lets the application require an authenticated channel for selected services; when it returns true and ctx.authenticated is false, the request is rejected with NRC 0x34 (authenticationRequired). examples/auth_challenge demonstrates the full flow (gated service rejected → cert verify → challenge → proof → gated service allowed).
  • CommunicationControl (0x28) — enhanced-address sub-functions completed: the 2-byte nodeIdentificationNumber carried by enableRxAndDisableTxWithEnhancedAddressInformation (0x04) and enableRxAndTxWithEnhancedAddressInformation (0x05) is now parsed and delivered to fn_comm_control; these sub-functions are length-checked (require ≥ 5 bytes, else NRC 0x13). New uds_comm_type_t enum names the communicationType message classes (normal / network-management / both), and uds_comm_control_type_t gains UDS_COMM_ENABLE_RX_DISABLE_TX_ENH (0x04) and UDS_COMM_ENABLE_RX_TX_ENH (0x05). (#55)

Changed

  • fn_comm_control gains a node_id parameter (BREAKING): the CommunicationControl (0x28) callback is now int (*)(uds_ctx_t *, uint8_t ctrl_type, uint8_t comm_type, uint16_t node_id). node_id carries the nodeIdentificationNumber for the enhanced-address sub-functions (0x04/0x05) and is 0 for 0x00–0x03. Implementers of fn_comm_control must update their signature. (#55)
  • fn_dtc_read now receives the request payload: the optional ReadDTCInformation (0x19) raw-fallback hook signature gains const uint8_t *req, uint16_t req_len before the output buffer, so applications serving the sub-functions the library does not frame (0x03, 0x05, 0x0F–0x13, 0x16–0x19) can read the request's status/severity mask, DTC, record number, or memory selection. Implementers of fn_dtc_read must update their signature. (#39)
  • uds_auth_type_t renumbered to ISO 14229-1:2020 (BREAKING): the Authentication (0x29) sub-function enum was off by one (deAuthenticate was 0x01). It now matches the standard — UDS_AUTH_DEAUTHENTICATE = 0x00, VERIFY_CERT_UNI = 0x01, VERIFY_CERT_BI = 0x02, PROOF_OF_OWNERSHIP = 0x03, TRANSMIT_CERT = 0x04, REQUEST_CHALLENGE = 0x05 (was REQUEST_TOKEN = 0x06), plus new VERIFY_PROOF_UNI = 0x06, VERIFY_PROOF_BI = 0x07, CONFIGURATION = 0x08. Update any code/wire that used the old values.
  • ISO-TP frame padding default is now 0xCC (was 0x00): transmitted SF/FF/CF/FC frames pad unused bytes with 0xCC per ISO 15765-2:2016 instead of 0x00. This changes only the on-wire fill of otherwise-identical frames; protocol behavior is unchanged. Call uds_tp_isotp_set_pad_byte(&iso, 0x00) to restore the previous fill. (#67)

Fixed

  • ECUReset (0x11) reset hook could fire before a secured response was sent: building on the send-before-reset ordering fix (#76), when a 0x11 is wrapped in a SecuredDataTransmission (0x84) the inner 0x51 is only captured — the response the tester receives is the outer secured frame, sent later. fn_reset is now deferred until that outer frame is on the wire, and is skipped entirely if the response cannot be sent (or securing fails). A captured ResponseOnEvent (0x86) inner dispatch can never trigger a reset. New reset_pending context state. (#76)
  • ECUReset enableRapidPowerShutDown (0x11 sub 0x04) was incomplete: the sub-function was rejected by the 0x11 sub-function mask (which only admitted 0x01–0x03), and even when reached the response omitted the mandatory powerDownTime byte. The mask now admits 0x01–0x05, and the 0x04 positive response is {0x51, 0x04, powerDownTime} sourced from the new cfg.power_down_time. uds_reset_type_t gains UDS_RESET_ENABLE_RAPID_SHUTDOWN (0x04) and UDS_RESET_DISABLE_RAPID_SHUTDOWN (0x05). (ISO 14229-1)
  • TransferData (0x36) wrong block sequence returned NRC 0x24 instead of 0x73: a mismatched blockSequenceCounter now returns wrongBlockSequenceCounter (0x73) per ISO 14229-1, distinct from requestSequenceError (0x24).
  • TransferData (0x36) accepted before RequestDownload/Upload: a transfer must now be armed by a successful RequestDownload (0x34) or RequestUpload (0x35); TransferData outside an active transfer is rejected with requestSequenceError (0x24) and never reaches fn_transfer_data. The transfer is disarmed by RequestTransferExit (0x37) and aborted on S3 session timeout. New transfer_active context state.
  • Responses exceeding the TX buffer were dropped silently: uds_send_response() returned an internal error and sent nothing when a response was larger than tx_buffer_size, leaving the tester to time out. It now emits responseTooLong (NRC 0x14) for on-the-wire responses (captured inner 0x84/0x86 responses still surface the internal error to their wrapper).

Test Results

All Tests Passed

  • Total Tests: 59
  • Passed: 59
  • Failed: 0

Build Information

  • Version: 1.20.0
  • Build Date: 2026-06-22 14:11:36 UTC
  • Compliance: ISO 14229-1 (UDS)
  • Platform Support: Bare Metal, FreeRTOS, Zephyr, Linux, Windows

Supported Services

UDSLib v1.20.0 implements 16 ISO 14229-1 services:

Service Description SID
Diagnostic Session Control Session management 0x10
ECU Reset Reset operations 0x11
Clear Diagnostic Information DTC clearing 0x14
Read DTC Information DTC reporting 0x19
Read Data By Identifier Data reading 0x22
Read Memory By Address Memory access 0x23
Security Access Seed/Key exchange 0x27
Communication Control TX/RX control 0x28
Authentication Certificate exchange 0x29
Write Data By Identifier Data writing 0x2E
Routine Control Routine execution 0x31
Request Download OTA init 0x34
Transfer Data Block streaming 0x36
Request Transfer Exit OTA completion 0x37
Write Memory By Address Memory writing 0x3D
Tester Present Keep-alive 0x3E
Control DTC Setting DTC ON/OFF 0x85

Installation

Download Pre-built Binaries

Download the attached artifacts:

  • uds_host_sim - Host-based ECU simulator
  • unit_tests - Complete test suite

Build from Source

git clone https://github.com/w1ne/udslib.git
cd udslib
git checkout v1.20.0
mkdir build && cd build
cmake ..
make
ctest

Documentation

Licensing

  • Community: PolyForm Noncommercial 1.0.0 (noncommercial use). See LICENSE.
  • Commercial: 5,000 EUR for production/commercial use, includes integration + 1 year support.
  • Contact: andrii@shylenko.com for commercial terms and support.

Report Issues

Found a bug? Open an issue

Full Changelog

See CHANGELOG.md for complete version history.


Code Coverage

Line Coverage: 86.6% · Function Coverage: 98.9%

Summary coverage rate:
lines......: 86.6% (1626 of 1878 lines)
functions..: 98.9% (88 of 89 functions)
branches...: no data found

Full coverage report available in release artifacts.