Repository navigation
Decode calibration replies, expire stale calibrations, keep the display type, recover unbonded reconnects - #98
Merged
Conversation
…ay type, recover unbonded reconnects - The 0x34 reply is result + detail bytes: 0/1 accepted (detail 0), 2 rejected with a reason, 3 factory calibrated (meanings from xDrip4iOS). "Accepted high" used to show as refused. Settings now shows the refusal reason, and the calibration state is requested after every reply. - A queued calibration more than 5 minutes old when the sensor connects is dropped and shown as not sent. - The display type is saved in the manager state, so a relaunch keeps the slot it paired with. - A stored-key reconnect that isn't answered as authenticated and bonded (e.g. 05 01 02 after "Forget This Device") drops the key so the saved code pairs again, like a challenge mismatch or noAppKey.
ps2
added a commit
to LoopKit/LoopWorkspace
that referenced
this pull request
Oct 22, 2026
- G7SensorKit: calibration reply decoding and stale calibration expiry (LoopKit/G7SensorKit#98), reconnect after a SystemMemoryReset (LoopKit/G7SensorKit#100), temporary sensor issue in settings (LoopKit/G7SensorKit#99) - LoopSupport: view the diagnostic report before sharing or sending it (LoopKit/LoopSupport#42) - OmnipodKit: pump view signal loss uses the last response time (loopandlearn/OmnipodKit#196) - EversenseKit: retry GetTxCertificate with tx_flags inverted on the 365 (LoopKit/EversenseKit#8)
ps2
added a commit
to jeremybarnum/G7SensorKit
that referenced
this pull request
Oct 23, 2026
…tch setting - A reconnect the sensor answers authenticated but not bonded (05 01 02 after the system bond was lost) runs the certificate phase with the saved key and bonds again, without the code (EJM0's fix). If that fails, the key is dropped and the next connection pairs with the code, as LoopKit#98 does. - A pairing whose bond the sensor never confirmed, because the system pairing request couldn't show with the app in the background, used to surface later as a wrong pairing code. When that key is refused, the new Sensor Pairing Not Finished alert says to keep the app open and accept the request; it is retracted at the next reading (Kristin Kandschur's fix, worded for any app). - A Read on Apple Watch setting in the G7 settings, offered when a paired watch has the app installed or while it is on. The manager reports it as isConfigurationSharingEnabled, so the host passes the sensor to its watch only while it is on; the footer says the watch takes the sensor's watch slot. Eavesdropping, the code entry the watch needs sits under the setting. - The settings card counts down to the next reading in minutes and seconds, instead of counting up the minutes since the last; once a reading is a minute late it shows the minutes since, as before. - The setting, the new-sensor alert and the status text are localizable. Co-Authored-By: elias maurer <eliasjosefmaurer@gmail.com> Co-Authored-By: Kristin Kandschur <kristin.kandschur@proton.me>
kristinkand
added a commit
to kristinkand/G7SensorKit
that referenced
this pull request
Oct 24, 2026
…with the code From Pete Schwamb's LoopKit#80 (b97ad44, after LoopKit#98): a stored-key reconnect the sensor doesn't answer as authenticated, or whose certificate phase fails while bonding again (05 01 02 after the system bond was lost), throws storedKeyNotBonded. That counts as a stale key: it's dropped while a code is at hand, and the next connection pairs with it. Before, the first case was an unexpectedResponse that kept the key, and the second failed on every connection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LgnnHLJbhxmQaEjQNYR5VZ
kristinkand
pushed a commit
to kristinkand/G7SensorKit
that referenced
this pull request
Oct 24, 2026
…ay type, recover unbonded reconnects (LoopKit#98) - The 0x34 reply is result + detail bytes: 0/1 accepted (detail 0), 2 rejected with a reason, 3 factory calibrated (meanings from xDrip4iOS). "Accepted high" used to show as refused. Settings now shows the refusal reason, and the calibration state is requested after every reply. - A queued calibration more than 5 minutes old when the sensor connects is dropped and shown as not sent. - The display type is saved in the manager state, so a relaunch keeps the slot it paired with. - A stored-key reconnect that isn't answered as authenticated and bonded (e.g. 05 01 02 after "Forget This Device") drops the key so the saved code pairs again, like a challenge mismatch or noAppKey. (cherry picked from commit 45a1a96, LoopKit/G7SensorKit next-dev. This fork already decides the display slot from configuredByAnotherController, so the stored displayType is left out; the reconnect part was already here as storedKeyNotBonded.)
EJM0
pushed a commit
to EJM0/G7SensorKit
that referenced
this pull request
Oct 24, 2026
…with the code From Pete Schwamb's LoopKit#80 (b97ad44, after LoopKit#98): a stored-key reconnect the sensor doesn't answer as authenticated, or whose certificate phase fails while bonding again (05 01 02 after the system bond was lost), throws storedKeyNotBonded. That counts as a stale key: it's dropped while a code is at hand, and the next connection pairs with it. Before, the first case was an unexpectedResponse that kept the key, and the second failed on every connection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LgnnHLJbhxmQaEjQNYR5VZ (cherry picked from commit 30ec7a1)
ps2
added a commit
to jeremybarnum/G7SensorKit
that referenced
this pull request
Oct 24, 2026
…tch setting - A reconnect the sensor answers authenticated but not bonded (05 01 02 after the system bond was lost) runs the certificate phase with the saved key and bonds again, without the code (EJM0's fix). If that fails, the key is dropped and the next connection pairs with the code, as LoopKit#98 does. - A pairing whose bond the sensor never confirmed, because the system pairing request couldn't show with the app in the background, used to surface later as a wrong pairing code. When that key is refused, the new Sensor Pairing Not Finished alert says to keep the app open and accept the request; it is retracted at the next reading (kristinkand's fix, worded for any app). - A Read on Apple Watch setting in the G7 settings, offered when a paired watch has the app installed or while it is on. The manager reports it as isConfigurationSharingEnabled, so the host passes the sensor to its watch only while it is on; the footer says the watch takes the sensor's watch slot. Eavesdropping, the code entry the watch needs sits under the setting. - The settings card counts down to the next reading in minutes and seconds, instead of counting up the minutes since the last; once a reading is a minute late it shows the minutes since, as before. - The setting, the new-sensor alert and the status text are localizable. Co-Authored-By: elias maurer <eliasjosefmaurer@gmail.com> Co-Authored-By: kristinkand <163904051+kristinkand@users.noreply.github.com>
kristinkand
added a commit
to kristinkand/G7SensorKit
that referenced
this pull request
Oct 24, 2026
…with the code From Pete Schwamb's LoopKit#80 (b97ad44, after LoopKit#98): a stored-key reconnect the sensor doesn't answer as authenticated, or whose certificate phase fails while bonding again (05 01 02 after the system bond was lost), throws storedKeyNotBonded. That counts as a stale key: it's dropped while a code is at hand, and the next connection pairs with it. Before, the first case was an unexpectedResponse that kept the key, and the second failed on every connection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LgnnHLJbhxmQaEjQNYR5VZ
kristinkand
added a commit
to kristinkand/G7SensorKit
that referenced
this pull request
Oct 24, 2026
…with the code From Pete Schwamb's LoopKit#80 (b97ad44, after LoopKit#98): a stored-key reconnect the sensor doesn't answer as authenticated, or whose certificate phase fails while bonding again (05 01 02 after the system bond was lost), throws storedKeyNotBonded. That counts as a stale key: it's dropped while a code is at hand, and the next connection pairs with it. Before, the first case was an unexpectedResponse that kept the key, and the second failed on every connection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LgnnHLJbhxmQaEjQNYR5VZ
kristinkand
pushed a commit
to kristinkand/G7SensorKit
that referenced
this pull request
Oct 24, 2026
…ay type, recover unbonded reconnects (LoopKit#98) - The 0x34 reply is result + detail bytes: 0/1 accepted (detail 0), 2 rejected with a reason, 3 factory calibrated (meanings from xDrip4iOS). "Accepted high" used to show as refused. Settings now shows the refusal reason, and the calibration state is requested after every reply. - A queued calibration more than 5 minutes old when the sensor connects is dropped and shown as not sent. - The display type is saved in the manager state, so a relaunch keeps the slot it paired with. - A stored-key reconnect that isn't answered as authenticated and bonded (e.g. 05 01 02 after "Forget This Device") drops the key so the saved code pairs again, like a challenge mismatch or noAppKey. (cherry picked from commit 45a1a96, LoopKit/G7SensorKit next-dev. This fork already decides the display slot from configuredByAnotherController, so the stored displayType is left out; the reconnect part was already here as storedKeyNotBonded.)
kristinkand
added a commit
to kristinkand/G7SensorKit
that referenced
this pull request
Oct 24, 2026
…with the code From Pete Schwamb's LoopKit#80 (b97ad44, after LoopKit#98): a stored-key reconnect the sensor doesn't answer as authenticated, or whose certificate phase fails while bonding again (05 01 02 after the system bond was lost), throws storedKeyNotBonded. That counts as a stale key: it's dropped while a code is at hand, and the next connection pairs with it. Before, the first case was an unexpectedResponse that kept the key, and the second failed on every connection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LgnnHLJbhxmQaEjQNYR5VZ
EJM0
pushed a commit
to EJM0/G7SensorKit
that referenced
this pull request
Oct 24, 2026
…with the code From Pete Schwamb's LoopKit#80 (b97ad44, after LoopKit#98): a stored-key reconnect the sensor doesn't answer as authenticated, or whose certificate phase fails while bonding again (05 01 02 after the system bond was lost), throws storedKeyNotBonded. That counts as a stale key: it's dropped while a code is at hand, and the next connection pairs with it. Before, the first case was an unexpectedResponse that kept the key, and the second failed on every connection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LgnnHLJbhxmQaEjQNYR5VZ (cherry picked from commit 30ec7a1)
kristinkand
pushed a commit
to kristinkand/G7SensorKit
that referenced
this pull request
Oct 25, 2026
…ay type, recover unbonded reconnects (LoopKit#98) - The 0x34 reply is result + detail bytes: 0/1 accepted (detail 0), 2 rejected with a reason, 3 factory calibrated (meanings from xDrip4iOS). "Accepted high" used to show as refused. Settings now shows the refusal reason, and the calibration state is requested after every reply. - A queued calibration more than 5 minutes old when the sensor connects is dropped and shown as not sent. - The display type is saved in the manager state, so a relaunch keeps the slot it paired with. - A stored-key reconnect that isn't answered as authenticated and bonded (e.g. 05 01 02 after "Forget This Device") drops the key so the saved code pairs again, like a challenge mismatch or noAppKey. (cherry picked from commit 45a1a96, LoopKit/G7SensorKit next-dev. This fork already decides the display slot from configuredByAnotherController, so the stored displayType is left out; the reconnect part was already here as storedKeyNotBonded.) (cherry picked from commit 8d07c48)
EJM0
pushed a commit
to EJM0/G7SensorKit
that referenced
this pull request
Oct 25, 2026
…connect into the tail, Pete Schwamb's LoopKit#83, LoopKit#93, LoopKit#98 ba78db3: as the app leaves the screen the hold keeps running, no start delay (CBConnectPeripheralOptionStartDelayKey doesn't hold on the watch) and no connect into the sensor's advertising tail, which watchOS counts against the watch. 5390728 is the refused-rebond fix this branch has as 4a2f884. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0135v4JApHewuwGjWKiSPDNY
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.
Four fixes from comparing the direct-mode code with xDrip4iOS 7.1.1.
Calibration reply decoding. The
0x34reply is34 xx result detail. Result 0 is accepted (high), 1 accepted (low), 2 rejected with a reason in the detail byte, and 3 factory calibrated. An acceptance only counts when the detail byte is 0. We read the two bytes as one number and treated only 1 as accepted, so an "accepted high" reply (34 xx 00 00) showed as refused. The byte meanings are from xDrip4iOS (DexcomG7CalibrationMessages.swift).34 00 01 00(2026-09-15), still decodes as accepted.0x32) is now requested after every reply, not just after an acceptance, so the settings screen follows what the sensor actually did.Queued calibrations expire. A calibration still waiting when the sensor connects more than 5 minutes after it was entered is dropped and shown as "not sent", instead of going out with a stale meter value. This covers a calibration carried across an app relaunch. xDrip uses the same 5-minute limit.
Display type is saved. It was not part of the manager's saved state, so every relaunch went back to the phone slot. Older saved state still defaults to phone.
Stored-key reconnect that isn't bonded. When a reconnect with a stored key gets back anything other than authenticated and bonded (e.g.
05 01 02after "Forget This Device" in iOS Bluetooth settings), the stored key is now dropped and the next connection pairs again with the saved code, the same as for a challenge mismatch ornoAppKey. Before, it threwunexpectedResponse("reconnect")and stayed on "Connection Refused" until the user re-paired by hand. Without a saved code the key is kept, as before.Testing: the G7SensorKit unit tests pass (176), with new tests for each change, and the LoopWorkspace scheme builds. Not tried on a sensor.