The latest development version of this page may be more current than this released version.

Terrestrial Network Overview

Introduction

The Hubble Terrestrial Network is the name Hubble uses for its network built on Bluetooth® Low Energy (BLE). It is a framework designed to provide secure and efficient communication within a Bluetooth Low Energy (BLE) environment. Advanced encryption techniques and Bluetooth technology protect data integrity and privacy across distributed systems. The Hubble Terrestrial API, defined in the hubble/ble.h header file, provides a comprehensive set of functions for initializing, configuring, and managing network operations.

The application builds an advertising payload with the Hubble API and hands the resulting bytes to the platform BLE stack, which broadcasts them. Hubble gateways within range receive the advertisements, filter them by the Hubble Service UUID, and forward the encrypted payload to the Hubble backend.

Note

While this network is called the Hubble Terrestrial Network, the SDK code and APIs use the ble namespace for it. Terrestrial functions, types, and configuration options carry a ble marker — for example the hubble_ble_advertise_get() function, the hubble/ble.h header, and the CONFIG_HUBBLE_BLE_NETWORK option — reflecting the Bluetooth Low Energy technology the network is built on.

Key Features

Secure Communication

The Hubble Terrestrial Network uses a 128 or 256-bit encryption key to encrypt caller-supplied payload data and authenticate packets, minimizing the risk of unauthorized access and tampering. See Cryptographic Overview.

Time Synchronization

When Unix-time mode is selected, functions are available to initialize the network with the current time and update it as needed. This ensures that all nodes remain synchronized, which facilitates coordinated operations and data consistency. See Time Management for best practices on provisioning time and accounting for clock drift.

How It Works

At a high level, a terrestrial transmission follows this sequence:

  1. Initialize the SDK with hubble_init(), providing the device key and the initial value required by the configured counter source.

  2. Build an advertising payload with hubble_ble_advertise_get(), optionally including up to HUBBLE_BLE_MAX_DATA_LEN bytes of application data.

  3. Place the returned bytes in a Service Data — 16-bit UUID advertising structure and hand the advertisement to the platform BLE stack.

  4. The platform broadcasts the advertisement. Refresh it when it expires so the ephemeral device identifier keeps rotating.

The SDK encrypts the payload with the configured Hubble device key and derives the packet identifiers from the SDK time counter:

  • CONFIG_HUBBLE_COUNTER_SOURCE_UNIX_TIME uses Unix time in milliseconds.

  • CONFIG_HUBBLE_COUNTER_SOURCE_DEVICE_UPTIME uses a device-uptime-derived counter and does not require UTC time. In this mode, the initial_time parameter to hubble_init() is the initial counter value.

Advertising Packet

Hubble’s terrestrial advertising follows the BLE specification. Each packet has three main components: a header defining the packet type, a 48-bit advertising address, and a payload containing the Hubble protocol fields plus optional customer data.

hubble_ble_advertise_get() produces only the Service Data payload. The application is responsible for assembling the full advertisement — the Service UUID list, the Service Data AD structure, and (optionally) the flags — around it.

Packet Header

The header’s Protocol Data Unit (PDU) type determines the packet size and communication directionality. Hubble supports any BLE advertising PDU type that carries the 16-bit Service UUID 0xFCA6; gateways filter by Service UUID rather than by PDU type. Recommended configurations:

  • ADV_NONCONN_IND — non-connectable, broadcast-only packets with minimal power consumption.

  • ADV_IND — connectable packets for devices that accept BLE connections alongside Hubble messaging.

The Flags AD type (0x01) is optional for non-connectable devices, though applications may include it if needed. Only legacy advertising is supported; extended advertisements are not.

Addressing

Use Non-Resolvable Private Addresses (NRPA) for the 48-bit advertising address. They are randomly generated, cannot be resolved to a real identity, change frequently, and require no keys to generate or interpret.

Payload Structure

The advertising payload follows Bluetooth’s AD structure format: [Length] [AD Type] [AD Data…]. Hubble is carried in a Service Data AD structure that contains the Hubble protocol fields plus up to HUBBLE_BLE_MAX_DATA_LEN (13) bytes of optional customer data.

The Hubble 16-bit Service UUID (0xFCA6) is listed once in the Service-UUID AD structure and again inside the Service Data AD structure, following the Bluetooth specification.

Advertisement layout

Field

