Added homekit-decode.sh to the mix, and updated the readmes.

This commit is contained in:
Scott Garrett committed 2026-09-01 10:56:23 -04:00
1 parent 27ebf13f6f
commit 589ebaff46
3 files changed
+131 -12

No files matched your search

+70 -1
View File
@@ -9,6 +9,11 @@ is inside.
No build, no install, no package step. Two ways to use it: a browser app and a
command-line script that share the same decode logic.
There is also a separate, standalone command-line decoder for Apple **HomeKit**
setup codes — the `X-HM://` payload an accessory shows on first setup. That is a
different format from Matter's `MT:` (see [HomeKit setup-code decoder](#homekit-setup-code-decoder));
it has no browser counterpart and no companion tables.
## What it decodes
Given an `MT:` URI, the payload (84 bits, see [Data format](#data-format)) is
@@ -31,6 +36,7 @@ split into these fields:
|---|---|
| [`matter-qr-decoder.html`](matter-qr-decoder.html) | The browser app. Single self-contained HTML file (Vue 3 + Bootstrap 5.3, loaded from CDNs). |
| [`matter-decode.sh`](matter-decode.sh) | A pure-bash CLI port of the same decode logic. No camera scanning. |
| [`homekit-decode.sh`](homekit-decode.sh) | A standalone pure-bash decoder for Apple **HomeKit** setup codes (the `X-HM://` payload) — a different format from Matter's `MT:`, with no browser counterpart and no companion tables. |
| [`manufacturers.tsv`](manufacturers.tsv) | Tab-separated `vendor ID → name` table (~900 rows) used to turn a numeric vendor ID into a name. Shared by both tools; optional. |
| [`gen-manufacturers.py`](gen-manufacturers.py) | Python 3 script that regenerates `manufacturers.tsv`; pulls the upstream `manufacturers.xml` over the network by default (or a URL/local file/HTML block you pass in). |
| [`products.tsv`](products.tsv) | Tab-separated `vendor ID → product ID → name` table (3 columns) used by `matter-decode.sh` to turn a product ID into a name, for any vendor that has a catalog (e.g. **LIFX**, vendor `0x1306` / `4870`). Optional. |
@@ -227,9 +233,72 @@ product name and vice-versa.
The table is hand-edited and optional: a missing file simply means no equivalent
is considered. The canonical (col-2) id should not itself appear in col-1.
## HomeKit setup-code decoder
`homekit-decode.sh` decodes a **HomeKit** setup code — the `X-HM://` payload an
Apple accessory (or its packaging) shows on first setup. It is a *different*
on-wire format from Matter's `MT:`, a standalone tool with no browser app and no
companion tables — the accessory-category names are inlined in the script.
```sh
./homekit-decode.sh # defaults to the demo payload 005KEOUCE
./homekit-decode.sh "X-HM://005KEOUCE"
```
A leading `X-HM://` is stripped if present; the first 9 characters are the fixed
parameter block and anything after them is a variable-length **setup id**, kept
verbatim (it is not part of the numeric block).
Example output:
```
$ ./homekit-decode.sh
Setup PIN: 38313374
Flag: 10
Supports NFC: False
Supports IP: True
Supports BLE: False
Supports WAC/MFi: True
Category ID: 5 (Lightbulb)
Reserved: 0
Version: 0
Setup ID: <none>
Setup Payload: X-HM://005KEOUCE
```
### How it decodes
Unlike Matter's **base38** payload (`0-9 A-Z - .`), the 9-character HomeKit block
is **base36** (`0-9 A-Z`, 36 symbols) — an out-of-range character is a hard
error. The resulting integer is sliced **least-significant-bit first** into the
HomeKit field layout:
```
pin(27) | flag(4) | categoryId(8) | reserved(4) | version(3)
```
- **Flag** is a 4-bit sub-flag set: `1` = NFC, `2` = IP, `4` = BLE, `8` = WAC/MFi
(each printed True/False).
- **Category ID** is resolved to its HomeKit
[`homekit_accessory_category`](https://developer.apple.com/documentation/homekit/hmaccessorycategory)
name (e.g. `5` → Lightbulb, `8` → Switch); an id not in the table prints
"unknown".
- The fields are packed back into a 9-character block and printed as a
reconstructed `X-HM://…` payload, so the output is a complete record the barcode
can be rebuilt from.
The script uses the **corrected** bit layout that `composeSetupUri` in the
`homekit-code` package actually encodes; an earlier version had the
`categoryId` / `flag` / `version` positions misaligned. Each fix is noted in the
script's header comments.
---
## License
The vendor mapping is derived from Matter/CHIP's `manufacturers.xml`, which is
Apache-2.0. The LIFX product mapping is derived from LIFX's `products.json`.
Vendor equivalences (`vendor-equivalents.tsv`) are maintained locally. The app
Vendor equivalences (`vendor-equivalents.tsv`) are maintained locally. The
HomeKit decoder's accessory-category names follow Apple's HomeKit
`homekit_accessory_category` definitions. The app
itself is a small single-file utility.