Skip to content

Own the full WiFi-module flash lifecycle in Core so consumers don't reimplement orchestration #269

Description

@cptkoolbeenz

Goal

Maximize reuse: any app/API flashing a WINC WiFi module should call one Core method and get the whole lifecycle (prep → port handoff → tool → recovery). Today daqifi-desktop had to wrap FirmwareUpdateService.UpdateWifiModuleAsync with a stack of workarounds because Core doesn't fully own the flow. Those workarounds are reusable device/protocol logic that belongs in Core.

What the desktop currently reimplements around Core (should move in)

  1. Port-release wait after device.Disconnect() (highest priority — already cost real debugging time)
    UpdateWifiModuleAsync disconnects the device then immediately launches the external WINC tool. Windows hasn't freed the USB-CDC COM handle yet, so the tool can't open the port and exits in ~1s. The desktop works around this with a ~1.5s pre-launch delay in its WifiPromptDelayProcessRunner. Core should wait for the port to actually be free (configurable, e.g. PostDisconnectPortReleaseDelay in FirmwareUpdateServiceOptions) between the disconnect and the tool launch.

  2. The "release the managed connection" handoff
    UpdateWifiModuleAsync requires a connected device (EnsureDeviceConnected) and disconnects it internally — but the desktop found that wasn't enough to free the port for the tool, so it now disconnects its own SerialStreamingDevice and passes Core a no-op BootloaderSessionStreamingDeviceAdapter just to satisfy the connected-device precondition. Core owning the full prep+disconnect+wait sequence would remove this hack entirely.

  3. No-op flash validation — ✅ done in feat(firmware): own the WiFi flash lifecycle and verify success from tool output #270, via output verification (supersedes the duration guard).
    Originally planned as a "false-success duration guard" (fail if the tool returns implausibly fast, <15s). That was superseded by a better approach: Core now verifies the flash from the tool's actual output — success requires the WINC tool's success marker (Operation completed successfully). The captured logs show the port-not-released case produces no tool output at all, so the missing marker fails it — without a magic-number threshold, and it also catches Programming device failed and exit-0-with-failure-markers, which a duration heuristic would not. No runtime guard is needed or wanted.

  4. LAN-update-mode prep + post-flash recovery sequences
    Desktop SerialStreamingDevice.EnableLanUpdateMode (POWer:STATe 1 → settle → SetLanFirmwareUpdateMode) and ResetLanAfterUpdate / transparent-mode-exit (SetUsbTransparentMode 0 / EnableNetworkLan / Apply / Save) duplicate / complement Core's sequence. Core should own the canonical prep and post-flash recovery so consumers don't hand-roll SCPI ordering.

  5. Chip-info read retry wrapper
    Desktop wraps ILanChipInfoProvider.GetLanChipInfoAsync in a 3×/2s retry (TryGetLanChipInfoAsync). A GetLanChipInfoAsync(retries, delay) helper in Core would let every consumer share it.

Acceptance

A consumer flashes a WINC module by calling a single Core entry point that: prepares LAN update mode, releases the serial port and waits for the OS to free it, runs the WINC tool (with the bridge-activation prompt hook still injectable for UX), validates the run wasn't a no-op, and restores normal LAN/transparent state — with no port-handoff or no-op-adapter workarounds needed in the consumer.

Filed from the daqifi-desktop WiFi-firmware work (PR #639). Related: #268 (parser resilience).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions