UltraWideLock v0.4.0

Specification#

Every number the lock ships with. The radios and the protocol, the boards, the memory budget on the smallest part, the obstruction classifier, the side-of-door routes, and how a running lock is updated. The landing page says what the lock does; this page says exactly how.

Radios and protocol#

UWBDS-TWR under an STS session, channels 5 and 9
Resolutionone timestamp tick is about 15.65 ps, which light crosses in 4.692 mm
Unlock bound1.00 m, from ULTRAWIDELOCK_UNLOCK_RANGE_CM
BLEcredential service 0xFFF2, AUTH0 / AUTH1 / EXCHANGE
NFCECP, on the nRF5340 DK target
Side of doora second UWB anchor in the same ranging round, or two BLE witnesses
Matterhand-written node over Thread, or over Wi-Fi on ESP32
Door Lock clusterLockOperation events, AutoRelockTime, DoorLockAlarm, Approach Direction
Matter clientCASE as initiator and the Binding cluster, to open a second lock. Off by default
Updatessigned delta over BLE or USB, applied from inside MCUboot; whole signed image on ESP32
PortsZephyr, ESP-IDF, and a Zephyr-free FreeRTOS port
Tests9,608 host checks across 18 suites, no hardware needed
LicenseISC. The vendored Qorvo UWB driver is LicenseRef-QORVO-2

How a door opens#

Five steps, in the order they happen.

  1. BLE. The phone finds the credential service 0xFFF2.
  2. Authenticate. AUTH0, AUTH1 and EXCHANGE run, and both ends hold the URSK.
  3. Range. The key ladder seeds an STS session, then a DS-TWR round measures the distance from the lock.
  4. Gate. A trusted range inside the bound moves the bolt.
  5. Matter. Lock state goes out over Thread, into Apple Home.

The credential is verified on the lock itself, so there is no remote verifier to compromise.

Why time of flight#

One timestamp tick is 15.65 ps, which light crosses in 4.692 mm. A relay can add delay and nothing else, which is why a relayed round measures longer than the true distance rather than shorter: there is no attack that makes light arrive early. The landing page's ranging instrument computes its readings from the firmware's own constants, and web/site/check_hero_constants.py fails the site build when they drift from the C tree.

Hardware targets#

ApplicationHardwareConnectivity
dwm3001cdk-lockDWM3001CDK, nRF52833 + DW3110UWB, Matter over Thread
dwm3001cdk-lock-freertosthe same board, no ZephyrUWB, Matter over Thread
nrf5340dk-locknRF5340 DK, DWM3000EVB, NFC12A1UWB and NFC, Matter over Thread
esp32-matter-lockESP32-S3 / C5 / C6 with DWM3000EVBUWB, Matter over Wi-Fi
satelliteCDK, nRF5340 DK, or the ESP32 tierUWB responder, sealed link to the lock

Bare make targets mean the DWM3001CDK; the nRF5340 DK is nrf- prefixed and the ESP32 esp-. Configuring lists every option.

All of it on one nRF52833#

512 KB of flash and 128 KB of RAM carry the reader, the DW3110 radio, an OpenThread MTD and a Matter node at the same time. A hand-written Matter node, rather than CHIP, is what makes it fit.

PartWhat it carries
readerAUTH0 / AUTH1 / EXCHANGE, key ladder, STS, DS-TWR
matterhand-written node, Door Lock cluster, five fabrics
threadOpenThread MTD, joins a real network
classifierline-of-sight vs obstructed, 776 B of flash
BudgetUsedOfShare
Flash417,684 B433,664 B96.31%
RAM118,312 B131,072 B90.26%

Both are tight, and flash is the tighter. make cdk-size reports them and make cdk-size-check fails the build when the headroom is gone.

ToolchainNCS v3.3.0, Zephyr 4.3.99
SigningECDSA-P256, verified by MCUboot
note

Repository defaults are bench defaults. Keys and identities in the tree are for development. Do not secure valuables with it.

The nRF5340 DK image has its own budget: memory usage.

Obstruction detection#

A phone in a hand and a phone through a wall both measure one metre. The shape of the arrival separates them: a direct path lands as one sharp edge, a path through a door arrives late, spread and weaker.

A decision tree reads the DW3000's own receive diagnostics in 776 bytes of flash, with no interpreter and no allocation.

Modeldepth-2 decision tree, generated by emlearn
Cost776 B flash, 0 B RAM, 28 B stack
Inputfive CIA registers plus the measured range
Gatethe host suite certifies the C matches the trained model

The site draws this pair as two signals everywhere it appears: mint is the first path, direct and trusted; amber is the late path, obstructed or carrying a relay's added delay. make mlgate runs the certification.

Side of the door#

A phone on the couch and a phone on the porch can be the same distance from the door. Only one of them should open it. The question is answered by either of two routes, and both fail closed.

A second UWB anchor. The satellite joins the phone's own ranging round as responder 1, so both distances come from one round rather than two guesses stitched together. It reports its distance sealed and bound to the block it was measured in, and the lock fuses the pair only when both halves carry the same block. It builds for the DWM3001CDK, the nRF5340 DK, and the ESP32 tier over an ESP-NOW carrier.

sh
make anchorlink             # the lock half
make sat-build SAT_THREAD=1 # the satellite half

Two BLE witnesses. One nRF52840 dongle inside, one outside, a differential read consulted at the one moment it is reliable, and a door-transition latch that holds the answer between crossings. One image, role set at install.

sh
make witness-build
make witness-flash          # over USB DFU, no probe

The side gate fails closed for passive unlock: no agreeing second opinion, no walk-up open. A dead dongle, a dropped mesh, a reboot or corrupt storage each leave the lock refusing to open from inside. Outside, the recovery is a retry, an NFC tap, or the app.

The design is in inside latch, the ranging route in second anchor, and both are proved on a bench in the runbook.

Update over the air#

Either chip, from a browser. The flash page finds the board, reads what it is running, and sends the one update that applies.

DWM3001CDKESP32-S3 / C5 / C6
Transportmcumgr, over BLE or USBnative GATT frames
Payloadsigned delta, about 11 KBsigned whole image, about 2 MB
Whyone MCUboot slot in 512 KBtwo full OTA slots
Timesecondsseveral minutes over BLE

Writing starts once the update window is open on the board: SW2 on the CDK, a double-click on the ESP32's button. That press is the whole availability gate; authenticity is a P-256 signature, checked before the first byte is written and again by the bootloader. The CDK can also be reinstalled whole over the cable through MCUboot serial recovery, which runs from the bootloader alone.

Chrome or Edge on a computer, or Chrome on Android. Neither Web Bluetooth nor WebSerial exists in Safari, so not from an iPhone.

sh
make fota                   # CDK: one file a phone can install
make fota-done              # after every phone push, to record what the board runs
make ota-fan  PREV_HEXES=…  # the delta fan and the index the web page reads
make release  RELEASE_KEY=… # the published bundle

Without hardware#

PageWhat it runs
Digital twinthe untouched ultrawidelock_uwb sources compiled to WASM against the same shim the host suite links. Every block is a real CCM*-encrypted exchange decoded by the firmware's own RX state machine
Web flasherinstalls a merged ESP32 image over WebSerial with no toolchain, and updates either board over the air once one is running
Subsystem graphwhat depends on what, extracted from the source tree: 17 subsystems and 49 edges, or 393 files with their symbols and 703 links
sh
git clone https://github.com/ultrawidelock/ultrawidelock.git
cd ultrawidelock
make check                  # 18 suites, 9,608 checks, no hardware