Value

Notes

AD structure length

0x03

Length of the Service-UUID AD structure.

AD type (Service UUID list)

0x03

Complete list of 16-bit Service Class UUIDs.

Hubble Service UUID

0xFCA6

Mandatory.

AD structure length

13–26

Length of the Service Data AD structure (varies with customer data).

AD type (Service Data)

0x16

Service Data — 16-bit UUID.

Hubble Service UUID

0xFCA6

Mandatory.

Protocol version

6 bits

Range 0–63.

Sequence number

10 bits

Range 0–1023.

Ephemeral device identifier

32 bits

Rotates over time; not linkable to the real device identity.

Authentication tag

32 bits

Authenticates the packet.

Customer payload

0–13 bytes

Encrypted application data (optional).

The fixed overhead — the UUID prefix, Hubble protocol/address field, and authentication tag — is HUBBLE_BLE_ADV_HEADER_SIZE (12) bytes. The Hubble protocol/address field contains the protocol version, sequence number, and ephemeral device identifier; it is separate from the BLE advertising address described above. The maximum output length is therefore HUBBLE_BLE_ADV_HEADER_SIZE + HUBBLE_BLE_MAX_DATA_LEN = 25 bytes. If your application advertises other services or service data, the space available for Hubble customer data is smaller because BLE advertisements have a finite length.

Customer Payload

The customer payload carries up to 13 bytes of application-defined data set via the input parameter of hubble_ble_advertise_get(). The SDK encrypts this data with the key configured through hubble_key_set() (or hubble_init()) before it is placed in the advertisement.

API Overview

Initialization

Initialize the network before calling other Hubble Terrestrial API functions. The hubble_init() function sets up the required configurations and prepares the network for operation. In Unix-time mode, initial_time is the Unix time in milliseconds. In device-uptime mode, initial_time is the initial counter value, and 0 is valid:

int hubble_init(uint64_t initial_time, const void *key);

Time Management

When using CONFIG_HUBBLE_COUNTER_SOURCE_UNIX_TIME, the API provides functions to set and update the Unix time (milliseconds since the Unix epoch). The hubble_time_set() function enables precise time synchronization throughout the network:

int hubble_time_set(uint64_t unix_time);

Encryption Key Management

An encryption key secures Hubble advertisement payloads. The hubble_key_set() function configures this key for ongoing network operations:

int hubble_key_set(const void *key);

Common API Workflow

A typical terrestrial application initializes the SDK once, then periodically regenerates the advertisement so the ephemeral device identifier keeps rotating.

Typical workflow:

  1. Provision the Hubble key (see Register devices).

  2. Initialize the SDK with the initial value required by the selected counter source.

  3. Build an advertisement, optionally with customer data.

  4. Hand the payload to the platform BLE stack and start advertising.

  5. Refresh the advertisement when it expires.

uint8_t data[HUBBLE_BLE_MAX_DATA_LEN];
size_t data_len = fill_application_data(data);

uint8_t service_data[HUBBLE_BLE_ADV_HEADER_SIZE + HUBBLE_BLE_MAX_DATA_LEN];
size_t service_data_len;

err = hubble_init(initial_counter_or_unix_time_ms, master_key);
if (err != 0) {
        return err;
}

for (;;) {
        service_data_len = sizeof(service_data);

        err = hubble_ble_advertise_get(data, data_len, service_data,
                                       &service_data_len);
        if (err != 0) {
                return err;
        }

        ble_advertise_with_service_data(HUBBLE_BLE_UUID, service_data,
                                        service_data_len);

        sleep_ms(hubble_ble_advertise_expiration_get());
}

Configuration Notes

Enable the terrestrial network with CONFIG_HUBBLE_BLE_NETWORK.

Important related options include:

  • CONFIG_HUBBLE_COUNTER_SOURCE_UNIX_TIME for Unix-time-based operation.

  • CONFIG_HUBBLE_COUNTER_SOURCE_DEVICE_UPTIME for uptime-counter operation.

  • CONFIG_HUBBLE_NETWORK_KEY_128 or CONFIG_HUBBLE_NETWORK_KEY_256 for key size selection.

  • CONFIG_HUBBLE_NETWORK_CRYPTO_* for crypto backend selection.

See Configuration Options for the complete configuration reference. The full terrestrial API is documented in the BLE Network API reference.