Skip to content

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.

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.

Terminal window
bmcli uds discover --channel=10356/1 --allow-functional --dry-run --format=json
bmcli uds discover --channel=10356/1 --allow-functional --format=json
bmcli uds discover --channel=10356/1 --allow-functional --probes=3 --timeout=500 --format=json
bmcli uds discover --channel=10356/1 --allow-functional --data="22 F1 90" --format=json

The 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 as 0x791/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.

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.

Terminal window
bmcli uds config set --channel=10356/0 --request-id=0x7E0 --response-id=0x7E8
bmcli uds config set --channel=10356/0 --request-id=0x7E0 --response-id=0x7E8 --flags=fdf --padding=0xCC
bmcli 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.

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 as nrc, reason, and error.message distinguish 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.

Terminal window
# --- Raw hex ---
# TesterPresent with a normal positive response
bmcli 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 session
bmcli uds request 10 03
# ECUReset -> hard reset
bmcli uds request 11 01
# CommunicationControl -> enable RX/TX
bmcli uds request 28 00 01
# RoutineControl -> start routine by identifier
bmcli uds request 31 01 FF 00
# RequestDownload
bmcli 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 hardReset
bmcli uds request DiagnosticSessionControl extended
bmcli uds request ReadDataByIdentifier VIN
bmcli uds request ReadDataByIdentifier 0xF190
bmcli uds request CommunicationControl enableRxAndTx
bmcli uds request RoutineControl startRoutine 0xFF00
# --- Options ---
# Dry-run: show built request bytes without sending
bmcli uds request --dry-run 22 F1 90
# Override session parameters for this request
bmcli 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 runtime
bmcli 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.

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.

Terminal window
bmcli uds did read 0xF190 --format=json
bmcli uds did write 0xF1A1 --data=12345678 --verify --format=json

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:

Terminal window
bmcli uds session change default --format=json
bmcli uds session change programming --format=json
bmcli uds session change extended --format=json
bmcli uds ecu-reset hard --dry-run --format=json

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.

Terminal window
bmcli uds memory read --address=0x20000000 --size=16 --format=json
bmcli uds memory write --address=0x20000000 --data=01020304 --format=json
bmcli uds memory read --address=0x20000000 --size=16 \
--address-length=4 --size-length=2 --dry-run --format=json

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.

Terminal window
bmcli uds routine start 0x1234 --data=A55A --format=json
bmcli uds routine results 0x1234 --format=json
bmcli uds routine stop 0x1234 --format=json

All 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.

Load UDS service definitions from an XML file.

Terminal window
bmcli uds load --file=res/uds.xml

Save current UDS definitions to XML.

Terminal window
bmcli uds save --file=output.xml

List loaded UDS services and their sub-functions.

Terminal window
bmcli uds list
bmcli uds list DiagnosticSessionControl

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.

Terminal window
bmcli uds unlock --level=0x11 --algo=res/sa.dll # Windows DLL
bmcli 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)

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=auto to detect by extension/content.
  • A multi-segment file is downloaded as separate 34/36/37 cycles per segment.
  • The 0x74 response’s maxNumberOfBlockLength is parsed and respected (override with --maxblock). Each 0x36 response is validated (SID + seq); 0x37 is 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-run performs 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 ECU 0x74 response can negotiate the actual maximum. CSV has no download-plan schema and is rejected explicitly; it never falls through to text output.
Terminal window
bmcli uds download --file=firmware.bin --addr=0x08000000
bmcli uds download --file=app.hex --format=auto --alf=0x44 --maxblock=0x0FFF
bmcli 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

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.

Terminal window
bmcli checksum --file=app.hex --algo=crc32-ieee # builtin
bmcli checksum --file=app.hex --algo=crc32-ieee --segment=0 # one segment only
bmcli checksum --file=app.hex --algo=./compute_checksum.dll # external DLL
bmcli 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);

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.

Terminal window
# Finite, validated requests
bmcli uds present send --count=3 --interval=2000
# Finite, suppressed requests
bmcli uds present send --count=10 --interval=2000 --suppress-positive-response
# Daemon-owned keep-alive for a longer diagnostic workflow
bmcli uds present start --interval=2000 --suppress-positive-response
bmcli uds present status --format=json
bmcli uds present stop

send 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

Read, query, and clear Diagnostic Trouble Codes (UDS services 0x19 / 0x14). DTC codes are 3 bytes (24-bit) per ISO 14229-1.

Terminal window
# List DTCs; bare `uds dtc` and `active` are retained aliases
bmcli uds dtc list
bmcli uds dtc active
# Select DTCs matching any named status bit
bmcli uds dtc list --status=test-failed,confirmed
# Query all DTCs the ECU defines, regardless of status
bmcli uds dtc supported
# Get number of DTCs matching a mask (count only, no detail)
bmcli uds dtc count
# List only confirmed DTCs
bmcli uds dtc active --mask=0x09
# Query snapshot record IDs
bmcli uds dtc snapshot-id
# Read one snapshot or extended-data record for DTC 0x001234
bmcli uds dtc snapshot --dtc=0x001234 --record=0x01
bmcli uds dtc extended --dtc=0x001234 --record=0x01
# Use record 0xFF when the ECU supports returning all records
bmcli uds dtc snapshot --dtc=0x001234 --record=0xFF
# Clear all DTC groups (the default group is 0xFFFFFF)
bmcli uds dtc clear
bmcli 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.