mirror of
https://github.com/espressif/esp-rainmaker.git
synced 2026-01-19 18:05:36 +00:00
Merge branch 'rainmaker_over_thread' into 'master'
Add RainMaker over Thread support See merge request app-frameworks/esp-rainmaker!454
This commit is contained in:
@@ -135,26 +135,27 @@ build_idf_v5.0:
|
||||
variables:
|
||||
EXAMPLE_TARGETS: "esp32 esp32s2 esp32c3 esp32s3"
|
||||
EXAMPLES: "switch led_light fan temperature_sensor multi_device gpio"
|
||||
COMPONENT_MGR_142: "1"
|
||||
|
||||
build_idf_v5.1:
|
||||
extends: .build_template
|
||||
image: espressif/idf:release-v5.1
|
||||
variables:
|
||||
EXAMPLE_TARGETS: "esp32 esp32s2 esp32c3 esp32s3 esp32c6 esp32c2"
|
||||
EXAMPLE_TARGETS: "esp32 esp32s2 esp32c3 esp32s3 esp32c6 esp32c2 esp32h2"
|
||||
EXAMPLES: "switch led_light fan temperature_sensor multi_device gpio"
|
||||
|
||||
build_idf_v5.2:
|
||||
extends: .build_template
|
||||
image: espressif/idf:release-v5.2
|
||||
variables:
|
||||
EXAMPLE_TARGETS: "esp32 esp32s2 esp32c3 esp32s3 esp32c6 esp32c2"
|
||||
EXAMPLE_TARGETS: "esp32 esp32s2 esp32c3 esp32s3 esp32c6 esp32c2 esp32h2"
|
||||
EXAMPLES: "switch led_light fan temperature_sensor multi_device gpio"
|
||||
|
||||
build_idf_v5.3:
|
||||
extends: .build_template
|
||||
image: espressif/idf:release-v5.3
|
||||
variables:
|
||||
EXAMPLE_TARGETS: "esp32 esp32s2 esp32c3 esp32s3 esp32c6 esp32c2"
|
||||
EXAMPLE_TARGETS: "esp32 esp32s2 esp32c3 esp32s3 esp32c6 esp32c2 esp32h2"
|
||||
EXAMPLES: "switch led_light fan temperature_sensor multi_device gpio"
|
||||
|
||||
build_matter:
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Changes
|
||||
|
||||
## 18-Jul-2024: Use network_provsioning for ESP-IDF v5.1 or later to support RainMaker over Thread
|
||||
- The network_provisioning component can be used for provisioning both Wi-Fi or Thread devices. It also stays backward capabitable with wifi_provisioning component.
|
||||
|
||||
## 27-Feb-2024: Add support for closing provisioning window after PoP mismatch
|
||||
- For ESP IDF v5.1.3 and later, provisioning will be stopped if there are 5 attempts to establish secure session with wrong PoP. This count can be set to any value between 0 and 20. 0 means that provisioning will not be stopped (which will be same as the earlier behaviour before this change).
|
||||
|
||||
|
||||
@@ -16,13 +16,16 @@ set(core_srcs "src/core/esp_rmaker_core.c"
|
||||
"src/core/esp_rmaker_secure_boot_digest.c"
|
||||
)
|
||||
|
||||
set(priv_req protobuf-c json_parser json_generator wifi_provisioning
|
||||
set(priv_req protobuf-c json_parser json_generator
|
||||
nvs_flash esp_http_client app_update esp-tls mbedtls esp_https_ota
|
||||
console esp_local_ctrl esp_https_server mdns esp_schedule efuse driver rmaker_common)
|
||||
|
||||
# NAT64 and DNS64 features were introduced for openthread component in IDF v5.1
|
||||
if ("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.1")
|
||||
list(APPEND priv_req openthread)
|
||||
# NAT64 and DNS64 features were introduced for openthread component in IDF v5.1
|
||||
list(APPEND priv_req openthread network_provisioning)
|
||||
else()
|
||||
# wifi_provisioning could be replaced by network_provisioning for IDF v5.1+
|
||||
list(APPEND priv_req wifi_provisioning)
|
||||
endif()
|
||||
|
||||
if(CONFIG_ESP_RMAKER_ASSISTED_CLAIM)
|
||||
|
||||
@@ -176,6 +176,8 @@ menu "ESP RainMaker Config"
|
||||
config ESP_RMAKER_LOCAL_CTRL_FEATURE_ENABLE
|
||||
bool "ESP RainMaker Local Control Feature"
|
||||
default n
|
||||
#TODO: Enable Local Control for Thread devices
|
||||
depends on ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
select ESP_HTTPS_SERVER_ENABLE
|
||||
help
|
||||
Enabling this allows to discover and control the node over local Wi-Fi network.
|
||||
@@ -189,6 +191,7 @@ menu "ESP RainMaker Config"
|
||||
config ESP_RMAKER_LOCAL_CTRL_AUTO_ENABLE
|
||||
bool "Auto ESP RainMaker Local Control"
|
||||
default n
|
||||
depends on ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
select ESP_RMAKER_LOCAL_CTRL_FEATURE_ENABLE
|
||||
help
|
||||
Automatically enabled local control when RainMaker starts.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
## IDF Component Manager Manifest File
|
||||
version: "1.3.0"
|
||||
version: "1.4.0"
|
||||
description: ESP RainMaker firmware agent
|
||||
url: https://github.com/espressif/esp-rainmaker/tree/master/components/esp_rainmaker
|
||||
repository: https://github.com/espressif/esp-rainmaker.git
|
||||
@@ -27,3 +27,7 @@ dependencies:
|
||||
espressif/esp_schedule:
|
||||
version: "~1.2.0"
|
||||
override_path: '../esp_schedule/'
|
||||
espressif/network_provisioning:
|
||||
version: "~1.0.0"
|
||||
rules:
|
||||
- if: "idf_version >= 5.1"
|
||||
|
||||
@@ -44,8 +44,8 @@ esp_rmaker_user_mapping_state_t esp_rmaker_user_node_mapping_get_state(void);
|
||||
* Create User Mapping Endpoint
|
||||
*
|
||||
* This will create a custom provisioning endpoint for user-node mapping.
|
||||
* This should be called after wifi_prov_mgr_init() but before
|
||||
* wifi_prov_mgr_start_provisioning()
|
||||
* This should be called after network_prov_mgr_init()/wifi_prov_mgr_init() but before
|
||||
* network_prov_mgr_start_provisioning()/wifi_prov_mgr_start_provisioning()
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* @return error on failure
|
||||
@@ -57,7 +57,7 @@ esp_err_t esp_rmaker_user_mapping_endpoint_create(void);
|
||||
*
|
||||
* This will register the callback for the custom provisioning endpoint
|
||||
* for user-node mapping which was created with esp_rmaker_user_mapping_endpoint_create().
|
||||
* This should be called immediately after wifi_prov_mgr_start_provisioning().
|
||||
* This should be called immediately after network_prov_mgr_start_provisioning()/wifi_prov_mgr_start_provisioning().
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* @return error on failure
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
#include <esp_log.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_console.h>
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
#include <network_provisioning/manager.h>
|
||||
#else
|
||||
#include <wifi_provisioning/manager.h>
|
||||
#endif
|
||||
|
||||
#include <esp_rmaker_core.h>
|
||||
#include <esp_rmaker_user_mapping.h>
|
||||
@@ -84,11 +88,19 @@ static int wifi_prov_handler(int argc, char** argv)
|
||||
memcpy(wifi_config.sta.password, argv[2], strlen(argv[2]));
|
||||
}
|
||||
|
||||
/* If device is still provisioning, use wifi_prov_mgr_configure_sta */
|
||||
/* If device is still provisioning, use network_prov_mgr_configure_wifi_sta/wifi_prov_mgr_configure_sta */
|
||||
bool provisioned = false;
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
network_prov_mgr_is_wifi_provisioned(&provisioned);
|
||||
#else
|
||||
wifi_prov_mgr_is_provisioned(&provisioned);
|
||||
#endif
|
||||
if (!provisioned) { // provisioning in progress
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
network_prov_mgr_configure_wifi_sta(&wifi_config);
|
||||
#else
|
||||
wifi_prov_mgr_configure_sta(&wifi_config);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,11 @@
|
||||
#include <esp_rmaker_factory.h>
|
||||
#include <esp_rmaker_utils.h>
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
#include <network_provisioning/manager.h>
|
||||
#else
|
||||
#include <wifi_provisioning/manager.h>
|
||||
#endif
|
||||
#include <esp_event.h>
|
||||
#include <esp_tls.h>
|
||||
#include <esp_rmaker_core.h>
|
||||
@@ -813,6 +817,27 @@ esp_err_t esp_rmaker_claiming_handler(uint32_t session_id, const uint8_t *inbuf,
|
||||
static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
if (event_base == NETWORK_PROV_EVENT) {
|
||||
switch (event_id) {
|
||||
case NETWORK_PROV_INIT: {
|
||||
static const char *capabilities[] = {"claim"};
|
||||
network_prov_mgr_set_app_info("rmaker", "1.0", capabilities, 1);
|
||||
if (network_prov_mgr_endpoint_create(CLAIM_ENDPOINT) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to create claim end point.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NETWORK_PROV_START:
|
||||
if (network_prov_mgr_endpoint_register(CLAIM_ENDPOINT, esp_rmaker_claiming_handler, arg) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to register claim end point.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (event_base == WIFI_PROV_EVENT) {
|
||||
switch (event_id) {
|
||||
case WIFI_PROV_INIT: {
|
||||
@@ -832,6 +857,7 @@ static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_ESP_RMAKER_ASSISTED_CLAIM */
|
||||
esp_err_t __esp_rmaker_claim_init(esp_rmaker_claim_data_t *claim_data)
|
||||
@@ -975,8 +1001,13 @@ esp_err_t esp_rmaker_assisted_claim_perform(esp_rmaker_claim_data_t *claim_data)
|
||||
if (claim_data->state == RMAKER_CLAIM_STATE_VERIFY_DONE) {
|
||||
err = ESP_OK;
|
||||
}
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
esp_event_handler_unregister(NETWORK_PROV_EVENT, NETWORK_PROV_INIT, &event_handler);
|
||||
esp_event_handler_unregister(NETWORK_PROV_EVENT, NETWORK_PROV_START, &event_handler);
|
||||
#else
|
||||
esp_event_handler_unregister(WIFI_PROV_EVENT, WIFI_PROV_INIT, &event_handler);
|
||||
esp_event_handler_unregister(WIFI_PROV_EVENT, WIFI_PROV_START, &event_handler);
|
||||
#endif
|
||||
esp_rmaker_claim_data_free(claim_data);
|
||||
vEventGroupDelete(claim_event_group);
|
||||
return err;
|
||||
@@ -986,8 +1017,13 @@ esp_rmaker_claim_data_t *esp_rmaker_assisted_claim_init(void)
|
||||
ESP_LOGI(TAG, "Initialising Assisted Claiming. This may take time.");
|
||||
esp_rmaker_claim_data_t *claim_data = esp_rmaker_claim_init();
|
||||
if (claim_data) {
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
esp_event_handler_register(NETWORK_PROV_EVENT, NETWORK_PROV_INIT, &event_handler, claim_data);
|
||||
esp_event_handler_register(NETWORK_PROV_EVENT, NETWORK_PROV_START, &event_handler, claim_data);
|
||||
#else
|
||||
esp_event_handler_register(WIFI_PROV_EVENT, WIFI_PROV_INIT, &event_handler, claim_data);
|
||||
esp_event_handler_register(WIFI_PROV_EVENT, WIFI_PROV_START, &event_handler, claim_data);
|
||||
#endif
|
||||
}
|
||||
return claim_data;
|
||||
}
|
||||
|
||||
@@ -18,12 +18,18 @@
|
||||
#include <nvs.h>
|
||||
#include <esp_event.h>
|
||||
#include <esp_local_ctrl.h>
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
#include <network_provisioning/manager.h>
|
||||
#else
|
||||
#include <wifi_provisioning/manager.h>
|
||||
#endif
|
||||
#include <esp_rmaker_internal.h>
|
||||
#include <esp_rmaker_standard_services.h>
|
||||
#include <esp_https_server.h>
|
||||
#include <esp_rmaker_work_queue.h>
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
#include <mdns.h>
|
||||
#endif
|
||||
#include <esp_rmaker_utils.h>
|
||||
|
||||
#include <esp_idf_version.h>
|
||||
@@ -67,7 +73,7 @@ enum property_flags {
|
||||
static bool g_local_ctrl_is_started = false;
|
||||
|
||||
static char *g_serv_name;
|
||||
static bool wait_for_wifi_prov;
|
||||
static bool wait_for_provisioning;
|
||||
/********* Handler functions for responding to control requests / commands *********/
|
||||
|
||||
static esp_err_t get_property_values(size_t props_count,
|
||||
@@ -279,8 +285,11 @@ static esp_err_t __esp_rmaker_start_local_ctrl_service(const char *serv_name)
|
||||
https_conf.httpd.ctrl_port = ESP_RMAKER_LOCAL_CTRL_HTTP_CTRL_PORT;
|
||||
https_conf.httpd.stack_size = CONFIG_ESP_RMAKER_LOCAL_CTRL_STACK_SIZE;
|
||||
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
mdns_init();
|
||||
mdns_hostname_set(serv_name);
|
||||
#endif
|
||||
|
||||
|
||||
esp_local_ctrl_config_t config = {
|
||||
.transport = ESP_LOCAL_CTRL_TRANSPORT_HTTPD,
|
||||
@@ -334,8 +343,14 @@ static esp_err_t __esp_rmaker_start_local_ctrl_service(const char *serv_name)
|
||||
/* Start esp_local_ctrl service */
|
||||
ESP_ERROR_CHECK(esp_local_ctrl_start(&config));
|
||||
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
/* The instance name of mdns service set by esp_local_ctrl_start is 'Local Control Service'.
|
||||
* We should ensure that each end-device should have an unique instance name.
|
||||
*/
|
||||
mdns_service_instance_name_set("_esp_local_ctrl", "_tcp", serv_name);
|
||||
/* Add node_id in mdns */
|
||||
mdns_service_txt_item_set("_esp_local_ctrl", "_tcp", "node_id", esp_rmaker_get_node_id());
|
||||
#endif
|
||||
|
||||
if (pop) {
|
||||
free(pop);
|
||||
@@ -377,22 +392,39 @@ static void esp_rmaker_local_ctrl_prov_event_handler(void* arg, esp_event_base_t
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Event %"PRIu32, event_id);
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
if (event_base == NETWORK_PROV_EVENT) {
|
||||
#else
|
||||
if (event_base == WIFI_PROV_EVENT) {
|
||||
#endif
|
||||
switch (event_id) {
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
case NETWORK_PROV_START:
|
||||
#else
|
||||
case WIFI_PROV_START:
|
||||
wait_for_wifi_prov = true;
|
||||
#endif
|
||||
wait_for_provisioning = true;
|
||||
break;
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
case NETWORK_PROV_DEINIT:
|
||||
#else
|
||||
case WIFI_PROV_DEINIT:
|
||||
if (wait_for_wifi_prov == true) {
|
||||
wait_for_wifi_prov = false;
|
||||
#endif
|
||||
if (wait_for_provisioning == true) {
|
||||
wait_for_provisioning = false;
|
||||
if (g_serv_name) {
|
||||
__esp_rmaker_start_local_ctrl_service(g_serv_name);
|
||||
free(g_serv_name);
|
||||
g_serv_name = NULL;
|
||||
}
|
||||
}
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
esp_event_handler_unregister(NETWORK_PROV_EVENT, NETWORK_PROV_START, &esp_rmaker_local_ctrl_prov_event_handler);
|
||||
esp_event_handler_unregister(NETWORK_PROV_EVENT, NETWORK_PROV_DEINIT, &esp_rmaker_local_ctrl_prov_event_handler);
|
||||
#else
|
||||
esp_event_handler_unregister(WIFI_PROV_EVENT, WIFI_PROV_START, &esp_rmaker_local_ctrl_prov_event_handler);
|
||||
esp_event_handler_unregister(WIFI_PROV_EVENT, WIFI_PROV_DEINIT, &esp_rmaker_local_ctrl_prov_event_handler);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -410,14 +442,19 @@ esp_err_t esp_rmaker_init_local_ctrl_service(void)
|
||||
/* ESP Local Control uses protocomm_httpd, which is also used by SoftAP Provisioning.
|
||||
* If local control is started before provisioning ends, it fails because only one protocomm_httpd
|
||||
* instance is allowed at a time.
|
||||
* So, we check for the WIFI_PROV_START event, and if received, wait for the WIFI_PROV_DEINIT event
|
||||
* before starting local control.
|
||||
* So, we check for the NETWORK_PROV_START event, and if received, wait for the NETWORK_PROV_DEINIT
|
||||
* event before starting local control.
|
||||
* This would not be required in case of BLE Provisioning, but this code has no easy way of knowing
|
||||
* what provisioning transport is being used and hence this logic will come into picture for both,
|
||||
* SoftAP and BLE provisioning.
|
||||
*/
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
esp_event_handler_register(NETWORK_PROV_EVENT, NETWORK_PROV_START, &esp_rmaker_local_ctrl_prov_event_handler, NULL);
|
||||
esp_event_handler_register(NETWORK_PROV_EVENT, NETWORK_PROV_DEINIT, &esp_rmaker_local_ctrl_prov_event_handler, NULL);
|
||||
#else
|
||||
esp_event_handler_register(WIFI_PROV_EVENT, WIFI_PROV_START, &esp_rmaker_local_ctrl_prov_event_handler, NULL);
|
||||
esp_event_handler_register(WIFI_PROV_EVENT, WIFI_PROV_DEINIT, &esp_rmaker_local_ctrl_prov_event_handler, NULL);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -427,7 +464,7 @@ esp_err_t esp_rmaker_start_local_ctrl_service(const char *serv_name)
|
||||
esp_rmaker_local_ctrl_service_enable();
|
||||
}
|
||||
|
||||
if (!wait_for_wifi_prov) {
|
||||
if (!wait_for_provisioning) {
|
||||
return __esp_rmaker_start_local_ctrl_service(serv_name);
|
||||
}
|
||||
|
||||
@@ -460,12 +497,19 @@ esp_err_t esp_rmaker_local_ctrl_disable(void)
|
||||
free(g_serv_name);
|
||||
g_serv_name = NULL;
|
||||
}
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
esp_event_handler_unregister(NETWORK_PROV_EVENT, NETWORK_PROV_START, &esp_rmaker_local_ctrl_prov_event_handler);
|
||||
esp_event_handler_unregister(NETWORK_PROV_EVENT, NETWORK_PROV_DEINIT, &esp_rmaker_local_ctrl_prov_event_handler);
|
||||
#else
|
||||
esp_event_handler_unregister(WIFI_PROV_EVENT, WIFI_PROV_START, &esp_rmaker_local_ctrl_prov_event_handler);
|
||||
esp_event_handler_unregister(WIFI_PROV_EVENT, WIFI_PROV_DEINIT, &esp_rmaker_local_ctrl_prov_event_handler);
|
||||
#endif
|
||||
if (!g_local_ctrl_is_started) {
|
||||
return ESP_OK;
|
||||
}
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
mdns_free();
|
||||
#endif
|
||||
esp_err_t err = esp_local_ctrl_stop();
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
|
||||
@@ -18,7 +18,11 @@
|
||||
#include <nvs.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/semphr.h>
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
#include <network_provisioning/manager.h>
|
||||
#else
|
||||
#include <wifi_provisioning/manager.h>
|
||||
#endif
|
||||
#include <json_generator.h>
|
||||
#include <esp_rmaker_work_queue.h>
|
||||
#include <esp_rmaker_core.h>
|
||||
@@ -71,6 +75,24 @@ static void esp_rmaker_user_mapping_cleanup_data(void)
|
||||
static void esp_rmaker_user_mapping_event_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
if (event_base == NETWORK_PROV_EVENT) {
|
||||
switch (event_id) {
|
||||
case NETWORK_PROV_INIT: {
|
||||
if (esp_rmaker_user_mapping_endpoint_create() != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to create user mapping end point.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NETWORK_PROV_START:
|
||||
if (esp_rmaker_user_mapping_endpoint_register() != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to register user mapping end point.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (event_base == WIFI_PROV_EVENT) {
|
||||
switch (event_id) {
|
||||
case WIFI_PROV_INIT: {
|
||||
@@ -87,6 +109,7 @@ static void esp_rmaker_user_mapping_event_handler(void* arg, esp_event_base_t ev
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
} else if ((event_base == RMAKER_COMMON_EVENT) && (event_id == RMAKER_MQTT_EVENT_PUBLISHED)) {
|
||||
/* Checking for the PUBACK for the user node association message to be sure that the message
|
||||
* has indeed reached the RainMaker cloud.
|
||||
@@ -302,30 +325,51 @@ int esp_rmaker_user_mapping_handler(uint32_t session_id, const uint8_t *inbuf, s
|
||||
}
|
||||
esp_err_t esp_rmaker_user_mapping_endpoint_create(void)
|
||||
{
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
esp_err_t err = network_prov_mgr_endpoint_create(USER_MAPPING_ENDPOINT);
|
||||
#else
|
||||
esp_err_t err = wifi_prov_mgr_endpoint_create(USER_MAPPING_ENDPOINT);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_rmaker_user_mapping_endpoint_register(void)
|
||||
{
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
return network_prov_mgr_endpoint_register(USER_MAPPING_ENDPOINT, esp_rmaker_user_mapping_handler, NULL);
|
||||
#else
|
||||
return wifi_prov_mgr_endpoint_register(USER_MAPPING_ENDPOINT, esp_rmaker_user_mapping_handler, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t esp_rmaker_user_mapping_prov_init(void)
|
||||
{
|
||||
int ret = ESP_OK;
|
||||
ret = esp_event_handler_register(WIFI_PROV_EVENT, WIFI_PROV_INIT, &esp_rmaker_user_mapping_event_handler, NULL);
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
ret = esp_event_handler_register(NETWORK_PROV_EVENT, NETWORK_PROV_INIT, &esp_rmaker_user_mapping_event_handler, NULL);
|
||||
#else
|
||||
ret = esp_event_handler_register(WIFI_PROV_EVENT, WIFI_PROV_INIT,&esp_rmaker_user_mapping_event_handler, NULL);
|
||||
#endif
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
ret = esp_event_handler_register(WIFI_PROV_EVENT, WIFI_PROV_START, &esp_rmaker_user_mapping_event_handler, NULL);
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
ret = esp_event_handler_register(NETWORK_PROV_EVENT, NETWORK_PROV_START, &esp_rmaker_user_mapping_event_handler, NULL);
|
||||
#else
|
||||
ret = esp_event_handler_register(WIFI_PROV_EVENT, WIFI_PROV_START,&esp_rmaker_user_mapping_event_handler, NULL);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_rmaker_user_mapping_prov_deinit(void)
|
||||
{
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
esp_event_handler_unregister(NETWORK_PROV_EVENT, NETWORK_PROV_INIT, &esp_rmaker_user_mapping_event_handler);
|
||||
esp_event_handler_unregister(NETWORK_PROV_EVENT, NETWORK_PROV_START, &esp_rmaker_user_mapping_event_handler);
|
||||
#else
|
||||
esp_event_handler_unregister(WIFI_PROV_EVENT, WIFI_PROV_INIT, &esp_rmaker_user_mapping_event_handler);
|
||||
esp_event_handler_unregister(WIFI_PROV_EVENT, WIFI_PROV_START, &esp_rmaker_user_mapping_event_handler);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
16
examples/common/app_network/CMakeLists.txt
Normal file
16
examples/common/app_network/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
set(priv_req qrcode nvs_flash esp_event rmaker_common vfs)
|
||||
|
||||
if ("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "5.1")
|
||||
list(APPEND priv_req network_provisioning openthread)
|
||||
else()
|
||||
list(APPEND priv_req wifi_provisioning)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "app_wifi_internal.c" "app_network.c" "app_thread_internal.c"
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "private_include"
|
||||
PRIV_REQUIRES ${priv_req})
|
||||
|
||||
if(CONFIG_APP_WIFI_SHOW_DEMO_INTRO_TEXT)
|
||||
target_compile_definitions(${COMPONENT_TARGET} PRIVATE "-D RMAKER_DEMO_PROJECT_NAME=\"${CMAKE_PROJECT_NAME}\"")
|
||||
endif()
|
||||
@@ -1,12 +1,12 @@
|
||||
menu "ESP RainMaker App Wi-Fi Provisioning"
|
||||
|
||||
config APP_WIFI_PROV_SHOW_QR
|
||||
config APP_NETWORK_PROV_SHOW_QR
|
||||
bool "Show provisioning QR code"
|
||||
default y
|
||||
help
|
||||
Show the QR code for provisioning.
|
||||
|
||||
config APP_WIFI_PROV_MAX_POP_MISMATCH
|
||||
config APP_NETWORK_PROV_MAX_POP_MISMATCH
|
||||
int
|
||||
default 5
|
||||
range 0 20
|
||||
@@ -17,26 +17,27 @@ menu "ESP RainMaker App Wi-Fi Provisioning"
|
||||
This safeguards the device from brute-force attempt by limiting the wrong pop allowed.
|
||||
Needs IDF version >= 5.1.3
|
||||
|
||||
choice APP_WIFI_PROV_TRANSPORT
|
||||
choice APP_NETWORK_PROV_TRANSPORT
|
||||
bool "Provisioning Transport method"
|
||||
default APP_WIFI_PROV_TRANSPORT_BLE
|
||||
default APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
help
|
||||
Wi-Fi provisioning component offers both, SoftAP and BLE transports. Choose any one.
|
||||
Wi-Fi/Network provisioning component offers both, SoftAP and BLE transports. Choose any one.
|
||||
|
||||
config APP_WIFI_PROV_TRANSPORT_SOFTAP
|
||||
config APP_NETWORK_PROV_TRANSPORT_SOFTAP
|
||||
bool "Soft AP"
|
||||
config APP_WIFI_PROV_TRANSPORT_BLE
|
||||
depends on !IDF_TARGET_ESP32H2
|
||||
config APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
bool "BLE"
|
||||
select BT_ENABLED
|
||||
depends on !IDF_TARGET_ESP32S2
|
||||
endchoice
|
||||
|
||||
config APP_WIFI_PROV_TRANSPORT
|
||||
config APP_NETWORK_PROV_TRANSPORT
|
||||
int
|
||||
default 1 if APP_WIFI_PROV_TRANSPORT_SOFTAP
|
||||
default 2 if APP_WIFI_PROV_TRANSPORT_BLE
|
||||
default 1 if APP_NETWORK_PROV_TRANSPORT_SOFTAP
|
||||
default 2 if APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
|
||||
config APP_WIFI_RESET_PROV_ON_FAILURE
|
||||
config APP_NETWORK_RESET_PROV_ON_FAILURE
|
||||
bool
|
||||
default y
|
||||
prompt "Reset provisioned credentials and state machine after session failure"
|
||||
@@ -44,23 +45,23 @@ menu "ESP RainMaker App Wi-Fi Provisioning"
|
||||
Enable reseting provisioned credentials and state machine after session failure.
|
||||
This will restart the provisioning service after retries are exhausted.
|
||||
|
||||
config APP_WIFI_PROV_MAX_RETRY_CNT
|
||||
config APP_NETWORK_PROV_MAX_RETRY_CNT
|
||||
int
|
||||
default 5
|
||||
prompt "Max retries before reseting provisioning state machine"
|
||||
depends on APP_WIFI_RESET_PROV_ON_FAILURE
|
||||
depends on APP_NETWORK_RESET_PROV_ON_FAILURE
|
||||
help
|
||||
Set the Maximum retry to avoid reconnecting to an inexistent AP or if credentials
|
||||
Set the Maximum retry to avoid reconnecting to an inexistent network or if credentials
|
||||
are misconfigured. Provisioned credentials are erased and internal state machine
|
||||
is reset after this threshold is reached.
|
||||
|
||||
config APP_WIFI_SHOW_DEMO_INTRO_TEXT
|
||||
config APP_NETWORK_SHOW_DEMO_INTRO_TEXT
|
||||
bool "Show intro text for demos"
|
||||
default n
|
||||
help
|
||||
Show some intro text for demos in order to help users understand more about ESP RainMaker.
|
||||
|
||||
config APP_WIFI_PROV_TIMEOUT_PERIOD
|
||||
config APP_NETWORK_PROV_TIMEOUT_PERIOD
|
||||
int "Provisioning Timeout"
|
||||
default 30
|
||||
help
|
||||
@@ -68,10 +69,17 @@ menu "ESP RainMaker App Wi-Fi Provisioning"
|
||||
to restart provisioning. It is always recommended to set this to some non zero value, especially
|
||||
if you are not using PoP. Set to 0 if you do not want provisioning to auto stop.
|
||||
|
||||
config APP_WIFI_PROV_NAME_PREFIX
|
||||
config APP_NETWORK_PROV_NAME_PREFIX
|
||||
string "Provisioning Name Prefix"
|
||||
default "PROV"
|
||||
help
|
||||
Provisioning Name Prefix.
|
||||
|
||||
config APP_WIFI_PROV_COMPAT
|
||||
bool "Stay compatible with App Wi-Fi component"
|
||||
depends on ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
default y
|
||||
help
|
||||
Stay compatible with Previous App Wi-Fi component
|
||||
|
||||
endmenu
|
||||
477
examples/common/app_network/app_network.c
Normal file
477
examples/common/app_network/app_network.c
Normal file
@@ -0,0 +1,477 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <sdkconfig.h>
|
||||
#include <string.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/event_groups.h>
|
||||
#include <esp_event.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_idf_version.h>
|
||||
#include <esp_rmaker_utils.h>
|
||||
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
#include <app_wifi_internal.h>
|
||||
#include <esp_netif_types.h>
|
||||
#endif /* CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI */
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD
|
||||
#include <esp_openthread_types.h>
|
||||
#include <app_thread_internal.h>
|
||||
#endif
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
#include <esp_mac.h>
|
||||
#include <network_provisioning/manager.h>
|
||||
#ifdef CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
#include <network_provisioning/scheme_ble.h>
|
||||
#else /* CONFIG_APP_NETOWRK_PROV_TRANSPORT_SOFTAP */
|
||||
#include <network_provisioning/scheme_softap.h>
|
||||
#endif /* CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE */
|
||||
#else
|
||||
#include <wifi_provisioning/manager.h>
|
||||
#ifdef CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
#include <wifi_provisioning/scheme_ble.h>
|
||||
#else /* CONFIG_APP_NETWORK_PROV_TRANSPORT_SOFTAP */
|
||||
#include <wifi_provisioning/scheme_softap.h>
|
||||
#endif /* CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE */
|
||||
#include <esp_wifi.h>
|
||||
#endif
|
||||
|
||||
#include <qrcode.h>
|
||||
#include <nvs.h>
|
||||
#include <nvs_flash.h>
|
||||
#include <esp_timer.h>
|
||||
#include <app_network.h>
|
||||
|
||||
ESP_EVENT_DEFINE_BASE(APP_NETWORK_EVENT);
|
||||
static const char *TAG = "app_network";
|
||||
static const int NETWORK_CONNECTED_EVENT = BIT0;
|
||||
static EventGroupHandle_t network_event_group;
|
||||
|
||||
#define PROV_QR_VERSION "v1"
|
||||
|
||||
#define PROV_TRANSPORT_SOFTAP "softap"
|
||||
#define PROV_TRANSPORT_BLE "ble"
|
||||
#define QRCODE_BASE_URL "https://rainmaker.espressif.com/qrcode.html"
|
||||
|
||||
#define CREDENTIALS_NAMESPACE "rmaker_creds"
|
||||
#define RANDOM_NVS_KEY "random"
|
||||
|
||||
#define POP_STR_SIZE 9
|
||||
static esp_timer_handle_t prov_stop_timer;
|
||||
/* Timeout period in minutes */
|
||||
#define APP_NETWORK_PROV_TIMEOUT_PERIOD CONFIG_APP_NETWORK_PROV_TIMEOUT_PERIOD
|
||||
/* Autofetch period in micro-seconds */
|
||||
static uint64_t prov_timeout_period = (APP_NETWORK_PROV_TIMEOUT_PERIOD * 60 * 1000000LL);
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 3)
|
||||
#define APP_PROV_STOP_ON_CREDS_MISMATCH
|
||||
#elif (CONFIG_APP_NETWOKR_PROV_MAX_RETRY_CNT > 0)
|
||||
#warning "Provisioning window stop on max credentials failures, needs IDF version >= 5.1.3"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_APP_NETWORK_SHOW_DEMO_INTRO_TEXT
|
||||
|
||||
#define ESP_RAINMAKER_GITHUB_EXAMPLES_PATH "https://github.com/espressif/esp-rainmaker/blob/master/examples"
|
||||
#define ESP_RAINMAKER_INTRO_LINK "https://rainmaker.espressif.com"
|
||||
#define ESP_RMAKER_PHONE_APP_LINK "http://bit.ly/esp-rmaker"
|
||||
char esp_rainmaker_ascii_art[] = \
|
||||
" ______ _____ _____ _____ _____ _ _ __ __ _ ________ _____\n"\
|
||||
" | ____|/ ____| __ \\ | __ \\ /\\ |_ _| \\ | | \\/ | /\\ | |/ / ____| __ \\\n"\
|
||||
" | |__ | (___ | |__) | | |__) | / \\ | | | \\| | \\ / | / \\ | ' /| |__ | |__) |\n"\
|
||||
" | __| \\___ \\| ___/ | _ / / /\\ \\ | | | . ` | |\\/| | / /\\ \\ | < | __| | _ /\n"\
|
||||
" | |____ ____) | | | | \\ \\ / ____ \\ _| |_| |\\ | | | |/ ____ \\| . \\| |____| | \\ \\\n"\
|
||||
" |______|_____/|_| |_| \\_\\/_/ \\_\\_____|_| \\_|_| |_/_/ \\_\\_|\\_\\______|_| \\_\\\n";
|
||||
|
||||
static void intro_print(bool provisioned)
|
||||
{
|
||||
printf("####################################################################################################\n");
|
||||
printf("%s\n", esp_rainmaker_ascii_art);
|
||||
printf("Welcome to ESP RainMaker %s demo application!\n", RMAKER_DEMO_PROJECT_NAME);
|
||||
if (!provisioned) {
|
||||
printf("Follow these steps to get started:\n");
|
||||
printf("1. Download the ESP RainMaker phone app by visiting this link from your phone's browser:\n\n");
|
||||
printf(" %s\n\n", ESP_RMAKER_PHONE_APP_LINK);
|
||||
printf("2. Sign up and follow the steps on screen to add the device to your Wi-Fi/Thread network.\n");
|
||||
printf("3. You are now ready to use the device and control it locally as well as remotely.\n");
|
||||
printf(" You can also use the Boot button on the board to control your device.\n");
|
||||
}
|
||||
printf("\nIf you want to reset network credentials, or reset to factory, press and hold the Boot button.\n");
|
||||
printf("\nThis application uses ESP RainMaker, which is based on ESP IDF.\n");
|
||||
printf("Check out the source code for this application here:\n %s/%s\n",
|
||||
ESP_RAINMAKER_GITHUB_EXAMPLES_PATH, RMAKER_DEMO_PROJECT_NAME);
|
||||
printf("\nPlease visit %s for additional information.\n\n", ESP_RAINMAKER_INTRO_LINK);
|
||||
printf("####################################################################################################\n");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void intro_print(bool provisioned)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
#endif /* !APP_NETWORK_SHOW_DEMO_INTRO_TEXT */
|
||||
|
||||
static uint8_t *custom_mfg_data = NULL;
|
||||
static size_t custom_mfg_data_len = 0;
|
||||
|
||||
esp_err_t app_network_set_custom_mfg_data(uint16_t device_type, uint8_t device_subtype)
|
||||
{
|
||||
int8_t mfg_data[] = {MFG_DATA_HEADER, MGF_DATA_APP_ID, MFG_DATA_VERSION, MFG_DATA_CUSTOMER_ID};
|
||||
size_t mfg_data_len = sizeof(mfg_data) + 4; // 4 bytes of device type, subtype, and extra-code
|
||||
custom_mfg_data = (uint8_t *)MEM_ALLOC_EXTRAM(mfg_data_len);
|
||||
if (custom_mfg_data == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory to custom mfg data");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
memcpy(custom_mfg_data, mfg_data, sizeof(mfg_data));
|
||||
custom_mfg_data[8] = 0xff & (device_type >> 8);
|
||||
custom_mfg_data[9] = 0xff & device_type;
|
||||
custom_mfg_data[10] = device_subtype;
|
||||
custom_mfg_data[11] = 0;
|
||||
custom_mfg_data_len = mfg_data_len;
|
||||
ESP_LOG_BUFFER_HEXDUMP("tag", custom_mfg_data, mfg_data_len, 3);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void app_network_print_qr(const char *name, const char *pop, const char *transport)
|
||||
{
|
||||
if (!name || !transport) {
|
||||
ESP_LOGW(TAG, "Cannot generate QR code payload. Data missing.");
|
||||
return;
|
||||
}
|
||||
char payload[150];
|
||||
if (pop) {
|
||||
snprintf(payload, sizeof(payload), "{\"ver\":\"%s\",\"name\":\"%s\"" \
|
||||
",\"pop\":\"%s\",\"transport\":\"%s\"}",
|
||||
PROV_QR_VERSION, name, pop, transport);
|
||||
} else {
|
||||
snprintf(payload, sizeof(payload), "{\"ver\":\"%s\",\"name\":\"%s\"" \
|
||||
",\"transport\":\"%s\"}",
|
||||
PROV_QR_VERSION, name, transport);
|
||||
}
|
||||
#ifdef CONFIG_APP_NETWORK_PROV_SHOW_QR
|
||||
ESP_LOGI(TAG, "Scan this QR code from the ESP RainMaker phone app for Provisioning.");
|
||||
qrcode_display(payload);
|
||||
#endif /* CONFIG_APP_NETWORK_PROV_SHOW_QR */
|
||||
ESP_LOGI(TAG, "If QR code is not visible, copy paste the below URL in a browser.\n%s?data=%s", QRCODE_BASE_URL, payload);
|
||||
esp_event_post(APP_NETWORK_EVENT, APP_NETWORK_EVENT_QR_DISPLAY, payload, strlen(payload) + 1, portMAX_DELAY);
|
||||
}
|
||||
|
||||
/* Free random_bytes after use only if function returns ESP_OK */
|
||||
static esp_err_t read_random_bytes_from_nvs(uint8_t **random_bytes, size_t *len)
|
||||
{
|
||||
nvs_handle handle;
|
||||
esp_err_t err;
|
||||
*len = 0;
|
||||
|
||||
if ((err = nvs_open_from_partition(CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME, CREDENTIALS_NAMESPACE,
|
||||
NVS_READONLY, &handle)) != ESP_OK) {
|
||||
ESP_LOGD(TAG, "NVS open for %s %s %s failed with error %d", CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME, CREDENTIALS_NAMESPACE, RANDOM_NVS_KEY, err);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if ((err = nvs_get_blob(handle, RANDOM_NVS_KEY, NULL, len)) != ESP_OK) {
|
||||
ESP_LOGD(TAG, "Error %d. Failed to read key %s.", err, RANDOM_NVS_KEY);
|
||||
nvs_close(handle);
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
*random_bytes = calloc(*len, 1);
|
||||
if (*random_bytes) {
|
||||
nvs_get_blob(handle, RANDOM_NVS_KEY, *random_bytes, len);
|
||||
nvs_close(handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
nvs_close(handle);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
static char *custom_pop;
|
||||
esp_err_t app_network_set_custom_pop(const char *pop)
|
||||
{
|
||||
/* NULL PoP is not allowed here. Use POP_TYPE_NONE instead. */
|
||||
if (!pop) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Freeing up the PoP in case it is already allocated */
|
||||
if (custom_pop) {
|
||||
free(custom_pop);
|
||||
custom_pop = NULL;
|
||||
}
|
||||
|
||||
custom_pop = strdup(pop);
|
||||
if (!custom_pop) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t get_device_service_name(char *service_name, size_t max)
|
||||
{
|
||||
uint8_t *nvs_random = NULL;
|
||||
const char *ssid_prefix = CONFIG_APP_NETWORK_PROV_NAME_PREFIX;
|
||||
size_t nvs_random_size = 0;
|
||||
if ((read_random_bytes_from_nvs(&nvs_random, &nvs_random_size) != ESP_OK) || nvs_random_size < 3) {
|
||||
uint8_t mac_addr[6];
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
esp_read_mac(mac_addr, ESP_MAC_BASE);
|
||||
#else
|
||||
esp_wifi_get_mac(WIFI_IF_STA, mac_addr);
|
||||
#endif
|
||||
snprintf(service_name, max, "%s_%02x%02x%02x", ssid_prefix, mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
} else {
|
||||
snprintf(service_name, max, "%s_%02x%02x%02x", ssid_prefix, nvs_random[nvs_random_size - 3],
|
||||
nvs_random[nvs_random_size - 2], nvs_random[nvs_random_size - 1]);
|
||||
}
|
||||
if (nvs_random) {
|
||||
free(nvs_random);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *get_device_pop(app_network_pop_type_t pop_type)
|
||||
{
|
||||
if (pop_type == POP_TYPE_NONE) {
|
||||
return NULL;
|
||||
} else if (pop_type == POP_TYPE_CUSTOM) {
|
||||
if (!custom_pop) {
|
||||
ESP_LOGE(TAG, "Custom PoP not set. Please use app_wifi_set_custom_pop().");
|
||||
return NULL;
|
||||
}
|
||||
return strdup(custom_pop);
|
||||
}
|
||||
char *pop = calloc(1, POP_STR_SIZE);
|
||||
if (!pop) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for PoP.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pop_type == POP_TYPE_MAC) {
|
||||
uint8_t mac_addr[6];
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
esp_err_t err = esp_read_mac(mac_addr, ESP_MAC_BASE);
|
||||
#else
|
||||
esp_err_t err = esp_wifi_get_mac(WIFI_IF_STA, mac_addr);
|
||||
#endif
|
||||
if (err == ESP_OK) {
|
||||
snprintf(pop, POP_STR_SIZE, "%02x%02x%02x%02x", mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
return pop;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to get MAC address to generate PoP.");
|
||||
goto pop_err;
|
||||
}
|
||||
} else if (pop_type == POP_TYPE_RANDOM) {
|
||||
uint8_t *nvs_random = NULL;
|
||||
size_t nvs_random_size = 0;
|
||||
if ((read_random_bytes_from_nvs(&nvs_random, &nvs_random_size) != ESP_OK) || nvs_random_size < 4) {
|
||||
ESP_LOGE(TAG, "Failed to read random bytes from NVS to generate PoP.");
|
||||
if (nvs_random) {
|
||||
free(nvs_random);
|
||||
}
|
||||
goto pop_err;
|
||||
} else {
|
||||
snprintf(pop, POP_STR_SIZE, "%02x%02x%02x%02x", nvs_random[0], nvs_random[1], nvs_random[2], nvs_random[3]);
|
||||
free(nvs_random);
|
||||
return pop;
|
||||
}
|
||||
}
|
||||
pop_err:
|
||||
free(pop);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void network_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
|
||||
{
|
||||
|
||||
#ifdef APP_PROV_STOP_ON_CREDS_MISMATCH
|
||||
static int failed_cnt = 0;
|
||||
#endif
|
||||
#ifdef APP_PROV_STOP_ON_CREDS_MISMATCH
|
||||
if (event_base == PROTOCOMM_SECURITY_SESSION_EVENT) {
|
||||
switch (event_id) {
|
||||
case PROTOCOMM_SECURITY_SESSION_SETUP_OK:
|
||||
ESP_LOGI(TAG, "Secured session established!");
|
||||
break;
|
||||
case PROTOCOMM_SECURITY_SESSION_INVALID_SECURITY_PARAMS:
|
||||
/* fall-through */
|
||||
case PROTOCOMM_SECURITY_SESSION_CREDENTIALS_MISMATCH:
|
||||
ESP_LOGE(TAG, "Received incorrect PoP or invalid security params! event: %d", (int) event_id);
|
||||
if (CONFIG_APP_NETWORK_PROV_MAX_POP_MISMATCH &&
|
||||
(++failed_cnt >= CONFIG_APP_NETWORK_PROV_MAX_POP_MISMATCH)) {
|
||||
/* stop provisioning for security reasons */
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
network_prov_mgr_stop_provisioning();
|
||||
#else
|
||||
wifi_prov_mgr_stop_provisioning();
|
||||
#endif
|
||||
ESP_LOGW(TAG, "Max PoP attempts reached! Provisioning disabled for security reasons. Please reboot device to restart provisioning");
|
||||
esp_event_post(APP_NETWORK_EVENT, APP_NETWORK_EVENT_PROV_CRED_MISMATCH, NULL, 0, portMAX_DELAY);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* APP_PROV_STOP_ON_CREDS_MISMATCH */
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
|
||||
ESP_LOGI(TAG, "Connected with IP Address:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||
/* Signal main application to continue execution */
|
||||
xEventGroupSetBits(network_event_group, NETWORK_CONNECTED_EVENT);
|
||||
}
|
||||
#endif /* CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI */
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD
|
||||
if (event_base == OPENTHREAD_EVENT && event_id == OPENTHREAD_EVENT_ATTACHED) {
|
||||
/* Signal main application to continue execution */
|
||||
xEventGroupSetBits(network_event_group, NETWORK_CONNECTED_EVENT);
|
||||
}
|
||||
#endif /* CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD */
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
if (event_base == NETWORK_PROV_EVENT && event_id == NETWORK_PROV_END) {
|
||||
#else
|
||||
if (event_base == WIFI_PROV_EVENT && event_id == WIFI_PROV_END) {
|
||||
#endif
|
||||
if (prov_stop_timer) {
|
||||
esp_timer_stop(prov_stop_timer);
|
||||
esp_timer_delete(prov_stop_timer);
|
||||
prov_stop_timer = NULL;
|
||||
}
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
network_prov_mgr_deinit();
|
||||
#else
|
||||
wifi_prov_mgr_deinit();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void app_network_init()
|
||||
{
|
||||
/* Initialize the event loop, if not done already. */
|
||||
esp_err_t err = esp_event_loop_create_default();
|
||||
/* If the default event loop is already initialized, we get ESP_ERR_INVALID_STATE */
|
||||
if (err != ESP_OK) {
|
||||
if (err == ESP_ERR_INVALID_STATE) {
|
||||
ESP_LOGW(TAG, "Event loop creation failed with ESP_ERR_INVALID_STATE. Proceeding since it must have been created elsewhere.");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to create default event loop, err = %x", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
ESP_ERROR_CHECK(wifi_init());
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD
|
||||
ESP_ERROR_CHECK(thread_init());
|
||||
#endif
|
||||
network_event_group = xEventGroupCreate();
|
||||
#ifdef APP_PROV_STOP_ON_CREDS_MISMATCH
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(PROTOCOMM_SECURITY_SESSION_EVENT, ESP_EVENT_ANY_ID, &network_event_handler, NULL));
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &network_event_handler, NULL));
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(OPENTHREAD_EVENT, ESP_EVENT_ANY_ID, &network_event_handler, NULL));
|
||||
#endif
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(NETWORK_PROV_EVENT, NETWORK_PROV_END, &network_event_handler, NULL));
|
||||
#else
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_PROV_EVENT, WIFI_PROV_END, &network_event_handler, NULL));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void app_network_prov_stop(void *priv)
|
||||
{
|
||||
ESP_LOGW(TAG, "Provisioning timed out. Please reboot device to restart provisioning.");
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
network_prov_mgr_stop_provisioning();
|
||||
#else
|
||||
wifi_prov_mgr_stop_provisioning();
|
||||
#endif
|
||||
esp_event_post(APP_NETWORK_EVENT, APP_NETWORK_EVENT_PROV_TIMEOUT, NULL, 0, portMAX_DELAY);
|
||||
}
|
||||
|
||||
esp_err_t app_network_start_timer(void)
|
||||
{
|
||||
if (prov_timeout_period == 0) {
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_timer_create_args_t prov_stop_timer_conf = {
|
||||
.callback = app_network_prov_stop,
|
||||
.arg = NULL,
|
||||
.dispatch_method = ESP_TIMER_TASK,
|
||||
.name = "app_wifi_prov_stop_tm"
|
||||
};
|
||||
if (esp_timer_create(&prov_stop_timer_conf, &prov_stop_timer) == ESP_OK) {
|
||||
esp_timer_start_once(prov_stop_timer, prov_timeout_period);
|
||||
ESP_LOGI(TAG, "Provisioning will auto stop after %d minute(s).",
|
||||
APP_NETWORK_PROV_TIMEOUT_PERIOD);
|
||||
return ESP_OK;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to create Provisioning auto stop timer.");
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t app_network_start(app_network_pop_type_t pop_type)
|
||||
{
|
||||
/* Do we want a proof-of-possession (ignored if Security 0 is selected):
|
||||
* - this should be a string with length > 0
|
||||
* - NULL if not used
|
||||
*/
|
||||
char *pop = get_device_pop(pop_type);
|
||||
if ((pop_type != POP_TYPE_NONE) && (pop == NULL)) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
/* What is the Device Service Name that we want
|
||||
* This translates to :
|
||||
* - device name when scheme is network_prov_scheme_ble/wifi_prov_scheme_ble
|
||||
*/
|
||||
char service_name[12];
|
||||
get_device_service_name(service_name, sizeof(service_name));
|
||||
/* What is the service key (Wi-Fi password)
|
||||
* NULL = Open network
|
||||
* This is ignored when scheme is network_prov_scheme_ble/wifi_prov_scheme_ble
|
||||
*/
|
||||
const char *service_key = NULL;
|
||||
esp_err_t err = ESP_OK;
|
||||
bool provisioned = false;
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
err = wifi_start(pop, service_name, service_key, custom_mfg_data, custom_mfg_data_len, &provisioned);
|
||||
#endif
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD
|
||||
err = thread_start(pop, service_name, service_key, custom_mfg_data, custom_mfg_data_len, &provisioned);
|
||||
#endif
|
||||
if (err != ESP_OK) {
|
||||
free(pop);
|
||||
return err;
|
||||
}
|
||||
if (!provisioned) {
|
||||
#ifdef CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
app_network_print_qr(service_name, pop, PROV_TRANSPORT_BLE);
|
||||
#else /* CONFIG_APP_NETWORK_PROV_TRANSPORT_SOFTAP */
|
||||
app_network_print_qr(service_name, pop, PROV_TRANSPORT_SOFTAP);
|
||||
#endif /* CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE */
|
||||
app_network_start_timer();
|
||||
}
|
||||
free(pop);
|
||||
intro_print(provisioned);
|
||||
if (custom_mfg_data) {
|
||||
free(custom_mfg_data);
|
||||
custom_mfg_data = NULL;
|
||||
custom_mfg_data_len = 0;
|
||||
}
|
||||
/* Wait for Network connection */
|
||||
xEventGroupWaitBits(network_event_group, NETWORK_CONNECTED_EVENT, false, true, portMAX_DELAY);
|
||||
return err;
|
||||
}
|
||||
@@ -27,19 +27,19 @@ extern "C" {
|
||||
#define MFG_DATA_DEVICE_EXTRA_CODE 0x00
|
||||
|
||||
/** ESP RainMaker Event Base */
|
||||
ESP_EVENT_DECLARE_BASE(APP_WIFI_EVENT);
|
||||
ESP_EVENT_DECLARE_BASE(APP_NETWORK_EVENT);
|
||||
|
||||
/** App Wi-Fir Events */
|
||||
/** App Network Events */
|
||||
typedef enum {
|
||||
/** QR code available for display. Associated data is the NULL terminated QR payload. */
|
||||
APP_WIFI_EVENT_QR_DISPLAY = 1,
|
||||
APP_NETWORK_EVENT_QR_DISPLAY = 1,
|
||||
/** Provisioning timed out */
|
||||
APP_WIFI_EVENT_PROV_TIMEOUT,
|
||||
APP_NETWORK_EVENT_PROV_TIMEOUT,
|
||||
/** Provisioning has restarted due to failures (Invalid SSID/Passphrase) */
|
||||
APP_WIFI_EVENT_PROV_RESTART,
|
||||
APP_NETWORK_EVENT_PROV_RESTART,
|
||||
/** Provisioning closed due to invalid credentials */
|
||||
APP_WIFI_EVENT_PROV_CRED_MISMATCH,
|
||||
} app_wifi_event_t;
|
||||
APP_NETWORK_EVENT_PROV_CRED_MISMATCH,
|
||||
} app_network_event_t;
|
||||
|
||||
/** Types of Proof of Possession */
|
||||
typedef enum {
|
||||
@@ -48,32 +48,32 @@ typedef enum {
|
||||
/** Use random stream generated and stored in fctry partition during claiming process as PoP */
|
||||
POP_TYPE_RANDOM,
|
||||
/** Do not use any PoP.
|
||||
* Use this option with caution. Consider using `CONFIG_APP_WIFI_PROV_TIMEOUT_PERIOD` with this.
|
||||
* Use this option with caution. Consider using `CONFIG_APP_NETWORK_PROV_TIMEOUT_PERIOD` with this.
|
||||
*/
|
||||
POP_TYPE_NONE,
|
||||
/** Use a custom PoP.
|
||||
* Set a custom PoP using app_wifi_set_custom_pop() first.
|
||||
* Set a custom PoP using app_network_set_custom_pop() first.
|
||||
*/
|
||||
POP_TYPE_CUSTOM
|
||||
} app_wifi_pop_type_t;
|
||||
} app_network_pop_type_t;
|
||||
|
||||
/** Initialize Wi-Fi
|
||||
/** Initialize Wi-Fi/Thread
|
||||
*
|
||||
* This initializes Wi-Fi and the Wi-Fi provisioning manager
|
||||
* This initializes Wi-Fi/Thread stack and the network provisioning manager
|
||||
*/
|
||||
void app_wifi_init();
|
||||
void app_network_init();
|
||||
|
||||
/** Start Wi-Fi
|
||||
/** Start Wi-Fi/Thread
|
||||
*
|
||||
* This will start provisioning if the node is not provisioned and will connect to Wi-Fi
|
||||
* if node is provisioned. Function will return successfully only after Wi-Fi is connect
|
||||
* This will start provisioning if the node is not provisioned and will connect to any network
|
||||
* if node is provisioned. Function will return successfully only after network is connected
|
||||
*
|
||||
* @param[in] pop_type The type for Proof of Possession (PoP) pin
|
||||
*
|
||||
* @return ESP_OK on success (Wi-Fi connected).
|
||||
*
|
||||
* @return ESP_OK on success (Network connected).
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t app_wifi_start(app_wifi_pop_type_t pop_type);
|
||||
esp_err_t app_network_start(app_network_pop_type_t pop_type);
|
||||
|
||||
/** Set custom manufacturing data
|
||||
*
|
||||
@@ -87,19 +87,33 @@ esp_err_t app_wifi_start(app_wifi_pop_type_t pop_type);
|
||||
* @return ESP_OK on success.
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t app_wifi_set_custom_mfg_data(uint16_t device_type, uint8_t device_subtype);
|
||||
esp_err_t app_network_set_custom_mfg_data(uint16_t device_type, uint8_t device_subtype);
|
||||
|
||||
/** Set custom PoP
|
||||
*
|
||||
* This can be used to set a custom Proof of Possession (PoP) pin for provisioning.
|
||||
* Applicable only if POP_TYPE_CUSTOM is used for app_wifi_start().
|
||||
* Applicable only if POP_TYPE_CUSTOM is used for app_network_start().
|
||||
*
|
||||
* @param[in] pop A NULL terminated PoP string (typically 8 characters alphanumeric)
|
||||
*
|
||||
* @return ESP_OK on success.
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t app_wifi_set_custom_pop(const char *pop);
|
||||
esp_err_t app_network_set_custom_pop(const char *pop);
|
||||
|
||||
#if CONFIG_APP_WIFI_PROV_COMPAT
|
||||
#define APP_WIFI_EVENT APP_NETWORK_EVENT
|
||||
typedef app_network_event_t app_wifi_event_t;
|
||||
#define APP_WIFI_EVENT_QR_DISPLAY APP_NETWORK_EVENT_QR_DISPLAY
|
||||
#define APP_WIFI_EVENT_PROV_TIMEOUT APP_NETWORK_EVENT_PROV_TIMEOUT
|
||||
#define APP_WIFI_EVENT_PROV_RESTART APP_NETWORK_EVENT_PROV_RESTART
|
||||
#define APP_WIFI_EVENT_PROV_CRED_MISMATCH APP_NETWORK_EVENT_PROV_CRED_MISMATCH
|
||||
typedef app_network_pop_type_t app_wifi_pop_type_t;
|
||||
#define app_wifi_init() app_network_init()
|
||||
#define app_wifi_start(pop_type) app_network_start(pop_type)
|
||||
#define app_wifi_set_custom_mfg_data(device_type, device_subtype) app_network_set_custom_mfg_data(device_type, device_subtype)
|
||||
#define app_wifi_set_custom_pop(pop) app_network_set_custom_pop(pop)
|
||||
#endif /* !CONFIG_APP_WIFI_PROV_COMPAT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
220
examples/common/app_network/app_thread_internal.c
Normal file
220
examples/common/app_network/app_thread_internal.c
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
* */
|
||||
#include <sdkconfig.h>
|
||||
#include <esp_event.h>
|
||||
#include <esp_idf_version.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_netif.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/event_groups.h>
|
||||
#include <freertos/task.h>
|
||||
#include <esp_rmaker_utils.h>
|
||||
#include <app_network.h>
|
||||
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD
|
||||
#include <app_thread_internal.h>
|
||||
#include <esp_vfs_eventfd.h>
|
||||
#include <esp_openthread.h>
|
||||
#include <esp_openthread_cli.h>
|
||||
#include <esp_openthread_lock.h>
|
||||
#include <esp_openthread_netif_glue.h>
|
||||
#include <esp_openthread_types.h>
|
||||
|
||||
#include <openthread/cli.h>
|
||||
#include <openthread/instance.h>
|
||||
#include <openthread/logging.h>
|
||||
#include <openthread/tasklet.h>
|
||||
#include <openthread/thread.h>
|
||||
|
||||
#include <network_provisioning/manager.h>
|
||||
#include <network_provisioning/scheme_ble.h>
|
||||
|
||||
|
||||
|
||||
static const char* TAG = "app_thread";
|
||||
/* Event handler for catching system events */
|
||||
static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
#ifdef CONFIG_APP_NETWORK_RESET_PROV_ON_FAILURE
|
||||
static int retries = 0;
|
||||
#endif
|
||||
if (event_base == NETWORK_PROV_EVENT) {
|
||||
switch (event_id) {
|
||||
case NETWORK_PROV_START:
|
||||
ESP_LOGI(TAG, "Provisioning started");
|
||||
break;
|
||||
case NETWORK_PROV_THREAD_DATASET_RECV: {
|
||||
break;
|
||||
}
|
||||
case NETWORK_PROV_THREAD_DATASET_FAIL: {
|
||||
#ifdef CONFIG_APP_NETWORK_RESET_PROV_ON_FAILURE
|
||||
retries++;
|
||||
if (retries >= CONFIG_APP_NETWORK_PROV_MAX_RETRY_CNT) {
|
||||
ESP_LOGI(TAG, "Failed to connect with provisioned network, reseting provisioned dataset");
|
||||
network_prov_mgr_reset_thread_sm_state_on_failure();
|
||||
esp_event_post(APP_NETWORK_EVENT, APP_NETWORK_EVENT_PROV_RESTART, NULL, 0, portMAX_DELAY);
|
||||
retries = 0;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case NETWORK_PROV_THREAD_DATASET_SUCCESS:
|
||||
ESP_LOGI(TAG, "Provisioning successful");
|
||||
#ifdef CONFIG_APP_NETWORK_RESET_PROV_ON_FAILURE
|
||||
retries = 0;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static esp_netif_t* init_openthread_netif(const esp_openthread_platform_config_t* config)
|
||||
{
|
||||
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD();
|
||||
esp_netif_t* netif = esp_netif_new(&cfg);
|
||||
assert(netif != NULL);
|
||||
ESP_ERROR_CHECK(esp_netif_attach(netif, esp_openthread_netif_glue_init(config)));
|
||||
|
||||
return netif;
|
||||
}
|
||||
|
||||
static void ot_task_worker(void* aContext)
|
||||
{
|
||||
esp_openthread_platform_config_t config = {
|
||||
.radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(),
|
||||
.host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(),
|
||||
.port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(),
|
||||
};
|
||||
/* Initialize the OpenThread stack */
|
||||
ESP_ERROR_CHECK(esp_openthread_init(&config));
|
||||
#if CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC
|
||||
/* The OpenThread log level directly matches ESP log level */
|
||||
(void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL);
|
||||
#endif
|
||||
esp_netif_t *openthread_netif = init_openthread_netif(&config);
|
||||
/* Initialize the esp_netif bindings */
|
||||
esp_netif_set_default_netif(openthread_netif);
|
||||
|
||||
/* Run the main loop */
|
||||
esp_openthread_launch_mainloop();
|
||||
/* Clean up */
|
||||
esp_netif_destroy(openthread_netif);
|
||||
esp_openthread_netif_glue_deinit();
|
||||
|
||||
esp_vfs_eventfd_unregister();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
#endif /* CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD */
|
||||
|
||||
esp_err_t thread_init()
|
||||
{
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD
|
||||
/* Initialize TCP/IP */
|
||||
esp_netif_init();
|
||||
|
||||
/* Register our event handler for OpenThread and Provisioning related events */
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(NETWORK_PROV_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
|
||||
esp_vfs_eventfd_config_t eventfd_config = {
|
||||
.max_fds = 3,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config));
|
||||
xTaskCreate(ot_task_worker, "ot_task", 6144, xTaskGetCurrentTaskHandle(), 5, NULL);
|
||||
return ESP_OK;
|
||||
#else
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif /* CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD */
|
||||
}
|
||||
|
||||
esp_err_t thread_start(const char *pop, const char *service_name, const char *service_key, uint8_t *mfg_data,
|
||||
size_t mfg_data_len, bool *provisioned)
|
||||
{
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD
|
||||
/* Configuration for the provisioning manager */
|
||||
network_prov_mgr_config_t config = {
|
||||
.scheme = network_prov_scheme_ble,
|
||||
|
||||
/* Any default scheme specific event handler that you would
|
||||
* like to choose. Since our example application requires
|
||||
* neither BT nor BLE, we can choose to release the associated
|
||||
* memory once provisioning is complete, or not needed
|
||||
* (in case when device is already provisioned). Choosing
|
||||
* appropriate scheme specific event handler allows the manager
|
||||
* to take care of this automatically.*/
|
||||
.scheme_event_handler = NETWORK_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM
|
||||
};
|
||||
|
||||
/* Initialize provisioning manager with the
|
||||
* configuration parameters set above */
|
||||
ESP_ERROR_CHECK(network_prov_mgr_init(config));
|
||||
|
||||
/* Let's find out if the device is provisioned */
|
||||
ESP_ERROR_CHECK(network_prov_mgr_is_thread_provisioned(provisioned));
|
||||
/* If device is not yet provisioned start provisioning service */
|
||||
if (!(*provisioned)) {
|
||||
ESP_LOGI(TAG, "Starting provisioning");
|
||||
|
||||
/* What is the security level that we want (0 or 1):
|
||||
* - NETWORK_PROV_SECURITY_0 is simply plain text communication.
|
||||
* - NETWORK_PROV_SECURITY_1 is secure communication which consists of secure handshake
|
||||
* using X25519 key exchange and proof of possession (pop) and AES-CTR
|
||||
* for encryption/decryption of messages.
|
||||
*/
|
||||
network_prov_security_t security = NETWORK_PROV_SECURITY_1;
|
||||
|
||||
/* This step is only useful when scheme is network_prov_scheme_ble. This will
|
||||
* set a custom 128 bit UUID which will be included in the BLE advertisement
|
||||
* and will correspond to the primary GATT service that provides provisioning
|
||||
* endpoints as GATT characteristics. Each GATT characteristic will be
|
||||
* formed using the primary service UUID as base, with different auto assigned
|
||||
* 12th and 13th bytes (assume counting starts from 0th byte). The client side
|
||||
* applications must identify the endpoints by reading the User Characteristic
|
||||
* Description descriptor (0x2901) for each characteristic, which contains the
|
||||
* endpoint name of the characteristic */
|
||||
uint8_t custom_service_uuid[] = {
|
||||
/* This is a random uuid. This can be modified if you want to change the BLE uuid. */
|
||||
/* 12th and 13th bit will be replaced by internal bits. */
|
||||
0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,
|
||||
0xea, 0x4a,0x82, 0x03, 0x04, 0x90, 0x1a, 0x02,
|
||||
};
|
||||
esp_err_t err = network_prov_scheme_ble_set_service_uuid(custom_service_uuid);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "thread_prov_scheme_ble_set_service_uuid failed %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (mfg_data) {
|
||||
err = network_prov_scheme_ble_set_mfg_data(mfg_data, mfg_data_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set mfg data, err=0x%x", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start provisioning service */
|
||||
ESP_ERROR_CHECK(network_prov_mgr_start_provisioning(security, pop, service_name, service_key));
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Already provisioned, enabling netif and starting Thread");
|
||||
/* We don't need the manager as device is already provisioned,
|
||||
* so let's release it's resources */
|
||||
network_prov_mgr_deinit();
|
||||
|
||||
esp_openthread_lock_acquire(portMAX_DELAY);
|
||||
otInstance* instance = esp_openthread_get_instance();
|
||||
(void)otIp6SetEnabled(instance, true);
|
||||
(void)otThreadSetEnabled(instance, true);
|
||||
esp_openthread_lock_release();
|
||||
}
|
||||
return ESP_OK;
|
||||
#else
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif /* CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD */
|
||||
}
|
||||
28
examples/common/app_network/app_wifi.h
Normal file
28
examples/common/app_network/app_wifi.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#pragma once
|
||||
#include <sdkconfig.h>
|
||||
#include <app_network.h>
|
||||
|
||||
#if CONFIG_APP_WIFI_PROV_COMPAT
|
||||
#define APP_WIFI_EVENT APP_NETWORK_EVENT
|
||||
typedef app_network_event_t app_wifi_event_t;
|
||||
#define APP_WIFI_EVENT_QR_DISPLAY APP_NETWORK_EVENT_QR_DISPLAY
|
||||
#define APP_WIFI_EVENT_PROV_TIMEOUT APP_NETWORK_EVENT_PROV_TIMEOUT
|
||||
#define APP_WIFI_EVENT_PROV_RESTART APP_NETWORK_EVENT_PROV_RESTART
|
||||
#define APP_WIFI_EVENT_PROV_CRED_MISMATCH APP_NETWORK_EVENT_PROV_CRED_MISMATCH
|
||||
typedef app_network_pop_type_t app_wifi_pop_type_t;
|
||||
#define app_wifi_init() app_network_init()
|
||||
#define app_wifi_start(pop_type) app_network_start(pop_type)
|
||||
#define app_wifi_set_custom_mfg_data(device_type, device_subtype) app_network_set_custom_mfg_data(device_type, device_subtype)
|
||||
#define app_wifi_set_custom_pop(pop) app_network_set_custom_pop(pop)
|
||||
#endif /* !CONFIG_APP_WIFI_PROV_COMPAT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
332
examples/common/app_network/app_wifi_internal.c
Normal file
332
examples/common/app_network/app_wifi_internal.c
Normal file
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <sdkconfig.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/event_groups.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_event.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_idf_version.h>
|
||||
#include <esp_rmaker_utils.h>
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)
|
||||
// Features supported in 4.1+
|
||||
#define ESP_NETIF_SUPPORTED
|
||||
#endif
|
||||
|
||||
#ifdef ESP_NETIF_SUPPORTED
|
||||
#include <esp_netif.h>
|
||||
#else
|
||||
#include <tcpip_adapter.h>
|
||||
#endif
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
#include <network_provisioning/manager.h>
|
||||
#ifdef CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
#include <network_provisioning/scheme_ble.h>
|
||||
#else /* CONFIG_APP_NETWORK_PROV_TRANSPORT_SOFTAP */
|
||||
#include <network_provisioning/scheme_softap.h>
|
||||
#endif /* CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE */
|
||||
#else
|
||||
#include <wifi_provisioning/manager.h>
|
||||
#ifdef CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
#include <wifi_provisioning/scheme_ble.h>
|
||||
#else /* CONFIG_APP_NETWORK_PROV_TRANSPORT_SOFTAP */
|
||||
#include <wifi_provisioning/scheme_softap.h>
|
||||
#endif /* CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE */
|
||||
|
||||
#endif
|
||||
|
||||
#include <app_wifi_internal.h>
|
||||
#include <app_network.h>
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 3)
|
||||
#define APP_PROV_STOP_ON_CREDS_MISMATCH
|
||||
#elif (CONFIG_APP_NETWORK_PROV_MAX_RETRY_CNT > 0)
|
||||
#warning "Provisioning window stop on max credentials failures, needs IDF version >= 5.1.3"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
static const char* TAG = "app_thread";
|
||||
/* Event handler for catching system events */
|
||||
static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
#ifdef CONFIG_APP_NETWORK_RESET_PROV_ON_FAILURE
|
||||
static int retries = 0;
|
||||
#endif
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
if (event_base == NETWORK_PROV_EVENT) {
|
||||
#else
|
||||
if (event_base == WIFI_PROV_EVENT) {
|
||||
#endif
|
||||
switch (event_id) {
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
case NETWORK_PROV_START:
|
||||
#else
|
||||
case WIFI_PROV_START:
|
||||
#endif
|
||||
ESP_LOGI(TAG, "Provisioning started");
|
||||
break;
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
case NETWORK_PROV_WIFI_CRED_RECV: {
|
||||
#else
|
||||
case WIFI_PROV_CRED_RECV: {
|
||||
#endif
|
||||
wifi_sta_config_t *wifi_sta_cfg = (wifi_sta_config_t *)event_data;
|
||||
ESP_LOGI(TAG, "Received Wi-Fi credentials"
|
||||
"\n\tSSID : %s\n\tPassword : %s",
|
||||
(const char *) wifi_sta_cfg->ssid,
|
||||
(const char *) wifi_sta_cfg->password);
|
||||
break;
|
||||
}
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
case NETWORK_PROV_WIFI_CRED_FAIL: {
|
||||
network_prov_wifi_sta_fail_reason_t *reason = (network_prov_wifi_sta_fail_reason_t *)event_data;
|
||||
#else
|
||||
case WIFI_PROV_CRED_FAIL: {
|
||||
wifi_prov_sta_fail_reason_t *reason = (wifi_prov_sta_fail_reason_t *)event_data;
|
||||
#endif
|
||||
ESP_LOGE(TAG, "Provisioning failed!\n\tReason : %s"
|
||||
"\n\tPlease reset to factory and retry provisioning",
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
(*reason == NETWORK_PROV_WIFI_STA_AUTH_ERROR) ?
|
||||
#else
|
||||
(*reason == WIFI_PROV_STA_AUTH_ERROR) ?
|
||||
#endif
|
||||
"Wi-Fi station authentication failed" : "Wi-Fi access-point not found");
|
||||
#ifdef CONFIG_APP_NETWORK_RESET_PROV_ON_FAILURE
|
||||
retries++;
|
||||
if (retries >= CONFIG_APP_NETWORK_PROV_MAX_RETRY_CNT) {
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 1)
|
||||
ESP_LOGI(TAG, "Failed to connect with provisioned AP, reseting provisioned credentials");
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
network_prov_mgr_reset_wifi_sm_state_on_failure();
|
||||
#else
|
||||
wifi_prov_mgr_reset_sm_state_on_failure();
|
||||
#endif // ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
esp_event_post(APP_NETWORK_EVENT, APP_NETWORK_EVENT_PROV_RESTART, NULL, 0, portMAX_DELAY);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Failed to connect with provisioned AP, please reset to provisioning manually");
|
||||
#endif // ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 1)
|
||||
retries = 0;
|
||||
}
|
||||
#endif // CONFIG_APP_NETWORK_RESET_PROV_ON_FAILURE
|
||||
break;
|
||||
}
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
case NETWORK_PROV_WIFI_CRED_SUCCESS:
|
||||
#else
|
||||
case WIFI_PROV_CRED_SUCCESS:
|
||||
#endif
|
||||
ESP_LOGI(TAG, "Provisioning successful");
|
||||
#ifdef CONFIG_APP_NETWORK_RESET_PROV_ON_FAILURE
|
||||
retries = 0;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
||||
esp_wifi_connect();
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
ESP_LOGI(TAG, "Disconnected. Connecting to the AP again...");
|
||||
esp_wifi_connect();
|
||||
}
|
||||
}
|
||||
|
||||
static void wifi_init_sta()
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
}
|
||||
#endif // CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
|
||||
esp_err_t wifi_init(void)
|
||||
{
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
/* Initialize TCP/IP */
|
||||
#ifdef ESP_NETIF_SUPPORTED
|
||||
esp_netif_init();
|
||||
#else
|
||||
tcpip_adapter_init();
|
||||
#endif
|
||||
/* Register our event handler for Wi-Fi, IP and Provisioning related events */
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(NETWORK_PROV_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
#else
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
#endif
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
|
||||
/* Initialize Wi-Fi including netif with default config */
|
||||
#ifdef ESP_NETIF_SUPPORTED
|
||||
esp_netif_create_default_wifi_sta();
|
||||
#endif
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
return ESP_OK;
|
||||
#else /* CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD */
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif /* CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI */
|
||||
}
|
||||
|
||||
esp_err_t wifi_start(const char *pop, const char *service_name, const char *service_key, uint8_t *mfg_data,
|
||||
size_t mfg_data_len, bool *provisioned)
|
||||
{
|
||||
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
/* Configuration for the provisioning manager */
|
||||
network_prov_mgr_config_t config = {
|
||||
/* What is the Provisioning Scheme that we want ?
|
||||
* network_prov_scheme_softap or network_prov_scheme_ble */
|
||||
#ifdef CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
.scheme = network_prov_scheme_ble,
|
||||
#else /* CONFIG_APP_NETWORK_PROV_TRANSPORT_SOFTAP */
|
||||
.scheme = network_prov_scheme_softap,
|
||||
#endif /* CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE */
|
||||
|
||||
/* Any default scheme specific event handler that you would
|
||||
* like to choose. Since our example application requires
|
||||
* neither BT nor BLE, we can choose to release the associated
|
||||
* memory once provisioning is complete, or not needed
|
||||
* (in case when device is already provisioned). Choosing
|
||||
* appropriate scheme specific event handler allows the manager
|
||||
* to take care of this automatically. This can be set to
|
||||
* NETWORK_PROV_EVENT_HANDLER_NONE when using network_prov_scheme_softap*/
|
||||
#ifdef CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
.scheme_event_handler = NETWORK_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM
|
||||
#else /* CONFIG_APP_NETWORK_PROV_TRANSPORT_SOFTAP */
|
||||
.scheme_event_handler = NETWORK_PROV_EVENT_HANDLER_NONE,
|
||||
#endif /* CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE */
|
||||
};
|
||||
|
||||
/* Initialize provisioning manager with the
|
||||
* configuration parameters set above */
|
||||
ESP_ERROR_CHECK(network_prov_mgr_init(config));
|
||||
#else // ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
/* Configuration for the provisioning manager */
|
||||
wifi_prov_mgr_config_t config = {
|
||||
/* What is the Provisioning Scheme that we want ?
|
||||
* wifi_prov_scheme_softap or wifi_prov_scheme_ble */
|
||||
#ifdef CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
.scheme = wifi_prov_scheme_ble,
|
||||
#else /* CONFIG_APP_NETWORK_PROV_TRANSPORT_SOFTAP */
|
||||
.scheme = wifi_prov_scheme_softap,
|
||||
#endif /* CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE */
|
||||
|
||||
/* Any default scheme specific event handler that you would
|
||||
* like to choose. Since our example application requires
|
||||
* neither BT nor BLE, we can choose to release the associated
|
||||
* memory once provisioning is complete, or not needed
|
||||
* (in case when device is already provisioned). Choosing
|
||||
* appropriate scheme specific event handler allows the manager
|
||||
* to take care of this automatically. This can be set to
|
||||
* WIFI_PROV_EVENT_HANDLER_NONE when using wifi_prov_scheme_softap*/
|
||||
#ifdef CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
.scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM
|
||||
#else /* CONFIG_APP_NETWORK_PROV_TRANSPORT_SOFTAP */
|
||||
.scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE,
|
||||
#endif /* CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE */
|
||||
};
|
||||
|
||||
/* Initialize provisioning manager with the
|
||||
* configuration parameters set above */
|
||||
ESP_ERROR_CHECK(wifi_prov_mgr_init(config));
|
||||
#endif // ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
/* Let's find out if the device is provisioned */
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
network_prov_mgr_is_wifi_provisioned(provisioned);
|
||||
#else
|
||||
wifi_prov_mgr_is_provisioned(provisioned);
|
||||
#endif
|
||||
/* If device is not yet provisioned start provisioning service */
|
||||
if (!(*provisioned)) {
|
||||
ESP_LOGI(TAG, "Starting provisioning");
|
||||
#ifdef ESP_NETIF_SUPPORTED
|
||||
#if CONFIG_ESP_WIFI_SOFTAP_SUPPORT
|
||||
esp_netif_create_default_wifi_ap();
|
||||
#endif
|
||||
#endif
|
||||
/* What is the security level that we want (0 or 1):
|
||||
* - NETWORK_PROV_SECURITY_0/WIFI_PROV_SECURITY_0 is simply plain text communication.
|
||||
* - NETWORK_PROV_SECURITY_1/WIFI_PROV_SECURITY_1 is secure communication which consists of secure handshake
|
||||
* using X25519 key exchange and proof of possession (pop) and AES-CTR
|
||||
* for encryption/decryption of messages.
|
||||
*/
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
network_prov_security_t security = NETWORK_PROV_SECURITY_1;
|
||||
#else
|
||||
wifi_prov_security_t security = WIFI_PROV_SECURITY_1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE
|
||||
/* This step is only useful when scheme is wifi_prov_scheme_ble. This will
|
||||
* set a custom 128 bit UUID which will be included in the BLE advertisement
|
||||
* and will correspond to the primary GATT service that provides provisioning
|
||||
* endpoints as GATT characteristics. Each GATT characteristic will be
|
||||
* formed using the primary service UUID as base, with different auto assigned
|
||||
* 12th and 13th bytes (assume counting starts from 0th byte). The client side
|
||||
* applications must identify the endpoints by reading the User Characteristic
|
||||
* Description descriptor (0x2901) for each characteristic, which contains the
|
||||
* endpoint name of the characteristic */
|
||||
uint8_t custom_service_uuid[] = {
|
||||
/* This is a random uuid. This can be modified if you want to change the BLE uuid. */
|
||||
/* 12th and 13th bit will be replaced by internal bits. */
|
||||
0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,
|
||||
0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02,
|
||||
};
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
esp_err_t err = network_prov_scheme_ble_set_service_uuid(custom_service_uuid);
|
||||
#else
|
||||
esp_err_t err = wifi_prov_scheme_ble_set_service_uuid(custom_service_uuid);
|
||||
#endif
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "wifi_prov_scheme_ble_set_service_uuid failed %d", err);
|
||||
return err;
|
||||
}
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
|
||||
if (mfg_data) {
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
err = network_prov_scheme_ble_set_mfg_data(mfg_data, mfg_data_len);
|
||||
#else
|
||||
err = wifi_prov_scheme_ble_set_mfg_data(mfg_data, mfg_data_len);
|
||||
#endif
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set mfg data, err=0x%x", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_APP_NETWORK_PROV_TRANSPORT_BLE */
|
||||
|
||||
/* Start provisioning service */
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
ESP_ERROR_CHECK(network_prov_mgr_start_provisioning(security, pop, service_name, service_key));
|
||||
#else
|
||||
ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning(security, pop, service_name, service_key));
|
||||
#endif
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Already provisioned, starting Wi-Fi STA");
|
||||
/* We don't need the manager as device is already provisioned,
|
||||
* so let's release it's resources */
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
|
||||
network_prov_mgr_deinit();
|
||||
#else
|
||||
wifi_prov_mgr_deinit();
|
||||
#endif
|
||||
|
||||
/* Start Wi-Fi station */
|
||||
wifi_init_sta();
|
||||
}
|
||||
return ESP_OK;
|
||||
#else /* CONFIG_ESP_RMAKER_NETWORK_OVER_THREAD */
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif /* CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI */
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
* */
|
||||
#pragma once
|
||||
#include <esp_err.h>
|
||||
#include <esp_event.h>
|
||||
#include <esp_openthread_types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if SOC_IEEE802154_SUPPORTED
|
||||
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
|
||||
{ \
|
||||
.radio_mode = RADIO_MODE_NATIVE, \
|
||||
}
|
||||
|
||||
#else
|
||||
#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \
|
||||
{ \
|
||||
.radio_mode = RADIO_MODE_UART_RCP, \
|
||||
.radio_uart_config = { \
|
||||
.port = 1, \
|
||||
.uart_config = { \
|
||||
.baud_rate = 460800, \
|
||||
.data_bits = UART_DATA_8_BITS, \
|
||||
.parity = UART_PARITY_DISABLE, \
|
||||
.stop_bits = UART_STOP_BITS_1, \
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, \
|
||||
.rx_flow_ctrl_thresh = 0, \
|
||||
.source_clk = UART_SCLK_DEFAULT, \
|
||||
}, \
|
||||
.rx_pin = 4, \
|
||||
.tx_pin = 5, \
|
||||
}, \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \
|
||||
{ \
|
||||
.host_connection_mode = HOST_CONNECTION_MODE_NONE, \
|
||||
}
|
||||
|
||||
#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \
|
||||
{ \
|
||||
.storage_partition_name = "nvs", \
|
||||
.netif_queue_size = 10, \
|
||||
.task_queue_size = 10, \
|
||||
}
|
||||
|
||||
esp_err_t thread_init();
|
||||
|
||||
esp_err_t thread_start(const char *pop, const char *service_name, const char *service_key, uint8_t *mfg_data,
|
||||
size_t mfg_data_len, bool *provisioned);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#pragma once
|
||||
#include <esp_err.h>
|
||||
#include <esp_event.h>
|
||||
#include "app_network.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Initialize Wi-Fi
|
||||
*
|
||||
* This initializes Wi-Fi and the network/wifi provisioning manager
|
||||
*
|
||||
* @return ESP_OK on success.
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t wifi_init();
|
||||
|
||||
/** Start Wi-Fi
|
||||
*
|
||||
* This will start provisioning if the node is not provisioned and will connect to Wi-Fi
|
||||
* if node is provisioned. Function will return successfully only after Wi-Fi is connect
|
||||
*
|
||||
* @param[in] pop The Proof of Possession (PoP) pin
|
||||
* @param[in] service_name The service name of network/wifi provisioning. This translates to
|
||||
* - Wi-Fi SSID when scheme is network_prov_scheme_softap/wifi_prov_scheme_softap
|
||||
* - device name when scheme is network_prov_scheme_ble/wifi_prov_scheme_ble
|
||||
* @param[in] service_key The service key of network/wifi provisioning. This translates to
|
||||
* - Wi-Fi password when scheme is network_prov_scheme_softap/wifi_prov_scheme_softap (NULL = Open network)
|
||||
* @param[in] mfg_data The manufactuer specific data of network/wifi provisioning.
|
||||
* @param[in] mfg_data The manufactuer specific data length of network/wifi provisioning.
|
||||
* @param[out] provisioned Whether the device is provisioned.
|
||||
*
|
||||
* @return ESP_OK on success (Wi-Fi connected).
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t wifi_start(const char *pop, const char *service_name, const char *service_key, uint8_t *mfg_data,
|
||||
size_t mfg_data_len, bool *provisioned);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,10 +0,0 @@
|
||||
set(priv_req wifi_provisioning qrcode nvs_flash esp_event rmaker_common)
|
||||
|
||||
idf_component_register(SRCS "app_wifi.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES
|
||||
PRIV_REQUIRES ${priv_req})
|
||||
|
||||
if(CONFIG_APP_WIFI_SHOW_DEMO_INTRO_TEXT)
|
||||
target_compile_definitions(${COMPONENT_TARGET} PRIVATE "-D RMAKER_DEMO_PROJECT_NAME=\"${CMAKE_PROJECT_NAME}\"")
|
||||
endif()
|
||||
@@ -1,585 +0,0 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/event_groups.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_event.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_idf_version.h>
|
||||
#include <inttypes.h>
|
||||
#include <esp_rmaker_utils.h>
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)
|
||||
// Features supported in 4.1+
|
||||
#define ESP_NETIF_SUPPORTED
|
||||
#endif
|
||||
|
||||
#ifdef ESP_NETIF_SUPPORTED
|
||||
#include <esp_netif.h>
|
||||
#else
|
||||
#include <tcpip_adapter.h>
|
||||
#endif
|
||||
|
||||
#include <wifi_provisioning/manager.h>
|
||||
#ifdef CONFIG_APP_WIFI_PROV_TRANSPORT_BLE
|
||||
#include <wifi_provisioning/scheme_ble.h>
|
||||
#else /* CONFIG_APP_WIFI_PROV_TRANSPORT_SOFTAP */
|
||||
#include <wifi_provisioning/scheme_softap.h>
|
||||
#endif /* CONFIG_APP_WIFI_PROV_TRANSPORT_BLE */
|
||||
|
||||
#include <qrcode.h>
|
||||
#include <nvs.h>
|
||||
#include <nvs_flash.h>
|
||||
#include <esp_timer.h>
|
||||
#include "app_wifi.h"
|
||||
|
||||
ESP_EVENT_DEFINE_BASE(APP_WIFI_EVENT);
|
||||
static const char *TAG = "app_wifi";
|
||||
static const int WIFI_CONNECTED_EVENT = BIT0;
|
||||
static EventGroupHandle_t wifi_event_group;
|
||||
|
||||
#define PROV_QR_VERSION "v1"
|
||||
|
||||
#define PROV_TRANSPORT_SOFTAP "softap"
|
||||
#define PROV_TRANSPORT_BLE "ble"
|
||||
#define QRCODE_BASE_URL "https://rainmaker.espressif.com/qrcode.html"
|
||||
|
||||
#define CREDENTIALS_NAMESPACE "rmaker_creds"
|
||||
#define RANDOM_NVS_KEY "random"
|
||||
|
||||
#define POP_STR_SIZE 9
|
||||
static esp_timer_handle_t prov_stop_timer;
|
||||
/* Timeout period in minutes */
|
||||
#define APP_WIFI_PROV_TIMEOUT_PERIOD CONFIG_APP_WIFI_PROV_TIMEOUT_PERIOD
|
||||
/* Autofetch period in micro-seconds */
|
||||
static uint64_t prov_timeout_period = (APP_WIFI_PROV_TIMEOUT_PERIOD * 60 * 1000000LL);
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 3)
|
||||
#define APP_PROV_STOP_ON_CREDS_MISMATCH
|
||||
#elif (CONFIG_APP_WIFI_PROV_MAX_RETRY_CNT > 0)
|
||||
#warning "Provisioning window stop on max credentials failures, needs IDF version >= 5.1.3"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_APP_WIFI_SHOW_DEMO_INTRO_TEXT
|
||||
|
||||
#define ESP_RAINMAKER_GITHUB_EXAMPLES_PATH "https://github.com/espressif/esp-rainmaker/blob/master/examples"
|
||||
#define ESP_RAINMAKER_INTRO_LINK "https://rainmaker.espressif.com"
|
||||
#define ESP_RMAKER_PHONE_APP_LINK "http://bit.ly/esp-rmaker"
|
||||
char esp_rainmaker_ascii_art[] = \
|
||||
" ______ _____ _____ _____ _____ _ _ __ __ _ ________ _____\n"\
|
||||
" | ____|/ ____| __ \\ | __ \\ /\\ |_ _| \\ | | \\/ | /\\ | |/ / ____| __ \\\n"\
|
||||
" | |__ | (___ | |__) | | |__) | / \\ | | | \\| | \\ / | / \\ | ' /| |__ | |__) |\n"\
|
||||
" | __| \\___ \\| ___/ | _ / / /\\ \\ | | | . ` | |\\/| | / /\\ \\ | < | __| | _ /\n"\
|
||||
" | |____ ____) | | | | \\ \\ / ____ \\ _| |_| |\\ | | | |/ ____ \\| . \\| |____| | \\ \\\n"\
|
||||
" |______|_____/|_| |_| \\_\\/_/ \\_\\_____|_| \\_|_| |_/_/ \\_\\_|\\_\\______|_| \\_\\\n";
|
||||
|
||||
static void intro_print(bool provisioned)
|
||||
{
|
||||
printf("####################################################################################################\n");
|
||||
printf("%s\n", esp_rainmaker_ascii_art);
|
||||
printf("Welcome to ESP RainMaker %s demo application!\n", RMAKER_DEMO_PROJECT_NAME);
|
||||
if (!provisioned) {
|
||||
printf("Follow these steps to get started:\n");
|
||||
printf("1. Download the ESP RainMaker phone app by visiting this link from your phone's browser:\n\n");
|
||||
printf(" %s\n\n", ESP_RMAKER_PHONE_APP_LINK);
|
||||
printf("2. Sign up and follow the steps on screen to add the device to your Wi-Fi network.\n");
|
||||
printf("3. You are now ready to use the device and control it locally as well as remotely.\n");
|
||||
printf(" You can also use the Boot button on the board to control your device.\n");
|
||||
}
|
||||
printf("\nIf you want to reset Wi-Fi credentials, or reset to factory, press and hold the Boot button.\n");
|
||||
printf("\nThis application uses ESP RainMaker, which is based on ESP IDF.\n");
|
||||
printf("Check out the source code for this application here:\n %s/%s\n",
|
||||
ESP_RAINMAKER_GITHUB_EXAMPLES_PATH, RMAKER_DEMO_PROJECT_NAME);
|
||||
printf("\nPlease visit %s for additional information.\n\n", ESP_RAINMAKER_INTRO_LINK);
|
||||
printf("####################################################################################################\n");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void intro_print(bool provisioned)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
#endif /* !APP_WIFI_SHOW_DEMO_INTRO_TEXT */
|
||||
|
||||
static uint8_t *custom_mfg_data = NULL;
|
||||
static size_t custom_mfg_data_len = 0;
|
||||
|
||||
esp_err_t app_wifi_set_custom_mfg_data(uint16_t device_type, uint8_t device_subtype)
|
||||
{
|
||||
int8_t mfg_data[] = {MFG_DATA_HEADER, MGF_DATA_APP_ID, MFG_DATA_VERSION, MFG_DATA_CUSTOMER_ID};
|
||||
size_t mfg_data_len = sizeof(mfg_data) + 4; // 4 bytes of device type, subtype, and extra-code
|
||||
custom_mfg_data = (uint8_t *)MEM_ALLOC_EXTRAM(mfg_data_len);
|
||||
if (custom_mfg_data == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory to custom mfg data");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
memcpy(custom_mfg_data, mfg_data, sizeof(mfg_data));
|
||||
custom_mfg_data[8] = 0xff & (device_type >> 8);
|
||||
custom_mfg_data[9] = 0xff & device_type;
|
||||
custom_mfg_data[10] = device_subtype;
|
||||
custom_mfg_data[11] = 0;
|
||||
custom_mfg_data_len = mfg_data_len;
|
||||
ESP_LOG_BUFFER_HEXDUMP("tag", custom_mfg_data, mfg_data_len, 3);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void app_wifi_print_qr(const char *name, const char *pop, const char *transport)
|
||||
{
|
||||
if (!name || !transport) {
|
||||
ESP_LOGW(TAG, "Cannot generate QR code payload. Data missing.");
|
||||
return;
|
||||
}
|
||||
char payload[150];
|
||||
if (pop) {
|
||||
snprintf(payload, sizeof(payload), "{\"ver\":\"%s\",\"name\":\"%s\"" \
|
||||
",\"pop\":\"%s\",\"transport\":\"%s\"}",
|
||||
PROV_QR_VERSION, name, pop, transport);
|
||||
} else {
|
||||
snprintf(payload, sizeof(payload), "{\"ver\":\"%s\",\"name\":\"%s\"" \
|
||||
",\"transport\":\"%s\"}",
|
||||
PROV_QR_VERSION, name, transport);
|
||||
}
|
||||
#ifdef CONFIG_APP_WIFI_PROV_SHOW_QR
|
||||
ESP_LOGI(TAG, "Scan this QR code from the ESP RainMaker phone app for Provisioning.");
|
||||
qrcode_display(payload);
|
||||
#endif /* CONFIG_APP_WIFI_PROV_SHOW_QR */
|
||||
ESP_LOGI(TAG, "If QR code is not visible, copy paste the below URL in a browser.\n%s?data=%s", QRCODE_BASE_URL, payload);
|
||||
esp_event_post(APP_WIFI_EVENT, APP_WIFI_EVENT_QR_DISPLAY, payload, strlen(payload) + 1, portMAX_DELAY);
|
||||
}
|
||||
|
||||
/* Event handler for catching system events */
|
||||
static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
#ifdef CONFIG_APP_WIFI_RESET_PROV_ON_FAILURE
|
||||
static int retries = 0;
|
||||
#endif
|
||||
|
||||
#ifdef APP_PROV_STOP_ON_CREDS_MISMATCH
|
||||
static int failed_cnt = 0;
|
||||
#endif
|
||||
|
||||
if (event_base == WIFI_PROV_EVENT) {
|
||||
switch (event_id) {
|
||||
case WIFI_PROV_START:
|
||||
ESP_LOGI(TAG, "Provisioning started");
|
||||
break;
|
||||
case WIFI_PROV_CRED_RECV: {
|
||||
wifi_sta_config_t *wifi_sta_cfg = (wifi_sta_config_t *)event_data;
|
||||
ESP_LOGI(TAG, "Received Wi-Fi credentials"
|
||||
"\n\tSSID : %s\n\tPassword : %s",
|
||||
(const char *) wifi_sta_cfg->ssid,
|
||||
(const char *) wifi_sta_cfg->password);
|
||||
break;
|
||||
}
|
||||
case WIFI_PROV_CRED_FAIL: {
|
||||
wifi_prov_sta_fail_reason_t *reason = (wifi_prov_sta_fail_reason_t *)event_data;
|
||||
ESP_LOGE(TAG, "Provisioning failed!\n\tReason : %s"
|
||||
"\n\tPlease reset to factory and retry provisioning",
|
||||
(*reason == WIFI_PROV_STA_AUTH_ERROR) ?
|
||||
"Wi-Fi station authentication failed" : "Wi-Fi access-point not found");
|
||||
#ifdef CONFIG_APP_WIFI_RESET_PROV_ON_FAILURE
|
||||
retries++;
|
||||
if (retries >= CONFIG_APP_WIFI_PROV_MAX_RETRY_CNT) {
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 1)
|
||||
ESP_LOGI(TAG, "Failed to connect with provisioned AP, reseting provisioned credentials");
|
||||
wifi_prov_mgr_reset_sm_state_on_failure();
|
||||
esp_event_post(APP_WIFI_EVENT, APP_WIFI_EVENT_PROV_RESTART, NULL, 0, portMAX_DELAY);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Failed to connect with provisioned AP, please reset to provisioning manually");
|
||||
#endif
|
||||
retries = 0;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case WIFI_PROV_CRED_SUCCESS:
|
||||
ESP_LOGI(TAG, "Provisioning successful");
|
||||
#ifdef CONFIG_APP_WIFI_RESET_PROV_ON_FAILURE
|
||||
retries = 0;
|
||||
#endif
|
||||
break;
|
||||
case WIFI_PROV_END:
|
||||
if (prov_stop_timer) {
|
||||
esp_timer_stop(prov_stop_timer);
|
||||
esp_timer_delete(prov_stop_timer);
|
||||
prov_stop_timer = NULL;
|
||||
}
|
||||
/* De-initialize manager once provisioning is finished */
|
||||
wifi_prov_mgr_deinit();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#ifdef APP_PROV_STOP_ON_CREDS_MISMATCH
|
||||
} else if (event_base == PROTOCOMM_SECURITY_SESSION_EVENT) {
|
||||
switch (event_id) {
|
||||
case PROTOCOMM_SECURITY_SESSION_SETUP_OK:
|
||||
ESP_LOGI(TAG, "Secured session established!");
|
||||
break;
|
||||
case PROTOCOMM_SECURITY_SESSION_INVALID_SECURITY_PARAMS:
|
||||
/* fall-through */
|
||||
case PROTOCOMM_SECURITY_SESSION_CREDENTIALS_MISMATCH:
|
||||
ESP_LOGE(TAG, "Received incorrect PoP or invalid security params! event: %d", (int) event_id);
|
||||
if (CONFIG_APP_WIFI_PROV_MAX_POP_MISMATCH &&
|
||||
(++failed_cnt >= CONFIG_APP_WIFI_PROV_MAX_POP_MISMATCH)) {
|
||||
/* stop provisioning for security reasons */
|
||||
wifi_prov_mgr_stop_provisioning();
|
||||
ESP_LOGW(TAG, "Max PoP attempts reached! Provisioning disabled for security reasons. Please reboot device to restart provisioning");
|
||||
esp_event_post(APP_WIFI_EVENT, APP_WIFI_EVENT_PROV_CRED_MISMATCH, NULL, 0, portMAX_DELAY);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
||||
esp_wifi_connect();
|
||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
|
||||
ESP_LOGI(TAG, "Connected with IP Address:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||
/* Signal main application to continue execution */
|
||||
xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_EVENT);
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
ESP_LOGI(TAG, "Disconnected. Connecting to the AP again...");
|
||||
esp_wifi_connect();
|
||||
}
|
||||
}
|
||||
|
||||
static void wifi_init_sta()
|
||||
{
|
||||
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
}
|
||||
|
||||
/* Free random_bytes after use only if function returns ESP_OK */
|
||||
static esp_err_t read_random_bytes_from_nvs(uint8_t **random_bytes, size_t *len)
|
||||
{
|
||||
nvs_handle handle;
|
||||
esp_err_t err;
|
||||
*len = 0;
|
||||
|
||||
if ((err = nvs_open_from_partition(CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME, CREDENTIALS_NAMESPACE,
|
||||
NVS_READONLY, &handle)) != ESP_OK) {
|
||||
ESP_LOGD(TAG, "NVS open for %s %s %s failed with error %d", CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME, CREDENTIALS_NAMESPACE, RANDOM_NVS_KEY, err);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if ((err = nvs_get_blob(handle, RANDOM_NVS_KEY, NULL, len)) != ESP_OK) {
|
||||
ESP_LOGD(TAG, "Error %d. Failed to read key %s.", err, RANDOM_NVS_KEY);
|
||||
nvs_close(handle);
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
*random_bytes = calloc(*len, 1);
|
||||
if (*random_bytes) {
|
||||
nvs_get_blob(handle, RANDOM_NVS_KEY, *random_bytes, len);
|
||||
nvs_close(handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
nvs_close(handle);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
static char *custom_pop;
|
||||
esp_err_t app_wifi_set_custom_pop(const char *pop)
|
||||
{
|
||||
/* NULL PoP is not allowed here. Use POP_TYPE_NONE instead. */
|
||||
if (!pop) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Freeing up the PoP in case it is already allocated */
|
||||
if (custom_pop) {
|
||||
free(custom_pop);
|
||||
custom_pop = NULL;
|
||||
}
|
||||
|
||||
custom_pop = strdup(pop);
|
||||
if (!custom_pop) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t get_device_service_name(char *service_name, size_t max)
|
||||
{
|
||||
uint8_t *nvs_random = NULL;
|
||||
const char *ssid_prefix = CONFIG_APP_WIFI_PROV_NAME_PREFIX;
|
||||
size_t nvs_random_size = 0;
|
||||
if ((read_random_bytes_from_nvs(&nvs_random, &nvs_random_size) != ESP_OK) || nvs_random_size < 3) {
|
||||
uint8_t eth_mac[6];
|
||||
esp_wifi_get_mac(WIFI_IF_STA, eth_mac);
|
||||
snprintf(service_name, max, "%s_%02x%02x%02x", ssid_prefix, eth_mac[3], eth_mac[4], eth_mac[5]);
|
||||
} else {
|
||||
snprintf(service_name, max, "%s_%02x%02x%02x", ssid_prefix, nvs_random[nvs_random_size - 3],
|
||||
nvs_random[nvs_random_size - 2], nvs_random[nvs_random_size - 1]);
|
||||
}
|
||||
if (nvs_random) {
|
||||
free(nvs_random);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *get_device_pop(app_wifi_pop_type_t pop_type)
|
||||
{
|
||||
if (pop_type == POP_TYPE_NONE) {
|
||||
return NULL;
|
||||
} else if (pop_type == POP_TYPE_CUSTOM) {
|
||||
if (!custom_pop) {
|
||||
ESP_LOGE(TAG, "Custom PoP not set. Please use app_wifi_set_custom_pop().");
|
||||
return NULL;
|
||||
}
|
||||
return strdup(custom_pop);
|
||||
}
|
||||
char *pop = calloc(1, POP_STR_SIZE);
|
||||
if (!pop) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for PoP.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pop_type == POP_TYPE_MAC) {
|
||||
uint8_t eth_mac[6];
|
||||
esp_err_t err = esp_wifi_get_mac(WIFI_IF_STA, eth_mac);
|
||||
if (err == ESP_OK) {
|
||||
snprintf(pop, POP_STR_SIZE, "%02x%02x%02x%02x", eth_mac[2], eth_mac[3], eth_mac[4], eth_mac[5]);
|
||||
return pop;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to get MAC address to generate PoP.");
|
||||
goto pop_err;
|
||||
}
|
||||
} else if (pop_type == POP_TYPE_RANDOM) {
|
||||
uint8_t *nvs_random = NULL;
|
||||
size_t nvs_random_size = 0;
|
||||
if ((read_random_bytes_from_nvs(&nvs_random, &nvs_random_size) != ESP_OK) || nvs_random_size < 4) {
|
||||
ESP_LOGE(TAG, "Failed to read random bytes from NVS to generate PoP.");
|
||||
if (nvs_random) {
|
||||
free(nvs_random);
|
||||
}
|
||||
goto pop_err;
|
||||
} else {
|
||||
snprintf(pop, POP_STR_SIZE, "%02x%02x%02x%02x", nvs_random[0], nvs_random[1], nvs_random[2], nvs_random[3]);
|
||||
free(nvs_random);
|
||||
return pop;
|
||||
}
|
||||
}
|
||||
pop_err:
|
||||
free(pop);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void app_wifi_init(void)
|
||||
{
|
||||
/* Initialize TCP/IP */
|
||||
#ifdef ESP_NETIF_SUPPORTED
|
||||
esp_netif_init();
|
||||
#else
|
||||
tcpip_adapter_init();
|
||||
#endif
|
||||
|
||||
/* Initialize the event loop, if not done already. */
|
||||
esp_err_t err = esp_event_loop_create_default();
|
||||
/* If the default event loop is already initialized, we get ESP_ERR_INVALID_STATE */
|
||||
if (err != ESP_OK) {
|
||||
if (err == ESP_ERR_INVALID_STATE) {
|
||||
ESP_LOGW(TAG, "Event loop creation failed with ESP_ERR_INVALID_STATE. Proceeding since it must have been created elsewhere.");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to create default event loop, err = %x", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
wifi_event_group = xEventGroupCreate();
|
||||
|
||||
/* Register our event handler for Wi-Fi, IP and Provisioning related events */
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
#ifdef APP_PROV_STOP_ON_CREDS_MISMATCH
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(PROTOCOMM_SECURITY_SESSION_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
#endif
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
|
||||
|
||||
/* Initialize Wi-Fi including netif with default config */
|
||||
#ifdef ESP_NETIF_SUPPORTED
|
||||
esp_netif_create_default_wifi_sta();
|
||||
#endif
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||
}
|
||||
|
||||
static void app_wifi_prov_stop(void *priv)
|
||||
{
|
||||
ESP_LOGW(TAG, "Provisioning timed out. Please reboot device to restart provisioning.");
|
||||
wifi_prov_mgr_stop_provisioning();
|
||||
esp_event_post(APP_WIFI_EVENT, APP_WIFI_EVENT_PROV_TIMEOUT, NULL, 0, portMAX_DELAY);
|
||||
}
|
||||
|
||||
esp_err_t app_wifi_start_timer(void)
|
||||
{
|
||||
if (prov_timeout_period == 0) {
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_timer_create_args_t prov_stop_timer_conf = {
|
||||
.callback = app_wifi_prov_stop,
|
||||
.arg = NULL,
|
||||
.dispatch_method = ESP_TIMER_TASK,
|
||||
.name = "app_wifi_prov_stop_tm"
|
||||
};
|
||||
if (esp_timer_create(&prov_stop_timer_conf, &prov_stop_timer) == ESP_OK) {
|
||||
esp_timer_start_once(prov_stop_timer, prov_timeout_period);
|
||||
ESP_LOGI(TAG, "Provisioning will auto stop after %d minute(s).",
|
||||
APP_WIFI_PROV_TIMEOUT_PERIOD);
|
||||
return ESP_OK;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to create Provisioning auto stop timer.");
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t app_wifi_start(app_wifi_pop_type_t pop_type)
|
||||
{
|
||||
/* Configuration for the provisioning manager */
|
||||
wifi_prov_mgr_config_t config = {
|
||||
/* What is the Provisioning Scheme that we want ?
|
||||
* wifi_prov_scheme_softap or wifi_prov_scheme_ble */
|
||||
#ifdef CONFIG_APP_WIFI_PROV_TRANSPORT_BLE
|
||||
.scheme = wifi_prov_scheme_ble,
|
||||
#else /* CONFIG_APP_WIFI_PROV_TRANSPORT_SOFTAP */
|
||||
.scheme = wifi_prov_scheme_softap,
|
||||
#endif /* CONFIG_APP_WIFI_PROV_TRANSPORT_BLE */
|
||||
|
||||
/* Any default scheme specific event handler that you would
|
||||
* like to choose. Since our example application requires
|
||||
* neither BT nor BLE, we can choose to release the associated
|
||||
* memory once provisioning is complete, or not needed
|
||||
* (in case when device is already provisioned). Choosing
|
||||
* appropriate scheme specific event handler allows the manager
|
||||
* to take care of this automatically. This can be set to
|
||||
* WIFI_PROV_EVENT_HANDLER_NONE when using wifi_prov_scheme_softap*/
|
||||
#ifdef CONFIG_APP_WIFI_PROV_TRANSPORT_BLE
|
||||
.scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM
|
||||
#else /* CONFIG_APP_WIFI_PROV_TRANSPORT_SOFTAP */
|
||||
.scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE,
|
||||
#endif /* CONFIG_APP_WIFI_PROV_TRANSPORT_BLE */
|
||||
};
|
||||
|
||||
/* Initialize provisioning manager with the
|
||||
* configuration parameters set above */
|
||||
ESP_ERROR_CHECK(wifi_prov_mgr_init(config));
|
||||
|
||||
bool provisioned = false;
|
||||
/* Let's find out if the device is provisioned */
|
||||
wifi_prov_mgr_is_provisioned(&provisioned);
|
||||
/* If device is not yet provisioned start provisioning service */
|
||||
if (!provisioned) {
|
||||
ESP_LOGI(TAG, "Starting provisioning");
|
||||
#ifdef ESP_NETIF_SUPPORTED
|
||||
#if CONFIG_ESP_WIFI_SOFTAP_SUPPORT
|
||||
esp_netif_create_default_wifi_ap();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* What is the Device Service Name that we want
|
||||
* This translates to :
|
||||
* - Wi-Fi SSID when scheme is wifi_prov_scheme_softap
|
||||
* - device name when scheme is wifi_prov_scheme_ble
|
||||
*/
|
||||
char service_name[12];
|
||||
get_device_service_name(service_name, sizeof(service_name));
|
||||
|
||||
/* What is the service key (Wi-Fi password)
|
||||
* NULL = Open network
|
||||
* This is ignored when scheme is wifi_prov_scheme_ble
|
||||
*/
|
||||
const char *service_key = NULL;
|
||||
|
||||
/* What is the security level that we want (0 or 1):
|
||||
* - WIFI_PROV_SECURITY_0 is simply plain text communication.
|
||||
* - WIFI_PROV_SECURITY_1 is secure communication which consists of secure handshake
|
||||
* using X25519 key exchange and proof of possession (pop) and AES-CTR
|
||||
* for encryption/decryption of messages.
|
||||
*/
|
||||
wifi_prov_security_t security = WIFI_PROV_SECURITY_1;
|
||||
|
||||
/* Do we want a proof-of-possession (ignored if Security 0 is selected):
|
||||
* - this should be a string with length > 0
|
||||
* - NULL if not used
|
||||
*/
|
||||
char *pop = get_device_pop(pop_type);
|
||||
if ((pop_type != POP_TYPE_NONE) && (pop == NULL)) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_APP_WIFI_PROV_TRANSPORT_BLE
|
||||
/* This step is only useful when scheme is wifi_prov_scheme_ble. This will
|
||||
* set a custom 128 bit UUID which will be included in the BLE advertisement
|
||||
* and will correspond to the primary GATT service that provides provisioning
|
||||
* endpoints as GATT characteristics. Each GATT characteristic will be
|
||||
* formed using the primary service UUID as base, with different auto assigned
|
||||
* 12th and 13th bytes (assume counting starts from 0th byte). The client side
|
||||
* applications must identify the endpoints by reading the User Characteristic
|
||||
* Description descriptor (0x2901) for each characteristic, which contains the
|
||||
* endpoint name of the characteristic */
|
||||
uint8_t custom_service_uuid[] = {
|
||||
/* This is a random uuid. This can be modified if you want to change the BLE uuid. */
|
||||
/* 12th and 13th bit will be replaced by internal bits. */
|
||||
0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,
|
||||
0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02,
|
||||
};
|
||||
esp_err_t err = wifi_prov_scheme_ble_set_service_uuid(custom_service_uuid);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "wifi_prov_scheme_ble_set_service_uuid failed %d", err);
|
||||
return err;
|
||||
}
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
|
||||
if (custom_mfg_data) {
|
||||
err = wifi_prov_scheme_ble_set_mfg_data(custom_mfg_data, custom_mfg_data_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set mfg data, err=0x%x", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_APP_WIFI_PROV_TRANSPORT_BLE */
|
||||
|
||||
/* Start provisioning service */
|
||||
ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning(security, pop, service_name, service_key));
|
||||
/* Print QR code for provisioning */
|
||||
#ifdef CONFIG_APP_WIFI_PROV_TRANSPORT_BLE
|
||||
app_wifi_print_qr(service_name, pop, PROV_TRANSPORT_BLE);
|
||||
#else /* CONFIG_APP_WIFI_PROV_TRANSPORT_SOFTAP */
|
||||
app_wifi_print_qr(service_name, pop, PROV_TRANSPORT_SOFTAP);
|
||||
#endif /* CONFIG_APP_WIFI_PROV_TRANSPORT_BLE */
|
||||
intro_print(provisioned);
|
||||
ESP_LOGI(TAG, "Provisioning Started. Name : %s, POP : %s", service_name, pop ? pop : "<null>");
|
||||
if (pop) {
|
||||
free(pop);
|
||||
}
|
||||
app_wifi_start_timer();
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Already provisioned, starting Wi-Fi STA");
|
||||
intro_print(provisioned);
|
||||
/* We don't need the manager as device is already provisioned,
|
||||
* so let's release it's resources */
|
||||
wifi_prov_mgr_deinit();
|
||||
|
||||
/* Start Wi-Fi station */
|
||||
wifi_init_sta();
|
||||
}
|
||||
if (custom_mfg_data) {
|
||||
free(custom_mfg_data);
|
||||
custom_mfg_data = NULL;
|
||||
custom_mfg_data_len = 0;
|
||||
}
|
||||
/* Wait for Wi-Fi connection */
|
||||
xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_EVENT, false, true, portMAX_DELAY);
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ menu "WS2812 RGB LED"
|
||||
|
||||
config WS2812_LED_GPIO
|
||||
int "WS2812 LED GPIO"
|
||||
default 8 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C6
|
||||
default 8 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2
|
||||
default 48 if IDF_TARGET_ESP32S3
|
||||
default 18
|
||||
depends on WS2812_LED_ENABLE
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <esp_rmaker_schedule.h>
|
||||
#include <esp_rmaker_scenes.h>
|
||||
|
||||
#include <app_wifi.h>
|
||||
#include <app_network.h>
|
||||
#include <app_insights.h>
|
||||
|
||||
#include "app_priv.h"
|
||||
@@ -70,10 +70,10 @@ void app_main()
|
||||
|
||||
/* Initialize Wi-Fi. Note that, this should be called before esp_rmaker_node_init()
|
||||
*/
|
||||
app_wifi_init();
|
||||
app_network_init();
|
||||
|
||||
/* Initialize the ESP RainMaker Agent.
|
||||
* Note that this should be called after app_wifi_init() but before app_wifi_start()
|
||||
* Note that this should be called after app_network_init() but before app_network_start()
|
||||
* */
|
||||
esp_rmaker_config_t rainmaker_cfg = {
|
||||
.enable_time_sync = false,
|
||||
@@ -118,7 +118,7 @@ void app_main()
|
||||
* else, it will start Wi-Fi provisioning. The function will return
|
||||
* after a connection has been successfully established
|
||||
*/
|
||||
err = app_wifi_start(POP_TYPE_RANDOM);
|
||||
err = app_network_start(POP_TYPE_RANDOM);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not start Wifi. Aborting!!!");
|
||||
vTaskDelay(5000/portTICK_PERIOD_MS);
|
||||
|
||||
14
examples/fan/sdkconfig.defaults.esp32h2
Normal file
14
examples/fan/sdkconfig.defaults.esp32h2
Normal file
@@ -0,0 +1,14 @@
|
||||
# Enable OpenThread
|
||||
CONFIG_OPENTHREAD_ENABLED=y
|
||||
CONFIG_OPENTHREAD_CLI=n
|
||||
|
||||
# Enable DNS64 client and Network connection resolve hook
|
||||
CONFIG_OPENTHREAD_DNS64_CLIENT=y
|
||||
CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT=y
|
||||
|
||||
# Increase network provisioning scan entries
|
||||
CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=64
|
||||
|
||||
# Use 4MB optimised partition
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_4mb_optimised.csv"
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <esp_rmaker_core.h>
|
||||
#include <esp_rmaker_standard_types.h>
|
||||
|
||||
#include <app_wifi.h>
|
||||
#include <app_network.h>
|
||||
#include <app_insights.h>
|
||||
|
||||
#include "app_priv.h"
|
||||
@@ -53,10 +53,10 @@ void app_main()
|
||||
|
||||
/* Initialize Wi-Fi. Note that, this should be called before esp_rmaker_node_init()
|
||||
*/
|
||||
app_wifi_init();
|
||||
app_network_init();
|
||||
|
||||
/* Initialize the ESP RainMaker Agent.
|
||||
* Note that this should be called after app_wifi_init() but before app_wifi_start()
|
||||
* Note that this should be called after app_network_init() but before app_network_start()
|
||||
* */
|
||||
esp_rmaker_config_t rainmaker_cfg = {
|
||||
.enable_time_sync = false,
|
||||
@@ -100,7 +100,7 @@ void app_main()
|
||||
* else, it will start Wi-Fi provisioning. The function will return
|
||||
* after a connection has been successfully established
|
||||
*/
|
||||
err = app_wifi_start(POP_TYPE_RANDOM);
|
||||
err = app_network_start(POP_TYPE_RANDOM);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not start Wifi. Aborting!!!");
|
||||
vTaskDelay(5000/portTICK_PERIOD_MS);
|
||||
|
||||
14
examples/gpio/sdkconfig.defaults.esp32h2
Normal file
14
examples/gpio/sdkconfig.defaults.esp32h2
Normal file
@@ -0,0 +1,14 @@
|
||||
# Enable OpenThread
|
||||
CONFIG_OPENTHREAD_ENABLED=y
|
||||
CONFIG_OPENTHREAD_CLI=n
|
||||
|
||||
# Enable DNS64 client and Network connection resolve hook
|
||||
CONFIG_OPENTHREAD_DNS64_CLIENT=y
|
||||
CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT=y
|
||||
|
||||
# Increase network provisioning scan entries
|
||||
CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=64
|
||||
|
||||
# Use 4MB optimised partition
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_4mb_optimised.csv"
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <esp_log.h>
|
||||
#include <nvs_flash.h>
|
||||
|
||||
#include <esp_rmaker_console.h>
|
||||
#include <esp_rmaker_core.h>
|
||||
#include <esp_rmaker_standard_params.h>
|
||||
#include <esp_rmaker_standard_devices.h>
|
||||
@@ -20,7 +21,7 @@
|
||||
#include <esp_rmaker_console.h>
|
||||
#include <esp_rmaker_scenes.h>
|
||||
|
||||
#include <app_wifi.h>
|
||||
#include <app_network.h>
|
||||
#include <app_insights.h>
|
||||
|
||||
#include "app_priv.h"
|
||||
@@ -135,12 +136,12 @@ void app_main()
|
||||
}
|
||||
ESP_ERROR_CHECK( err );
|
||||
|
||||
/* Initialize Wi-Fi. Note that, this should be called before esp_rmaker_node_init()
|
||||
/* Initialize Wi-Fi/Thread. Note that, this should be called before esp_rmaker_node_init()
|
||||
*/
|
||||
app_wifi_init();
|
||||
app_network_init();
|
||||
|
||||
/* Initialize the ESP RainMaker Agent.
|
||||
* Note that this should be called after app_wifi_init() but before app_wifi_start()
|
||||
* Note that this should be called after app_network_init() but before app_network_start()
|
||||
* */
|
||||
esp_rmaker_config_t rainmaker_cfg = {
|
||||
.enable_time_sync = false,
|
||||
@@ -189,15 +190,15 @@ void app_main()
|
||||
/* Start the ESP RainMaker Agent */
|
||||
esp_rmaker_start();
|
||||
|
||||
err = app_wifi_set_custom_mfg_data(MGF_DATA_DEVICE_TYPE_LIGHT, MFG_DATA_DEVICE_SUBTYPE_LIGHT);
|
||||
/* Start the Wi-Fi.
|
||||
err = app_network_set_custom_mfg_data(MGF_DATA_DEVICE_TYPE_LIGHT, MFG_DATA_DEVICE_SUBTYPE_LIGHT);
|
||||
/* Start the Wi-Fi/Thread.
|
||||
* If the node is provisioned, it will start connection attempts,
|
||||
* else, it will start Wi-Fi provisioning. The function will return
|
||||
* after a connection has been successfully established
|
||||
*/
|
||||
err = app_wifi_start(POP_TYPE_RANDOM);
|
||||
err = app_network_start(POP_TYPE_RANDOM);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not start Wifi. Aborting!!!");
|
||||
ESP_LOGE(TAG, "Could not start network. Aborting!!!");
|
||||
vTaskDelay(5000/portTICK_PERIOD_MS);
|
||||
abort();
|
||||
}
|
||||
|
||||
14
examples/led_light/sdkconfig.defaults.esp32h2
Normal file
14
examples/led_light/sdkconfig.defaults.esp32h2
Normal file
@@ -0,0 +1,14 @@
|
||||
# Enable OpenThread
|
||||
CONFIG_OPENTHREAD_ENABLED=y
|
||||
CONFIG_OPENTHREAD_CLI=n
|
||||
|
||||
# Enable DNS64 client and Network connection resolve hook
|
||||
CONFIG_OPENTHREAD_DNS64_CLIENT=y
|
||||
CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT=y
|
||||
|
||||
# Increase network provisioning scan entries
|
||||
CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=64
|
||||
|
||||
# Use 4MB optimised partition
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_4mb_optimised.csv"
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <esp_rmaker_schedule.h>
|
||||
#include <esp_rmaker_scenes.h>
|
||||
|
||||
#include <app_wifi.h>
|
||||
#include <app_network.h>
|
||||
#include <app_insights.h>
|
||||
|
||||
#include "app_priv.h"
|
||||
@@ -78,10 +78,10 @@ void app_main()
|
||||
|
||||
/* Initialize Wi-Fi. Note that, this should be called before esp_rmaker_node_init()
|
||||
*/
|
||||
app_wifi_init();
|
||||
app_network_init();
|
||||
|
||||
/* Initialize the ESP RainMaker Agent.
|
||||
* Note that this should be called after app_wifi_init() but before app_wifi_start()
|
||||
* Note that this should be called after app_network_init() but before app_network_start()
|
||||
* */
|
||||
esp_rmaker_config_t rainmaker_cfg = {
|
||||
.enable_time_sync = false,
|
||||
@@ -147,7 +147,7 @@ void app_main()
|
||||
* else, it will start Wi-Fi provisioning. The function will return
|
||||
* after a connection has been successfully established
|
||||
*/
|
||||
err = app_wifi_start(POP_TYPE_RANDOM);
|
||||
err = app_network_start(POP_TYPE_RANDOM);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not start Wifi. Aborting!!!");
|
||||
vTaskDelay(5000/portTICK_PERIOD_MS);
|
||||
|
||||
14
examples/multi_device/sdkconfig.defaults.esp32h2
Normal file
14
examples/multi_device/sdkconfig.defaults.esp32h2
Normal file
@@ -0,0 +1,14 @@
|
||||
# Enable OpenThread
|
||||
CONFIG_OPENTHREAD_ENABLED=y
|
||||
CONFIG_OPENTHREAD_CLI=n
|
||||
|
||||
# Enable DNS64 client and Network connection resolve hook
|
||||
CONFIG_OPENTHREAD_DNS64_CLIENT=y
|
||||
CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT=y
|
||||
|
||||
# Increase network provisioning scan entries
|
||||
CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=64
|
||||
|
||||
# Use 4MB optimised partition
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_4mb_optimised.csv"
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <esp_rmaker_common_events.h>
|
||||
|
||||
#include <app_wifi.h>
|
||||
#include <app_network.h>
|
||||
#include <app_insights.h>
|
||||
|
||||
#include "app_priv.h"
|
||||
@@ -100,15 +100,15 @@ static void event_handler(void* arg, esp_event_base_t event_base,
|
||||
default:
|
||||
ESP_LOGW(TAG, "Unhandled RainMaker Common Event: %"PRIi32, event_id);
|
||||
}
|
||||
} else if (event_base == APP_WIFI_EVENT) {
|
||||
} else if (event_base == APP_NETWORK_EVENT) {
|
||||
switch (event_id) {
|
||||
case APP_WIFI_EVENT_QR_DISPLAY:
|
||||
case APP_NETWORK_EVENT_QR_DISPLAY:
|
||||
ESP_LOGI(TAG, "Provisioning QR : %s", (char *)event_data);
|
||||
break;
|
||||
case APP_WIFI_EVENT_PROV_TIMEOUT:
|
||||
case APP_NETWORK_EVENT_PROV_TIMEOUT:
|
||||
ESP_LOGI(TAG, "Provisioning Timed Out. Please reboot.");
|
||||
break;
|
||||
case APP_WIFI_EVENT_PROV_RESTART:
|
||||
case APP_NETWORK_EVENT_PROV_RESTART:
|
||||
ESP_LOGI(TAG, "Provisioning has restarted due to failures.");
|
||||
break;
|
||||
default:
|
||||
@@ -166,16 +166,16 @@ void app_main()
|
||||
|
||||
/* Initialize Wi-Fi. Note that, this should be called before esp_rmaker_node_init()
|
||||
*/
|
||||
app_wifi_init();
|
||||
app_network_init();
|
||||
|
||||
/* Register an event handler to catch RainMaker events */
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(RMAKER_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(RMAKER_COMMON_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(APP_WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(APP_NETWORK_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
ESP_ERROR_CHECK(esp_event_handler_register(RMAKER_OTA_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
|
||||
|
||||
/* Initialize the ESP RainMaker Agent.
|
||||
* Note that this should be called after app_wifi_init() but before app_wifi_start()
|
||||
* Note that this should be called after app_network_init() but before app_nenetworkk_start()
|
||||
* */
|
||||
esp_rmaker_config_t rainmaker_cfg = {
|
||||
.enable_time_sync = false,
|
||||
@@ -240,13 +240,13 @@ void app_main()
|
||||
/* Start the ESP RainMaker Agent */
|
||||
esp_rmaker_start();
|
||||
|
||||
err = app_wifi_set_custom_mfg_data(MGF_DATA_DEVICE_TYPE_SWITCH, MFG_DATA_DEVICE_SUBTYPE_SWITCH);
|
||||
err = app_network_set_custom_mfg_data(MGF_DATA_DEVICE_TYPE_SWITCH, MFG_DATA_DEVICE_SUBTYPE_SWITCH);
|
||||
/* Start the Wi-Fi.
|
||||
* If the node is provisioned, it will start connection attempts,
|
||||
* else, it will start Wi-Fi provisioning. The function will return
|
||||
* after a connection has been successfully established
|
||||
*/
|
||||
err = app_wifi_start(POP_TYPE_RANDOM);
|
||||
err = app_network_start(POP_TYPE_RANDOM);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not start Wifi. Aborting!!!");
|
||||
vTaskDelay(5000/portTICK_PERIOD_MS);
|
||||
|
||||
14
examples/switch/sdkconfig.defaults.esp32h2
Normal file
14
examples/switch/sdkconfig.defaults.esp32h2
Normal file
@@ -0,0 +1,14 @@
|
||||
# Enable OpenThread
|
||||
CONFIG_OPENTHREAD_ENABLED=y
|
||||
CONFIG_OPENTHREAD_CLI=n
|
||||
|
||||
# Enable DNS64 client and Network connection resolve hook
|
||||
CONFIG_OPENTHREAD_DNS64_CLIENT=y
|
||||
CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT=y
|
||||
|
||||
# Increase network provisioning scan entries
|
||||
CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=64
|
||||
|
||||
# Use 4MB optimised partition
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_4mb_optimised.csv"
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <esp_rmaker_standard_params.h>
|
||||
#include <esp_rmaker_standard_devices.h>
|
||||
|
||||
#include <app_wifi.h>
|
||||
#include <app_network.h>
|
||||
#include <app_insights.h>
|
||||
|
||||
#include "app_priv.h"
|
||||
@@ -43,10 +43,10 @@ void app_main()
|
||||
|
||||
/* Initialize Wi-Fi. Note that, this should be called before esp_rmaker_node_init()
|
||||
*/
|
||||
app_wifi_init();
|
||||
app_network_init();
|
||||
|
||||
/* Initialize the ESP RainMaker Agent.
|
||||
* Note that this should be called after app_wifi_init() but before app_wifi_start()
|
||||
* Note that this should be called after app_network_init() but before app_network_start()
|
||||
* */
|
||||
esp_rmaker_config_t rainmaker_cfg = {
|
||||
.enable_time_sync = false,
|
||||
@@ -76,7 +76,7 @@ void app_main()
|
||||
* else, it will start Wi-Fi provisioning. The function will return
|
||||
* after a connection has been successfully established
|
||||
*/
|
||||
err = app_wifi_start(POP_TYPE_RANDOM);
|
||||
err = app_network_start(POP_TYPE_RANDOM);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not start Wifi. Aborting!!!");
|
||||
vTaskDelay(5000/portTICK_PERIOD_MS);
|
||||
|
||||
14
examples/temperature_sensor/sdkconfig.defaults.esp32h2
Normal file
14
examples/temperature_sensor/sdkconfig.defaults.esp32h2
Normal file
@@ -0,0 +1,14 @@
|
||||
# Enable OpenThread
|
||||
CONFIG_OPENTHREAD_ENABLED=y
|
||||
CONFIG_OPENTHREAD_CLI=n
|
||||
|
||||
# Enable DNS64 client and Network connection resolve hook
|
||||
CONFIG_OPENTHREAD_DNS64_CLIENT=y
|
||||
CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT=y
|
||||
|
||||
# Increase network provisioning scan entries
|
||||
CONFIG_NETWORK_PROV_SCAN_MAX_ENTRIES=64
|
||||
|
||||
# Use 4MB optimised partition
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_4mb_optimised.csv"
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <esp_log.h>
|
||||
#include <esp_err.h>
|
||||
#include <nvs_flash.h>
|
||||
#include <app_wifi.h>
|
||||
#include <app_network.h>
|
||||
#include <app_insights.h>
|
||||
#include <esp_app_rainmaker.h>
|
||||
#include <iot_button.h>
|
||||
@@ -302,10 +302,10 @@ void esp_app_rainmaker_main()
|
||||
|
||||
/* Initialize Wi-Fi. Note that, this should be called before esp_rmaker_node_init()
|
||||
*/
|
||||
app_wifi_init();
|
||||
app_network_init();
|
||||
|
||||
/* Initialize the ESP RainMaker Agent.
|
||||
* Note that this should be called after app_wifi_init() but before app_wifi_start()
|
||||
* Note that this should be called after app_network_init() but before app_network_start()
|
||||
* */
|
||||
esp_rmaker_config_t rainmaker_cfg = {
|
||||
.enable_time_sync = false,
|
||||
@@ -349,7 +349,7 @@ void esp_app_rainmaker_main()
|
||||
* else, it will start Wi-Fi provisioning. The function will return
|
||||
* after a connection has been successfully established
|
||||
*/
|
||||
err = app_wifi_start(POP_TYPE_RANDOM);
|
||||
err = app_network_start(POP_TYPE_RANDOM);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Could not start Wifi. Aborting!!!");
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
|
||||
Reference in New Issue
Block a user