Repository navigation
cbio: authenticate the GS1 link and stream live glucose and history - #136
Closed
shroominic wants to merge 3 commits into
Closed
shroominic wants to merge 3 commits into
shroominic wants to merge 3 commits into
Conversation
Add the vendor V120 read builders and a strict 0A glucose decoder, plus a transport-free sync session that polls the newest index and pages stored history under explicit budgets. Every failure path returns a status instead of a measurement, records stay raw with isUnitVerified false, and the 08 raw-data layout is refused. The device-backed harness sends only the documented read queries (03 F0 04 09, 03 F0 03 0A, 06 0A <index> 00 00 C). On the live sensor all four reads return the same five-byte frame 23 F7 6F D9 F4, which fails the plaintext contract, so the capability currently terminates in decodeFailed. No activation, clock, reset, threshold, key, or authentication write is sent.
…tory The live sensor answers the vendor's own read queries once the link is authenticated with the vendor's per-frame stream mask, and the answer is its stored record stream: 9981 raw records, one per minute, contiguous from 2026-09-10T19:57:00Z to 2026-09-17T18:17:00Z on the last run. - cbio_crypto.dart carries the vendor stream mask and the frame transforms. The five-byte prompt the sensor sends unmasks to the valid control frame `04 00 00 00 FC`, which is what identified the encoding. - cbio_vendor_frames.dart builds the masked link frames the sensor accepts: device information, authentication, clock, and the two data reads. No activation, reset, threshold, key-registration, or firmware frame. - cbio_history_archive.dart assembles the raw `08` stream into an ordered archive with one record per index, plus explicit gap, overlap, and contiguity reporting. - The authenticated harness sends the vendor's masked sequence, records every write byte-for-byte in masked and plaintext form, and resumes the raw read at a given index so a bounded window can reach the newest record. Proven on the sensor: authentication succeeds with the 2A25 address octets as read (`result=1 status=0`); the `0A` path holds 1782 records that are all zero and stop at 2026-09-12T01:38:00Z; the `08` path streams to the present with raw `current` 39..97 and `temp` 274..460. Derived values stay marked `isUnitVerified == false` because no reference measurement confirms the scale.
This was referenced Sep 17, 2026
Open
Closed
Owner
Author
|
Carried by the GS1 consolidation in PR #209 (branch feature/cbio-gs1, head 3eca4f4). This PR is contained in the consolidated line; the merge that carries it is c85f827. Closing as subsumed by the consolidation - not as won't fix. The per-defect evidence stays in this thread, and the carrying commit above is where the change now lives. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #135. Stacked on
feature/cbio-gs1-live(PR #127); base is that branch,not
main. Stays open.What this adds
The vendor's own authenticated link, sent from the phone to the real sensor,
plus the bounded live/history capability it feeds.
packages/cgm_cbio/lib/src/cbio_crypto.dartcarries the vendor's staticper-frame stream mask and the mask/unmask transforms. The five bytes the
sensor sends when it wants authentication unmask to
04 00 00 00 FC, a validcontrol frame; that is what identified the encoding. Key and credential
provenance is recorded by derivation in
docs/testing/cbio-gs1-auth-material.md(sibling branch
docs/cbio-gs1-auth-material, PR docs(cbio): GS1 auth key source and runtime call sequence #138) and is not restated in code comments, this body, or the issue.packages/cgm_cbio/lib/src/cbio_vendor_frames.dartbuilds the masked framesthe sensor accepts: device information, authentication, the vendor clock, and
the
06 0A/06 08reads. Activation (07), reset, threshold,key-registration, and firmware frames are deliberately absent.
packages/cgm_cbio/lib/src/cbio_history_archive.dartingests the raw08stream, keeps one record per index, and reports
accepted,duplicate,notRawBatch,gap, pluscontiguousandsawOverlapinstead of guessing.openhealth/integration_test/cbio_glucose_authenticated_test.dartsends thevendor's masked sequence, logs every write byte-for-byte in masked and
plaintext form, and can resume the raw read at any index so a bounded window
reaches the newest record.
Proven on the live sensor
04 01 01 00 FA(result=1 status=0) for theaddress octets the 2A25 characteristic returns. Runs 1-3 first spent one
rejected attempt (
result=0 status=2) on those same six bytes reversed asecond time; run 4 used them as read and authenticated on the first attempt.
0Apath returns 1782 records, index 1..1782, and every packed field iszero; it stops at
2026-09-12T01:38:00Z.08path streams 9981 records, index 1..9981, contiguous, one perminute, from
2026-09-10T19:57:00Zto2026-09-17T18:17:00Z— the lastrecord lands in the same minute the read ran, so this is live data and not a
frozen archive.
current39..97,temp274..460. The newestrecord at capture time was index 9981, raw
current50, rawtemp315.Not claimed
current / 10gives 3.9..9.7 mmol/L, which is plausibleand matches how two independent clients read the field, but no reference
measurement confirms it, so
isUnitVerifiedstaysfalseand the raw integeris exposed next to any converted number.
0Afield is meaningful on this sensor. It is zero throughout while08carries signal, so only08is usable here.Safety
Four or five writes per session, all listed in the record, all logged
byte-for-byte in masked and plaintext form. No activation, reset, threshold,
calibration, key, or authentication-registration frame beyond the vendor's own
link authentication; no pairing or bond; the GATT link is released at the end of
each run; the longest read window was 300 s of read-only notifications. No
credential or key bytes appear in this PR.
Verification
dart format --output=none --set-exit-if-changed lib test- passeddart analyze --fatal-infos- no issuesdart test- 60 tests passed, including the published mask vectors, thearchive's gap/overlap/duplicate behavior, and a cross-check that the archive
and
parseCbioRawDataFrameagree on the same framesflutter analyzeinopenhealth- no issuesrecovered across them,
All tests passed!Full record:
docs/testing/cbio-gs1-glucose-live.md.