manager.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  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. #pragma once
  15. #include <protocomm.h>
  16. #include "esp_event.h"
  17. #include "wifi_provisioning/wifi_config.h"
  18. #ifdef __cplusplus
  19. extern "C" {
  20. #endif
  21. ESP_EVENT_DECLARE_BASE(WIFI_PROV_EVENT);
  22. /**
  23. * @brief Events generated by manager
  24. *
  25. * These events are generated in order of declaration and, for the
  26. * stretch of time between initialization and de-initialization of
  27. * the manager, each event is signaled only once
  28. */
  29. typedef enum {
  30. /**
  31. * Emitted when the manager is initialized
  32. */
  33. WIFI_PROV_INIT,
  34. /**
  35. * Indicates that provisioning has started
  36. */
  37. WIFI_PROV_START,
  38. /**
  39. * Emitted when Wi-Fi AP credentials are received via `protocomm`
  40. * endpoint `wifi_config`. The event data in this case is a pointer
  41. * to the corresponding `wifi_sta_config_t` structure
  42. */
  43. WIFI_PROV_CRED_RECV,
  44. /**
  45. * Emitted when device fails to connect to the AP of which the
  46. * credentials were received earlier on event `WIFI_PROV_CRED_RECV`.
  47. * The event data in this case is a pointer to the disconnection
  48. * reason code with type `wifi_prov_sta_fail_reason_t`
  49. */
  50. WIFI_PROV_CRED_FAIL,
  51. /**
  52. * Emitted when device successfully connects to the AP of which the
  53. * credentials were received earlier on event `WIFI_PROV_CRED_RECV`
  54. */
  55. WIFI_PROV_CRED_SUCCESS,
  56. /**
  57. * Signals that provisioning service has stopped
  58. */
  59. WIFI_PROV_END,
  60. /**
  61. * Signals that manager has been de-initialized
  62. */
  63. WIFI_PROV_DEINIT,
  64. } wifi_prov_cb_event_t;
  65. typedef void (*wifi_prov_cb_func_t)(void *user_data, wifi_prov_cb_event_t event, void *event_data);
  66. /**
  67. * @brief Event handler that is used by the manager while
  68. * provisioning service is active
  69. */
  70. typedef struct {
  71. /**
  72. * Callback function to be executed on provisioning events
  73. */
  74. wifi_prov_cb_func_t event_cb;
  75. /**
  76. * User context data to pass as parameter to callback function
  77. */
  78. void *user_data;
  79. } wifi_prov_event_handler_t;
  80. /**
  81. * @brief Event handler can be set to none if not used
  82. */
  83. #define WIFI_PROV_EVENT_HANDLER_NONE { \
  84. .event_cb = NULL, \
  85. .user_data = NULL \
  86. }
  87. /**
  88. * @brief Structure for specifying the provisioning scheme to be
  89. * followed by the manager
  90. *
  91. * @note Ready to use schemes are available:
  92. * - wifi_prov_scheme_ble : for provisioning over BLE transport + GATT server
  93. * - wifi_prov_scheme_softap : for provisioning over SoftAP transport + HTTP server
  94. * - wifi_prov_scheme_console : for provisioning over Serial UART transport + Console (for debugging)
  95. */
  96. typedef struct wifi_prov_scheme {
  97. /**
  98. * Function which is to be called by the manager when it is to
  99. * start the provisioning service associated with a protocomm instance
  100. * and a scheme specific configuration
  101. */
  102. esp_err_t (*prov_start) (protocomm_t *pc, void *config);
  103. /**
  104. * Function which is to be called by the manager to stop the
  105. * provisioning service previously associated with a protocomm instance
  106. */
  107. esp_err_t (*prov_stop) (protocomm_t *pc);
  108. /**
  109. * Function which is to be called by the manager to generate
  110. * a new configuration for the provisioning service, that is
  111. * to be passed to prov_start()
  112. */
  113. void *(*new_config) (void);
  114. /**
  115. * Function which is to be called by the manager to delete a
  116. * configuration generated using new_config()
  117. */
  118. void (*delete_config) (void *config);
  119. /**
  120. * Function which is to be called by the manager to set the
  121. * service name and key values in the configuration structure
  122. */
  123. esp_err_t (*set_config_service) (void *config, const char *service_name, const char *service_key);
  124. /**
  125. * Function which is to be called by the manager to set a protocomm endpoint
  126. * with an identifying name and UUID in the configuration structure
  127. */
  128. esp_err_t (*set_config_endpoint) (void *config, const char *endpoint_name, uint16_t uuid);
  129. /**
  130. * Sets mode of operation of Wi-Fi during provisioning
  131. * This is set to :
  132. * - WIFI_MODE_APSTA for SoftAP transport
  133. * - WIFI_MODE_STA for BLE transport
  134. */
  135. wifi_mode_t wifi_mode;
  136. } wifi_prov_scheme_t;
  137. /**
  138. * @brief Structure for specifying the manager configuration
  139. */
  140. typedef struct {
  141. /**
  142. * Provisioning scheme to use. Following schemes are already available:
  143. * - wifi_prov_scheme_ble : for provisioning over BLE transport + GATT server
  144. * - wifi_prov_scheme_softap : for provisioning over SoftAP transport + HTTP server + mDNS (optional)
  145. * - wifi_prov_scheme_console : for provisioning over Serial UART transport + Console (for debugging)
  146. */
  147. wifi_prov_scheme_t scheme;
  148. /**
  149. * Event handler required by the scheme for incorporating scheme specific
  150. * behavior while provisioning manager is running. Various options may be
  151. * provided by the scheme for setting this field. Use WIFI_PROV_EVENT_HANDLER_NONE
  152. * when not used. When using scheme wifi_prov_scheme_ble, the following
  153. * options are available:
  154. * - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM
  155. * - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE
  156. * - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT
  157. */
  158. wifi_prov_event_handler_t scheme_event_handler;
  159. /**
  160. * Event handler that can be set for the purpose of incorporating application
  161. * specific behavior. Use WIFI_PROV_EVENT_HANDLER_NONE when not used.
  162. */
  163. wifi_prov_event_handler_t app_event_handler;
  164. } wifi_prov_mgr_config_t;
  165. /**
  166. * @brief Security modes supported by the Provisioning Manager.
  167. *
  168. * These are same as the security modes provided by protocomm
  169. */
  170. typedef enum wifi_prov_security {
  171. /**
  172. * No security (plain-text communication)
  173. */
  174. WIFI_PROV_SECURITY_0 = 0,
  175. /**
  176. * This secure communication mode consists of
  177. * X25519 key exchange
  178. * + proof of possession (pop) based authentication
  179. * + AES-CTR encryption
  180. */
  181. WIFI_PROV_SECURITY_1
  182. } wifi_prov_security_t;
  183. /**
  184. * @brief Initialize provisioning manager instance
  185. *
  186. * Configures the manager and allocates internal resources
  187. *
  188. * Configuration specifies the provisioning scheme (transport)
  189. * and event handlers
  190. *
  191. * Event WIFI_PROV_INIT is emitted right after initialization
  192. * is complete
  193. *
  194. * @param[in] config Configuration structure
  195. *
  196. * @return
  197. * - ESP_OK : Success
  198. * - ESP_FAIL : Fail
  199. */
  200. esp_err_t wifi_prov_mgr_init(wifi_prov_mgr_config_t config);
  201. /**
  202. * @brief Stop provisioning (if running) and release
  203. * resource used by the manager
  204. *
  205. * Event WIFI_PROV_DEINIT is emitted right after de-initialization
  206. * is finished
  207. *
  208. * If provisioning service is still active when this API is called,
  209. * it first stops the service, hence emitting WIFI_PROV_END, and
  210. * then performs the de-initialization
  211. */
  212. void wifi_prov_mgr_deinit(void);
  213. /**
  214. * @brief Checks if device is provisioned
  215. *
  216. * This checks if Wi-Fi credentials are present on the NVS
  217. *
  218. * The Wi-Fi credentials are assumed to be kept in the same
  219. * NVS namespace as used by esp_wifi component
  220. *
  221. * If one were to call esp_wifi_set_config() directly instead
  222. * of going through the provisioning process, this function will
  223. * still yield true (i.e. device will be found to be provisioned)
  224. *
  225. * @note Calling wifi_prov_mgr_start_provisioning() automatically
  226. * resets the provision state, irrespective of what the
  227. * state was prior to making the call.
  228. *
  229. * @param[out] provisioned True if provisioned, else false
  230. *
  231. * @return
  232. * - ESP_OK : Retrieved provision state successfully
  233. * - ESP_FAIL : Wi-Fi not initialized
  234. * - ESP_ERR_INVALID_ARG : Null argument supplied
  235. * - ESP_ERR_INVALID_STATE : Manager not initialized
  236. */
  237. esp_err_t wifi_prov_mgr_is_provisioned(bool *provisioned);
  238. /**
  239. * @brief Start provisioning service
  240. *
  241. * This starts the provisioning service according to the scheme
  242. * configured at the time of initialization. For scheme :
  243. * - wifi_prov_scheme_ble : This starts protocomm_ble, which internally initializes
  244. * BLE transport and starts GATT server for handling
  245. * provisioning requests
  246. * - wifi_prov_scheme_softap : This activates SoftAP mode of Wi-Fi and starts
  247. * protocomm_httpd, which internally starts an HTTP
  248. * server for handling provisioning requests (If mDNS is
  249. * active it also starts advertising service with type
  250. * _esp_wifi_prov._tcp)
  251. *
  252. * Event WIFI_PROV_START is emitted right after provisioning starts without failure
  253. *
  254. * @note This API will start provisioning service even if device is found to be
  255. * already provisioned, i.e. wifi_prov_mgr_is_provisioned() yields true
  256. *
  257. * @param[in] security Specify which protocomm security scheme to use :
  258. * - WIFI_PROV_SECURITY_0 : For no security
  259. * - WIFI_PROV_SECURITY_1 : x25519 secure handshake for session
  260. * establishment followed by AES-CTR encryption of provisioning messages
  261. * @param[in] pop Pointer to proof of possession string (NULL if not needed). This
  262. * is relevant only for protocomm security 1, in which case it is used
  263. * for authenticating secure session
  264. * @param[in] service_name Unique name of the service. This translates to:
  265. * - Wi-Fi SSID when provisioning mode is softAP
  266. * - Device name when provisioning mode is BLE
  267. * @param[in] service_key Key required by client to access the service (NULL if not needed).
  268. * This translates to:
  269. * - Wi-Fi password when provisioning mode is softAP
  270. * - ignored when provisioning mode is BLE
  271. *
  272. * @return
  273. * - ESP_OK : Provisioning started successfully
  274. * - ESP_FAIL : Failed to start provisioning service
  275. * - ESP_ERR_INVALID_STATE : Provisioning manager not initialized or already started
  276. */
  277. esp_err_t wifi_prov_mgr_start_provisioning(wifi_prov_security_t security, const char *pop,
  278. const char *service_name, const char *service_key);
  279. /**
  280. * @brief Stop provisioning service
  281. *
  282. * If provisioning service is active, this API will initiate a process to stop
  283. * the service and return. Once the service actually stops, the event WIFI_PROV_END
  284. * will be emitted.
  285. *
  286. * If wifi_prov_mgr_deinit() is called without calling this API first, it will
  287. * automatically stop the provisioning service and emit the WIFI_PROV_END, followed
  288. * by WIFI_PROV_DEINIT, before returning.
  289. *
  290. * This API will generally be used along with wifi_prov_mgr_disable_auto_stop()
  291. * in the scenario when the main application has registered its own endpoints,
  292. * and wishes that the provisioning service is stopped only when some protocomm
  293. * command from the client side application is received.
  294. *
  295. * Calling this API inside an endpoint handler, with sufficient cleanup_delay,
  296. * will allow the response / acknowledgment to be sent successfully before the
  297. * underlying protocomm service is stopped.
  298. *
  299. * Cleaup_delay is set when calling wifi_prov_mgr_disable_auto_stop().
  300. * If not specified, it defaults to 1000ms.
  301. *
  302. * For straightforward cases, using this API is usually not necessary as
  303. * provisioning is stopped automatically once WIFI_PROV_CRED_SUCCESS is emitted.
  304. * Stopping is delayed (maximum 30 seconds) thus allowing the client side
  305. * application to query for Wi-Fi state, i.e. after receiving the first query
  306. * and sending `Wi-Fi state connected` response the service is stopped immediately.
  307. */
  308. void wifi_prov_mgr_stop_provisioning(void);
  309. /**
  310. * @brief Wait for provisioning service to finish
  311. *
  312. * Calling this API will block until provisioning service is stopped
  313. * i.e. till event WIFI_PROV_END is emitted.
  314. *
  315. * This will not block if provisioning is not started or not initialized.
  316. */
  317. void wifi_prov_mgr_wait(void);
  318. /**
  319. * @brief Disable auto stopping of provisioning service upon completion
  320. *
  321. * By default, once provisioning is complete, the provisioning service is automatically
  322. * stopped, and all endpoints (along with those registered by main application) are
  323. * deactivated.
  324. *
  325. * This API is useful in the case when main application wishes to close provisioning service
  326. * only after it receives some protocomm command from the client side app. For example, after
  327. * connecting to Wi-Fi, the device may want to connect to the cloud, and only once that is
  328. * successfully, the device is said to be fully configured. But, then it is upto the main
  329. * application to explicitly call wifi_prov_mgr_stop_provisioning() later when the device is
  330. * fully configured and the provisioning service is no longer required.
  331. *
  332. * @note This must be called before executing wifi_prov_mgr_start_provisioning()
  333. *
  334. * @param[in] cleanup_delay Sets the delay after which the actual cleanup of transport related
  335. * resources is done after a call to wifi_prov_mgr_stop_provisioning()
  336. * returns. Minimum allowed value is 100ms. If not specified, this will
  337. * default to 1000ms.
  338. *
  339. * @return
  340. * - ESP_OK : Success
  341. * - ESP_ERR_INVALID_STATE : Manager not initialized or
  342. * provisioning service already started
  343. */
  344. esp_err_t wifi_prov_mgr_disable_auto_stop(uint32_t cleanup_delay);
  345. /**
  346. * @brief Set application version and capabilities in the JSON data returned by
  347. * proto-ver endpoint
  348. *
  349. * This function can be called multiple times, to specify information about the various
  350. * application specific services running on the device, identified by unique labels.
  351. *
  352. * The provisioning service itself registers an entry in the JSON data, by the label "prov",
  353. * containing only provisioning service version and capabilities. Application services should
  354. * use a label other than "prov" so as not to overwrite this.
  355. *
  356. * @note This must be called before executing wifi_prov_mgr_start_provisioning()
  357. *
  358. * @param[in] label String indicating the application name.
  359. *
  360. * @param[in] version String indicating the application version.
  361. * There is no constraint on format.
  362. *
  363. * @param[in] capabilities Array of strings with capabilities.
  364. * These could be used by the client side app to know
  365. * the application registered endpoint capabilities
  366. *
  367. * @param[in] total_capabilities Size of capabilities array
  368. *
  369. * @return
  370. * - ESP_OK : Success
  371. * - ESP_ERR_INVALID_STATE : Manager not initialized or
  372. * provisioning service already started
  373. * - ESP_ERR_NO_MEM : Failed to allocate memory for version string
  374. * - ESP_ERR_INVALID_ARG : Null argument
  375. */
  376. esp_err_t wifi_prov_mgr_set_app_info(const char *label, const char *version,
  377. const char**capabilities, size_t total_capabilities);
  378. /**
  379. * @brief Create an additional endpoint and allocate internal resources for it
  380. *
  381. * This API is to be called by the application if it wants to create an additional
  382. * endpoint. All additional endpoints will be assigned UUIDs starting from 0xFF54
  383. * and so on in the order of execution.
  384. *
  385. * protocomm handler for the created endpoint is to be registered later using
  386. * wifi_prov_mgr_endpoint_register() after provisioning has started.
  387. *
  388. * @note This API can only be called BEFORE provisioning is started
  389. *
  390. * @note Additional endpoints can be used for configuring client provided
  391. * parameters other than Wi-Fi credentials, that are necessary for the
  392. * main application and hence must be set prior to starting the application
  393. *
  394. * @note After session establishment, the additional endpoints must be targeted
  395. * first by the client side application before sending Wi-Fi configuration,
  396. * because once Wi-Fi configuration finishes the provisioning service is
  397. * stopped and hence all endpoints are unregistered
  398. *
  399. * @param[in] ep_name unique name of the endpoint
  400. *
  401. * @return
  402. * - ESP_OK : Success
  403. * - ESP_FAIL : Failure
  404. */
  405. esp_err_t wifi_prov_mgr_endpoint_create(const char *ep_name);
  406. /**
  407. * @brief Register a handler for the previously created endpoint
  408. *
  409. * This API can be called by the application to register a protocomm handler
  410. * to any endpoint that was created using wifi_prov_mgr_endpoint_create().
  411. *
  412. * @note This API can only be called AFTER provisioning has started
  413. *
  414. * @note Additional endpoints can be used for configuring client provided
  415. * parameters other than Wi-Fi credentials, that are necessary for the
  416. * main application and hence must be set prior to starting the application
  417. *
  418. * @note After session establishment, the additional endpoints must be targeted
  419. * first by the client side application before sending Wi-Fi configuration,
  420. * because once Wi-Fi configuration finishes the provisioning service is
  421. * stopped and hence all endpoints are unregistered
  422. *
  423. * @param[in] ep_name Name of the endpoint
  424. * @param[in] handler Endpoint handler function
  425. * @param[in] user_ctx User data
  426. *
  427. * @return
  428. * - ESP_OK : Success
  429. * - ESP_FAIL : Failure
  430. */
  431. esp_err_t wifi_prov_mgr_endpoint_register(const char *ep_name,
  432. protocomm_req_handler_t handler,
  433. void *user_ctx);
  434. /**
  435. * @brief Unregister the handler for an endpoint
  436. *
  437. * This API can be called if the application wants to selectively
  438. * unregister the handler of an endpoint while the provisioning
  439. * is still in progress.
  440. *
  441. * All the endpoint handlers are unregistered automatically when
  442. * the provisioning stops.
  443. *
  444. * @param[in] ep_name Name of the endpoint
  445. */
  446. void wifi_prov_mgr_endpoint_unregister(const char *ep_name);
  447. /**
  448. * @brief Event handler for provisioning manager
  449. *
  450. * This is called from the main event handler and controls the
  451. * provisioning manager's internal state machine depending on
  452. * incoming Wi-Fi events
  453. *
  454. * @note : This function is DEPRECATED, because events are now
  455. * handled internally using the event loop library, esp_event.
  456. * Calling this will do nothing and simply return ESP_OK.
  457. *
  458. * @param[in] ctx Event context data
  459. * @param[in] event Event info
  460. *
  461. * @return
  462. * - ESP_OK : Event handled successfully
  463. */
  464. esp_err_t wifi_prov_mgr_event_handler(void *ctx, system_event_t *event) __attribute__ ((deprecated));
  465. /**
  466. * @brief Get state of Wi-Fi Station during provisioning
  467. *
  468. * @param[out] state Pointer to wifi_prov_sta_state_t
  469. * variable to be filled
  470. *
  471. * @return
  472. * - ESP_OK : Successfully retrieved Wi-Fi state
  473. * - ESP_FAIL : Provisioning app not running
  474. */
  475. esp_err_t wifi_prov_mgr_get_wifi_state(wifi_prov_sta_state_t *state);
  476. /**
  477. * @brief Get reason code in case of Wi-Fi station
  478. * disconnection during provisioning
  479. *
  480. * @param[out] reason Pointer to wifi_prov_sta_fail_reason_t
  481. * variable to be filled
  482. *
  483. * @return
  484. * - ESP_OK : Successfully retrieved Wi-Fi disconnect reason
  485. * - ESP_FAIL : Provisioning app not running
  486. */
  487. esp_err_t wifi_prov_mgr_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t *reason);
  488. /**
  489. * @brief Runs Wi-Fi as Station with the supplied configuration
  490. *
  491. * Configures the Wi-Fi station mode to connect to the AP with
  492. * SSID and password specified in config structure and sets
  493. * Wi-Fi to run as station.
  494. *
  495. * This is automatically called by provisioning service upon
  496. * receiving new credentials.
  497. *
  498. * If credentials are to be supplied to the manager via a
  499. * different mode other than through protocomm, then this
  500. * API needs to be called.
  501. *
  502. * Event WIFI_PROV_CRED_RECV is emitted after credentials have
  503. * been applied and Wi-Fi station started
  504. *
  505. * @param[in] wifi_cfg Pointer to Wi-Fi configuration structure
  506. *
  507. * @return
  508. * - ESP_OK : Wi-Fi configured and started successfully
  509. * - ESP_FAIL : Failed to set configuration
  510. */
  511. esp_err_t wifi_prov_mgr_configure_sta(wifi_config_t *wifi_cfg);
  512. /**
  513. * @brief Reset Wi-Fi provisioning config
  514. *
  515. * Calling this API will restore WiFi stack persistent settings to default values.
  516. *
  517. * @return
  518. * - ESP_OK : Reset provisioning config successfully
  519. * - ESP_FAIL : Failed to reset provisioning config
  520. */
  521. esp_err_t wifi_prov_mgr_reset_provisioning(void);
  522. /**
  523. * @brief Reset internal state machine and clear provisioned credentials.
  524. *
  525. * This API can be used to restart provisioning in case invalid credentials are entered.
  526. *
  527. * @return
  528. * - ESP_OK : Reset provisioning state machine successfully
  529. * - ESP_FAIL : Failed to reset provisioning state machine
  530. * - ESP_ERR_INVALID_STATE : Manager not initialized
  531. */
  532. esp_err_t wifi_prov_mgr_reset_sm_state_on_failure(void);
  533. #ifdef __cplusplus
  534. }
  535. #endif