ESP Local Controller 本地控制客户端

[English]

esp_local_controller 是面向 ESP-IDF esp_local_ctrl 的 控制器侧 客户端。

组件

角色

esp_local_ctrl

设备端 Server :暴露属性

protocomm_ext

控制器 管道 (传输 + Security 0 / 1 / 2)

esp_local_controller

控制器 业务 (esp_local_ctrl/control protobuf)

本组件负责编解码本地控制 protobuf。会话传输与安全握手仍由 protocomm_ext 完成。

功能

  • HTTP、BLE(NimBLE Central)、UART Console

  • 解析 version JSON(local_ctrl.sec_ver / sec_patch_ver)

  • 按索引查询属性数量、读取 / 写入属性

  • 通过 protocomm_ext 支持 Security 0 / 1 / 2

支持目标: ESP32 / ESP32-S3 / ESP32-C2 / ESP32-C3 / ESP32-C5 / ESP32-C6 / ESP32-C61 / ESP32-H2 / ESP32-P4

典型流程

#include "esp_local_controller.h"
#include "protocomm_ext.h"
#include "protocomm_ext_security.h"

protocomm_ext_t *pc = protocomm_ext_new(&pe_cfg); /* 传输 + Sec0 占位 */
esp_local_controller_t *ctrl = esp_local_controller_create(pc);

esp_local_controller_fetch_version(ctrl, /* BLE: &ble_addr,否则 NULL */ NULL);
esp_local_controller_version_t ver = {0};
esp_local_controller_get_version(ctrl, &ver);
/* 按 ver.sec_ver 调用 protocomm_ext_set_security() 配置 PoP / Sec2 */
esp_local_controller_version_free(&ver);

esp_local_controller_establish_security(ctrl);

uint32_t count = 0;
esp_local_controller_get_property_count(ctrl, &count);

esp_local_controller_stop_session(ctrl);
esp_local_controller_delete(ctrl);
protocomm_ext_delete(pc);

若安全方案已知,可先 protocomm_ext_set_security(),再调用 esp_local_controller_start_session()。

线程安全: 同一实例的 API 非线程安全,请在单任务中串行调用。

添加依赖

dependencies:
  espressif/esp_local_controller: "^1.0.0"

示例

见 examples/esp_local_controller。设备侧请使用 IDF 官方示例 examples/protocols/esp_local_ctrl。

API 参考

Header File

Functions

esp_local_controller_t *esp_local_controller_create(protocomm_ext_t *pc)

Wrap an existing protocomm_ext instance.

Ownership of pc remains with the caller; call esp_local_controller_delete() before protocomm_ext_delete().

Registers BLE endpoint UUID mappings (ESP_LOCAL_CONTROLLER_EP_*_UUID).

备注

APIs on a given instance are not thread-safe. Serialize from one task.

参数

pc – [in] Existing protocomm_ext instance (must not be NULL)

返回

  • non-NULL: new controller instance

  • NULL: invalid argument, endpoint registration failure, or out of memory

void esp_local_controller_delete(esp_local_controller_t *ctrl)

Delete a controller created by esp_local_controller_create()

Does not delete the underlying protocomm_ext instance.

参数

ctrl – [in] Instance to delete (NULL-safe)

protocomm_ext_t *esp_local_controller_get_protocomm(esp_local_controller_t *ctrl)

Return the wrapped protocomm_ext instance.

参数

ctrl – [in] Controller instance

返回

Underlying protocomm_ext pointer, or NULL if ctrl is NULL

esp_err_t esp_local_controller_fetch_version(esp_local_controller_t *ctrl, const void *transport_connect_cfg)

Open transport session and read version JSON (plaintext)

Does not run the security handshake. Stores parsed version for esp_local_controller_get_version(). On failure, any previously cached version is invalidated and the transport session is closed.

参数
  • ctrl – [in] Controller instance

  • transport_connect_cfg – [in] HTTP/Console: NULL; BLE: ble_addr_t *

返回

  • ESP_OK: version fetched and parsed

  • ESP_ERR_INVALID_ARG: bad arguments

  • ESP_ERR_INVALID_RESPONSE: JSON missing / invalid sec_ver

  • Other: transport or allocation errors from protocomm_ext

esp_err_t esp_local_controller_establish_security(esp_local_controller_t *ctrl)

Run security_init + establish_security on esp_local_ctrl/session.

Call after protocomm_ext_set_security() with peer sec_ver / credentials (typically after esp_local_controller_fetch_version() + get_version()).

参数

ctrl – [in] Controller instance (session must already be open)

返回

  • ESP_OK: security established; property APIs may be used

  • ESP_ERR_INVALID_ARG: bad arguments

  • Other: errors from protocomm_ext security APIs

esp_err_t esp_local_controller_start_session(esp_local_controller_t *ctrl, const void *transport_connect_cfg)

Convenience: fetch_version + establish_security.

Prerequisite: call protocomm_ext_set_security() first when the peer scheme is already known (Sec0/1/2 credentials). Equivalent to the recommended split flow when discovery is not needed at runtime.

On establish failure, closes the session and invalidates cached version.

参数
返回

  • ESP_OK: session ready for property get/set

  • Other: see fetch_version / establish_security

