Skip to content

feat(cli): decrypt BLE packets in the cloud with ble decode - #58

Closed
buckleypaul wants to merge 1 commit into
mainfrom
feat/sync-decode
Closed

buckleypaul wants to merge 1 commit into
mainfrom
feat/sync-decode

Conversation

@buckleypaul

Copy link
Copy Markdown
Collaborator

Summary

Adds synchronous cloud decryption, so nearby packets can be attributed to devices without holding their keys.

  • cloud.decode_packets: one POST /org/{id}/packets/decode call of up to 25 advertisements. A 403 names the missing read-packets scope.
  • Organization.decode_packets: takes any number of AES-CTR/AES-EAX packets, dedupes identical advertisements, batches them, and returns results aligned to the input (None where the cloud could not decrypt). Packets outside the endpoint's 72h/2h window are answered None locally, since one invalid item fails the whole batch. Also adds get_device().
  • AesEaxPacket.raw keeps the service data byte for byte, as the endpoint needs it.
  • errors: HTTP 403/404/429 map to PermissionDeniedError, NotFoundError and RateLimitError; raise_for_response clips oversized error bodies.
  • ble decode: scans and streams cloud-decrypted rows, flushing every 25 packets or 2s and remembering each distinct advertisement's answer.
  • ble validate: needs only --device-id. It passes when the cloud decodes a nearby packet as that device, instead of polling retrieve_packets; --key adds an informational local decrypt check.
  • CLI cleanup: one _org_or_fail() helper for building the Organization, and the decode table printer reuses _StreamingTablePrinter.

tests/fake_packets.py builds correctly encrypted CTR and EAX advertisements for the new tests.

Test plan

  • pytest
  • ruff check src
  • hubblenetwork ble decode --timeout 30 against real devices
  • hubblenetwork ble validate --device-id <id> against a nearby device

Adds synchronous cloud decryption, so nearby packets can be attributed
to devices without holding their keys.

- cloud.decode_packets: one POST /org/{id}/packets/decode call of up to
  25 advertisements. A 403 names the missing read-packets scope.
- Organization.decode_packets: takes any number of AES-CTR/AES-EAX
  packets, dedupes identical advertisements, batches them, and returns
  results aligned to the input (None where the cloud could not decrypt).
  Packets outside the endpoint's 72h/2h window are answered None locally,
  since one invalid item fails the whole batch. Also adds get_device().
- AesEaxPacket.raw keeps the service data byte for byte, as the endpoint
  needs it.
- errors: HTTP 403/404/429 map to PermissionDeniedError, NotFoundError
  and RateLimitError; raise_for_response clips oversized error bodies.
- ble decode: scans and streams cloud-decrypted rows, flushing every 25
  packets or 2s and remembering each distinct advertisement's answer.
- ble validate: needs only --device-id. It passes when the cloud decodes
  a nearby packet as that device, instead of polling retrieve_packets;
  --key adds an informational local decrypt check.
- CLI cleanup: one _org_or_fail() helper for building the Organization,
  and the decode table printer reuses _StreamingTablePrinter.

tests/fake_packets.py builds correctly encrypted CTR and EAX
advertisements for the new tests.
@Micahscope

Copy link
Copy Markdown
Contributor

Now integrated into #57; can be closed

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