# Application Development Methodology

Use BMCLI as the high-level hardware adapter for dashboards, prototypes,
engineering tools, production-line utilities, LabVIEW integrations, and glue
applications. Keep product UI and domain behavior outside BMCLI.

## Select the integration shape

- Invoke BMCLI directly for operator-triggered, bounded actions.
- Use a shell script for a small fixed sequence with straightforward failure
  handling.
- Use Python or another host process for concurrent UI work, state machines,
  retries, JSON/JSONL parsing, caching, and reports.
- Use `gateway` when an existing upper computer already speaks the public
  remote BMAPI interface and must treat BMCLI-hosted USB CAN FD/LIN channels as
  remote analyzer channels. Query `bmcli help gateway start --format=json`
  before generating deployment commands. Its current canonical start shape is
  `bmcli gateway start --channel=<SN/port>[,<SN/port>...] --target=<client-IPv4>
  [--advertise=<gateway-IPv4>] [--name=<display-name>]`; UDP ports 3502 and 2502
  are fixed protocol ports rather than configurable `--bind` or `--port`
  options.
- For a browser dashboard, use the daemon-owned BMCLI Web service and its
  versioned typed API. Read `web-automation.md`, runtime capabilities, and
  `/api/v1/openapi.json` before generating the application. Never turn browser
  input into a shell command or assume an operation is exposed merely because
  it exists in CLI Help.

## Build the adapter

1. Model analyzer channel, bus timing, ECU identity, and DBC variant as explicit
   configuration. Read and validate the project bench profile at startup.
2. Wrap each bounded command in a typed function that supplies argv, checks exit
   code, parses JSON, records stderr, and applies a parent timeout.
3. Wrap JSONL commands as supervised streams with cancellation, bounded queues,
   reconnect policy, and raw capture retention.
4. Serialize operations that require exclusive access. Do not let separate UI
   callbacks race channel configuration, AutoSet, daemon startup, or flashing.
5. Make long-lived resources explicit: owner, start time, health, stop action,
   and recovery after host restart.
6. Convert BMCLI failures into domain errors such as hardware absent, stale bench,
   BUSOFF, transport timeout, UDS negative response, or invalid operator input.
7. Keep raw frames beside decoded signals. Treat a DBC as versioned application
   data and display its identity/hash in diagnostic views.

For LIN-backed tools, model master/slave role, bitrate, pull-up, power direction,
protocol version, checksum model, frame ID, DLC, and schedule ownership as typed
configuration. Open every daemon endpoint before installing slave responses.
Use the typed, read-only LDF views to inspect nodes, frames, signals, and named
schedules. `ldf schedule activate` may materialize a reviewed table containing
only unconditional and diagnostic frames into the runtime `system` table; inspect
that table with `lin schedule show system`. Event-triggered, sporadic, and node
configuration commands require host policy and are deliberately rejected by the
current executor. Keep the LDF source immutable and use raw message primitives
when no LDF exists or the required schedule semantics exceed this boundary.

For a remote BMAPI integration, keep the upper computer on the standard
`BM_Init -> BM_EnumerateRemote -> BM_OpenEx -> BM_Read/BM_Write -> BM_Close ->
BM_UnInit` lifecycle. Do not generate a custom UDP client. Use stable physical
`SN/port` values on the gateway host, but consume the returned remote channel
records on the upper computer instead of hard-coding logical indices. Treat the
gateway as the exclusive owner of exported RX queues and stop it before local
BMCLI traffic work.

## Design dashboards and operator tools

Separate acquisition rate from UI refresh rate. Aggregate high-rate frames in
the BMCLI data plane and send bounded snapshots or sampled series to the UI. Display
channel identity, timing, daemon state, dropped-data indicators, last update,
and stale/offline state. Require confirmation and authorization for controls
that transmit, change configuration, clear DTCs, unlock, or program an ECU.

For LabVIEW, prefer System Exec or a small wrapper VI around structured BMCLI
commands before adding a custom BMAPI binding. For Python, use `subprocess` and
standard JSON parsers; do not scrape human-readable output.

Test the adapter without hardware using recorded structured outputs, then run a
small representative HIL suite. Verify cancellation, process crashes, unplug and
replug, stale configuration, malformed output, BUSOFF, and UI reconnect behavior.
For gateway deployments, also verify firewall scope, the advertised/response
address, ports 3502 and 2502, exact CAN FD flags, LIN role translation, both
traffic directions, counters, and deterministic cleanup. The current GWR wire
protocol has no authentication or encryption and is limited to trusted networks.
