Conversation
The Anker manufacturer record (company id 0xffff) carries the device MAC, model, and a capability byte declaring which negotiation path the device accepts -- readable at scan time, before any frame is sent. Add a parser for it as the basis for choosing the cleartext vs encrypted handshake per device rather than by product class. Capability is length-relative (last byte when present, absent on the F3800), so it is derived from the sku length rather than read at a fixed offset. Decoded against the app's own field values for five bench records. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Move the AES-GCM negotiation out of PrimeDevice into SolixBLEDevice so any device can take it. The path is selected from the capability byte in the device's advertisement when the caller passes one, otherwise from the class default (encrypted for Prime devices, plain text for the Solix power stations). The device's declared MTU and auth mode from 4803 are echoed in 4005, and the timezone confer carries the local UTC offset. A fresh P-256 key pair is generated for every negotiation instead of the hard-coded key pairs; the keys the recorded test vectors were captured with move to the test constants and are pinned by the fake_time fixture. The cipher and ECDH primitives live in utilities as plain functions. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The client registration on the encrypted path now carries a client token (the class identifier unless the caller passes one) and the link only counts as negotiated once the device accepts it. Firmware that pairs clients answers a new token with status 9 and waits for its button: the device reports pairing_required, runs the registered pairing callbacks so a user can be prompted, and connect() keeps waiting instead of restarting the handshake. The grant the device then pushes on pattern 030101 authorizes the link. The device remembers the token, so later connections with the same token are accepted without a press. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This was referenced Sep 20, 2026
This branch has not been deployed
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.
Replaces the pairing half of #49.
Firmware that pairs clients (C2000 G2 v0.3.3.0) answers the client registration with status
09the first time it sees a token and waits for the button on the device; once pressed it pushes a grant on packet pattern030101and remembers the token, so later connections are accepted silently.SolixBLEDevice(ble_device, capability=None, client_token=None): the token registered in4027, defaulting to the class UUID string so the Prime bytes on the wire are unchanged.4827status00authorizes the link;09setspairing_requiredand runs the registeredadd_pairing_callback/remove_pairing_callbackcallbacks so the user can be told to press the button (the callback option from the feat(prime): A91B2 (240W) + A2345 (250W) live BLE telemetry + control #51 review).connect()keeps waiting for the grant instead of restarting the handshake; the grant on030101authorizes.negotiatednow requires the authorization; the plain-text path is unchanged.protocols.rst, including a note that an account'sowner_user_idpassed as the token registers the same bytes the app sends and pairs without a press.Validated on hardware: C2000 G2 with a fresh token (button press) and with a remembered one.
Suite: 369 passed.
🤖 Generated with Claude Code