Skip to content

docs: the opening packets are reads, and nothing requires them - #38

Merged
eman merged 1 commit into
mainfrom
correct-the-unlock-claim
Aug 18, 2026
Merged

docs: the opening packets are reads, and nothing requires them#38
eman merged 1 commit into
mainfrom
correct-the-unlock-claim

Conversation

@eman

@eman eman commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Two claims in these docs are not supported by anything in this repository, and both are now contradicted by direct evidence.

connection.md:3,28"the device requires an application-layer handshake to 'unlock' control capabilities and high-frequency telemetry", and "without this, the pump may ignore control commands (Start/Stop/Set Mode) and will only stream basic or empty telemetry."

device_info.md:50-52"Class 7 reading requires the device to be Authenticated via the handshake sequence. If the device is not authenticated, Class 7 requests may return empty payloads or fail."

Both entered in the initial documentation commit, hedged as "may ignore" and "may return ... or fail" — which is not how an observation gets written down. bench_findings.md, this repo's record of measured rather than inferred behaviour, says nothing about a handshake at all.

The mechanism could not have worked

The APDU's second byte is 0booLLLLLL — operation in the top two bits, payload length in the low six. So the 0x03 documented as "SET operation, 3 data bytes" is a GET with a 3-byte payload, and the three bytes after it are that payload, not a register address plus a value. That is where "register 0x9495, unlock code 0x96" came from.

All four packets are reads:

packet class operation reads
"Legacy Magic" ×3 2, Measured Data GET unit_family, unit_type, unit_version — answered 52 / 7 / 2
"Class 10 Unlock" ×5 10, Data Objects GET Object 86 Sub 6, operation status
"Extend 1" 5, Reference Values INFO scaling for item 0x4B, answered "unscaled"
"Extend 2" 11, 16-bit Measured INFO scaling for item 0x0F, answered "unscaled"

Reads cannot change device state, and INFO reads scaling metadata — it is not something that could extend an authorization.

And the field evidence closes it

Ten connection cycles sending none of them — two with the BLE bond cleared and re-paired, five across pump power cycles, three plain reconnects. All ten read all five Class 7 strings and reached full readiness. Nine accepted Class 3 START and STOP with the motor confirmed running. Across 1,019 captured frames there were no Class 2, Class 5 or Class 11 frames at all.

The bond-cleared cases are the ones that matter: a pump holding unlock state keyed to the bond was the one hypothesis that reconciled the earlier observations with the documentation, and it does not survive.

The independent ESPHome implementation agrees from the code side — its Class 7 read path holds no session reference and checks nothing.

Also corrected

  • The Class 10 read's object and sub were documented reversed: it is Object 86, Sub 6, not "SubID 0x5600 (Operation/Unlock) / ObjID 0x0006 (unlock object)".
  • The two address bytes described as one 16-bit "Service ID (GENI)" are a destination and a source — the pump's replies come back with the pair swapped, which a constant does not do.
  • packet_traces/02_authentication.md's byte-by-byte annotations, which are where the misparse is most visible.
  • The reimplementation guides now tell a new client to skip these packets rather than sending them "exactly N times".

What does not change

The packets themselves, and this client still sends them. Only the descriptions change.

Decode and experiment by jfriend00. See eman/esphome-alpha-hwr#174 for the full thread and eman/esphome-alpha-hwr#228 for the removal on that side.

Two claims in these docs are not supported by anything in this repository, and
both are now contradicted by direct evidence:

  connection.md: "the device requires an application-layer handshake to
  'unlock' control capabilities and high-frequency telemetry", and "without
  this, the pump may ignore control commands".

  device_info.md: "Class 7 reading requires the device to be Authenticated via
  the handshake sequence. If the device is not authenticated, Class 7 requests
  may return empty payloads or fail."

Both entered in the initial documentation commit, hedged as "may ignore" and
"may return ... or fail", which is not how an observation gets written down.
bench_findings.md -- this repo's record of measured rather than inferred
behaviour -- says nothing about a handshake at all.

The mechanism could not have worked. The APDU's second byte is 0booLLLLLL,
operation in the top two bits and payload length in the low six, so the 0x03
read as "SET operation, 3 data bytes" is a GET with a 3-byte payload. The
three bytes after it are that payload, not a register address plus a value,
which is where "register 0x9495, unlock code 0x96" came from. All four packets
are reads: a Class 2 GET of unit_family/unit_type/unit_version, a Class 10 GET
of Object 86 Sub 6, and two INFO queries. Reads cannot change device state.

