Home > 3rd-Party Integration > GATT Reference

GATT Reference

The complete BLE GATT surface a 3rd-party client needs to drive a Biscuit. Every value on this page is stable across the public firmware line and matches what the iOS and Android companion apps consume.


Advertising

Field Value
Local name Biscuit
Service UUID in advertisement 4fafc201-1fb5-459e-8fcc-c5c9c331914b

The local name is identical on every device; match on the service UUID. Biscuit does not include a per-device suffix in the advertised name.


Primary Service

Service UUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b

Characteristic UUID Properties Direction Use
Command beb5483e-36e1-4688-b7f5-ea07361b26a8 Write, Write Without Response Central to device Send CMD: lines
Response beb5483e-36e1-4688-b7f5-ea07361b26a9 Notify Device to central Receive RSP, STATUS, DATA, ERROR, TIME lines
Status beb5483e-36e1-4688-b7f5-ea07361b26aa Read Device to central Pollable JSON snapshot of device health
Settings beb5483e-36e1-4688-b7f5-ea07361b26ab Read, Write, Notify Bidirectional Read or update device configuration as JSON
Security beb5483e-36e1-4688-b7f5-ea07361b26ac Read, encrypted read required Device to central Optional encrypted-link setup and verification

Notifications must be enabled. Until the Response characteristic’s CCCD is set to 0x0001, the device does not send anything in response to commands. Subscribing is a prerequisite, not optional.


Device Information Service

Standard BLE Device Information Service (0x180A) exposes:

Characteristic UUID Content
Manufacturer Name 2A29 Biscuit Shop
Model Number 2A24 Board name, such as Biscuit Pro, Biscuit Ultra, Biscuit DIY, Nyan, or Crumb
Firmware Revision 2A26 Primary firmware version, e.g. v1.4.5
Software Revision 2A28 Scanner firmware version on Pro/Ultra
Serial Number 2A25 Per-device serial when exposed and provisioned

On Pro/Ultra, 2A26 is the WROOM revision and 2A28 is the C5 revision. On single-chip DIY, Nyan, and Crumb devices, the C5 owns 2A26 and 2A28 is absent.


T-Dongle Display Media Service

This optional service exists only on the T-Dongle C5 and is not included in the advertising packet.

Service UUID: fb1e5001-54ae-4a28-9f74-dfccb248601d

Characteristic UUID Properties Security Use
Info fb1e5002-54ae-4a28-9f74-dfccb248601d Read Open Protocol version, SD state, display dimensions, and limits
Control fb1e5003-54ae-4a28-9f74-dfccb248601d Write, Notify Encrypted Configuration, filename listing, upload control, assignment, deletion
Data RX fb1e5004-54ae-4a28-9f74-dfccb248601d Write, Write Without Response Encrypted Offset-addressed Biscuit Media Asset upload

Info returns compact JSON containing v, sd, width, height, maxBytes, maxFrames, maxFiles, maxFps, and maxDurationMs. Reading it does not request pairing. Subscribe to Control only when the user starts display media management; the encrypted subscription lets the platform perform its normal authentication flow.

Control requests are compact JSON objects containing v:1, a positive id, and one of get_config, list, set_enabled, set_assignment, begin_upload, commit_upload, cancel_upload, or delete_asset. File lists return filename and metadata events only; media bytes and thumbnails are never sent back to the client.

Every Data RX value begins with little-endian sessionId:uint32 and absoluteOffset:uint32, followed by file bytes. The device acknowledges each 8192-byte window over Control. Control JSON responses may span sequential notifications at the negotiated ATT payload limit, so reassemble a complete object before parsing. A committed .bma file is at most 1 MiB and contains 160x80 little-endian RGB565 frames, using raw pixels or simple run-length encoding, followed by CRC32. See T-Dongle Display Media for the complete binary and JSON schemas.


Connection Parameters

Parameter Value
MTU requested by device 517
Recommended client MTU At least 247
Data Length Extension Device requests 251-byte PDUs on connect
Connection interval 30 to 60 ms preferred
Slave latency 0
Supervision timeout 8000 ms

Below an MTU of 247, large notifications during wardrive streams will be fragmented across multiple ATT packets. Most BLE stacks reassemble these transparently, but throughput drops.


Message Framing

Every text-carrying characteristic uses the same line-oriented format:

TYPE:SUBTYPE:PAYLOAD\n

Every line ends with a single line-feed (\n, 0x0A). The payload may be empty; the trailing colon is still present (for example, CMD:stopscan:).

Message types

Type Direction Meaning
CMD Central to device A command
RSP Device to central Acceptance of a CMD (sent within 100 ms)
STATUS Device to central Execution-state change
DATA Device to central Live scan record
ERROR Device to central Command rejected or runtime error
TIME Device to central Time-sync request

