BMCLI replay
Reference version: BMCLI 1.6.3. Command names, parameters and machine-readable fields retain their source spelling.
Online (host-side) replay of an ASC or uncompressed BLF log file. CAN/CAN FD
works in standalone and daemon modes; LIN ASC/BLF replay uses a daemon-opened LIN channel so its role,
electrical setup and schedule ownership remain explicit. For on-device replay
from the device’s flash, use offline replay start (see
offline).
For BLF input, consecutive uncompressed LOG_CONTAINER payloads form one
logical object stream. An object header, body, or alignment padding may cross a
container boundary; container headers and their physical alignment padding are
not exposed as object bytes. Empty containers are allowed. Compressed,
truncated, or structurally invalid containers fail explicitly rather than
silently dropping or truncating frames.
replay start
Section titled “replay start”In daemon mode the list is an ordered subset of already-open channels. Every listed target and every explicit map target is validated before the worker starts; an unopened target fails the whole start without sending. List position is independent of physical port and daemon slot. Numeric channel selectors retain the existing enumeration-index-first/slot-fallback rule; closing another channel does not renumber the running replay.
One worker reads the file on one timeline and tracks transmit completions per
destination. Start/status JSON adds target_channels (ordered daemon slots),
channel_mappings (recorded_channel, destination channel slot), and
channel_mask (union of all destinations). Legacy channel is the first
listed target. Closing any destination stops the remaining whole replay at a
safe point; completed frames remain sent, with partial counters retained.
bmcli replay start --channel=0 --file=logfile.ascbmcli replay start --channel=10356/0 --file=logfile.asc --loop --speed=2# Replay a file recorded on a different channel as-is:bmcli replay start --channel=10356/0 --file=recorded_on_ch2.asc --ignore-channel# Fixed 20ms inter-frame gap instead of original timestamps:bmcli replay start --channel=0 --file=logfile.asc --msg-delay=20# As fast as possible (back-to-back):bmcli replay start --channel=0 --file=logfile.asc --ignore-timestamp# Loop with 500ms gap between iterations:bmcli replay start --channel=0 --file=logfile.asc --loop --cycle-delay=500| Option | Default | Description |
|---|---|---|
--channel |
(required) | Channel list (comma-separated SN/port, UID/port, or legacy index). Selected in listed order (opened by standalone, pre-opened for daemon); list position i is routing position i (1-based). Single channel = position 1 only. |
--file |
(required) | ASC or uncompressed BLF log file path |
--speed |
1.0 |
Speed multiplier in (0, 100] (2 = twice as fast). Only meaningful in retain-timestamp mode. Invalid text, NaN and out-of-range values fail before replay starts. |
--loop |
off | Loop cyclically |
--ignore-channel |
off | Send every frame to the first opened channel (single-channel dump), bypassing positional routing. |
--map-channel=<asc_ch>:<spec> |
(none) | Override: route ASC channel <asc_ch> to physical channel <spec>. Repeatable. See routing rules below. |
--map-strict |
off | Only ASC channels with an explicit --map-channel entry are sent; all others are skipped (and counted as errors). Disables positional default. |
--msg-delay=<ms> |
(off) | Fixed inter-frame spacing in [0, 60000) ms, overrides original timestamps. 0 = back-to-back. First frame is always sent immediately. |
--ignore-timestamp |
off | Semantic alias for --msg-delay=0: send frames back-to-back with no inter-frame delay. |
--cycle-delay=<ms> |
0 |
Interruptible gap in [0, 60000) ms applied only between loop iterations. |
Channel routing (per frame, highest-precedence first). The hardware port number is not consulted — ASC channel numbers are purely positional:
- explicit
--map-channel=N:specmatch → mapped channel --map-strict→ skip + count as error--ignore-channel→ first opened channel (--channelposition 1)- positional: ASC channel N → the N-th opened channel (if N is within the opened list)
- otherwise → skip
So with --channel=A,B,C opened, ASC ch1→A, ch2→B, ch3→C by default. ASC ch4 (no position 4) is skipped unless --ignore-channel or mapped. With a single --channel=A, only ASC ch1 is sent by default — use --ignore-channel to dump all frames onto A, or --map-channel=N:A to route a specific channel there.
# Multi-channel recording -> multi-channel hardware (purely positional)bmcli replay start --file=multi.asc --channel=10356/0,10356/1,10357/0# ASC ch1->10356/0, ch2->10356/1, ch3->10357/0
# Override specific channels (map on top of positional)bmcli replay start --file=multi.asc --channel=10356/0 \ --map-channel=1:10356/2 --map-channel=3:10357/0 --map-strict# ch1->10356/2, ch3->10357/0; everything else skipped (strict)
# Single channel, dump entire file onto itbmcli replay start --channel=10356/0 --file=recorded_on_ch5.asc --ignore-channel--map-channel resolves its spec independently of the --channel list (it opens the target channel). Do not list the same physical port in both --channel and --map-channel (the device-port open will fail — ports are exclusive).
Timing modes (evaluated in this order):
--ignore-timestamp→ back-to-back, no delay--msg-delay=<ms>→ fixed delay between every frame- default → retain original inter-frame timestamps (scaled by
1/speed)
The first frame of the initial iteration is sent immediately. Fixed-delay
deadlines are derived from the loop origin and frame index, so transmit
completion time does not accumulate into the requested spacing. At every loop
boundary an explicit --cycle-delay takes priority and is applied once. Without
an explicit cycle delay, retained-timestamp mode preserves the trace’s bounded
zero-to-first-frame interval. If that interval is zero, BMCLI applies a 1 ms
minimum loop guard; this keeps a one-frame retained trace from becoming an
unbounded busy loop. All timing and loop-boundary waits check stop state in
bounded slices.
Host replay submits CAN/CAN FD/LIN frames with BMAPI timeout 0, so the USB
transport and device queue provide their normal NAK/queue-full backpressure
without a one-second completion round trip on every frame. Each accepted frame
leases one nonzero six-bit hardware sequence identity. The replay completion
reader counts it as sent only after a matching real TX-completion event for
the same bus type, message ID, sequence and Broker generation. accepted
therefore means queued by BMAPI; sent means physically completed, and the two
may differ while replay is active.
If either the BMAPI host queue or the finite completion-identity window is
full, BMCLI pumps completions and retries the same frame without changing its
source order or deadline. A finite replay performs a data-driven EOF drain and
does not report success until every accepted frame has a matched completion.
Five seconds with no completion progress is a hard failure, as are write,
reader and completion errors. A valid completion that reports a hardware TX
error increments failed but remains a consumed event, so it does not suppress
the following input record. Cancellation remains interruptible and reports
pending accepted frames instead of presenting them as sent. Later frames still
reference the original absolute replay origin, so transient backpressure can
catch up without accumulating relative delays.
Daemon replay rejects a CAN channel configured in NoACK mode because BMAPI does
not publish a real transmit-completion event in that mode; queue acceptance is
not eligible to increase sent.
For retained timing, BMCLI honors the ASC header: with timestamps absolute,
the input timestamps remain absolute; with timestamps relative, record delays
are accumulated by the input layer. BLF timestamps are absolute. After this
normalization, each loop records one monotonic clock origin and the first source
timestamp. Every frame deadline is calculated directly as
origin + (timestamp - first_timestamp) / speed; actual wait completion and
send time never become the next frame’s origin. A late frame skips its expired
wait and subsequent frames continue along that same absolute timeline. Daemon
timing statistics are published and serialized from one synchronized snapshot,
including on start/reset and worker exit, so 32-bit builds cannot expose torn
or mixed-generation lateness counters.
ASC format support: Both classic CAN and CAN FD messages. Classic format
supports old (Ext/Std + R/T) and new Vector (Rx/Tx) styles. Frame-shaped
records are validated before transmission: channel/direction, standard versus
extended ID range, DLC/data-length agreement, exact payload bytes, and the
eight CAN FD tail fields must all be complete, with no trailing tokens.
Malformed records stop replay with an input error; unsupported non-frame event
records are skipped.
Historical Classic rows in the explicit directionless RTR form
timestamp channel id r [dlc] are accepted. Since the source has no direction,
BMCLI normalizes it to Rx; direction remains mandatory for data frames.
replay stop
Section titled “replay stop”bmcli replay stopIn standalone mode, use Ctrl+C.
replay status
Section titled “replay status”Survey of all replay-capable entities (mirror of logging status). Does NOT require --channel.
$ bmcli replay status[host] active=yes channels=10356/0 file=x.asc accepted=1260 sent=1234 failed=2 pending=24[dev 10356] replay=off[dev 10357] replay=on mode=always_on channels=0x0001 path=stored.asc cyclic=yes[host]— host-side (online) replay, tracked by the daemon.[dev SN]— each USB device’s on-device replay state viaBM_GetReplay.
Host replay likewise reports terminal errors/last_error for invalid input,
read, timing, write, or close failures instead of remaining deceptively active.
Standalone replay results and the daemon CLI/Web host status report
accepted, sent, failed, and pending. The counters reconcile as
accepted = sent + failed + pending; errors includes every failed completion.
They also report
current_lateness_ms, last_lateness_ms, max_lateness_ms,
average_lateness_ms, late_frames, late_threshold_ms, send_failures, and
dropped. late_threshold_ms is 2; late_frames counts only attempts whose
scheduling lateness is strictly greater than 2 ms. This measurement ends at
the first send attempt and does not include transmit-completion time.
Lateness is measured at the first send attempt relative to the absolute frame
deadline. A temporary full transmit queue is neither a send failure nor a drop;
the expected dropped value is therefore zero.
Optional --channel=<spec> filters to the matching entity.
In daemon mode, replay start, replay stop, and replay status honor the
global --format=json output contract. Status returns one object containing a
host object and a devices array; it never prefixes or appends human-readable
survey lines to JSON stdout. Daemon start and host status include the effective
timing_mode (retain_timestamp, fixed_delay, or back_to_back),
message_delay_ms, and cycle_delay_ms.
Source of truth: BMCLI 1.6.3 repository documentation. Run bmcli help <category> <action> --format=json for the exact contract of the installed version.