And the field evidence closes it. Ten connection cycles sending none of them --
two with the BLE bond cleared and re-paired, five across pump power cycles,
three plain reconnects -- read all five Class 7 strings and reached full
readiness every time. Nine accepted Class 3 START and STOP with the motor
confirmed running. Across 1,019 frames there were no Class 2, Class 5 or
Class 11 frames at all.

Also corrected: the object and sub of the Class 10 read were documented
reversed (it is Object 86, Sub 6, not "Sub 0x5600 / Object 0x0006"), and the
two address bytes described as one 16-bit "Service ID" are a destination and a
source -- the pump's replies swap them.

The packets themselves are unchanged and this client still sends them. The
docs now describe what they are, and the reimplementation guides tell a new
client to skip them.

See eman/esphome-alpha-hwr#174 for the decode, the captures, and the removal
on that side. Decode and experiment by jfriend00.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR corrects protocol and reimplementation documentation that previously described an “authentication/unlock handshake” as required, clarifying (with supporting decode notes and field evidence) that the opening frames are reads/INFO queries and are not required for readiness, device-info reads, or control.

Changes:

  • Reframes the “authentication” step across reimplementation docs as optional opening reads and updates packet interpretations (GET vs SET, object/sub IDs, INFO meaning).
  • Updates protocol docs (connection.md, device_info.md, and packet trace annotations) to remove unsupported authentication requirements and correct byte-level decoding.
  • Adjusts reimplementation guidance/checklists to tell new clients to skip the opening reads while still documenting what the reference client sends.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
docs/reimplementation/README.md Updates the minimal implementation and concept docs to mark “authentication” as not required and describe opening reads accurately.
docs/reimplementation/layer_by_layer.md Renames “Authentication” to optional opening reads and updates the described sequence.
docs/reimplementation/common_pitfalls.md Updates CRC vectors commentary and revises the “authentication sequence” guidance to reflect the corrected interpretation.
docs/reimplementation/checklist.md Renames the checklist section to optional opening reads and updates early-step guidance accordingly.
docs/protocol/packet_traces/02_authentication.md Adds a correction notice and fixes byte-by-byte annotations to reflect GET/INFO semantics and correct object/sub decoding.
docs/protocol/device_info.md Removes the “authenticated” requirement for Class 7 string reads and replaces it with “connected + subscribed” guidance plus rationale.
docs/protocol/connection.md Rewrites the connection sequence to remove the unlock claim and documents the opening reads as optional, with corrected interpretations.
Suppressed comments (3)

docs/reimplementation/common_pitfalls.md:123

  • The two INFO queries are listed in the opposite order to the rest of the docs (and to the reference client's EXTEND_1 then EXTEND_2 order). This makes it hard to reproduce the client's behavior when desired.
4. 1x INFO query, Class 11 item `0x0F`: `27 05 E7 F8 0B C1 0F D0 C3`
5. 1x INFO query, Class 5 item `0x4B`: `27 05 E7 F8 05 C1 4B C3 82`

docs/reimplementation/checklist.md:32

  • This checklist section now calls the frames "Opening reads" and describes them as INFO queries, but the last two items are still labeled "Extend 1/2 packet". Renaming them here would keep terminology consistent across the reimplementation docs.
- [ ] Send Extend 1 packet
  - Packet: `27 05 E7 F8 05 C1 4B C3 82`
- [ ] Send Extend 2 packet
  - Packet: `27 05 E7 F8 0B C1 0F D0 C3`

docs/protocol/connection.md:109

  • INFO queries do read data (scaling metadata); they just don't write/change device state. Saying "it reads nothing" is misleading and contradicts the sentence immediately before it.
INFO asks for a data item's scaling metadata; it reads nothing and changes
nothing, which is why "Authorization Extend" was never an accurate name. The

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

## Overview

After BLE connection, the pump requires a specific sequence of "magic packets" to unlock full functionality. This sequence must be sent **exactly** as specified.
> ## ⚠️ Corrected 2026-08-18 — this is not an authentication sequence
operation, so this read is redundant rather than enabling.

### Repetition
Must be sent **exactly 5 times** in sequence.
@@ -106,12 +106,21 @@ pump. Do not reproduce it.

**Cause:** Skipped or incorrect authentication sequence.
@@ -49,8 +83,12 @@ Send this packet 3 times with a small delay (~50ms) between writes.
| 6-8 | `94 95 96` | Payload (Capabilities/Family Query) |
@eman
eman merged commit fd2dd91 into main Aug 18, 2026
7 checks passed
@eman
eman deleted the correct-the-unlock-claim branch August 18, 2026 15:04
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.

2 participants