Skip to content

mi band 2/3/4: pairs-only support - #356

Open
abdulsaheel wants to merge 4 commits into
mainfrom
feat/miband234-pairs-only
Open

mi band 2/3/4: pairs-only support#356
abdulsaheel wants to merge 4 commits into
mainfrom
feat/miband234-pairs-only

Conversation

@abdulsaheel

@abdulsaheel abdulsaheel commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

adds legacy Mi Band 2/3/4 as a pairable band — auth key exchange, banks raw notifications. no decoded signals yet, experimental until real hardware confirms it.

Summary by Sourcery

Enable experimental, pairs-only support for Mi Band 2/3/4 with local authentication and raw notification capture.

New Features:

  • Add experimental pairing and reconnect support for Mi Band 2, 3, and 4 devices.
  • Persist locally generated pairing keys securely and support device pairing, synchronization, and forgetting.
  • Archive optional battery, step, and heart-rate notifications as raw data without decoding or historical offload.

Enhancements:

  • Integrate Mi Band support into device discovery, background synchronization, device management, and user-facing pairing flows.

Tests:

  • Add coverage for the AES authentication response, handshake state machine, raw notification archiving, and device lifecycle behavior.

no auth key vendor lock — locally generated, aes-128 challenge/response.
subscribes battery/steps/hr best-effort and archives them undecoded.
never touches history, never derives a metric.
@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 35 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Team

Run ID: ecca7a98-e70e-4730-9ccd-7fdd888fe8e7

📥 Commits

Reviewing files that changed from the base of the PR and between b98cae6 and d1f25cc.

⛔ Files ignored due to path filters (5)
  • test/adapter_signals_registry_test.dart is excluded by !test/**
  • test/adapters/miband234_auth_crypto_test.dart is excluded by !test/**
  • test/adapters/miband234_test.dart is excluded by !test/**
  • test/band_registry_test.dart is excluded by !test/**
  • test/miband_link_test.dart is excluded by !test/**
📒 Files selected for processing (8)
  • lib/ble/adapters/_registry.dart
  • lib/ble/adapters/miband234.dart
  • lib/ble/hrs_link.dart
  • lib/ble/miband_link.dart
  • lib/l10n/app_en.arb
  • lib/sync/background_sync.dart
  • lib/ui2/pairing/device_picker.dart
  • lib/ui2/profile/devices.dart

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai

sourcery-ai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds experimental pairs-only support for Mi Band 2/3/4 using a locally generated secure key and AES-128 challenge-response authentication, then collects optional notifications as unattributed raw archive data without decoding history or metrics; pairing, syncing, forgetting, UI registration, and replay-based tests are included, but real hardware validation remains outstanding.

Sequence diagram for Mi Band 2/3/4 pairing and authentication

sequenceDiagram
    participant User
    participant App
    participant Band as MiBand234
    participant SecureStorage
    participant Database

    User->>App: pairMiBand234(device)
    App->>SecureStorage: write pairing key
    App->>Band: write AUTH install key
    Band-->>App: key install response
    App->>Band: write AUTH challenge request
    Band-->>App: 16-byte challenge
    App->>App: miBand234AuthResponse(key, challenge)
    App->>Band: write AUTH encrypted response
    Band-->>App: authentication result
    alt authentication succeeds
        App->>Database: upsertDevice(miband234)
    else authentication fails
        App->>SecureStorage: delete pairing key
    end
Loading

File-Level Changes

Change Details Files
Registers Mi Band 2/3/4 as an experimental pairable adapter with authentication-only required GATT support and no decoded signals.
  • Adds Huami service and authentication, battery, and steps UUID constants.
  • Defines the registry entry with arrival-based timestamps and an empty signal declaration.
  • Adds AES-128/ECB challenge-response support and explicitly excludes history and metric decoding.
lib/ble/adapters/_registry.dart
lib/ble/adapters/miband234.dart
Implements the Mi Band authentication session and raw optional-channel collection.
  • Performs install-once, challenge, and authentication-result handshakes with bounded reply timeouts.
  • Subscribes to battery, steps, and standard heart-rate notifications only after authentication.
  • Archives optional notifications as tagged raw batches without producing decoded samples or checkpoints.
lib/ble/adapters/miband234.dart
Adds pairing lifecycle management, secure key storage, synchronization, and forgetting for Mi Band devices.
  • Generates and stores per-device 16-byte keys in secure storage and writes the device row only after authentication succeeds.
  • Connects paired bands for bounded snapshot sessions and persists raw archive rows with source attribution.
  • Handles teardown, failed-pair cleanup, key deletion, and dispatches forget operations separately from the primary band.
lib/ble/miband_link.dart
lib/ble/hrs_link.dart
Exposes Mi Band pairing in the application UI and localization.
  • Adds the device-picker description and pairing callback.
  • Adds a watch icon and experimental capability messaging for the device profile.
lib/l10n/app_en.arb
lib/ui2/pairing/device_picker.dart
lib/ui2/profile/devices.dart
Adds unit and replay coverage for cryptography, handshake sequencing, raw archiving, and lifecycle behavior.
  • Pins AES-128/ECB output to the published FIPS-197 vector and validates input sizes.
  • Tests first-pair versus reconnect handshakes, refusal and timeout behavior, and optional-channel forwarding.
  • Verifies raw archive contents, absence of decoded samples and checkpoints, device attribution, and forget behavior.
test/adapter_signals_registry_test.dart
test/adapters/miband234_auth_crypto_test.dart
test/adapters/miband234_test.dart
test/miband_link_test.dart

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Needs a human reviewer. This adds a new pairing trust boundary: it generates and installs a persistent AES key, stores it in secure storage, and uses the authentication exchange to grant access to the band. If the protocol or key lifecycle is wrong, reverting will not undo keys already installed or repair the resulting pairing; affected bands may require a factory reset, and a crypto flaw could expose authenticated access.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Failed to generate code suggestions for PR

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Failed to generate code suggestions for PR

Paired band never got run() invoked again after the handshake — add a
Sync now affordance for it on the device-detail screen (same
bounded-window snapshot shape as the ring's), and best-effort call it
alongside the ring at the end of every headless cycle.
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Unhandled Stream Error

The listen call on localLink.notify(kHuami234AuthChar) during pairing lacks an onError handler. If the band disconnects unexpectedly or the characteristic read fails, the stream will emit an error. Without an onError callback, this error will be thrown asynchronously into the zone, causing an unhandled exception that crashes the app. Add an onError handler (e.g., onError: (_) {}) to safely ignore the error and let the pairing timeout handle the failure.

final sub = localLink.notify(kHuami234AuthChar).listen((rec) {
  inbox.add(rec.$2);
});

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Failed to generate code suggestions for PR

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant