Skip to content

fix v2 realtime HR + wrist-off drop in decodeFrame, dedupe timestamp packing - #38

Closed
abdulsaheel wants to merge 1 commit into
mainfrom
audit/fixes-round1-protocol
Closed

fix v2 realtime HR + wrist-off drop in decodeFrame, dedupe timestamp packing#38
abdulsaheel wants to merge 1 commit into
mainfrom
audit/fixes-round1-protocol

Conversation

@abdulsaheel

@abdulsaheel abdulsaheel commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

couple of decode bugs found in an audit pass:

  • decodeFrame never actually called parseRealtimeHrV2 for rec_type==2 packets, so live v2 HR bodies were getting run through the old v1 parser (fabricated RR intervals, wrong wearing state)
  • R10 live decode only emitted realtime_hr when hr>0, so a legit off-wrist reading (hr==0) fell through to a bare 'data_record' and the wearing state got lost
  • pulled the copy-pasted sec/subsec LE byte packing out of 5 command builders into one helper
  • fixed README/CONTRIBUTING pointing at stuff that isn't in the repo (ts/ oracle, _external/noop, bWanShiTong path) and added the 4 source files missing from the file list (band.dart, hrs.dart, oura.dart, gen5_records.dart)

tests + analyze pass.

Summary by Sourcery

Correct realtime heart-rate decoding and centralize timestamp encoding while aligning repository documentation with the current project layout.

Bug Fixes:

  • Decode realtime heart-rate v2 packets with the correct parser and preserve their heart rate, timestamp, location, and wearing state.
  • Emit live R10 heart-rate records for off-wrist readings so zero-heart-rate periods retain their wearing state instead of becoming generic data records.

Enhancements:

  • Deduplicate little-endian timestamp encoding across clock and alarm command builders.

Documentation:

  • Update project documentation to describe supported formats and refer to parity fixtures and external reverse-engineering resources accurately.
  • Document the previously omitted band, gen5 records, generic heart-rate service, and Oura source modules.

…imestamp packing, fix stale docs

decodeFrame never routed rec_type==2 to parseRealtimeHrV2 so live v2 HR
packets got misdecoded by the v1 parser (garbage RR, wrong wearing state).
also R10 live decode only emitted realtime_hr when hr>0, so a legit
off-wrist reading (hr==0) fell through to an unlabeled data_record and lost
its wearing state.

pulled the copy-pasted sec/subsec LE packing out of the 5 command builders
into one _leTimestamp helper.

README/CONTRIBUTING were pointing at stuff that doesn't exist in the repo
(ts/ oracle, _external/noop, bWanShiTong path) and missing 4 real source
files from the file list.
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 29 minutes.

View limit details

Limit details: You’ve used the included review 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 309b0856-bb8a-447a-b8b9-6c079d51e3f3

📥 Commits

Reviewing files that changed from the base of the PR and between 72f93bc and 51a1233.

📒 Files selected for processing (4)
  • CONTRIBUTING.md
  • README.md
  • lib/src/commands.dart
  • lib/src/control.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 Aug 29, 2026

Copy link
Copy Markdown

Reviewer's Guide

Fixes frame-level realtime HR dispatch for v2 and R10—including legitimate off-wrist readings—while deduplicating timestamp serialization in command builders and correcting repository documentation to match the current codebase.

Flow diagram for realtime HR frame decoding

flowchart TD
    A[decodeFrame receives data_record] --> B{Compact packet?}
    B -- Yes --> C{rec_type == 2?}
    C -- Yes --> D[parseRealtimeHrV2]
    D --> E[realtime_hr with wearing state]
    C -- No --> F[parseRealtimeHr]
    F --> G[realtime_hr]
    B -- No --> H{rec_type == Record.r10?}
    H -- Yes --> I[parseR10Lite]
    I --> J[realtime_hr with wearing = hr > 0]
    H -- No --> K[data_record]
Loading

File-Level Changes

Change Details Files
Correct live heart-rate decoding and preserve off-wrist state in frame-level record dispatch.
  • Route compact rec_type 2 packets through the v2 realtime HR parser and expose its timestamp, heart rate, wearing state, and location.
  • Emit R10 realtime HR records for zero heart rate and derive wearing state from the HR value instead of falling back to an undecoded data record.
lib/src/control.dart
Centralize encoding of WHOOP timestamp fields used by clock and alarm commands.
  • Add a shared helper for six-byte little-endian seconds/subseconds packing.
  • Replace duplicated packing logic across gen4/gen5 clock and alarm builders while preserving payload layouts.
lib/src/commands.dart
Bring repository documentation in line with the current source layout and test model.
  • Document the frozen parity fixture as the oracle and remove references implying the deleted TypeScript implementation is run by tests.
  • Describe supported device formats and add missing source files to the README file list.
  • Clarify that external reverse-engineering projects are references rather than repository paths.
README.md
CONTRIBUTING.md

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

Approved.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@abdulsaheel

Copy link
Copy Markdown
Contributor Author

squashed into #42 for one clean review — closing this round.

@abdulsaheel
abdulsaheel deleted the audit/fixes-round1-protocol branch August 29, 2026 13:16
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