ble

package
v0.209.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2026 License: AGPL-3.0 Imports: 3 Imported by: 0

Documentation

Overview

Package ble decodes BLE advertisement payloads — currently just Apple Continuity manufacturer-data — into operator-facing structures. Pure offline parser; no transport, no hardware.

Wrap-vs-native judgement: the Apple Continuity format is a reverse-engineered public spec — furiousMAC's project, hexway's AppleJuice writeups, AppleBleee and AppleAir-style scanners all document the same TLV layout. The dissector is a short walker (~150 LoC of bytes-to-field) over a byte slice. Wrapping a FAP for this would require an SD-card install + a firmware-fork dependency for a pure parser. Native delivers host-side analysis (paste a captured Apple manufacturer-data hex from a forum post or a Wireshark capture and decode without a Flipper attached), inline test coverage against published vectors, and a table the operator can extend without rebuilding firmware.

What this package covers:

  • Apple Continuity TLV walker (with separator-tolerant hex intake; auto-strip of optional 4C00 manufacturer prefix and full AD-structure prefix).
  • Named action types per furiousMAC's catalog (0x02 iBeacon through 0x12 Find My).
  • Per-type field decoding for the well-documented action types — Nearby Info, Nearby Action, Handoff, Tethering, Proximity Pairing, AirDrop, Magic Switch.

What this package does NOT cover (deliberately out of scope):

  • Decryption of encrypted bodies (Handoff, ProximityPairing past the public prefix) — Apple's session keys are not publicly recoverable.
  • Tag-name lookup for the 0xDF range or any vendor-private types beyond Apple's set.
  • Round-trip re-encode — happy to add if a caller materialises.

Index

Constants

View Source
const AppleManufacturerID = 0x004C

AppleManufacturerID is Apple's Bluetooth SIG company identifier. See https://www.bluetooth.com/specifications/assigned-numbers/.

Variables

This section is empty.

Functions

This section is empty.

Types

type ActionTLV

type ActionTLV struct {
	// Type is the Action Type byte — 0x05 (AirDrop), 0x10 (Nearby
	// Info), etc. Stored as an int rather than byte so JSON renders
	// as a plain integer.
	Type int `json:"type"`
	// TypeHex is the operator-facing form of Type — uppercase,
	// always 2 chars, no 0x prefix ("05", "10"). Matches every
	// public reference's format.
	TypeHex string `json:"type_hex"`
	// Name is the canonical name for the action type, or
	// "Unknown" when the type isn't in our catalog. The walker
	// still records and returns unknown types so operators can
	// flag novel signatures.
	Name string `json:"name"`
	// Length is the declared payload length in bytes (the L byte
	// of the TLV).
	Length int `json:"length"`
	// Hex is the operator-facing hex rendering of Value — always
	// uppercase, no separators.
	Hex string `json:"hex"`
	// Value is the raw payload bytes.
	Value []byte `json:"-"`
	// Fields carries documented-action-type field decodes, keyed
	// by short snake_case names. Nil for unknown types or for
	// types whose body we don't dissect further.
	Fields map[string]any `json:"fields,omitempty"`
	// DecodeWarning is non-empty when the per-type decoder hit a
	// recoverable shape issue (e.g. payload shorter than the
	// documented minimum for that action). The TLV is still
	// returned so the operator can see the raw bytes; the warning
	// flags that Fields may be partial or missing.
	DecodeWarning string `json:"decode_warning,omitempty"`
}

ActionTLV is one decoded Continuity TLV entry. For documented action types Fields carries the parsed sub-fields by name; for unknown types Fields is nil and the operator has Hex.

type Continuity

type Continuity struct {
	// TLVs is the ordered list of action-type entries pulled from
	// the payload. May be empty when the payload is empty after
	// prefix-stripping (legal but unusual — an empty 0x004C
	// manufacturer record).
	TLVs []ActionTLV `json:"tlvs"`
	// Count is len(TLVs) — surfaced for callers that consume the
	// JSON directly without needing to compute it.
	Count int `json:"count"`
	// StrippedPrefix records what the parser stripped from the
	// front of the input before walking ("none", "manufacturer",
	// "ad_structure"). Useful to confirm the parser interpreted
	// the input as the operator expected.
	StrippedPrefix string `json:"stripped_prefix"`
}

Continuity is the top-level decode result.

func Decode

func Decode(hexBlob string) (Continuity, error)

Decode parses a hex-encoded Apple Continuity payload. Three input shapes are accepted; the parser strips any prefix it recognises:

  • Bare TLVs: 10 02 1B 00
  • With manufacturer ID: 4C 00 10 02 1B 00
  • Full AD structure: 06 FF 4C 00 10 02 1B 00

Separators (':' '-' '_' whitespace) are tolerated so callers can paste hex from Wireshark, btmon, etc., without preprocessing.

func DecodeBytes

func DecodeBytes(b []byte) (Continuity, error)

DecodeBytes is the byte-slice variant of Decode for callers that already have raw bytes. Same prefix-detection and walking logic.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL