mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
wifi_provisioning : Wi-Fi Provisioning Manager added
This commit is contained in:
parent
550b1897c8
commit
4ef6c85f0c
@ -1,10 +1,21 @@
|
||||
set(COMPONENT_ADD_INCLUDEDIRS include)
|
||||
set(COMPONENT_PRIV_INCLUDEDIRS proto-c ../protocomm/proto-c)
|
||||
set(COMPONENT_PRIV_INCLUDEDIRS src proto-c ../protocomm/proto-c)
|
||||
set(COMPONENT_SRCS "src/wifi_config.c"
|
||||
"src/manager.c"
|
||||
"src/handlers.c"
|
||||
"src/scheme_softap.c"
|
||||
"src/scheme_console.c"
|
||||
"proto-c/wifi_config.pb-c.c"
|
||||
"proto-c/wifi_constants.pb-c.c")
|
||||
|
||||
set(COMPONENT_REQUIRES lwip)
|
||||
set(COMPONENT_PRIV_REQUIRES protobuf-c protocomm)
|
||||
set(COMPONENT_REQUIRES lwip protocomm)
|
||||
set(COMPONENT_PRIV_REQUIRES protobuf-c bt mdns json)
|
||||
|
||||
if(CONFIG_BT_ENABLED)
|
||||
if(CONFIG_BT_BLUEDROID_ENABLED)
|
||||
list(APPEND COMPONENT_SRCS
|
||||
"src/scheme_ble.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
register_component()
|
||||
|
@ -1,3 +1,7 @@
|
||||
COMPONENT_SRCDIRS := src proto-c
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
COMPONENT_PRIV_INCLUDEDIRS := proto-c ../protocomm/proto-c/
|
||||
COMPONENT_PRIV_INCLUDEDIRS := src proto-c ../protocomm/proto-c/
|
||||
|
||||
ifneq ($(filter y, $(CONFIG_BT_ENABLED) $(CONFIG_BT_BLUEDROID_ENABLED)),y y)
|
||||
COMPONENT_OBJEXCLUDE := src/scheme_ble.o
|
||||
endif
|
||||
|
553
components/wifi_provisioning/include/wifi_provisioning/manager.h
Normal file
553
components/wifi_provisioning/include/wifi_provisioning/manager.h
Normal file
@ -0,0 +1,553 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <esp_event_loop.h>
|
||||
#include <protocomm.h>
|
||||
|
||||
#include "wifi_provisioning/wifi_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Events generated by manager
|
||||
*
|
||||
* These events are generated in order of declaration and, for the
|
||||
* stretch of time between initialization and de-initialization of
|
||||
* the manager, each event is signaled only once
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* Emitted when the manager is initialized
|
||||
*/
|
||||
WIFI_PROV_INIT,
|
||||
|
||||
/**
|
||||
* Indicates that provisioning has started
|
||||
*/
|
||||
WIFI_PROV_START,
|
||||
|
||||
/**
|
||||
* Emitted when Wi-Fi AP credentials are received via `protocomm`
|
||||
* endpoint `wifi_config`. The event data in this case is a pointer
|
||||
* to the corresponding `wifi_sta_config_t` structure
|
||||
*/
|
||||
WIFI_PROV_CRED_RECV,
|
||||
|
||||
/**
|
||||
* Emitted when device fails to connect to the AP of which the
|
||||
* credentials were received earlier on event `WIFI_PROV_CRED_RECV`.
|
||||
* The event data in this case is a pointer to the disconnection
|
||||
* reason code with type `wifi_prov_sta_fail_reason_t`
|
||||
*/
|
||||
WIFI_PROV_CRED_FAIL,
|
||||
|
||||
/**
|
||||
* Emitted when device successfully connects to the AP of which the
|
||||
* credentials were received earlier on event `WIFI_PROV_CRED_RECV`
|
||||
*/
|
||||
WIFI_PROV_CRED_SUCCESS,
|
||||
|
||||
/**
|
||||
* Signals that provisioning service has stopped
|
||||
*/
|
||||
WIFI_PROV_END,
|
||||
|
||||
/**
|
||||
* Signals that manager has been de-initialized
|
||||
*/
|
||||
WIFI_PROV_DEINIT,
|
||||
} wifi_prov_cb_event_t;
|
||||
|
||||
typedef void (*wifi_prov_cb_func_t)(void *user_data, wifi_prov_cb_event_t event, void *event_data);
|
||||
|
||||
/**
|
||||
* @brief Event handler that is used by the manager while
|
||||
* provisioning service is active
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Callback function to be executed on provisioning events
|
||||
*/
|
||||
wifi_prov_cb_func_t event_cb;
|
||||
|
||||
/**
|
||||
* User context data to pass as parameter to callback function
|
||||
*/
|
||||
void *user_data;
|
||||
} wifi_prov_event_handler_t;
|
||||
|
||||
/**
|
||||
* @brief Event handler can be set to none if not used
|
||||
*/
|
||||
#define WIFI_PROV_EVENT_HANDLER_NONE { \
|
||||
.event_cb = NULL, \
|
||||
.user_data = NULL \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Structure for specifying the provisioning scheme to be
|
||||
* followed by the manager
|
||||
*
|
||||
* @note Ready to use schemes are available:
|
||||
* - wifi_prov_scheme_ble : for provisioning over BLE transport + GATT server
|
||||
* - wifi_prov_scheme_softap : for provisioning over SoftAP transport + HTTP server
|
||||
* - wifi_prov_scheme_console : for provisioning over Serial UART transport + Console (for debugging)
|
||||
*/
|
||||
typedef struct wifi_prov_scheme {
|
||||
/**
|
||||
* Function which is to be called by the manager when it is to
|
||||
* start the provisioning service associated with a protocomm instance
|
||||
* and a scheme specific configuration
|
||||
*/
|
||||
esp_err_t (*prov_start) (protocomm_t *pc, void *config);
|
||||
|
||||
/**
|
||||
* Function which is to be called by the manager to stop the
|
||||
* provisioning service previously associated with a protocomm instance
|
||||
*/
|
||||
esp_err_t (*prov_stop) (protocomm_t *pc);
|
||||
|
||||
/**
|
||||
* Function which is to be called by the manager to generate
|
||||
* a new configuration for the provisioning service, that is
|
||||
* to be passed to prov_start()
|
||||
*/
|
||||
void *(*new_config) (void);
|
||||
|
||||
/**
|
||||
* Function which is to be called by the manager to delete a
|
||||
* configuration generated using new_config()
|
||||
*/
|
||||
void (*delete_config) (void *config);
|
||||
|
||||
/**
|
||||
* Function which is to be called by the manager to set the
|
||||
* service name and key values in the configuration structure
|
||||
*/
|
||||
esp_err_t (*set_config_service) (void *config, const char *service_name, const char *service_key);
|
||||
|
||||
/**
|
||||
* Function which is to be called by the manager to set a protocomm endpoint
|
||||
* with an identifying name and UUID in the configuration structure
|
||||
*/
|
||||
esp_err_t (*set_config_endpoint) (void *config, const char *endpoint_name, uint16_t uuid);
|
||||
|
||||
/**
|
||||
* Sets mode of operation of Wi-Fi during provisioning
|
||||
* This is set to :
|
||||
* - WIFI_MODE_APSTA for SoftAP transport
|
||||
* - WIFI_MODE_STA for BLE transport
|
||||
*/
|
||||
wifi_mode_t wifi_mode;
|
||||
} wifi_prov_scheme_t;
|
||||
|
||||
/**
|
||||
* @brief Structure for specifying the manager configuration
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Provisioning scheme to use. Following schemes are already available:
|
||||
* - wifi_prov_scheme_ble : for provisioning over BLE transport + GATT server
|
||||
* - wifi_prov_scheme_softap : for provisioning over SoftAP transport + HTTP server + mDNS (optional)
|
||||
* - wifi_prov_scheme_console : for provisioning over Serial UART transport + Console (for debugging)
|
||||
*/
|
||||
wifi_prov_scheme_t scheme;
|
||||
|
||||
/**
|
||||
* Event handler required by the scheme for incorporating scheme specific
|
||||
* behavior while provisioning manager is running. Various options may be
|
||||
* provided by the scheme for setting this field. Use WIFI_PROV_EVENT_HANDLER_NONE
|
||||
* when not used. When using scheme wifi_prov_scheme_ble, the following
|
||||
* options are available:
|
||||
* - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM
|
||||
* - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE
|
||||
* - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT
|
||||
*/
|
||||
wifi_prov_event_handler_t scheme_event_handler;
|
||||
|
||||
/**
|
||||
* Event handler that can be set for the purpose of incorporating application
|
||||
* specific behavior. Use WIFI_PROV_EVENT_HANDLER_NONE when not used.
|
||||
*/
|
||||
wifi_prov_event_handler_t app_event_handler;
|
||||
} wifi_prov_mgr_config_t;
|
||||
|
||||
/**
|
||||
* @brief Security modes supported by the Provisioning Manager.
|
||||
*
|
||||
* These are same as the security modes provided by protocomm
|
||||
*/
|
||||
typedef enum wifi_prov_security {
|
||||
/**
|
||||
* No security (plain-text communication)
|
||||
*/
|
||||
WIFI_PROV_SECURITY_0 = 0,
|
||||
|
||||
/**
|
||||
* This secure communication mode consists of
|
||||
* X25519 key exchange
|
||||
* + proof of possession (pop) based authentication
|
||||
* + AES-CTR encryption
|
||||
*/
|
||||
WIFI_PROV_SECURITY_1
|
||||
} wifi_prov_security_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize provisioning manager instance
|
||||
*
|
||||
* Configures the manager and allocates internal resources
|
||||
*
|
||||
* Configuration specifies the provisioning scheme (transport)
|
||||
* and event handlers
|
||||
*
|
||||
* Event WIFI_PROV_INIT is emitted right after initialization
|
||||
* is complete
|
||||
*
|
||||
* @param[in] config Configuration structure
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Success
|
||||
* - ESP_FAIL : Fail
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_init(wifi_prov_mgr_config_t config);
|
||||
|
||||
/**
|
||||
* @brief Stop provisioning (if running) and release
|
||||
* resource used by the manager
|
||||
*
|
||||
* Event WIFI_PROV_DEINIT is emitted right after de-initialization
|
||||
* is finished
|
||||
*
|
||||
* If provisioning service is still active when this API is called,
|
||||
* it first stops the service, hence emitting WIFI_PROV_END, and
|
||||
* then performs the de-initialization
|
||||
*/
|
||||
void wifi_prov_mgr_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Checks if device is provisioned
|
||||
*
|
||||
* This checks if Wi-Fi credentials are present on the NVS
|
||||
*
|
||||
* The Wi-Fi credentials are assumed to be kept in the same
|
||||
* NVS namespace as used by esp_wifi component
|
||||
*
|
||||
* If one were to call esp_wifi_set_config() directly instead
|
||||
* of going through the provisioning process, this function will
|
||||
* still yield true (i.e. device will be found to be provisioned)
|
||||
*
|
||||
* @note Calling wifi_prov_mgr_start_provisioning() automatically
|
||||
* resets the provision state, irrespective of what the
|
||||
* state was prior to making the call.
|
||||
*
|
||||
* @param[out] provisioned True if provisioned, else false
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Retrieved provision state successfully
|
||||
* - ESP_FAIL : Wi-Fi not initialized
|
||||
* - ESP_ERR_INVALID_ARG : Null argument supplied
|
||||
* - ESP_ERR_INVALID_STATE : Manager not initialized
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_is_provisioned(bool *provisioned);
|
||||
|
||||
/**
|
||||
* @brief Start provisioning service
|
||||
*
|
||||
* This starts the provisioning service according to the scheme
|
||||
* configured at the time of initialization. For scheme :
|
||||
* - wifi_prov_scheme_ble : This starts protocomm_ble, which internally initializes
|
||||
* BLE transport and starts GATT server for handling
|
||||
* provisioning requests
|
||||
* - wifi_prov_scheme_softap : This activates SoftAP mode of Wi-Fi and starts
|
||||
* protocomm_httpd, which internally starts an HTTP
|
||||
* server for handling provisioning requests (If mDNS is
|
||||
* active it also starts advertising service with type
|
||||
* _esp_wifi_prov._tcp)
|
||||
*
|
||||
* Event WIFI_PROV_START is emitted right after provisioning starts without failure
|
||||
*
|
||||
* @note This API will start provisioning service even if device is found to be
|
||||
* already provisioned, i.e. wifi_prov_mgr_is_provisioned() yields true
|
||||
*
|
||||
* @param[in] security Specify which protocomm security scheme to use :
|
||||
* - WIFI_PROV_SECURITY_0 : For no security
|
||||
* - WIFI_PROV_SECURITY_1 : x25519 secure handshake for session
|
||||
* establishment followed by AES-CTR encryption of provisioning messages
|
||||
* @param[in] pop Pointer to proof of possession string (NULL if not needed). This
|
||||
* is relevant only for protocomm security 1, in which case it is used
|
||||
* for authenticating secure session
|
||||
* @param[in] service_name Unique name of the service. This translates to:
|
||||
* - Wi-Fi SSID when provisioning mode is softAP
|
||||
* - Device name when provisioning mode is BLE
|
||||
* @param[in] service_key Key required by client to access the service (NULL if not needed).
|
||||
* This translates to:
|
||||
* - Wi-Fi password when provisioning mode is softAP
|
||||
* - ignored when provisioning mode is BLE
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Provisioning started successfully
|
||||
* - ESP_FAIL : Failed to start provisioning service
|
||||
* - ESP_ERR_INVALID_STATE : Provisioning manager not initialized or already started
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_start_provisioning(wifi_prov_security_t security, const char *pop,
|
||||
const char *service_name, const char *service_key);
|
||||
|
||||
/**
|
||||
* @brief Stop provisioning service
|
||||
*
|
||||
* If provisioning service is active, this API will initiate a process to stop
|
||||
* the service and return. Once the service actually stops, the event WIFI_PROV_END
|
||||
* will be emitted.
|
||||
*
|
||||
* If wifi_prov_mgr_deinit() is called without calling this API first, it will
|
||||
* automatically stop the provisioning service and emit the WIFI_PROV_END, followed
|
||||
* by WIFI_PROV_DEINIT, before returning.
|
||||
*
|
||||
* This API will generally be used along with wifi_prov_mgr_disable_auto_stop()
|
||||
* in the scenario when the main application has registered its own endpoints,
|
||||
* and wishes that the provisioning service is stopped only when some protocomm
|
||||
* command from the client side application is received.
|
||||
*
|
||||
* Calling this API inside an endpoint handler, with sufficient cleanup_delay,
|
||||
* will allow the response / acknowledgment to be sent successfully before the
|
||||
* underlying protocomm service is stopped.
|
||||
*
|
||||
* Cleaup_delay is set when calling wifi_prov_mgr_disable_auto_stop().
|
||||
* If not specified, it defaults to 1000ms.
|
||||
*
|
||||
* For straightforward cases, using this API is usually not necessary as
|
||||
* provisioning is stopped automatically once WIFI_PROV_CRED_SUCCESS is emitted.
|
||||
* Stopping is delayed (maximum 30 seconds) thus allowing the client side
|
||||
* application to query for Wi-Fi state, i.e. after receiving the first query
|
||||
* and sending `Wi-Fi state connected` response the service is stopped immediately.
|
||||
*/
|
||||
void wifi_prov_mgr_stop_provisioning(void);
|
||||
|
||||
/**
|
||||
* @brief Wait for provisioning service to finish
|
||||
*
|
||||
* Calling this API will block until provisioning service is stopped
|
||||
* i.e. till event WIFI_PROV_END is emitted.
|
||||
*
|
||||
* This will not block if provisioning is not started or not initialized.
|
||||
*/
|
||||
void wifi_prov_mgr_wait(void);
|
||||
|
||||
/**
|
||||
* @brief Disable auto stopping of provisioning service upon completion
|
||||
*
|
||||
* By default, once provisioning is complete, the provisioning service is automatically
|
||||
* stopped, and all endpoints (along with those registered by main application) are
|
||||
* deactivated.
|
||||
*
|
||||
* This API is useful in the case when main application wishes to close provisioning service
|
||||
* only after it receives some protocomm command from the client side app. For example, after
|
||||
* connecting to Wi-Fi, the device may want to connect to the cloud, and only once that is
|
||||
* successfully, the device is said to be fully configured. But, then it is upto the main
|
||||
* application to explicitly call wifi_prov_mgr_stop_provisioning() later when the device is
|
||||
* fully configured and the provisioning service is no longer required.
|
||||
*
|
||||
* @note This must be called before executing wifi_prov_mgr_start_provisioning()
|
||||
*
|
||||
* @param[in] cleanup_delay Sets the delay after which the actual cleanup of transport related
|
||||
* resources is done after a call to wifi_prov_mgr_stop_provisioning()
|
||||
* returns. Minimum allowed value is 100ms. If not specified, this will
|
||||
* default to 1000ms.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_INVALID_STATE : Manager not initialized or
|
||||
* provisioning service already started
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_disable_auto_stop(uint32_t cleanup_delay);
|
||||
|
||||
/**
|
||||
* @brief Set application version and capabilities in the JSON data returned by
|
||||
* proto-ver endpoint
|
||||
*
|
||||
* This function can be called multiple times, to specify information about the various
|
||||
* application specific services running on the device, identified by unique labels.
|
||||
*
|
||||
* The provisioning service itself registers an entry in the JSON data, by the label "prov",
|
||||
* containing only provisioning service version and capabilities. Application services should
|
||||
* use a label other than "prov" so as not to overwrite this.
|
||||
*
|
||||
* @note This must be called before executing wifi_prov_mgr_start_provisioning()
|
||||
*
|
||||
* @param[in] label String indicating the application name.
|
||||
*
|
||||
* @param[in] version String indicating the application version.
|
||||
* There is no constraint on format.
|
||||
*
|
||||
* @param[in] capabilities Array of strings with capabilities.
|
||||
* These could be used by the client side app to know
|
||||
* the application registered endpoint capabilities
|
||||
*
|
||||
* @param[in] total_capabilities Size of capabilities array
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_INVALID_STATE : Manager not initialized or
|
||||
* provisioning service already started
|
||||
* - ESP_ERR_NO_MEM : Failed to allocate memory for version string
|
||||
* - ESP_ERR_INVALID_ARG : Null argument
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_set_app_info(const char *label, const char *version,
|
||||
const char**capabilities, size_t total_capabilities);
|
||||
|
||||
/**
|
||||
* @brief Create an additional endpoint and allocate internal resources for it
|
||||
*
|
||||
* This API is to be called by the application if it wants to create an additional
|
||||
* endpoint. All additional endpoints will be assigned UUIDs starting from 0xFF54
|
||||
* and so on in the order of execution.
|
||||
*
|
||||
* protocomm handler for the created endpoint is to be registered later using
|
||||
* wifi_prov_mgr_endpoint_register() after provisioning has started.
|
||||
*
|
||||
* @note This API can only be called BEFORE provisioning is started
|
||||
*
|
||||
* @note Additional endpoints can be used for configuring client provided
|
||||
* parameters other than Wi-Fi credentials, that are necessary for the
|
||||
* main application and hence must be set prior to starting the application
|
||||
*
|
||||
* @note After session establishment, the additional endpoints must be targeted
|
||||
* first by the client side application before sending Wi-Fi configuration,
|
||||
* because once Wi-Fi configuration finishes the provisioning service is
|
||||
* stopped and hence all endpoints are unregistered
|
||||
*
|
||||
* @param[in] ep_name unique name of the endpoint
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Success
|
||||
* - ESP_FAIL : Failure
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_endpoint_create(const char *ep_name);
|
||||
|
||||
/**
|
||||
* @brief Register a handler for the previously created endpoint
|
||||
*
|
||||
* This API can be called by the application to register a protocomm handler
|
||||
* to any endpoint that was created using wifi_prov_mgr_endpoint_create().
|
||||
*
|
||||
* @note This API can only be called AFTER provisioning has started
|
||||
*
|
||||
* @note Additional endpoints can be used for configuring client provided
|
||||
* parameters other than Wi-Fi credentials, that are necessary for the
|
||||
* main application and hence must be set prior to starting the application
|
||||
*
|
||||
* @note After session establishment, the additional endpoints must be targeted
|
||||
* first by the client side application before sending Wi-Fi configuration,
|
||||
* because once Wi-Fi configuration finishes the provisioning service is
|
||||
* stopped and hence all endpoints are unregistered
|
||||
*
|
||||
* @param[in] ep_name Name of the endpoint
|
||||
* @param[in] handler Endpoint handler function
|
||||
* @param[in] user_ctx User data
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Success
|
||||
* - ESP_FAIL : Failure
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_endpoint_register(const char *ep_name,
|
||||
protocomm_req_handler_t handler,
|
||||
void *user_ctx);
|
||||
|
||||
/**
|
||||
* @brief Unregister the handler for an endpoint
|
||||
*
|
||||
* This API can be called if the application wants to selectively
|
||||
* unregister the handler of an endpoint while the provisioning
|
||||
* is still in progress.
|
||||
*
|
||||
* All the endpoint handlers are unregistered automatically when
|
||||
* the provisioning stops.
|
||||
*
|
||||
* @param[in] ep_name Name of the endpoint
|
||||
*/
|
||||
void wifi_prov_mgr_endpoint_unregister(const char *ep_name);
|
||||
|
||||
/**
|
||||
* @brief Event handler for provisioning manager
|
||||
*
|
||||
* This is called from the main event handler and controls the
|
||||
* provisioning manager's internal state machine depending on
|
||||
* incoming Wi-Fi events
|
||||
*
|
||||
* @param[in] ctx Event context data
|
||||
* @param[in] event Event info
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Event handled successfully
|
||||
* - ESP_ERR_FAIL : This event cannot be handled
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_event_handler(void *ctx, system_event_t *event);
|
||||
|
||||
/**
|
||||
* @brief Get state of Wi-Fi Station during provisioning
|
||||
*
|
||||
* @param[out] state Pointer to wifi_prov_sta_state_t
|
||||
* variable to be filled
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Successfully retrieved Wi-Fi state
|
||||
* - ESP_FAIL : Provisioning app not running
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_get_wifi_state(wifi_prov_sta_state_t *state);
|
||||
|
||||
/**
|
||||
* @brief Get reason code in case of Wi-Fi station
|
||||
* disconnection during provisioning
|
||||
*
|
||||
* @param[out] reason Pointer to wifi_prov_sta_fail_reason_t
|
||||
* variable to be filled
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Successfully retrieved Wi-Fi disconnect reason
|
||||
* - ESP_FAIL : Provisioning app not running
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t *reason);
|
||||
|
||||
/**
|
||||
* @brief Runs Wi-Fi as Station with the supplied configuration
|
||||
*
|
||||
* Configures the Wi-Fi station mode to connect to the AP with
|
||||
* SSID and password specified in config structure and sets
|
||||
* Wi-Fi to run as station.
|
||||
*
|
||||
* This is automatically called by provisioning service upon
|
||||
* receiving new credentials.
|
||||
*
|
||||
* If credentials are to be supplied to the manager via a
|
||||
* different mode other than through protocomm, then this
|
||||
* API needs to be called.
|
||||
*
|
||||
* Event WIFI_PROV_CRED_RECV is emitted after credentials have
|
||||
* been applied and Wi-Fi station started
|
||||
*
|
||||
* @param[in] wifi_cfg Pointer to Wi-Fi configuration structure
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Wi-Fi configured and started successfully
|
||||
* - ESP_FAIL : Failed to set configuration
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_configure_sta(wifi_config_t *wifi_cfg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,82 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <protocomm.h>
|
||||
#include <protocomm_ble.h>
|
||||
|
||||
#include "wifi_provisioning/manager.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Scheme that can be used by manager for provisioning
|
||||
* over BLE transport with GATT server
|
||||
*/
|
||||
extern const wifi_prov_scheme_t wifi_prov_scheme_ble;
|
||||
|
||||
/* This scheme specific event handler is to be used when application
|
||||
* doesn't require BT and BLE after provisioning has finished */
|
||||
#define WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM { \
|
||||
.event_cb = wifi_prov_scheme_ble_event_cb_free_btdm, \
|
||||
.user_data = NULL \
|
||||
}
|
||||
|
||||
/* This scheme specific event handler is to be used when application
|
||||
* doesn't require BLE to be active after provisioning has finished */
|
||||
#define WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE { \
|
||||
.event_cb = wifi_prov_scheme_ble_event_cb_free_ble, \
|
||||
.user_data = NULL \
|
||||
}
|
||||
|
||||
/* This scheme specific event handler is to be used when application
|
||||
* doesn't require BT to be active after provisioning has finished */
|
||||
#define WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT { \
|
||||
.event_cb = wifi_prov_scheme_ble_event_cb_free_bt, \
|
||||
.user_data = NULL \
|
||||
}
|
||||
|
||||
void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event_t event, void *event_data);
|
||||
void wifi_prov_scheme_ble_event_cb_free_ble (void *user_data, wifi_prov_cb_event_t event, void *event_data);
|
||||
void wifi_prov_scheme_ble_event_cb_free_bt (void *user_data, wifi_prov_cb_event_t event, void *event_data);
|
||||
|
||||
/**
|
||||
* @brief Set the 128 bit GATT service UUID used for provisioning
|
||||
*
|
||||
* This API is used to override the default 128 bit provisioning
|
||||
* service UUID, which is 0000ffff-0000-1000-8000-00805f9b34fb.
|
||||
*
|
||||
* This must be called before starting provisioning, i.e. before
|
||||
* making a call to wifi_prov_mgr_start_provisioning(), otherwise
|
||||
* the default UUID will be used.
|
||||
*
|
||||
* @note The data being pointed to by the argument must be valid
|
||||
* atleast till provisioning is started. Upon start, the
|
||||
* manager will store an internal copy of this UUID, and
|
||||
* this data can be freed or invalidated afterwords.
|
||||
*
|
||||
* @param[in] uuid128 A custom 128 bit UUID
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Success
|
||||
* - ESP_ERR_INVALID_ARG : Null argument
|
||||
*/
|
||||
esp_err_t wifi_prov_scheme_ble_set_service_uuid(uint8_t *uuid128);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,34 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <protocomm.h>
|
||||
#include <protocomm_console.h>
|
||||
|
||||
#include "wifi_provisioning/manager.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Scheme that can be used by manager for provisioning
|
||||
* over console (Serial UART)
|
||||
*/
|
||||
extern const wifi_prov_scheme_t wifi_prov_scheme_console;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,34 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <protocomm.h>
|
||||
#include <protocomm_httpd.h>
|
||||
|
||||
#include "wifi_provisioning/manager.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Scheme that can be used by manager for provisioning
|
||||
* over SoftAP transport with HTTP server
|
||||
*/
|
||||
extern const wifi_prov_scheme_t wifi_prov_scheme_softap;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
146
components/wifi_provisioning/src/handlers.c
Normal file
146
components/wifi_provisioning/src/handlers.c
Normal file
@ -0,0 +1,146 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_log.h>
|
||||
|
||||
#include <esp_wifi.h>
|
||||
#include <tcpip_adapter.h>
|
||||
|
||||
#include "wifi_provisioning/wifi_config.h"
|
||||
#include "wifi_provisioning/manager.h"
|
||||
#include "wifi_provisioning_priv.h"
|
||||
|
||||
static const char *TAG = "wifi_prov_handlers";
|
||||
|
||||
/* Provide definition of wifi_prov_ctx_t */
|
||||
struct wifi_prov_ctx {
|
||||
wifi_config_t wifi_cfg;
|
||||
};
|
||||
|
||||
static wifi_config_t *get_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
return (*ctx ? & (*ctx)->wifi_cfg : NULL);
|
||||
}
|
||||
|
||||
static wifi_config_t *new_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
free(*ctx);
|
||||
(*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t));
|
||||
return get_config(ctx);
|
||||
}
|
||||
|
||||
static void free_config(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
}
|
||||
|
||||
static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
/* Initialize to zero */
|
||||
memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t));
|
||||
|
||||
if (wifi_prov_mgr_get_wifi_state(&resp_data->wifi_state) != ESP_OK) {
|
||||
ESP_LOGW(TAG, "Wi-Fi provisioning manager not running");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (resp_data->wifi_state == WIFI_PROV_STA_CONNECTED) {
|
||||
ESP_LOGD(TAG, "Got state : connected");
|
||||
|
||||
/* IP Addr assigned to STA */
|
||||
tcpip_adapter_ip_info_t ip_info;
|
||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info);
|
||||
char *ip_addr = ip4addr_ntoa(&ip_info.ip);
|
||||
strcpy(resp_data->conn_info.ip_addr, ip_addr);
|
||||
|
||||
/* AP information to which STA is connected */
|
||||
wifi_ap_record_t ap_info;
|
||||
esp_wifi_sta_get_ap_info(&ap_info);
|
||||
memcpy(resp_data->conn_info.bssid, (char *)ap_info.bssid, sizeof(ap_info.bssid));
|
||||
memcpy(resp_data->conn_info.ssid, (char *)ap_info.ssid, sizeof(ap_info.ssid));
|
||||
resp_data->conn_info.channel = ap_info.primary;
|
||||
resp_data->conn_info.auth_mode = ap_info.authmode;
|
||||
|
||||
/* Tell manager to stop provisioning service */
|
||||
wifi_prov_mgr_done();
|
||||
} else if (resp_data->wifi_state == WIFI_PROV_STA_DISCONNECTED) {
|
||||
ESP_LOGD(TAG, "Got state : disconnected");
|
||||
|
||||
/* If disconnected, convey reason */
|
||||
wifi_prov_mgr_get_wifi_disconnect_reason(&resp_data->fail_reason);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Got state : connecting");
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
wifi_config_t *wifi_cfg = get_config(ctx);
|
||||
if (wifi_cfg) {
|
||||
free_config(ctx);
|
||||
}
|
||||
|
||||
wifi_cfg = new_config(ctx);
|
||||
if (!wifi_cfg) {
|
||||
ESP_LOGE(TAG, "Unable to allocate Wi-Fi config");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Wi-Fi Credentials Received");
|
||||
|
||||
/* Using strncpy allows the max SSID length to be 32 bytes (as per 802.11 standard).
|
||||
* But this doesn't guarantee that the saved SSID will be null terminated, because
|
||||
* wifi_cfg->sta.ssid is also 32 bytes long (without extra 1 byte for null character) */
|
||||
strncpy((char *) wifi_cfg->sta.ssid, req_data->ssid, sizeof(wifi_cfg->sta.ssid));
|
||||
|
||||
/* Using strlcpy allows both max passphrase length (63 bytes) and ensures null termination
|
||||
* because size of wifi_cfg->sta.password is 64 bytes (1 extra byte for null character) */
|
||||
strlcpy((char *) wifi_cfg->sta.password, req_data->password, sizeof(wifi_cfg->sta.password));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx)
|
||||
{
|
||||
wifi_config_t *wifi_cfg = get_config(ctx);
|
||||
if (!wifi_cfg) {
|
||||
ESP_LOGE(TAG, "Wi-Fi config not set");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t ret = wifi_prov_mgr_configure_sta(wifi_cfg);
|
||||
if (ret == ESP_OK) {
|
||||
ESP_LOGD(TAG, "Wi-Fi Credentials Applied");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to apply Wi-Fi Credentials");
|
||||
}
|
||||
|
||||
free_config(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
wifi_prov_config_handlers_t get_wifi_prov_handlers(void)
|
||||
{
|
||||
wifi_prov_config_handlers_t wifi_prov_handlers = {
|
||||
.get_status_handler = get_status_handler,
|
||||
.set_config_handler = set_config_handler,
|
||||
.apply_config_handler = apply_config_handler,
|
||||
.ctx = NULL
|
||||
};
|
||||
return wifi_prov_handlers;
|
||||
}
|
1117
components/wifi_provisioning/src/manager.c
Normal file
1117
components/wifi_provisioning/src/manager.c
Normal file
File diff suppressed because it is too large
Load Diff
232
components/wifi_provisioning/src/scheme_ble.c
Normal file
232
components/wifi_provisioning/src/scheme_ble.c
Normal file
@ -0,0 +1,232 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <string.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_bt.h>
|
||||
|
||||
#include <protocomm.h>
|
||||
#include <protocomm_ble.h>
|
||||
|
||||
#include "wifi_provisioning/scheme_ble.h"
|
||||
#include "wifi_provisioning_priv.h"
|
||||
|
||||
static const char *TAG = "wifi_prov_scheme_ble";
|
||||
|
||||
extern const wifi_prov_scheme_t wifi_prov_scheme_ble;
|
||||
|
||||
static uint8_t *custom_service_uuid;
|
||||
|
||||
static esp_err_t prov_start(protocomm_t *pc, void *config)
|
||||
{
|
||||
if (!pc) {
|
||||
ESP_LOGE(TAG, "Protocomm handle cannot be null");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!config) {
|
||||
ESP_LOGE(TAG, "Cannot start with null configuration");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
protocomm_ble_config_t *ble_config = (protocomm_ble_config_t *) config;
|
||||
|
||||
/* Start protocomm as BLE service */
|
||||
if (protocomm_ble_start(pc, ble_config) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to start protocomm BLE service");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t wifi_prov_scheme_ble_set_service_uuid(uint8_t *uuid128)
|
||||
{
|
||||
if (!uuid128) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
custom_service_uuid = uuid128;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void *new_config(void)
|
||||
{
|
||||
protocomm_ble_config_t *ble_config = calloc(1, sizeof(protocomm_ble_config_t));
|
||||
if (!ble_config) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for new configuration");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The default provisioning service UUID */
|
||||
const uint8_t service_uuid[16] = {
|
||||
/* LSB <---------------------------------------
|
||||
* ---------------------------------------> MSB */
|
||||
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
|
||||
0x00, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
|
||||
};
|
||||
|
||||
memcpy(ble_config->service_uuid, service_uuid, sizeof(ble_config->service_uuid));
|
||||
return ble_config;
|
||||
}
|
||||
|
||||
static void delete_config(void *config)
|
||||
{
|
||||
if (!config) {
|
||||
ESP_LOGE(TAG, "Cannot delete null configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
protocomm_ble_config_t *ble_config = (protocomm_ble_config_t *) config;
|
||||
for (unsigned int i = 0; i < ble_config->nu_lookup_count; i++) {
|
||||
free((void *)ble_config->nu_lookup[i].name);
|
||||
}
|
||||
free(ble_config->nu_lookup);
|
||||
free(ble_config);
|
||||
}
|
||||
|
||||
static esp_err_t set_config_service(void *config, const char *service_name, const char *service_key)
|
||||
{
|
||||
if (!config) {
|
||||
ESP_LOGE(TAG, "Cannot set null configuration");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!service_name) {
|
||||
ESP_LOGE(TAG, "Service name cannot be NULL");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
protocomm_ble_config_t *ble_config = (protocomm_ble_config_t *) config;
|
||||
strlcpy(ble_config->device_name, service_name, sizeof(ble_config->device_name));
|
||||
|
||||
/* If a custom service UUID has been provided, override the default one */
|
||||
if (custom_service_uuid) {
|
||||
memcpy(ble_config->service_uuid, custom_service_uuid, sizeof(ble_config->service_uuid));
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t set_config_endpoint(void *config, const char *endpoint_name, uint16_t uuid)
|
||||
{
|
||||
if (!config) {
|
||||
ESP_LOGE(TAG, "Cannot set null configuration");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!endpoint_name) {
|
||||
ESP_LOGE(TAG, "EP name cannot be null");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
protocomm_ble_config_t *ble_config = (protocomm_ble_config_t *) config;
|
||||
|
||||
char *copy_ep_name = strdup(endpoint_name);
|
||||
if (!copy_ep_name) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for EP name");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
protocomm_ble_name_uuid_t *lookup_table = (
|
||||
realloc(ble_config->nu_lookup, (ble_config->nu_lookup_count + 1) * sizeof(protocomm_ble_name_uuid_t)));
|
||||
if (!lookup_table) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for EP-UUID lookup table");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
lookup_table[ble_config->nu_lookup_count].name = copy_ep_name;
|
||||
lookup_table[ble_config->nu_lookup_count].uuid = uuid;
|
||||
ble_config->nu_lookup = lookup_table;
|
||||
ble_config->nu_lookup_count += 1;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Used when both BT and BLE are not needed by application */
|
||||
void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event_t event, void *event_data)
|
||||
{
|
||||
esp_err_t err;
|
||||
switch (event) {
|
||||
case WIFI_PROV_INIT:
|
||||
/* Release BT memory, as we need only BLE */
|
||||
err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "bt_mem_release of classic BT failed %d", err);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "BT memory released");
|
||||
}
|
||||
break;
|
||||
|
||||
case WIFI_PROV_DEINIT:
|
||||
/* Release memory used by BLE and Bluedroid host stack */
|
||||
err = esp_bt_mem_release(ESP_BT_MODE_BTDM);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "bt_mem_release of BTDM failed %d", err);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "BTDM memory released");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Used when BT is not needed by application */
|
||||
void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t event, void *event_data)
|
||||
{
|
||||
esp_err_t err;
|
||||
switch (event) {
|
||||
case WIFI_PROV_INIT:
|
||||
/* Release BT memory, as we need only BLE */
|
||||
err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "bt_mem_release of classic BT failed %d", err);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "BT memory released");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Used when BLE is not needed by application */
|
||||
void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_t event, void *event_data)
|
||||
{
|
||||
esp_err_t err;
|
||||
switch (event) {
|
||||
case WIFI_PROV_DEINIT:
|
||||
/* Release memory used by BLE stack */
|
||||
err = esp_bt_mem_release(ESP_BT_MODE_BLE);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "bt_mem_release of BLE failed %d", err);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "BLE memory released");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const wifi_prov_scheme_t wifi_prov_scheme_ble = {
|
||||
.prov_start = prov_start,
|
||||
.prov_stop = protocomm_ble_stop,
|
||||
.new_config = new_config,
|
||||
.delete_config = delete_config,
|
||||
.set_config_service = set_config_service,
|
||||
.set_config_endpoint = set_config_endpoint,
|
||||
.wifi_mode = WIFI_MODE_STA
|
||||
};
|
92
components/wifi_provisioning/src/scheme_console.c
Normal file
92
components/wifi_provisioning/src/scheme_console.c
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <string.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_wifi.h>
|
||||
|
||||
#include <protocomm.h>
|
||||
#include <protocomm_console.h>
|
||||
|
||||
#include "wifi_provisioning/scheme_console.h"
|
||||
#include "wifi_provisioning_priv.h"
|
||||
|
||||
static const char *TAG = "wifi_prov_scheme_console";
|
||||
|
||||
extern const wifi_prov_scheme_t wifi_prov_scheme_console;
|
||||
|
||||
static esp_err_t prov_start(protocomm_t *pc, void *config)
|
||||
{
|
||||
if (!pc) {
|
||||
ESP_LOGE(TAG, "Protocomm handle cannot be null");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!config) {
|
||||
ESP_LOGE(TAG, "Cannot start with null configuration");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
protocomm_console_config_t *console_config = (protocomm_console_config_t *) config;
|
||||
|
||||
/* Start protocomm console */
|
||||
esp_err_t err = protocomm_console_start(pc, console_config);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to start protocomm HTTP server");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void *new_config(void)
|
||||
{
|
||||
protocomm_console_config_t *console_config = malloc(sizeof(protocomm_console_config_t));
|
||||
if (!console_config) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for new configuration");
|
||||
return NULL;
|
||||
}
|
||||
protocomm_console_config_t default_config = PROTOCOMM_CONSOLE_DEFAULT_CONFIG();
|
||||
memcpy(console_config, &default_config, sizeof(default_config));
|
||||
return console_config;
|
||||
}
|
||||
|
||||
static void delete_config(void *config)
|
||||
{
|
||||
if (!config) {
|
||||
ESP_LOGE(TAG, "Cannot delete null configuration");
|
||||
return;
|
||||
}
|
||||
free(config);
|
||||
}
|
||||
|
||||
static esp_err_t set_config_service(void *config, const char *service_name, const char *service_key)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t set_config_endpoint(void *config, const char *endpoint_name, uint16_t uuid)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
const wifi_prov_scheme_t wifi_prov_scheme_console = {
|
||||
.prov_start = prov_start,
|
||||
.prov_stop = protocomm_console_stop,
|
||||
.new_config = new_config,
|
||||
.delete_config = delete_config,
|
||||
.set_config_service = set_config_service,
|
||||
.set_config_endpoint = set_config_endpoint,
|
||||
.wifi_mode = WIFI_MODE_STA
|
||||
};
|
202
components/wifi_provisioning/src/scheme_softap.c
Normal file
202
components/wifi_provisioning/src/scheme_softap.c
Normal file
@ -0,0 +1,202 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <string.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_wifi.h>
|
||||
|
||||
#include <mdns.h>
|
||||
#include <protocomm.h>
|
||||
#include <protocomm_httpd.h>
|
||||
|
||||
#include "wifi_provisioning/scheme_softap.h"
|
||||
#include "wifi_provisioning_priv.h"
|
||||
|
||||
typedef struct softap_config {
|
||||
protocomm_httpd_config_t httpd_config;
|
||||
char ssid[33];
|
||||
char password[65];
|
||||
} wifi_prov_softap_config_t;
|
||||
|
||||
static const char *TAG = "wifi_prov_scheme_softap";
|
||||
|
||||
extern const wifi_prov_scheme_t wifi_prov_scheme_softap;
|
||||
|
||||
static esp_err_t start_wifi_ap(const char *ssid, const char *pass)
|
||||
{
|
||||
/* Build Wi-Fi configuration for AP mode */
|
||||
wifi_config_t wifi_config = {
|
||||
.ap = {
|
||||
.max_connection = 5,
|
||||
},
|
||||
};
|
||||
|
||||
strncpy((char *) wifi_config.ap.ssid, ssid, sizeof(wifi_config.ap.ssid));
|
||||
wifi_config.ap.ssid_len = strnlen(ssid, sizeof(wifi_config.ap.ssid));
|
||||
|
||||
if (strlen(pass) == 0) {
|
||||
memset(wifi_config.ap.password, 0, sizeof(wifi_config.ap.password));
|
||||
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
||||
} else {
|
||||
strlcpy((char *) wifi_config.ap.password, pass, sizeof(wifi_config.ap.password));
|
||||
wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;
|
||||
}
|
||||
|
||||
/* Start Wi-Fi in AP mode with configuration built above */
|
||||
esp_err_t err = esp_wifi_set_mode(WIFI_MODE_AP);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set Wi-Fi mode : %d", err);
|
||||
return err;
|
||||
}
|
||||
err = esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set Wi-Fi config : %d", err);
|
||||
return err;
|
||||
}
|
||||
err = esp_wifi_start();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to start Wi-Fi : %d", err);
|
||||
return err;
|
||||
}
|
||||
ESP_LOGD(TAG, "Wi-Fi SoftAP started");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t prov_start(protocomm_t *pc, void *config)
|
||||
{
|
||||
if (!pc) {
|
||||
ESP_LOGE(TAG, "Protocomm handle cannot be null");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!config) {
|
||||
ESP_LOGE(TAG, "Cannot start with null configuration");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
wifi_prov_softap_config_t *softap_config = (wifi_prov_softap_config_t *) config;
|
||||
|
||||
protocomm_httpd_config_t *httpd_config = &softap_config->httpd_config;
|
||||
|
||||
/* Start protocomm server on top of HTTP */
|
||||
esp_err_t err = protocomm_httpd_start(pc, httpd_config);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to start protocomm HTTP server");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Start Wi-Fi softAP with specified ssid and password */
|
||||
err = start_wifi_ap(softap_config->ssid, softap_config->password);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to start Wi-Fi AP");
|
||||
protocomm_httpd_stop(pc);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Add mDNS service for allowing discovery of provisioning
|
||||
* service on the SoftAP network (Optional). Even though
|
||||
* this is an http service we identify it by _esp_wifi_prov so
|
||||
* that application is free to use _http without conflict */
|
||||
err = mdns_service_add("Wi-Fi Provisioning Service", "_esp_wifi_prov", "_tcp",
|
||||
softap_config->httpd_config.data.config.port, NULL, 0);
|
||||
if (err != ESP_OK) {
|
||||
/* mDNS is not mandatory for provisioning to work,
|
||||
* so print warning and return without failure */
|
||||
ESP_LOGW(TAG, "Error adding mDNS service! Check if mDNS is running");
|
||||
} else {
|
||||
/* Information to identify the roles of the various
|
||||
* protocomm endpoint URIs provided by the service */
|
||||
err |= mdns_service_txt_item_set("_esp_wifi_prov", "_tcp", "version_endpoint", "/proto-ver");
|
||||
err |= mdns_service_txt_item_set("_esp_wifi_prov", "_tcp", "session_endpoint", "/prov-session");
|
||||
err |= mdns_service_txt_item_set("_esp_wifi_prov", "_tcp", "config_endpoint", "/prov-config");
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error adding mDNS service text item");
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t prov_stop(protocomm_t *pc)
|
||||
{
|
||||
esp_err_t err = protocomm_httpd_stop(pc);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGW(TAG, "Error occurred while stopping protocomm_httpd");
|
||||
}
|
||||
|
||||
mdns_service_remove("_esp_wifi_prov", "_tcp");
|
||||
return err;
|
||||
}
|
||||
|
||||
static void *new_config(void)
|
||||
{
|
||||
wifi_prov_softap_config_t *softap_config = calloc(1, sizeof(wifi_prov_softap_config_t));
|
||||
if (!softap_config) {
|
||||
ESP_LOGE(TAG, "Error allocating memory for new configuration");
|
||||
return NULL;
|
||||
}
|
||||
protocomm_httpd_config_t default_config = {
|
||||
.data = {
|
||||
.config = PROTOCOMM_HTTPD_DEFAULT_CONFIG()
|
||||
}
|
||||
};
|
||||
softap_config->httpd_config = default_config;
|
||||
return softap_config;
|
||||
}
|
||||
|
||||
static void delete_config(void *config)
|
||||
{
|
||||
if (!config) {
|
||||
ESP_LOGE(TAG, "Cannot delete null configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
wifi_prov_softap_config_t *softap_config = (wifi_prov_softap_config_t *) config;
|
||||
free(softap_config);
|
||||
}
|
||||
|
||||
static esp_err_t set_config_service(void *config, const char *service_name, const char *service_key)
|
||||
{
|
||||
if (!config) {
|
||||
ESP_LOGE(TAG, "Cannot set null configuration");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!service_name) {
|
||||
ESP_LOGE(TAG, "Service name cannot be NULL");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
wifi_prov_softap_config_t *softap_config = (wifi_prov_softap_config_t *) config;
|
||||
strlcpy(softap_config->ssid, service_name, sizeof(softap_config->ssid));
|
||||
if (service_key) {
|
||||
strlcpy(softap_config->password, service_key, sizeof(softap_config->password));
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t set_config_endpoint(void *config, const char *endpoint_name, uint16_t uuid)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
const wifi_prov_scheme_t wifi_prov_scheme_softap = {
|
||||
.prov_start = prov_start,
|
||||
.prov_stop = prov_stop,
|
||||
.new_config = new_config,
|
||||
.delete_config = delete_config,
|
||||
.set_config_service = set_config_service,
|
||||
.set_config_endpoint = set_config_endpoint,
|
||||
.wifi_mode = WIFI_MODE_APSTA
|
||||
};
|
44
components/wifi_provisioning/src/wifi_provisioning_priv.h
Normal file
44
components/wifi_provisioning/src/wifi_provisioning_priv.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <esp_event_loop.h>
|
||||
|
||||
#include <protocomm.h>
|
||||
#include <protocomm_security.h>
|
||||
|
||||
#include "wifi_provisioning/manager.h"
|
||||
#include "wifi_provisioning/wifi_config.h"
|
||||
|
||||
/**
|
||||
* @brief Notify manager that provisioning is done
|
||||
*
|
||||
* Stops the provisioning. This is called by the get_status_handler()
|
||||
* when the status is connected. This has no effect if main application
|
||||
* has disabled auto stop on completion by calling
|
||||
* wifi_prov_mgr_disable_auto_stop()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Provisioning will be stopped
|
||||
* - ESP_FAIL : Failed to stop provisioning
|
||||
*/
|
||||
esp_err_t wifi_prov_mgr_done(void);
|
||||
|
||||
/**
|
||||
* @brief Get protocomm handlers for wifi_config provisioning endpoint
|
||||
*
|
||||
* @return wifi_prov_config_handlers_t structure
|
||||
*/
|
||||
wifi_prov_config_handlers_t get_wifi_prov_handlers(void);
|
Loading…
Reference in New Issue
Block a user