05_ble_json

Example of the component iotmertech/iotmer v0.1.14
# Example 05 — BLE JSON channel

Minimal ESP-IDF app that enables the optional **`iotmer_ble`** component and exposes a BLE GATT JSON channel.

This example is intentionally small: it demonstrates a **JSON-over-BLE** transport and a few commissioning commands
implemented in `main`.

## Build

```bash
cd components/iotmer/examples/05_ble_json
idf.py set-target esp32c3    # or esp32, esp32s3, esp32c6, …
idf.py menuconfig
idf.py build flash monitor
```

## Configure

- **Component config → IOTMER BLE (JSON channel)**: enable `CONFIG_IOTMER_BLE=y`, set name prefix and security.
  - This example sets `CONFIG_IOTMER_BLE_GAP_NAME_PREFIX="MER-"` in `sdkconfig.defaults` (advertised name is `MER-` + short hex suffix).
- **Component config → Bluetooth**: enable controller + NimBLE host for your target.

## GATT contract

- Service UUID: `1d14d6ee-1001-4000-8024-b5a3c0ffee01`
- RX characteristic (write): `1d14d6ee-1002-4000-8024-b5a3c0ffee01`
- TX characteristic (notify/read): `1d14d6ee-1003-4000-8024-b5a3c0ffee01`

Central apps should subscribe to TX notifications before sending requests.

## JSON requests and responses

Requests are UTF‑8 JSON written to RX. Responses are UTF‑8 JSON received via TX notifications.

All requests include:

- `type` (string)
- `rid` (string): request id generated by the central; echoed back in responses

### `ping`

Request:

- `{"type":"ping","rid":"1"}`

Response:

- `{"type":"pong","rid":"1"}`

### `wifi.set`

Request:

- `{"type":"wifi.set","rid":"2","ssid":"MyWiFi","pass":"MyPassword"}`

Response:

- `{"type":"wifi.set.ok","rid":"2"}`

#### Optional: `claim_code` (bind-claim)

If `claim_code` is provided, the device will attempt to bind the device to a user identity after Wi‑Fi comes up.

Request:

- `{"type":"wifi.set","rid":"2","ssid":"MyWiFi","pass":"MyPassword","claim_code":"pc_..."}`

Additional responses (order may vary slightly):

- `{"type":"claim.bind.start","rid":"2"}`
- `{"type":"wifi.connect.ok","rid":"2"}`
- `{"type":"creds.ok","rid":"2"}`
- Success: `{"type":"claim.bind.ok","rid":"2"}`
- Failure: `{"type":"error","rid":"2","code":"claim.bind","message":"ESP_ERR_..."}`

If the backend returns HTTP **410 Gone**, it means the **claim code expired** (generate a new one and retry quickly).

### `wifi.clear`

Request:

- `{"type":"wifi.clear","rid":"3"}`

Response:

- `{"type":"wifi.clear.ok","rid":"3"}`

## macOS note (pairing cache)

If you see **CoreBluetooth error 14** ("Peer removed pairing information") while connecting from a PC client,
forget/remove the device under **System Settings → Bluetooth**, then retry.

## Protocol documentation

See the published docs for the full contract carried over `iotmer_ble`:
[BLE JSON provisioning](https://docs.iotmer.com/docs/sdk/esp-idf/ble-json-provisioning).

## PC test client (optional)

See `pc_ble_client/` (Python + Bleak).

To create a project from this example, run:

idf.py create-project-from-example "iotmertech/iotmer=0.1.14:05_ble_json"

or download archive (~9.81 KB)