mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
feat(ble): add BLE UART daemon notify API
This commit is contained in:
@@ -114,6 +114,28 @@ Do not send requests to a daemon bound to a shared network interface unless that
|
||||
|
||||
The CLI prints only the response payload. If the device returns a JSON object, the CLI prints it as JSON.
|
||||
|
||||
## Send a notification from the CLI
|
||||
|
||||
Use `daemon-notify` for fire-and-forget operations where the caller only needs the daemon to write to the BLE device and does not need a protocol response:
|
||||
|
||||
```bash
|
||||
python main.py daemon-notify --op set_led --json '{"state": true}'
|
||||
```
|
||||
|
||||
Send a raw string notification with the default operation name `raw`:
|
||||
|
||||
```bash
|
||||
python main.py daemon-notify "hello"
|
||||
```
|
||||
|
||||
Use a non-default daemon address:
|
||||
|
||||
```bash
|
||||
python main.py daemon-notify --host 127.0.0.1 --port 8899 --op set_led --json '{"state": true}'
|
||||
```
|
||||
|
||||
`daemon-notify` returns after the local BLE write completes. It does not wait for the device to send a JSONL response.
|
||||
|
||||
## HTTP API
|
||||
|
||||
Daemon mode exposes a local HTTP API.
|
||||
@@ -135,7 +157,7 @@ Response fields:
|
||||
| `is_connected` | Whether the BLE client is currently connected |
|
||||
| `pending_requests` | Number of pending request futures |
|
||||
| `single_flight` | Whether the daemon serializes requests |
|
||||
| `max_request_data_bytes` | Maximum JSON-encoded `data` size accepted by `/request` |
|
||||
| `max_request_data_bytes` | Maximum JSON-encoded `data` size accepted by `/request` and `/notify` |
|
||||
| `protocol` | Wire protocol name and version |
|
||||
|
||||
### `POST /request`
|
||||
@@ -189,6 +211,54 @@ HTTP error behavior:
|
||||
| `502` | Device returned a protocol error or invalid response |
|
||||
| `504` | Timed out waiting for the device response |
|
||||
|
||||
### `POST /notify`
|
||||
|
||||
Sends one notification to the BLE device and returns without waiting for a protocol response:
|
||||
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:8888/notify \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"op":"set_led","data":{"state":true}}'
|
||||
```
|
||||
|
||||
Request body:
|
||||
|
||||
```json
|
||||
{
|
||||
"op": "set_led",
|
||||
"data": {
|
||||
"state": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Fields:
|
||||
|
||||
| Field | Required | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `op` | No | Operation name. Defaults to `raw`. |
|
||||
| `data` | Yes | Notification payload. Can be a string, number, boolean, array, object, or null. |
|
||||
|
||||
Limits:
|
||||
|
||||
- `op` must be 1 to 64 characters.
|
||||
- JSON-encoded `data` must not exceed 4096 bytes.
|
||||
|
||||
Successful response:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true
|
||||
}
|
||||
```
|
||||
|
||||
HTTP error behavior:
|
||||
|
||||
| HTTP status | Meaning |
|
||||
| --- | --- |
|
||||
| `413` | Request data exceeds the daemon payload limit |
|
||||
| `500` | Failed to send data to the BLE device |
|
||||
|
||||
## BLE JSONL RPC protocol
|
||||
|
||||
The daemon communicates with the BLE device using newline-delimited JSON. Every message is one JSON object followed by `\n`.
|
||||
@@ -226,7 +296,7 @@ Fields:
|
||||
| Field | Meaning |
|
||||
| --- | --- |
|
||||
| `v` | Protocol version. Current value is `1`. |
|
||||
| `id` | Request ID generated by the daemon. The device must echo this in the response. |
|
||||
| `id` | Request ID generated by the daemon. The device must echo this in `/request` responses. `/notify` uses an empty string because no response is expected. |
|
||||
| `op` | Operation name selected by the client. |
|
||||
| `data` | Request payload. |
|
||||
|
||||
@@ -295,7 +365,8 @@ On the BLE device, implement this loop conceptually:
|
||||
3. Parse each line as JSON.
|
||||
4. Read `id`, `op`, and `data`.
|
||||
5. Execute the requested operation.
|
||||
6. Send a JSON response with the same `id` and a final `\n`.
|
||||
6. If `id` is non-empty, send a JSON response with the same `id` and a final `\n`.
|
||||
7. If `id` is empty, treat the message as fire-and-forget and normally do not send a response.
|
||||
|
||||
For example, an `echo` operation can return the same data:
|
||||
|
||||
@@ -303,6 +374,14 @@ For example, an `echo` operation can return the same data:
|
||||
{"v":1,"id":"6f8f...","ok":true,"data":"hello"}
|
||||
```
|
||||
|
||||
For notifications sent through `/notify`, the daemon uses an empty `id`:
|
||||
|
||||
```json
|
||||
{"v":1,"id":"","op":"set_led","data":{"state":true}}
|
||||
```
|
||||
|
||||
Firmware can execute the operation without responding. If it does respond with `id: ""`, the daemon will log the message as unsolicited because no pending request is waiting for that ID.
|
||||
|
||||
## Single-flight behavior
|
||||
|
||||
The daemon currently processes one `/request` at a time. This is exposed as:
|
||||
|
||||
Reference in New Issue
Block a user