A RSP means “command accepted”, not “command finished”. For commands that produce output (scans, attacks, wardrive), the actual completion signal arrives as a subsequent STATUS: line.

Status codes

STATUS: lines carry a numeric code in the SUBTYPE position:

Code Meaning
0 Booting
1 Ready
2 Busy (a scan or attack is running)
3 OK
4 Warning
5 Error
6 Scan complete

STATUS:1:Ready is the signal that no further DATA: lines will arrive for the previous operation.


Notification Packing

During wardrive and other high-throughput scans, the device packs multiple DATA: records into a single BLE notification to reduce radio overhead. Records inside a packed notification are newline-delimited:

DATA:AP:Network1,AA:BB:CC:DD:EE:FF,6,-58,[WPA2_PSK]
DATA:BT:Device1,11:22:33:44:55:66,-72,BLE
DATA:AP:Network2,22:33:44:55:66:77,11,-65,[WPA3_PSK]

The pack buffer flushes on any of:

Trigger What happens
Buffer reaches 240 bytes Immediate flush
50 ms elapsed since first buffered record Timer-based flush
A non-DATA message is queued Immediate flush, preserving order

Always split each notification on \n and process each line independently. Never assume one notification equals one record.

Read Security once before subscribing to normal traffic when you want the platform to offer LE Secure Connections Just Works bonding. A successful read returns:

{"v":1,"mode":"optional","encrypted":true,"bonded":true,"bonds":1}

This protected read is the only pairing trigger. Do not call createBond() or issue a second read at the same time. If the user declines or the read fails, continue using the open Command, Response, Status, and Settings characteristics. Older firmware simply omits Security.

Just Works encrypts the link but does not verify the user’s or device’s identity. For silent reconnects, remember a bond only after Security reports bonded:true.


Status Characteristic JSON

The Status characteristic returns a JSON object summarizing current device health. It is safe to read at any time. The iOS app normally polls every 15 seconds, or every five seconds while a diagnostic pill is enabled in the foreground.

Pro/Ultra after both chips advertise protocol-3 update control:

{"status":1,"battery":85,"c5Connected":true,"c5State":1,"wroomPartition":"ota_0","c5Partition":"ota_1","otaProtocol":3}

Single-chip initial value:

{"status":0,"battery":-1,"sd":false,"c5Partition":"ota_0","otaProtocol":3}

Full schema (optional keys appear only once the relevant subsystem reports):

Key Type Meaning
status int Shared status: 0 Booting, 1 Ready, 2 Busy, 3 OK, 4 Warning, 5 Error, 6 Scan complete
battery int Battery percentage 0 to 100, or -1 if not yet measured
c5Connected bool Optional on Pro/Ultra. Scanner subsystem link alive.
c5State int Optional on Pro/Ultra. Scanner state: 0 Booting, 1 Ready, 2 Busy, 6 Scan complete.
wroomHeap [free, total] Optional on Pro/Ultra. Present when the device is reporting heap.
c5Heap [free, total] Optional on Pro/Ultra.
temperatureC number or null Optional in updated v1.6.0 Pro/Ultra/DIY builds. C5 temperature in Celsius; null when invalid or stale. This is not a measured WROOM temperature.
wroomCpuMhz int or null Optional. Actual WROOM CPU frequency in MHz; null on single-chip devices or when unavailable.
c5CpuMhz int or null Optional. Actual C5 CPU frequency in MHz; null when unavailable or its report is stale.
sd bool Optional mounted state. Single-chip devices may report both true and false.
op string Optional. pktmon or eapol while an SD-backed capture is running.
wroomPartition string Optional. Running WROOM slot: ota_0 or ota_1.
c5Partition string Optional. Running C5 slot; absent until known on a dual-chip device.
otaProtocol int Optional. 2 supports base64 credentials; 3 adds explicit normal/force update mode. Dual-chip devices report 3 only when both chips support it.
lastOtaResult string Optional. running, success, error, or cancelled.
lastOtaRoute string Optional. direct or c5_uart.
lastOtaCode string Optional. Stable lower-snake-case diagnostic code.

Temperature and C5 frequency become null after five seconds without a fresh reading or report respectively. Their validity is independent: a sensor failure can leave a usable CPU frequency. Clear displayed values when fields are missing or null, on disconnect, and when status responses stop.

Treat the JSON keys as opaque string identifiers. Field values may evolve across firmware releases; the keys themselves are stable across the public firmware line.

Single-chip DIY, Nyan, and Crumb devices omit the C5-link fields and report only c5Partition among the partition keys. Pro and Ultra can report both chip slots. Older firmware omits these keys; clients should display an unknown/not-reported state rather than assuming ota_0.