Skip to content

[Bug]: WRfit SR16 Sleep paging is only getting the first page #141

Open

Description

@brantpeery

What happened?

Ring: RWfit-family ring on JieLi 0xAB framing (SR16). Its feature list reports sleep supported (body byte 87 = 1).
App: PulseLoop 2.11.1 on Android, Samsung.

What happens: the ring records sleep and shows it on its screen, but PulseLoop shows no sleep after syncing. Heart rate and SpO2 history do sync.

What the app does: RWfitSyncEngine.requestJieliHistory() sends {05,05,10} once per connection (RWfitSyncEngine.kt:86-92). No second page and no {05,05,30} is ever sent; the driver marks the 0x30 variants "unported" (RWfitDriver.kt ~153-186). RWfitJLHistory.decodeSleep (RWfitJLHistory.kt:195-290) runs on each reply with no saved state, and only emits a session when a 0x22 end follows a 0x11 start in the same payload. So a night split across pages or connections, or a night not yet closed, is dropped silently.

What the vendor SDK does: sleep is the only stream synced with GET_DEL_GET_DEL (DHBleSdk.java ~969: read a page, delete it with {05,05,30}, repeat until the reply is a bare 3-byte body), and the parser walks 7-byte records across the joined data (h.java O()). The WeChat SDK uses the same getDeleteGetDelete strategy for sleep. PulseLoopiOS PR #138 implemented exactly this (RWfitHistorySync.swift:136-180): a sleep page journal, the delete after each page, and decoding once at the end. Android hasn't ported it. The vendor connect sequence also sends session-create and timezone before syncing, which Android skips.

Real-world impact (SR16, night of Oct 25–26, 2026): PulseLoop received the first sleep page (2:11 to 5:57 AM, start marker 0x11, no end) on 7 consecutive connections (7:54 to 8:26 AM EDT) and discarded it every time, because decodeSleep requires 0x11 and 0x22 in the same reply. The end of the night is on the next page, which it never requests: it sends {05,05,10} once per connection and never {05,05,30}, so each new connection got the same page 1 again. A separate tool that read {05,05,10} repeatedly on one connection (no delete) got page 2 (6:02 to 7:46 AM), then the 0x22 end at 7:49 AM, then an empty reply. Joined, the night is 2:11 to 7:49 AM, 5 h 38 min (deep 59, light 211, REM 58, awake 10 min); PulseLoop shows no sleep for it. Example page-1 reply as PulseLoop received it: ab1100a46d89050510 32717334110000 ... (truncated). The full capture (all 7 connections) is available.

Suggested fix: port the iOS RWfit history flow for at least sleep: page until empty, keep a per-device journal of sleep pages, decode the joined pages, and delete only after the data is saved. Keep the other streams as they are or move them to GET_GET_DEL.

Captured bytes: request ab0100039d12050510. A sync on the evening before the night, with no sleep recorded yet, returned an empty sleep body ab1100039d12050510. I can attach a diagnostics export from a failed morning sync.

issue_body.md

Steps to reproduce

  1. Sync the ring in the morning after sleep
  2. Sleep will continue to show no record.

Which ring are you using?

Other / not sure

iOS version

Android

iPhone model

Samsung S24

PulseLoop version / commit

DL from APK distribution page

Which area is affected?

Data sync / decoding

Logs / screenshots

Console conversation + my own debugging tool output showing full sleep conversation with the ring

Before submitting

  • I searched existing issues and this isn't a duplicate.
  • I removed any personal health data / secrets from logs and screenshots.

Activity

  1. brantpeery commented on Oct 28, 2026

    @brantpeery
    Author

    I attached this here so iOS could take advantage of the full log as well. I know this is an Android issue, but I suspect is should be fixed in iOS first and pushed to Android.

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

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions