Skip to content

[PIN Lock] 1 - Detect and persist board PIN #358

Description

@KacperKozak

What to build

Discover whether a Board's firmware supports the VESC PIN write-lock, and persist the PIN alongside the rest of the Board Link so later sessions can use it.

Protocol reference: docs/pin-lock.md. The feature only exists on surfdado's fork; stock firmware silently drops the packet, so detection is a probe plus timeout.

Board Probe sends COMM_LOCK_STATUS (155) once, on the confirmed transport only (each blind probe with a wrong PIN bumps the firmware's bruteforce cooldown). A reply carrying magic 169 means pinlock firmware; the reply also states whether a PIN is currently set.

Two facts flow through to the Board Link: supportsPinLock and pinCode. A Board Link for a board that has a PIN set but no saved pinCode is incomplete — it reports outdated link integrity, which keeps telemetry working while blocking Firmware-Dependent Commands (CONTEXT.md:325). That is the correct semantic: re-link is the recovery path, and outdated already latches and already means re-link.

This requires bumping linkVersion 3 -> 4, so every existing link re-probes once. Accepted.

outdated now has a third cause, and the existing rider copy ("board link needs update", CONTEXT.md:436) is wrong for it — a rider who sees that will re-link, skip the PIN step, and loop. Carry a reason alongside the state so the surface can say the PIN was rejected.

Likely files

  • modules/vescape-core/ios/protocol/VescProtocol.swift - packet framing; REFLOAT_MAGIC lives here
  • modules/vescape-core/ios/connection/BoardTransportDetector.swift - Board Probe; sendProbeBurst / finalizeCurrentObservation
  • modules/vescape-core/ios/connection/TransportDetection.swift - Probe / Candidate shapes carrying probe facts
  • modules/vescape-core/ios/telemetry/BoardLinkPersistence.swift - compose / settings, linkVersion
  • modules/vescape-core/ios/runtime/BoardSession.swift - LinkIdentity, isComplete, LinkIntegrity
  • modules/vescape-core/src/index.ts - LinkIntegrity type, bridge payload types
  • CONTEXT.md - Board Link / Link Integrity Check definitions need the PIN fact

Implementation hints

hasBms is the precedent for a probe-discovered capability persisted on the link. Its full path:

BoardTransportDetector -> TransportDetection.Probe/.Candidate -> VescapeCoreModule bridge dict
  -> BoardLinkPersistence.compose/settings -> LinkIdentity -> BoardSessionController

Follow it exactly; every one of those sites needs the new fields.

COMM_LOCK_STATUS request is a magic byte then PIN as big-endian uint16:

[155][magic=169][pin_hi][pin_lo]

Reply:

[155][169][writelock][pin_matches][pin_is_set][lock_on_boot][pin_hi][pin_lo]

Do not read the trailing two bytes. They are the stored PIN in cleartext, marked in-source as development-only, and will be removed upstream.

pin_matches is unreliable during the firmware's cooldown — it returns 0 even for a correct PIN. pin_is_set and the magic byte are returned regardless, so the capability probe must read only those and ignore pin_matches.

isComplete at BoardSession.swift currently pins linkVersion == 3 with exact equality. Bump to 4 and add the PIN condition; a board that needs a PIN and has none saved is not complete.

Both native platforms plus index.ts need this — see the @parity tags on BoardLinkPersistence.swift and BoardSession.swift.

Acceptance criteria

  • Board Probe sends COMM_LOCK_STATUS once, on the confirmed transport only
  • Stock firmware (no reply) resolves to supportsPinLock = false without stalling the probe
  • Probe records whether a PIN is currently set on the board
  • supportsPinLock and pinCode persist on the Board Link and survive app restart
  • linkVersion bumped to 4; existing links re-probe once instead of breaking
  • A board with a PIN set and no saved pinCode reports outdated link integrity
  • Telemetry still flows on such a board; Firmware-Dependent Commands are blocked
  • outdated carries a distinguishable reason for PIN vs stale-version
  • Trailing PIN bytes of the reply are never read
  • iOS, Android and index.ts stay in @parity; CONTEXT.md updated

Blocked by

None - can start immediately.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:pin-lockVESC PIN write-lock: capability probe, PIN on Board Link, unlock-wrapped writescomplexity:highCritical paths, subtle correctness, native pipelines. Use opus.ready-for-agentFully specified, ready for an AFK agent

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions