# 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 today, put a narrow local backend between the browser
  and BMCLI. The backend owns subprocesses and exposes only application-specific
  endpoints. Never let browser input become an arbitrary command line.
- Do not assume BMCLI has an embedded web server or REST API until runtime help
  lists the corresponding command. When that capability is released, query its
  help and migrate deliberately.

## 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, supply direction,
protocol version, checksum model, frame ID, DLC, and schedule ownership as typed
configuration. Open every daemon endpoint before installing slave responses.
BMCLI currently exposes master-write/header-request/capture primitives, not LDF
parsing or a schedule engine, so keep reviewed LDF-derived schedules in the host
application and invoke the current runtime-discovered commands.

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