esp_err_t esp_local_controller_stop_session(esp_local_controller_t *ctrl)

Close the transport session.

参数

ctrl – [in] Controller instance

返回

Result of protocomm_ext_close_session(), or ESP_ERR_INVALID_ARG

esp_err_t esp_local_controller_get_version(esp_local_controller_t *ctrl, esp_local_controller_version_t *out)

Deep-copy the last successfully fetched version into out.

参数
  • ctrl – [in] Controller instance

  • out – [out] Output version (must not be NULL)

返回

  • ESP_OK: out filled; caller must call esp_local_controller_version_free()

  • ESP_ERR_INVALID_ARG: bad arguments

  • ESP_ERR_INVALID_STATE: no successful fetch yet

  • ESP_ERR_NO_MEM: strdup failed

void esp_local_controller_version_free(esp_local_controller_version_t *ver)

Free heap fields inside a version struct from get_version / parse_version.

参数

ver – [inout] Version to clear (NULL-safe for pointer; no-op if NULL)

esp_err_t esp_local_controller_get_property_count(esp_local_controller_t *ctrl, uint32_t *count)

Query how many properties the peer exposes.

Requires an established secure session (or Sec0 after establish_security).

参数
  • ctrl – [in] Controller instance

  • count – [out] Property count

返回

ESP_OK on success, or a transport / protocol error

esp_err_t esp_local_controller_get_property_values(esp_local_controller_t *ctrl, const uint32_t *indices, size_t index_count, esp_local_controller_prop_t **out_props, size_t *out_count)

Fetch property metadata + values for the given indices.

On success, allocates *out_props of length *out_count. If the peer returns zero properties, *out_props is NULL and *out_count is 0. Caller frees with esp_local_controller_props_free() (NULL-safe).

参数
  • ctrl – [in] Controller instance

  • indices – [in] Array of zero-based property indices

  • index_count – [in] Number of indices (must be > 0)

  • out_props – [out] Allocated property array

  • out_count – [out] Number of entries in *out_props

返回

ESP_OK on success, or a transport / protocol / OOM error

void esp_local_controller_props_free(esp_local_controller_prop_t *props, size_t count)

Free an array from esp_local_controller_get_property_values()

参数
  • props – [in] Property array (NULL-safe)

  • count – [in] Number of elements

esp_err_t esp_local_controller_set_property_values(esp_local_controller_t *ctrl, const esp_local_controller_prop_set_t *props, size_t prop_count)

Set one or more property values by index.

参数
  • ctrl – [in] Controller instance

  • props – [in] Array of set descriptors

  • prop_count – [in] Number of entries (must be > 0)

返回

ESP_OK on success, or a transport / protocol / OOM error

esp_err_t esp_local_controller_parse_version(const char *json, esp_local_controller_version_t *out)

Parse version JSON into out (exposed for unit tests / advanced use)

备注

Prefer esp_local_controller_fetch_version() in application code.

参数
返回

  • ESP_OK: parsed

  • ESP_ERR_INVALID_ARG / ESP_ERR_INVALID_RESPONSE / ESP_ERR_NO_MEM

Structures

struct esp_local_controller_version_t

Parsed fields from the plaintext version endpoint JSON.

Device format: {"local_ctrl":{"ver":"...","sec_ver":N,"sec_patch_ver":M}}

Public Members

char *ver

Heap copy of local_ctrl.ver; free with version free helper

int sec_ver

0 / 1 / 2; -1 if missing

int sec_patch_ver

Patch; -1 if missing

struct esp_local_controller_prop_t

One property returned by esp_local_controller_get_property_values()

Caller owns name and value; free with esp_local_controller_props_free().

Public Members

char *name

Property name (may be NULL)

uint32_t type

Application-defined type

uint32_t flags

Application-defined flags (e.g. read-only)

uint8_t *value

Raw value bytes (may be NULL)

size_t value_len

Length of value

struct esp_local_controller_prop_set_t

One property value for esp_local_controller_set_property_values()

Public Members

uint32_t index

Zero-based property index on the device

const uint8_t *value

Value bytes (may be NULL if value_len == 0)

size_t value_len

Length of value

Macros

ESP_LOCAL_CONTROLLER_EP_VERSION

Version endpoint name (IDF esp_local_ctrl)

ESP_LOCAL_CONTROLLER_EP_SESSION

Session endpoint name (IDF esp_local_ctrl)

ESP_LOCAL_CONTROLLER_EP_CONTROL

Control endpoint name (IDF esp_local_ctrl)

ESP_LOCAL_CONTROLLER_EP_VERSION_UUID

BLE UUID16 for version, matching IDF declare_ep starting at 0xFF50.

ESP_LOCAL_CONTROLLER_EP_SESSION_UUID

BLE UUID16 for session (version + 1).

ESP_LOCAL_CONTROLLER_EP_CONTROL_UUID

BLE UUID16 for control (version + 2).

ESP_LOCAL_CONTROLLER_MAX_PROPERTIES

Upper bound on property indices / returned props accepted from a peer. Rejects oversized count / n_props before allocating (DoS / OOM guard). IDF device examples typically use a much smaller max_properties.

Type Definitions

typedef struct esp_local_controller esp_local_controller_t

Opaque local-controller instance.