Research
How Bluetooth detection of smart glasses works
A description of the detection pipeline as it is implemented today, including the parts that are deliberately uncalibrated. If you want the short version, read How it works; this page is the reference.
Pipeline
Core Bluetooth discovery
↓ adapter exact copy of what iOS provides
↓ normaliser company ID, payload split, UUID canonicalisation
↓ signature engine data-driven matching → evidence items
↓ confidence engine noisy-OR + single-dimension cap → score, level
↓ deduplicator (peripheral, signature) sessions with timeout
↓ user interface evidence list, level, coarse signal category The detection core has no dependency on Core Bluetooth beyond the adapter, which is what allows it to be unit-tested against recorded advertisements and demo data. Known fact The input is limited to the fields Apple exposes: local name, manufacturer data, service data, service UUIDs, overflow service UUIDs, transmit power, connectable flag and solicited service UUIDs.
Normalisation rules
- Company identifier. The first two bytes of manufacturer-specific data, little-endian, as defined in the Bluetooth Core Specification Supplement. Fewer than two bytes means no company identifier.
- Manufacturer payload. The bytes after the company identifier. Pattern offsets are relative to this payload.
- Service UUIDs. 16-bit SIG UUIDs are canonicalised to four hex characters; the 128-bit Bluetooth Base UUID form collapses to the same value. Advertised and overflow UUIDs are matched; solicited UUIDs are shown but not matched.
- Local name. Trimmed; empty becomes absent. Patterns are case-insensitive.
- RSSI. 127 means unavailable in Core Bluetooth; zero and positive values are discarded.
Evidence kinds
Manufacturer identifier, service UUID, local name, service data, manufacturer-data pattern, repeated observation, and a reserved kind for other verified signals. Each evidence item carries its weight, the matched value, a plain-language explanation and the signature it came from, which is what the app shows when you ask why something was detected.
One rule matters more than the rest: a manufacturer-data pattern is evaluated only when the advertisement's company identifier equals the signature's company identifier. Identical bytes under a different company mean something else.
Confidence (uncalibrated)
score = 1 − Π (1 − wᵢ) over all evidence items (noisy-OR)
if distinct kinds (excluding repeated observation) ≤ 1:
score = min(score, singleDimensionCap)
level: ≥ 0.75 HIGH · ≥ 0.50 MEDIUM · ≥ 0.25 LOW · else NONE Experimental default weights: manufacturer identifier 0.30, service UUID 0.40, local name 0.45, service data 0.35, manufacturer-data pattern 0.50, repeated observation 0.10. Cap 0.49. Repeated-observation threshold 3.
| Evidence | Score | Level |
|---|---|---|
| Company identifier only | 0.30 | LOW |
| Company identifier only, 100 observations | 0.37 | LOW (the cap would hold it at or below 0.49 regardless) |
| Company identifier + service UUID | 0.58 | MEDIUM |
| Company identifier + service UUID + 3 observations | 0.62 | MEDIUM |
| Company identifier + service UUID + payload pattern | 0.79 | HIGH |
| Company identifier + service UUID + name | 0.77 | HIGH |
Why noisy-OR with a cap
- Independent evidence should compound, and noisy-OR does that without a hand-tuned lookup table.
- A single identifier, especially a company identifier shared by headsets, controllers and glasses, must never produce HIGH. The cap enforces that structurally rather than through weight tuning.
- Repeated observation is weak evidence: it says the thing is still here, not that it is glasses.
Calibration plan
- Collect exports per scenario from the validation plan (in case, pairing mode, paired to another phone, recording, and so on).
- For each signature, tabulate which evidence kinds appear in each state.
- Set weights so that the minimum evidence set seen in at least 80% of glasses-present scenarios yields MEDIUM, and the evidence set that also appears near non-glasses hardware from the same manufacturer yields at most LOW.
- Record the calibration in the decision log and bump the catalogue date.
Deduplication
A session is keyed by the iOS peripheral identifier and the signature identifier. It ends after 120 seconds without an observation. Sessions track first and last seen, count, strongest, latest and smoothed RSSI, and changes in the evidence set or confidence level. The iOS identifier is not a hardware address and may rotate with the peripheral's private address; a rotation appears as a new session. We do not attempt to link sessions across rotations, because that would be tracking.
Signal strength
RSSI is shown as one of four coarse categories (very strong ≥ −50 dBm, strong ≥ −65, moderate ≥ −80, weak below that) with an exponential moving average available for experimentation. It is never converted to metres. The reasons are on the RSSI and distance page.
Where the false-positive risk sits
Company-identifier-only matches will be common: Meta makes Quest headsets and controllers, and many manufacturers make many products. They stay LOW and are hidden from consumer notifications. Service UUID 0xFD5F is registered to Meta Platforms Technologies; if Quest controllers also advertise it, MEDIUM detections would fire near a Quest. Hardware testing must check this before any weight is trusted. Read more on false positives and false negatives.
Related pages
Sources
- Advertisement Data Retrieval Keys — Apple Developer Documentation, accessed 16 September 2026
- centralManager(_:didDiscover:advertisementData:rssi:) — Apple Developer Documentation, accessed 16 September 2026
- Core Specification Supplement (manufacturer specific data, Part A §1.4) — Bluetooth SIG, accessed 16 September 2026
- Assigned Numbers — Bluetooth SIG, accessed 16 September 2026