1 // Copyright 2019 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #pragma once 16 17 #ifdef __cplusplus 18 extern "C" { 19 #endif 20 21 #include <protocomm.h> 22 23 /** 24 * @brief Property description data structure, which is to be populated 25 * and passed to the `esp_local_ctrl_add_property()` function 26 * 27 * Once a property is added, its structure is available for read-only access 28 * inside `get_prop_values()` and `set_prop_values()` handlers. 29 */ 30 typedef struct esp_local_ctrl_prop { 31 /** 32 * Unique name of property 33 */ 34 char *name; 35 36 /** 37 * Type of property. This may be set to application defined enums 38 */ 39 uint32_t type; 40 41 /** 42 * Size of the property value, which: 43 * - if zero, the property can have values of variable size 44 * - if non-zero, the property can have values of fixed size only, 45 * therefore, checks are performed internally by esp_local_ctrl 46 * when setting the value of such a property 47 */ 48 size_t size; 49 50 /** 51 * Flags set for this property. This could be a bit field. 52 * A flag may indicate property behavior, e.g. read-only / constant 53 */ 54 uint32_t flags; 55 56 /** 57 * Pointer to some context data relevant for this property. This will 58 * be available for use inside the `get_prop_values` and `set_prop_values` 59 * handlers as a part of this property structure. When set, this is valid 60 * throughout the lifetime of a property, till either the property is 61 * removed or the esp_local_ctrl service is stopped. 62 */ 63 void *ctx; 64 65 /** 66 * Function used by esp_local_ctrl to internally free the property 67 * context when `esp_local_ctrl_remove_property()` or 68 * `esp_local_ctrl_stop()` is called. 69 */ 70 void (*ctx_free_fn)(void *ctx); 71 } esp_local_ctrl_prop_t; 72 73 /** 74 * @brief Property value data structure. This gets passed to the 75 * `get_prop_values()` and `set_prop_values()` handlers for 76 * the purpose of retrieving or setting the present value 77 * of a property. 78 */ 79 typedef struct esp_local_ctrl_prop_val { 80 /** 81 * Pointer to memory holding property value 82 */ 83 void *data; 84 85 /** 86 * Size of property value 87 */ 88 size_t size; 89 90 /** 91 * This may be set by the application in `get_prop_values()` handler 92 * to tell `esp_local_ctrl` to call this function on the data pointer 93 * above, for freeing its resources after sending the `get_prop_values` 94 * response. 95 */ 96 void (*free_fn)(void *data); 97 } esp_local_ctrl_prop_val_t; 98 99 /** 100 * @brief Handlers for receiving and responding to local 101 * control commands for getting and setting properties. 102 */ 103 typedef struct esp_local_ctrl_handlers { 104 /** 105 * @brief Handler function to be implemented for retrieving current 106 * values of properties 107 * 108 * @note If any of the properties have fixed sizes, the size field of 109 * corresponding element in `prop_values` need to be set 110 * 111 * @param[in] props_count Total elements in the props array 112 * @param[in] props Array of properties, the current values for which 113 * have been requested by the client 114 * @param[out] prop_values Array of empty property values, the elements of 115 * which need to be populated with the current values 116 * of those properties specified by props argument 117 * @param[in] usr_ctx This provides value of the `usr_ctx` field of 118 * `esp_local_ctrl_handlers_t` structure 119 * 120 * @return Returning different error codes will convey the corresponding 121 * protocol level errors to the client : 122 * - ESP_OK : Success 123 * - ESP_ERR_INVALID_ARG : InvalidArgument 124 * - ESP_ERR_INVALID_STATE : InvalidProto 125 * - All other error codes : InternalError 126 */ 127 esp_err_t (*get_prop_values)(size_t props_count, 128 const esp_local_ctrl_prop_t props[], 129 esp_local_ctrl_prop_val_t prop_values[], 130 void *usr_ctx); 131 132 /** 133 * @brief Handler function to be implemented for changing values of properties 134 * 135 * @note If any of the properties have variable sizes, the size field 136 * of the corresponding element in `prop_values` must be checked 137 * explicitly before making any assumptions on the size. 138 * 139 * @param[in] props_count Total elements in the props array 140 * @param[in] props Array of properties, the values for which the 141 * client requests to change 142 * @param[in] prop_values Array of property values, the elements of which 143 * need to be used for updating those properties 144 * specified by props argument 145 * @param[in] usr_ctx This provides value of the `usr_ctx` field of 146 * `esp_local_ctrl_handlers_t` structure 147 * 148 * @return Returning different error codes will convey the corresponding 149 * protocol level errors to the client : 150 * - ESP_OK : Success 151 * - ESP_ERR_INVALID_ARG : InvalidArgument 152 * - ESP_ERR_INVALID_STATE : InvalidProto 153 * - All other error codes : InternalError 154 */ 155 esp_err_t (*set_prop_values)(size_t props_count, 156 const esp_local_ctrl_prop_t props[], 157 const esp_local_ctrl_prop_val_t prop_values[], 158 void *usr_ctx); 159 160 /** 161 * Context pointer to be passed to above handler functions upon invocation. 162 * This is different from the property level context, as this is valid 163 * throughout the lifetime of the `esp_local_ctrl` service, and freed only 164 * when the service is stopped. 165 */ 166 void *usr_ctx; 167 168 /** 169 * Pointer to function which will be internally invoked on `usr_ctx` for 170 * freeing the context resources when `esp_local_ctrl_stop()` is called. 171 */ 172 void (*usr_ctx_free_fn)(void *usr_ctx); 173 } esp_local_ctrl_handlers_t; 174 175 /** 176 * @brief Transport mode (BLE / HTTPD) over which the service will be provided 177 * 178 * This is forward declaration of a private structure, implemented internally 179 * by `esp_local_ctrl`. 180 */ 181 typedef struct esp_local_ctrl_transport esp_local_ctrl_transport_t; 182 183 /** 184 * @brief Function for obtaining BLE transport mode 185 */ 186 const esp_local_ctrl_transport_t *esp_local_ctrl_get_transport_ble(void); 187 188 /** 189 * @brief Function for obtaining HTTPD transport mode 190 */ 191 const esp_local_ctrl_transport_t *esp_local_ctrl_get_transport_httpd(void); 192 193 #define ESP_LOCAL_CTRL_TRANSPORT_BLE esp_local_ctrl_get_transport_ble() 194 #define ESP_LOCAL_CTRL_TRANSPORT_HTTPD esp_local_ctrl_get_transport_httpd() 195 196 /** 197 * @brief Configuration for transport mode BLE 198 * 199 * This is a forward declaration for `protocomm_ble_config_t`. 200 * To use this, application must set CONFIG_BT_BLUEDROID_ENABLED 201 * and include `protocomm_ble.h`. 202 */ 203 typedef struct protocomm_ble_config esp_local_ctrl_transport_config_ble_t; 204 205 /** 206 * @brief Configuration for transport mode HTTPD 207 * 208 * This is a forward declaration for `httpd_ssl_config_t`. 209 * To use this, application must set CONFIG_ESP_HTTPS_SERVER_ENABLE 210 * and include `esp_https_server.h` 211 */ 212 typedef struct httpd_ssl_config esp_local_ctrl_transport_config_httpd_t; 213 214 /** 215 * @brief Transport mode (BLE / HTTPD) configuration 216 */ 217 typedef union { 218 /** 219 * This is same as `protocomm_ble_config_t`. See `protocomm_ble.h` for 220 * available configuration parameters. 221 */ 222 esp_local_ctrl_transport_config_ble_t *ble; 223 224 /** 225 * This is same as `httpd_ssl_config_t`. See `esp_https_server.h` for 226 * available configuration parameters. 227 */ 228 esp_local_ctrl_transport_config_httpd_t *httpd; 229 } esp_local_ctrl_transport_config_t; 230 231 /** 232 * @brief Security types for esp_local_control 233 */ 234 typedef enum esp_local_ctrl_proto_sec { 235 PROTOCOM_SEC0 = 0, 236 PROTOCOM_SEC1, 237 PROTOCOM_SEC_CUSTOM, 238 } esp_local_ctrl_proto_sec_t; 239 240 /** 241 * Protocom security configs 242 */ 243 typedef struct esp_local_ctrl_proto_sec_cfg { 244 /** 245 * This sets protocom security version, sec0/sec1 or custom 246 * If custom, user must provide handle via `proto_sec_custom_handle` below 247 */ 248 esp_local_ctrl_proto_sec_t version; 249 250 /** 251 * Custom security handle if security is set custom via `proto_sec` above 252 * This handle must follow `protocomm_security_t` signature 253 */ 254 void *custom_handle; 255 256 /** 257 * Proof of possession to be used for local control. Could be NULL. 258 */ 259 void *pop; 260 } esp_local_ctrl_proto_sec_cfg_t; 261 262 /** 263 * @brief Configuration structure to pass to `esp_local_ctrl_start()` 264 */ 265 typedef struct esp_local_ctrl_config { 266 /** 267 * Transport layer over which service will be provided 268 */ 269 const esp_local_ctrl_transport_t *transport; 270 271 /** 272 * Transport layer over which service will be provided 273 */ 274 esp_local_ctrl_transport_config_t transport_config; 275 276 /** 277 * Security version and POP 278 */ 279 esp_local_ctrl_proto_sec_cfg_t proto_sec; 280 281 /** 282 * Register handlers for responding to get/set requests on properties 283 */ 284 esp_local_ctrl_handlers_t handlers; 285 286 /** 287 * This limits the number of properties that are available at a time 288 */ 289 size_t max_properties; 290 } esp_local_ctrl_config_t; 291 292 /** 293 * @brief Start local control service 294 * 295 * @param[in] config Pointer to configuration structure 296 * 297 * @return 298 * - ESP_OK : Success 299 * - ESP_FAIL : Failure 300 */ 301 esp_err_t esp_local_ctrl_start(const esp_local_ctrl_config_t *config); 302 303 /** 304 * @brief Stop local control service 305 */ 306 esp_err_t esp_local_ctrl_stop(void); 307 308 /** 309 * @brief Add a new property 310 * 311 * This adds a new property and allocates internal resources for it. 312 * The total number of properties that could be added is limited by 313 * configuration option `max_properties` 314 * 315 * @param[in] prop Property description structure 316 * 317 * @return 318 * - ESP_OK : Success 319 * - ESP_FAIL : Failure 320 */ 321 esp_err_t esp_local_ctrl_add_property(const esp_local_ctrl_prop_t *prop); 322 323 /** 324 * @brief Remove a property 325 * 326 * This finds a property by name, and releases the internal resources 327 * which are associated with it. 328 * 329 * @param[in] name Name of the property to remove 330 * 331 * @return 332 * - ESP_OK : Success 333 * - ESP_ERR_NOT_FOUND : Failure 334 */ 335 esp_err_t esp_local_ctrl_remove_property(const char *name); 336 337 /** 338 * @brief Get property description structure by name 339 * 340 * This API may be used to get a property's context structure 341 * `esp_local_ctrl_prop_t` when its name is known 342 * 343 * @param[in] name Name of the property to find 344 * 345 * @return 346 * - Pointer to property 347 * - NULL if not found 348 */ 349 const esp_local_ctrl_prop_t *esp_local_ctrl_get_property(const char *name); 350 351 /** 352 * @brief Register protocomm handler for a custom endpoint 353 * 354 * This API can be called by the application to register a protocomm handler 355 * for an endpoint after the local control service has started. 356 * 357 * @note In case of BLE transport the names and uuids of all custom 358 * endpoints must be provided beforehand as a part of the `protocomm_ble_config_t` 359 * structure set in `esp_local_ctrl_config_t`, and passed to `esp_local_ctrl_start()`. 360 * 361 * @param[in] ep_name Name of the endpoint 362 * @param[in] handler Endpoint handler function 363 * @param[in] user_ctx User data 364 * 365 * @return 366 * - ESP_OK : Success 367 * - ESP_FAIL : Failure 368 */ 369 esp_err_t esp_local_ctrl_set_handler(const char *ep_name, 370 protocomm_req_handler_t handler, 371 void *user_ctx); 372 373 #ifdef __cplusplus 374 } 375 #endif 376