Skip to content

Don't offer firmware updates to non-Nyquist devices — the update path has no device-type gate #825

Description

@cptkoolbeenz

The app now connects to devices that are not Nyquist hardware and carry their own, separate firmware. It still offers them the Nyquist firmware release, because the outdated-check compares versions without ever looking at what the device is.

Concretely: a Gloor IAQ board (ESP32-S3, device_pn not Nq*, own firmware versioning) connects over TCP and serial and gets flagged as having outdated firmware — because its version string sorts below the latest Nyquist release. Accepting that offer would flash PIC32 Nyquist firmware onto an ESP32-S3.

Where

IsFirmwareOutdated is set in two places, and neither considers device type:

Daqifi.Desktop/ViewModels/DaqifiViewModel.cs:1469

connectedDevice.IsFirmwareOutdated =
    FirmwareVersion.Compare(DeviceVersion, latestFirmwareVersion) < 0;

Daqifi.Desktop/Device/Firmware/FirmwareUpdateCoordinator.cs:845

var updateCheck = await _firmwareDownloadService.CheckForUpdateAsync(
    device.DeviceVersion ?? string.Empty, includePreRelease: true);
device.IsFirmwareOutdated = updateCheck.UpdateAvailable;

The only existing guard is at DaqifiViewModel.cs:1458 — skip if the device has no DeviceVersion property. That filters devices with no version at all, not devices with a version from a different product line. Any device reporting a version gets compared against the Nyquist release feed.

Suggested fix

IStreamingDevice.DeviceType already exists (IStreamingDevice.cs:64) and DeviceTypeDetector.DetectFromPartNumber maps only nq1/nq2/nq3 to Nyquist1/2/3, everything else to Unknown. So the gate is available at both call sites — no new plumbing:

// The firmware feed is Nyquist-only. A device from another product line has
// its own firmware and must never be offered this one.
if (device.DeviceType is not (DeviceType.Nyquist1 or DeviceType.Nyquist2 or DeviceType.Nyquist3))
{
    device.IsFirmwareOutdated = false;
    continue;
}

Worth deciding explicitly how DeviceType.Unknown should behave. Defaulting Unknown → no update offered is the safe direction: a device the app cannot identify is precisely the one that should not be flashed with Nyquist firmware. It does mean a genuine Nyquist that fails to report its part number stops being offered updates, which is a visible-but-harmless regression, versus the current failure mode of offering a cross-family flash.

Also worth checking the UI: if the update affordance keys off IsFirmwareOutdated alone, the fix above is sufficient; if anything else can reach the flash path (a manual "update firmware" button that ignores the flag), that needs the same gate.

Why now

This will get worse rather than better — more non-Nyquist devices are coming, each with independent firmware and versioning. A per-device-family firmware source is the eventual shape, but the immediate need is just: do not offer a Nyquist image to something that is not a Nyquist.

Reproducing

Connect a Gloor IAQ board (TacunaDevelopment/Gloor_IAQ, firmware reports device_pn = "ESP32-S3", device_fw_rev = "0.1") over TCP :9760 or manual serial, and observe the firmware-update offer.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions