Skip to content

feat(core): model board_id in USB and BLE device-info status - #32

Merged
tburkhalterr merged 1 commit into
mainfrom
feat/device-board-id
Aug 4, 2026
Merged

feat(core): model board_id in USB and BLE device-info status#32
tburkhalterr merged 1 commit into
mainfrom
feat/device-board-id

Conversation

@tburkhalterr

Copy link
Copy Markdown
Contributor

Firmware now reports its board model as a stable slug (board_id, e.g. crowpanel_28) in device info on both transports (canshift-firmware#67, context in CANShift/canshift-firmware#66). This adds the matching contract in @canshift/core so the tuner can auto-detect an already-flashed device's board for the multi-board flashing chain.

Where the field landed

BLE STATUS — src/schemas/ble-status.ts (already modeled, added the typed field)
Firmware emits { ver, board_id, can, is_day }. The wire schema is deliberately .passthrough(), so board_id already flowed through untyped — this makes it a typed optional: board_id on BleStatusWireSchema, boardId?: string on BleStatus, and the ver→firmwareVersion style mapping board_id → boardId in bleStatusFromWire.

USB CMD_GET_STATUS — src/schemas/usb-status.ts (new)
The USB device-info response { status:"ok", version, protocol, is_day, board_id } was not modeled anywhere in core — the tuner had no typed contract for it, yet USB is the flasher's primary connection and #66's board auto-detection reads exactly this frame. Added a schema mirroring the BLE parseBleStatus pattern:

  • UsbStatusWireSchema (.passthrough(), matching the BLE status forward-compat convention) with status as the success discriminator, version/protocol/is_day required, board_id optional.
  • Domain UsbStatus = { firmwareVersion, protocolVersion, isDay, boardId? } (version→firmwareVersion, protocol→protocolVersion, board_id→boardId).
  • usbStatusFromWire + parseUsbStatus(raw): UsbStatusResult (the ok / invalid_json / not_an_object / wrong_shape discriminated result the tuner consumes).

Both are exported from the barrel (parseUsbStatus, USB_STATUS_MAX_STRING_LEN, types UsbStatus / UsbStatusResult), mirroring the BLE status export surface.

Naming / convention

board_id (snake_case) on the wire ↔ boardId (camelCase) in TS, via the *FromWire boundary mapper — same convention as ver → firmwareVersion, is_day → isDay.

No schema-version bump

These are ephemeral device→app status frames, not persisted DashboardConfig, so the CURRENT_SCHEMA_VERSION + migration rule does not apply. The change is purely additive: boardId is optional on both, so a frame from older firmware without it still parses.

Note: the firmware-caps-parity suite checks #define caps, not status-frame JSON keys, so there is no automated status-field parity assertion today — this keeps core's status contract in sync with firmware manually. A grep-style parity assertion could be a follow-up but is out of scope here.

Test plan

  • npm run build / npm run lint / npm run format:check — clean
  • npm test — 1039 passed, 3 skipped (unrelated); firmware-parity suites green with the sibling firmware checkout (which has canshift-firmware#67 merged). New coverage:
    • BLE: wire accepts board_id; bleStatusFromWire exposes boardId and omits it when absent; parseBleStatus exposes it end-to-end
    • USB: frame with board_id parses and exposes boardId; frame without it stays valid; passthrough tolerates unknown keys; invalid JSON / non-object / wrong-shape rejection paths

References CANShift/canshift-firmware#66. Do not merge — ready for review; the 2.5.0 release is handled separately.

@tburkhalterr
tburkhalterr merged commit edbf478 into main Aug 4, 2026
4 checks passed
@tburkhalterr
tburkhalterr deleted the feat/device-board-id branch August 4, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant