·
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 now0xCC(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, or0x00to 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 newuds_input_sdu_addr()(uds_input_sdu()stays as a physical-default wrapper). Services gate on a newaddress_modefield inuds_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_listhook. New config fielddtc_severity_availability_mask. (#39) - DTC classification helpers (
uds/uds_dtc.h):uds_dtc_category()decodes Powertrain/Chassis/Body/Network from a DTC, plus namedUDS_DTC_STATUS_*,UDS_DTC_SEVERITY_*, andUDS_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-madefn_dtc_list/fn_dtc_extdata/fn_dtc_clearcallbacks. 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_listhook (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 rawfn_dtc_readhook 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_SAFETYservice-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 0x07eventTypeRecordis 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 thefn_nvm_savesession/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) andauthenticationConfiguration(0x08, returns the newcfg.auth_configurationbyte) are handled natively. A newctx.authenticatedflag (set by the application'sfn_authon success) is auto-cleared on deAuthenticate, session change, S3 timeout, and reset — mirroringsecurity_level. The certificate/proof/challenge sub-functions (0x01–0x07) remain delegated tofn_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 andctx.authenticatedis false, the request is rejected with NRC 0x34 (authenticationRequired).examples/auth_challengedemonstrates 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). Newuds_comm_type_tenum names the communicationType message classes (normal / network-management / both), anduds_comm_control_type_tgainsUDS_COMM_ENABLE_RX_DISABLE_TX_ENH(0x04) andUDS_COMM_ENABLE_RX_TX_ENH(0x05). (#55)
Changed
fn_comm_controlgains anode_idparameter (BREAKING): the CommunicationControl (0x28) callback is nowint (*)(uds_ctx_t *, uint8_t ctrl_type, uint8_t comm_type, uint16_t node_id).node_idcarries the nodeIdentificationNumber for the enhanced-address sub-functions (0x04/0x05) and is 0 for 0x00–0x03. Implementers offn_comm_controlmust update their signature. (#55)fn_dtc_readnow receives the request payload: the optional ReadDTCInformation (0x19) raw-fallback hook signature gainsconst uint8_t *req, uint16_t req_lenbefore 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 offn_dtc_readmust update their signature. (#39)uds_auth_type_trenumbered to ISO 14229-1:2020 (BREAKING): the Authentication (0x29) sub-function enum was off by one (deAuthenticatewas 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(wasREQUEST_TOKEN = 0x06), plus newVERIFY_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(was0x00): transmitted SF/FF/CF/FC frames pad unused bytes with0xCCper ISO 15765-2:2016 instead of0x00. This changes only the on-wire fill of otherwise-identical frames; protocol behavior is unchanged. Calluds_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
0x51is only captured — the response the tester receives is the outer secured frame, sent later.fn_resetis 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. Newreset_pendingcontext 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
powerDownTimebyte. The mask now admits 0x01–0x05, and the 0x04 positive response is{0x51, 0x04, powerDownTime}sourced from the newcfg.power_down_time.uds_reset_type_tgainsUDS_RESET_ENABLE_RAPID_SHUTDOWN(0x04) andUDS_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 fromrequestSequenceError (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 reachesfn_transfer_data. The transfer is disarmed by RequestTransferExit (0x37) and aborted on S3 session timeout. Newtransfer_activecontext state. - Responses exceeding the TX buffer were dropped silently:
uds_send_response()returned an internal error and sent nothing when a response was larger thantx_buffer_size, leaving the tester to time out. It now emitsresponseTooLong (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 simulatorunit_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
ctestDocumentation
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.