BMCLI uds
Reference version: BMCLI 1.6.3. Command names, parameters and machine-readable fields retain their source spelling.
UDS (ISO 14229) diagnostic services over ISOTP. Daemon workflows maintain
endpoint state through uds config get|set.
uds discover
Section titled “uds discover”Discover standard 11-bit physical UDS response IDs by transmitting one
single-frame request to functional ID 0x7DF. This command runs standalone,
requires exclusive hardware access, and refuses to transmit unless the caller
passes --allow-functional after user authorization.
bmcli uds discover --channel=10356/1 --allow-functional --dry-run --format=jsonbmcli uds discover --channel=10356/1 --allow-functional --format=jsonbmcli uds discover --channel=10356/1 --allow-functional --probes=3 --timeout=500 --format=jsonbmcli uds discover --channel=10356/1 --allow-functional --data="22 F1 90" --format=jsonThe default request is TesterPresent (3E 00). --data accepts a documented
1-7 byte UDS request. The default --probes=3 sends three independent requests;
an ID is qualified only if it returns a matching UDS response in every probe
window. For TesterPresent, 02 7E 00 is matched using the ISO-TP length, so any
following CAN padding bytes are ignored. --timeout is the response window for
each probe. Matching responses are collected from any 11-bit CAN ID; the
implementation does not assume the OBD-only 0x7E8-0x7EF range.
The output includes conventionally inferred physical request IDs (`response ID
- 8
), so pairs such as0x791/0x799are represented correctly. Treat inferred IDs as candidates until an ECU identity read confirms the target. If several IDs answer every probe, BMCLI returnsstatus=needs_selectionandselection_required=true`. The caller must show those IDs to the user and must not choose or persist one automatically.
uds config get/set
Section titled “uds config get/set”Run channel open before setting the daemon endpoint. JSON config get
includes channel_selector, a stable identity, alongside the legacy numeric
channel. Local uds unlock and live uds download inherit this configuration
(channel, IDs, FD and padding) and then apply explicit endpoint options. A
partially specified override preserves the other daemon values. Download
--dry-run stays local and does not query the daemon.
Read or set daemon UDS endpoint parameters. The configuration persists for subsequent UDS commands while that daemon is running. Explicitly closing its channel through CLI or REST invalidates the configuration and stops a TesterPresent task bound to that channel. Reopening a device in the same daemon slot never inherits the closed channel’s diagnostic IDs.
bmcli uds config set --channel=10356/0 --request-id=0x7E0 --response-id=0x7E8bmcli uds config set --channel=10356/0 --request-id=0x7E0 --response-id=0x7E8 --flags=fdf --padding=0xCCbmcli uds config get --format=json| Option | Required | Description |
|---|---|---|
--channel |
set | Channel (e.g. 0, 10356/1) |
--request-id |
set | TX CAN ID (varies per ECU, e.g. 0x7E0, 0x791) |
--response-id |
set | RX CAN ID (varies per ECU, e.g. 0x7E8, 0x799) |
--flags |
set, optional | fdf for CAN FD |
--padding |
set, optional | ISOTP pad value |
There are no defaults for --channel, --request-id, or --response-id.
They vary per ECU, and silent defaults would only mask missing parameters with
a misleading bus timeout. Always specify them explicitly when setting the
configuration.
Omitting --padding disables ISO-TP frame padding. Supplying it enables
padding with that exact byte; --padding=0x00 is distinct from omission and
uses zero-valued padding on the wire.
uds request
Section titled “uds request”Send a UDS request and receive the response. Supports raw hex bytes and named services from loaded UDS XML definitions.
Exit codes (script fail-fast):
0: positive response, or a deliberately suppressed response after the request was transmitted successfully.1: negative response, timeout, transport failure, configuration error, or other command failure. Structured JSON fields such asnrc,reason, anderror.messagedistinguish these cases.
NRC 0x78 (responsePending) handling: if the ECU replies 7F <SID> 78, bmcli does NOT treat it as a final failure — it restarts the P2* wait and reads again for the deferred final response (a new ISOTP message), per ISO 14229-1 §7.5.3. Caps at 30 iterations / 30 s. This matters for real ECUs that stall on session switches (10 02), resets (11 01), or long services (31 01/34/37).
Requires either prior uds config set or --channel, --request-id, and
--response-id on this command line. Missing parameters produce a clear error
with no silent defaults.
# --- Raw hex ---
# TesterPresent with a normal positive responsebmcli uds request 3E 00
# Ask BMCLI to set suppressPosRspMsgIndicationBit (transmits 3E 80)bmcli uds request 3E 00 --suppress-positive-response
# ReadDataByIdentifier (VIN)bmcli uds request 22 F1 90
# DiagnosticSessionControl -> extended sessionbmcli uds request 10 03
# ECUReset -> hard resetbmcli uds request 11 01
# CommunicationControl -> enable RX/TXbmcli uds request 28 00 01
# RoutineControl -> start routine by identifierbmcli uds request 31 01 FF 00
# RequestDownloadbmcli uds request 34 00 44 00 00 00 00 00 00 10 00
# TransferData (block sequence 0x01)bmcli uds request 36 01 AA BB CC DD EE FF
# --- Named services (requires loaded uds.xml) ---
bmcli uds request hardResetbmcli uds request DiagnosticSessionControl extendedbmcli uds request ReadDataByIdentifier VINbmcli uds request ReadDataByIdentifier 0xF190bmcli uds request CommunicationControl enableRxAndTxbmcli uds request RoutineControl startRoutine 0xFF00
# --- Options ---
# Dry-run: show built request bytes without sendingbmcli uds request --dry-run 22 F1 90
# Override session parameters for this requestbmcli uds request --timeout=3000 --channel=10356/0 \ --request-id=0x7E0 --response-id=0x7E8 3E 00
# Layer the UDS and ISO-TP timers and bound total command runtimebmcli uds request --p2-timeout=1000 --p2-star-timeout=5000 \ --n-cr-timeout=1000 --deadline=10000 --block-size=64 22 F1 90| Option | Default | Description |
|---|---|---|
--channel |
session | Override the channel for this request only |
--flags |
session | Select classic or fdf for this request only |
--request-id |
session | Override TX ID for this request only |
--response-id |
session | Override RX ID for this request only |
--timeout |
5000 |
Compatibility fallback for P2, P2* and N_Cr, 1..60000 ms |
--p2-timeout |
--timeout |
First response-frame wait, 1..60000 ms |
--p2-star-timeout |
--timeout |
First-frame wait after NRC 0x78 responsePending, 1..60000 ms |
--n-cr-timeout |
--timeout |
Sliding gap deadline between valid ISO-TP frames, 1..60000 ms |
--deadline |
disabled | Non-refreshing total command deadline, 1..60000 ms when supplied |
--block-size |
64 |
Receiver Block Size advertised in FC/CTS, 1..255 |
--data |
— | Raw hex data (alternative to positional args) |
--suppress-positive-response |
off | Set bit 7 on a supported subfunction and accept a successfully transmitted request with no positive response |
--dry-run |
— | Show request bytes without sending |
Positional args: hex bytes (3E 80) or service name + parameters.
Value options accept both --option=value and --option value. Their value
tokens are never interpreted as positional request bytes; for example,
--channel 10356/1 and --channel=10356/1 produce the same payload. An option
name without its value, or an empty --option=, is rejected before daemon or
hardware access. Hexadecimal byte strings consist of complete two-nibble bytes
within each contiguous run; ABC and A BB are invalid.
Quote space-separated --data values, for example --data "22 F1 90".
One-off channel, ID, and flag options never modify the state returned by
uds config get. Request and response IDs must be distinct 29-bit CAN IDs;
explicit ID zero is valid. BMCLI rejects malformed or truncated hex data and
invalid timeouts before opening ISO-TP. Invalid one-off request IDs, timeouts,
and raw data return the canonical error envelope with
error.code=invalid_argument;
the human-readable message identifies the rejected value class. Configure
ISO-TP padding through uds config set --padding=<byte>; raw-request Help does
not expose a separate one-off padding option.
The first response frame uses P2. After a valid NRC 0x78, the next first
frame uses P2*. Once a multi-frame response has started, each valid FF/CF and
completed FC/CTS refreshes N_Cr. --deadline, when present, starts with the
command and never refreshes, so it can stop a continuously valid but too-slow
segmented response without widening or changing N_Cr. Standalone and daemon
execution use the same parameter model. P2 begins only after the complete
request has been transmitted; an explicit --deadline bounds that transmission
as part of the whole command, while the no-deadline compatibility path retains
the legacy --timeout bound.
The default receiver Block Size is 64 because it needs far fewer FC/CTS turns than BS=8 for a maximum classic-CAN PDU. Both values are supported. On the current Linux BMAPI runtime, each extra FC turn can expose the library’s roughly 250 ms libusb event wait, so BS=8 is correct but measurably slower; select it only when required by the peer and size an explicit command deadline for the complete transfer. This does not change or relax N_Cr.
Suppression is service-aware. BMCLI accepts it only for UDS services whose
second request byte is a subfunction. It rejects the option for services such
as ReadDataByIdentifier (0x22) so bit 7 cannot silently corrupt the first DID
byte. A raw request that already contains the suppression bit, such as 3E 80,
is recognized as suppressed even without the option. After a suppressed request
is transmitted successfully, BMCLI returns response_suppressed immediately;
it neither waits for nor consumes a response belonging to another transaction.
uds did read/write
Section titled “uds did read/write”Read or write one 16-bit Data Identifier with service 0x22 or 0x2E.
Values remain raw bytes unless an ECU data definition assigns a type and unit.
--verify performs one explicit 0x22 read after a positive write and fails if
the returned bytes differ; BMCLI never retries the write itself.
For all UDS Helpers, error.retryable=true is limited to transient failures of
read-only operations. A timeout after a state-changing request is reported as
non-retryable because the ECU may already have completed the operation.
bmcli uds did read 0xF190 --format=jsonbmcli uds did write 0xF1A1 --data=12345678 --verify --format=jsonuds session change / ecu-reset
Section titled “uds session change / ecu-reset”Use named values for common subfunctions or a numeric subfunction reported by
runtime Help. ECU Reset accepts hard (0x01), key-off-on (0x02), and
soft (0x03), or a numeric value from 1 through 127. hard requests an ECU
hard reset but does not guarantee a complete power cycle; key-off-on requests
the target ECU’s key-off/on reset behavior; soft requests software
reinitialization without requiring a full power cycle. Support and exact effects
remain ECU-specific.
A session response containing timing bytes reports P2 in milliseconds and P2* in the standard 10 ms units. ECU reset is a state-changing ECU operation, not an analyzer reset, and is never automatically retried. Inspect the exact request without changing ECU state first:
bmcli uds session change default --format=jsonbmcli uds session change programming --format=jsonbmcli uds session change extended --format=jsonbmcli uds ecu-reset hard --dry-run --format=jsonuds memory read/write
Section titled “uds memory read/write”ReadMemoryByAddress (0x23) and WriteMemoryByAddress (0x3D) use ISO 14229
ALFID layout: the low nibble is address width and the high nibble is memory-size
width. BMCLI derives the minimum lossless widths, or accepts explicit widths of
1..8 bytes. Addresses, allowed ranges, security/session preconditions and data
meaning are ECU-specific and must not be guessed.
The current software ISO-TP P0 scope is 4095 bytes, including the UDS service
byte. A memory read therefore accepts at most 4094 data bytes. A memory-write
request is rejected before copying or transmitting if its SID, ALFID, address,
size and data would exceed 4095 bytes. Semantic-helper timeouts are strict
decimal integers from 1 through 60000 milliseconds.
Once a UDS multi-frame response starts, each accepted consecutive frame and
completed FC/CTS refreshes N_Cr. A valid long response may therefore take longer
than one P2 interval overall; an individual frame gap still times out. The generic
isotp recv command retains its existing overall receive deadline.
For generic uds request and isotp recv, BMCLI defaults to a bounded 64-frame
receiver CTS window and accepts an explicit --block-size from 1 through 255.
The value describes how many consecutive frames the remote sender may transmit
before BMCLI sends the next FC/CTS. It does not alter the sender-side Block Size
reported by an ECU when BMCLI is transmitting.
bmcli uds memory read --address=0x20000000 --size=16 --format=jsonbmcli uds memory write --address=0x20000000 --data=01020304 --format=jsonbmcli uds memory read --address=0x20000000 --size=16 \ --address-length=4 --size-length=2 --dry-run --format=jsonuds routine start/stop/results
Section titled “uds routine start/stop/results”Control one 16-bit routine identifier with service 0x31. --data is the
routine option record. The positive response payload after the echoed control
type and routine identifier is returned unchanged as routine_status_record;
BMCLI does not impose an OEM-specific schema on it.
bmcli uds routine start 0x1234 --data=A55A --format=jsonbmcli uds routine results 0x1234 --format=jsonbmcli uds routine stop 0x1234 --format=jsonAll semantic helpers use the configured daemon endpoint, the same software
ISO-TP transaction path as uds request, the same bounded NRC 0x78 handling,
and strict positive SID/echo validation. Use --dry-run to inspect exact bytes
without transmitting. They do not replace uds request for less common UDS
services.
These nine bounded Helper operations accept the same one-request padding
override in both execution modes: uds did read|write, uds session change,
uds ecu-reset, uds memory read|write, and uds routine start|stop|results. --padding=<byte> enables padding with an exact value from
0 through 255, including the distinct value 0x00; --no-padding disables it
for this request. The options are mutually exclusive. If both are omitted, the
Helper inherits the configured session padding. An explicit option outranks the
session but never changes uds config get, project/user configuration, or the
next Helper invocation. Successful and dry-run JSON reports padding plus
padding_value ("0xNN" when enabled, null when disabled); text reports
padding=0xNN or padding=off.
Semantic --dry-run is a pure request builder and therefore does not require a
configured/open channel or diagnostic IDs. If --channel, --request-id, or
--response-id is supplied anyway, BMCLI validates that field; an explicitly
complete request/response pair must be distinct. Actual transmission still
requires the complete channel/request-ID/response-ID tuple. Because dry-run has
no bus or configuration side effect, a local or remote claim never blocks it;
the corresponding transmitting command remains protected by channel ownership.
These bounded helpers support text and one complete JSON document only. Use
--format=json for automation and Web integration. CSV is intentionally not a
UDS result format, and JSONL is reserved for streaming/progress commands.
Machine-readable failures retain the top-level state and use the common
error object: code, message, details, and retryable.
Ownership conflicts follow the same JSON contract rather than returning
prefixed text. After ISO-TP reassembly, an ISO 14229 negative response must be
exactly 7F <request-SID> <NRC>; shorter or longer payloads are reported as
invalid_response and never interpreted as responsePending.
uds load
Section titled “uds load”Load UDS service definitions from an XML file.
bmcli uds load --file=res/uds.xmluds save
Section titled “uds save”Save current UDS definitions to XML.
bmcli uds save --file=output.xmluds list
Section titled “uds list”List loaded UDS services and their sub-functions.
bmcli uds listbmcli uds list DiagnosticSessionControluds unlock
Section titled “uds unlock”Perform SecurityAccess (service 0x27) — the request-seed / send-key sequence.
--algo is always a path to an external security DLL/.so (must export
GenerateKeyEx or GenerateKeyExOpt). UDS SecurityAccess has no standard
algorithm, so bmcli ships no builtins — the OEM algorithm is always provided
as a DLL. --level accepts hex (0x11) or decimal (17); it is the
SecurityAccess sub-function.
Both 0x27 responses are read with NRC 0x78 (responsePending) retry, so an ECU that defers its reply is handled correctly.
bmcli uds unlock --level=0x11 --algo=res/sa.dll # Windows DLLbmcli uds unlock --level=0x11 --algo=./libsecurity.so # Linux .so| Option | Description |
|---|---|
--level |
Security access level (UDS sub-function), hex or decimal (required, e.g. 0x11) |
--algo |
Path to security algorithm DLL/.so (required) |
--timeout |
Timeout ms (default 5000) |
uds download
Section titled “uds download”Transfer a firmware image to ECU memory via services 0x34 (RequestDownload), 0x36 (TransferData), 0x37 (RequestTransferExit). Multi-format, multi-segment:
- Parses Intel HEX (
.hex, type 04 ext-linear addresses), Motorola S19 (.s19/.srec, S1/S2/S3), or raw binary (.bin). Use--format=autoto detect by extension/content. - A multi-segment file is downloaded as separate 34/36/37 cycles per segment.
- The
0x74response’smaxNumberOfBlockLengthis parsed and respected (override with--maxblock). Each0x36response is validated (SID + seq);0x37is validated too. A wrong-sequence or NRC aborts with a structured, AI-readable error (stage / segment / percent / expect / actual). - NRC 0x78 (responsePending) on any response is handled transparently.
- Before opening the diagnostic endpoint, every segment is checked against the selected ALF address/length widths, 32-bit address bounds, and every other segment for overlap. Gaps and adjacent segments remain valid.
--dry-runperforms that complete image/segment validation offline and prints the detected format, segment addresses,has_holes/gap_before, total bytes, transfer order, and estimated 0x36 block counts in text, JSON, and JSONL. It returns before daemon IPC or BMAPI initialization, never opens an endpoint, and never transmits 0x34/0x36/0x37. Without--maxblock, the plan labels the current 4095-byte fallback as an estimate because only an ECU0x74response can negotiate the actual maximum. CSV has no download-plan schema and is rejected explicitly; it never falls through to text output.
bmcli uds download --file=firmware.bin --addr=0x08000000bmcli uds download --file=app.hex --format=auto --alf=0x44 --maxblock=0x0FFFbmcli uds download --file=app.hex --dry-run --format=json| Option | Description |
|---|---|
--file |
Firmware file: .bin / .hex / .s19 (required) |
--format |
auto (default) / bin / hex / s19 |
--addr |
Start address, 0..0xFFFFFFFF (bin only; hex/s19 use per-segment addresses) |
--size |
Truncate to 1..0xFFFFFFFF bytes (bin only) |
--alf |
addressAndLengthFormatIdentifier 0..0xFF for 0x34 (default 0x44; high nibble = size bytes, low = address bytes) |
--maxblock |
Override the 0x74-negotiated maxNumberOfBlockLength; minimum 3 bytes |
--dry-run |
Validate the complete image and print an offline 0x34/0x36/0x37 plan without requiring an endpoint or transmitting |
checksum
Section titled “checksum”Compute a checksum / CRC of a file. This is a general-purpose tool (not part
of UDS) — useful for assembling RoutineControl 31 01 02 02 <crc> check requests.
Lives under its own top-level category, parallel to convert/database.
--algo follows the same unified resolution rule as uds unlock: builtin name
first, else external DLL/.so exporting ComputeChecksum.
bmcli checksum --file=app.hex --algo=crc32-ieee # builtinbmcli checksum --file=app.hex --algo=crc32-ieee --segment=0 # one segment onlybmcli checksum --file=app.hex --algo=./compute_checksum.dll # external DLLbmcli checksum --self-test # validate CRC check values| Option | Description |
|---|---|
--file |
Input file (required, or use --self-test) |
--format |
auto (default) / bin / hex / s19 |
--algo |
Builtin name (crc32-ieee, crc16-ccitt, crc16-xmodem, crc16-modbus) or external DLL/.so (default crc32-ieee) |
--segment |
all (default) or segment index N — compute over one segment |
--poly / --init / --xorout |
Override CRC parameters (advanced) |
Built-in crc32-ieee matches Python zlib.crc32 and the IEEE 802.3 CRC-32
(poly 0x04C11DB7, init 0xFFFFFFFF, reflected, xorout 0xFFFFFFFF; check value
0xCBF43926 for ASCII “123456789”). Output JSON includes both the combined
checksum and per-segment CRCs.
The external DLL signature (example/checksum_dll/compute_checksum_impl.c):
int ComputeChecksum(const uint8_t *data, uint32_t dataLen, uint8_t *outChecksum, uint32_t maxOutSize, uint32_t *outSize, uint32_t polynomial, uint32_t initValue, uint32_t xorOutValue, void *userArg);uds present send / start / stop / status
Section titled “uds present send / start / stop / status”Manage TesterPresent keep-alive. The default request is 3E 00; BMCLI waits for
and validates 7E 00. Add --suppress-positive-response to send 3E 80 and
avoid waiting for the deliberately suppressed positive response.
# Finite, validated requestsbmcli uds present send --count=3 --interval=2000
# Finite, suppressed requestsbmcli uds present send --count=10 --interval=2000 --suppress-positive-response
# Daemon-owned keep-alive for a longer diagnostic workflowbmcli uds present start --interval=2000 --suppress-positive-responsebmcli uds present status --format=jsonbmcli uds present stopsend is finite: --count defaults to 1, --interval to 2000 ms, and
--timeout to 1000 ms. It may run standalone when all endpoint options are
provided, or use daemon session configuration.
Request and response IDs follow the same distinct 29-bit contract as other UDS
operations, including support for explicit CAN ID zero. In daemon mode,
TesterPresent also refuses a response route already owned by XCP.
start requires the daemon. It snapshots the channel, request ID, response ID,
interval, timeout, and suppression mode, then owns one background keep-alive
task until stop, daemon shutdown, or fatal daemon cleanup. status reports
whether the task is active plus sent, response, failure, skipped, and
last-result counters. Its protocol wait runs outside the daemon command lock,
so status, stop, channel close, and configuration remain bounded. A cycle that
finds its correlated route owned by a foreground operation is not transmitted;
it increments skipped instead. stop cancels a live wait and is idempotent
when no task is active.
| Option | Commands | Default | Description |
|---|---|---|---|
--interval=<milliseconds> |
send, start | 2000 |
Period between requests |
--count=<N> |
send | 1 |
Finite request count |
--timeout=<milliseconds> |
send, start | 1000 |
Send and positive-response timeout |
--suppress-positive-response |
send, start | off | Send 3E 80 and do not wait for 7E 00 |
--channel, --request-id, --response-id |
send, start | session | Override or snapshot the UDS endpoint |
--dry-run |
send, start | off | Resolve the operation without transmitting or starting a task |
uds dtc
Section titled “uds dtc”Read, query, and clear Diagnostic Trouble Codes (UDS services 0x19 / 0x14). DTC codes are 3 bytes (24-bit) per ISO 14229-1.
# List DTCs; bare `uds dtc` and `active` are retained aliasesbmcli uds dtc listbmcli uds dtc active
# Select DTCs matching any named status bitbmcli uds dtc list --status=test-failed,confirmed
# Query all DTCs the ECU defines, regardless of statusbmcli uds dtc supported
# Get number of DTCs matching a mask (count only, no detail)bmcli uds dtc count
# List only confirmed DTCsbmcli uds dtc active --mask=0x09
# Query snapshot record IDsbmcli uds dtc snapshot-id
# Read one snapshot or extended-data record for DTC 0x001234bmcli uds dtc snapshot --dtc=0x001234 --record=0x01bmcli uds dtc extended --dtc=0x001234 --record=0x01
# Use record 0xFF when the ECU supports returning all recordsbmcli uds dtc snapshot --dtc=0x001234 --record=0xFF
# Clear all DTC groups (the default group is 0xFFFFFF)bmcli uds dtc clearbmcli uds dtc clear --group=0xFFFFFF| Subcommand | Hex Alias | UDS Service | Description |
|---|---|---|---|
(default) / list / active |
0x02 |
0x19 0x02 |
List DTCs matching status bits, with 3-byte codes + status |
count |
0x01 |
0x19 0x01 |
Count of DTCs matching mask |
supported |
0x0A |
0x19 0x0A |
All DTCs the ECU supports |
snapshot-id |
0x03 |
0x19 0x03 |
Snapshot record IDs per DTC |
snapshot |
0x04 |
19 04 <DTC3> <record> |
Snapshot data for a specific DTC and record selector |
extended |
0x06 |
19 06 <DTC3> <record> |
Extended data for a specific DTC and record selector |
clear |
— | 14 <group3> |
Clear a DTC group; FFFFFF selects all groups |
| Option | Default | Description |
|---|---|---|
--channel |
session | Override channel |
--flags |
session | Override configured classic CAN/CAN FD transport |
--padding |
session | Override configured ISO-TP padding with this byte |
--mask |
0xFF |
Status mask filter for active and count |
--status |
none | Comma-separated ISO status names for list/active/count; match-any and mutually exclusive with --mask |
--dtc |
required | 24-bit DTC for snapshot and extended; hexadecimal notation is recommended |
--record |
required | Record byte for snapshot and extended; 0xFF requests all records |
--group |
0xFFFFFF |
24-bit group for clear |
--timeout |
5000 |
Timeout in the range 1..60000 ms |
--request-id / --response-id |
session | Override the configured diagnostic IDs |
Accepted --status values are test-failed,
test-failed-this-operation-cycle, pending, confirmed,
test-not-completed-since-last-clear, test-failed-since-last-clear,
test-not-completed-this-operation-cycle, and
warning-indicator-requested. JSON output uses the ISO-style flag names such
as confirmedDTC in the status_flags array.
active, count, supported, snapshot-id, snapshot, extended, and
clear each have an action-specific machine-readable Help contract. For
example, run bmcli uds dtc snapshot --help --format=json before constructing
the request. Positional hex aliases remain available for the implemented 0x19
subfunctions; the former --sub option is not accepted.
The positive response to count is interpreted as
59 01 <status-availability> <DTC-format> <count-high> <count-low>. Snapshot
and extended-data requests are exactly six bytes, including service and
subfunction; no extra status-mask byte is inserted. JSON list records retain
the hexadecimal status byte and also expose status_flags as an array.
For an explicit record, snapshot/extended JSON separates requested_record,
response_record, and record_data; snapshot output additionally reports
number_of_identifiers. Selector 0xFF can return multiple OEM-sized records
whose boundaries cannot be inferred without external definitions. BMCLI
therefore reports record_selector="all", records_encoding="raw", and the
complete record section in records_data; it does not mislabel the first byte
as the only returned record.
With global --verbose, list output may enrich at most 32 DTCs with snapshot
and extended-data requests. All enrichment shares one additional command-timeout
budget and accepts at most 1024 response bytes per detail. JSON reports
detail_attempted, detail_completed, and details_truncated, with non-fatal
detail failures represented as null. Text output prints each attempted detail
or unavailable, followed by the same attempted/completed/truncated summary.
Neither format can turn a bounded list into an unbounded request sequence.
Elapsed link-setup time counts against the budget, and the remaining absolute
deadline caps transmit, ordinary receive, and every NRC 0x78 continuation;
responsePending cannot extend it.
Daemon and standalone DTC commands use one shared parser, byte transaction,
response decoder, and formatter. The two modes differ only in endpoint and
channel ownership, so snapshot-id, error envelopes, and verbose limits have
the same schema and behavior. In JSON mode, both success and failure documents
are emitted on stdout; stderr remains diagnostic-only. Standalone and one-off DTC endpoints accept
--flags=classic|fdf and optional --padding=<byte>; invalid flag names are
rejected. UDS request/response IDs are explicit values, so CAN ID zero is valid
when supplied and the two IDs remain distinct.
Source of truth: BMCLI 1.6.3 repository documentation. Run bmcli help <category> <action> --format=json for the exact contract of the installed version.