Bluetooth Low Energy

How Spotflow devices forward telemetry through a Bluetooth Low Energy gateway using the Spotflow BLE GATT service and framed stream protocol.

Bluetooth Low Energy support uses a gateway architecture. A leaf device exposes the Spotflow Observability Service over BLE, and a gateway connects to that service, reads device context, receives framed messages, and forwards them to Spotflow over MQTT.

This page describes the BLE communication format: roles, GATT service layout, stream characteristics, message types, and frame encoding.

Roles

RoleDevice
BLE centralGateway
BLE peripheralLeaf device
GATT clientGateway
GATT serverLeaf device

The leaf device is the source of telemetry. The gateway bridges the BLE stream to Spotflow MQTT topics.

GATT service

The Spotflow BLE protocol uses the following UUID layout:

ItemUUID
Service UUID26530001-81E5-4861-82AE-2C92E6887922

The service exposes these characteristics:

NameUUID fragmentPropertiesDescription
Capabilities26530002-81E5-4861-82AE-2C92E6887922READProtocol version. The initial protocol version is 0x01.
Device ID26530003-81E5-4861-82AE-2C92E6887922READDevice ID the gateway uses when connecting the device to Spotflow.
Session Metadata26530004-81E5-4861-82AE-2C92E6887922READCBOR-encoded Session Metadata message. The gateway forwards this payload to the ingest-cbor MQTT topic.
TX Stream26530005-81E5-4861-82AE-2C92E6887922NOTIFYDevice-to-gateway stream for telemetry and reported configuration messages.
RX Stream26530006-81E5-4861-82AE-2C92E6887922WRITE without responseGateway-to-device stream for desired configuration messages.

Streams

The protocol uses one stream in each direction:

StreamDirectionBLE propertyUsed for
TX StreamDevice to gatewayNOTIFYTelemetry and reported configuration
RX StreamGateway to deviceWRITE without responseDesired configuration

Both streams use the same frame format. Framing is required because BLE messages may be larger than the negotiated MTU, which can be as low as 23 bytes.

Because there is a single stream in each direction, multiplexing is handled by the message type in each frame rather than by separate GATT characteristics.

Message types

The first byte of each frame identifies the message type. The receiver reads this byte before parsing the rest of the frame.

Message typeByte identifierFragmentedAllowed in
ACK0x00NoTX/RX
NACK0x01NoTX/RX
TELEMETRY0x02YesTX
REPORTED_CONFIGURATION0x03YesTX
DESIRED_CONFIGURATION0x04YesRX

ACK and NACK are defined by the frame format, but application-level acknowledgement is not currently implemented.

Frame format

Every frame starts with the message type byte:

Byte  0: Message type
Byte 1+: Data

Fragmented message types use the following frame layouts.

First fragment:

Byte    0: Message type
Byte    1: Flags
Byte    2: Message sequence number, uint8
Bytes 3-4: Total message byte length, uint16 little-endian
Bytes  5+: Fragment data

Continuation fragment:

Byte   0: Message type
Byte   1: Flags
Byte   2: Message sequence number, uint8
Bytes 3+: Fragment data

The pair of message type and sequence number identifies one fragmented message within a rolling window of 256 messages of that type.

Flags

BitNameMeaning
0IS_FIRSTFirst or only fragment of a message.
1IS_LASTLast or only fragment of a message.
2NEEDS_ACKReserved for application-level acknowledgement. ACK/NACK handling is not currently implemented.
3-7ReservedSet to 0. Receivers must not depend on these bits.

Gateway flow

A gateway connects a BLE leaf device to Spotflow with this flow:

  1. Scan for a device advertising the Spotflow GATT service.
  2. Connect to the device.
  3. Read the Capabilities characteristic and check protocol compatibility.
  4. Read the Device ID characteristic.
  5. Read the Session Metadata characteristic.
  6. Establish an MQTT connection to Spotflow using the device ID and the gateway-provided ingest key.
  7. Publish the Session Metadata payload to the ingest-cbor topic.
  8. Enable notifications on the TX Stream characteristic.
  9. Forward TELEMETRY messages from the TX Stream to the ingest-cbor MQTT topic.
  10. Forward REPORTED_CONFIGURATION messages from the TX Stream to the config-cbor-d2c MQTT topic.
  11. Forward MQTT messages from the config-cbor-c2d topic to the RX Stream as DESIRED_CONFIGURATION messages.

The gateway forwards complete message payloads between BLE and MQTT. It does not need to interpret Spotflow telemetry payloads to route them.

Delivery guarantees

The current BLE stream uses NOTIFY for device-to-gateway data and WRITE without response for gateway-to-device data. This provides best-effort delivery at the application level.

The frame format defines ACK, NACK, and the NEEDS_ACK flag for application-level acknowledgement, but that acknowledgement flow is not currently implemented.

Sample

The Spotflow device SDK includes a Zephyr sample that demonstrates the BLE transport: zephyr/samples/ble.

Use the Spotflow Web App as a BLE Gateway

For development and testing, the Spotflow Web App can act as a BLE gateway. It connects to a BLE leaf device and forwards telemetry to Spotflow over MQTT.

Open the BLE Gateway page from the user menu in the top-right corner of the application.

BLE gateway link
Link to the BLE gateway.

On the BLE Gateway page, select the ingest key to use for the MQTT connection. Then click Scan for BLE devices to find nearby BLE leaf devices advertising the Spotflow GATT service.

Select a device from the list to connect. Once connected, the browser forwards telemetry from the BLE device to Spotflow over MQTT.

BLE gateway in the web app.
BLE gateway in the web app.

This setup is intended for development and testing because the browser Bluetooth API provides limited control over the BLE stack.

How is this guide?