diff --git a/examples/provisioning/README.md b/examples/provisioning/README.md index 98134d411..4a755e3f5 100644 --- a/examples/provisioning/README.md +++ b/examples/provisioning/README.md @@ -3,7 +3,7 @@ This primarily consists of a single unified example wifi_prov_mgr * wifi_prov_mgr - Abstracts out most of the complexity of Wi-Fi provisioning and allows easy switching between the SoftAP (using HTTP) and BLE transports. + Abstracts out most of the complexity of Wi-Fi provisioning and allows easy switching between the SoftAP (using HTTP) and BLE transports. It also demonstrates how applications can register and use additional custom data endpoints. Provisioning applications are available for various platforms: diff --git a/examples/provisioning/legacy/console_prov/CMakeLists.txt b/examples/provisioning/legacy/console_prov/CMakeLists.txt index 5352f1e19..654200588 100644 --- a/examples/provisioning/legacy/console_prov/CMakeLists.txt +++ b/examples/provisioning/legacy/console_prov/CMakeLists.txt @@ -2,6 +2,5 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -set(SUPPORTED_TARGETS esp32) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(console_prov) diff --git a/examples/provisioning/legacy/custom_config/CMakeLists.txt b/examples/provisioning/legacy/custom_config/CMakeLists.txt index ca8359f82..ec9b0ce66 100644 --- a/examples/provisioning/legacy/custom_config/CMakeLists.txt +++ b/examples/provisioning/legacy/custom_config/CMakeLists.txt @@ -2,6 +2,5 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -set(SUPPORTED_TARGETS esp32) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(custom_config) diff --git a/examples/provisioning/legacy/softap_prov/CMakeLists.txt b/examples/provisioning/legacy/softap_prov/CMakeLists.txt index e63c8e4ed..fa6ac1433 100644 --- a/examples/provisioning/legacy/softap_prov/CMakeLists.txt +++ b/examples/provisioning/legacy/softap_prov/CMakeLists.txt @@ -2,6 +2,5 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -set(SUPPORTED_TARGETS esp32) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(softap_prov) diff --git a/examples/provisioning/wifi_prov_mgr/CMakeLists.txt b/examples/provisioning/wifi_prov_mgr/CMakeLists.txt index a628955d3..b036d9ce6 100644 --- a/examples/provisioning/wifi_prov_mgr/CMakeLists.txt +++ b/examples/provisioning/wifi_prov_mgr/CMakeLists.txt @@ -2,6 +2,5 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -set(SUPPORTED_TARGETS esp32) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(wifi_prov_mgr) diff --git a/examples/provisioning/wifi_prov_mgr/README.md b/examples/provisioning/wifi_prov_mgr/README.md index d514d7bde..e9c811248 100644 --- a/examples/provisioning/wifi_prov_mgr/README.md +++ b/examples/provisioning/wifi_prov_mgr/README.md @@ -4,7 +4,9 @@ `wifi_prov_mgr` example demonstrates the usage of `wifi_provisioning` manager component for building a provisioning application. -For this example BLE is chosen as the mode of transport, over which the provisioning related communication is to take place, between the device (to be provisioned) and the client (owner of the device). +For this example, BLE is chosen as the default mode of transport, over which the provisioning related communication is to take place. NimBLE has been configured as the default host, but you can also switch to Bluedroid using menuconfig -> Components -> Bluetooth -> Bluetooth Host. + +> Note: Since ESP32-S2 does not support BLE, the SoftAP will be the default mode of transport in that case. Even for ESP32, you can change to SoftAP transport from menuconfig. In the provisioning process the device is configured as a Wi-Fi station with specified credentials. Once configured, the device will retain the Wi-Fi configuration, until a flash erase is performed. @@ -22,7 +24,7 @@ This example can be used, as it is, for adding a provisioning service to any app ### Hardware Required -Example should be able to run on any commonly available ESP32 development board. +Example should be able to run on any commonly available ESP32/ESP32-S2 development board. ### Application Required @@ -49,7 +51,7 @@ There are various applications, specific to Windows and macOS platform which can ``` idf.py menuconfig ``` - +* Set the BLE/Soft AP transport under "Example Configuration" options. ESP32-S2 will have only SoftAP option. * Set serial port under Serial Flasher Options. ### Build and Flash @@ -157,6 +159,26 @@ Enter passphrase for MyHomeWiFiAP : ==== Provisioning was successful ==== ``` +### Sending Custom Data + +The provisioning manager allows applications to send some custom data during provisioning, which may be +required for some other operations like connecting to some cloud service. This is achieved by creating +and registering additional endpoints using the below APIs + +``` +wifi_prov_mgr_endpoint_create(); +wifi_prov_mgr_endpoint_register(); +``` + +In this particular example, we have added an endpoint named "custom-data" which can be tested +by passing the `--custom_data ` option to the esp\_prov tool. Following output is +expected on success: + +``` +==== Sending Custom data to esp32 ==== +CustomData response: SUCCESS +``` + ## Troubleshooting ### Provisioning failed diff --git a/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild b/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild new file mode 100644 index 000000000..3cd03d66b --- /dev/null +++ b/examples/provisioning/wifi_prov_mgr/main/Kconfig.projbuild @@ -0,0 +1,22 @@ +menu "Example Configuration" + + choice EXAMPLE_PROV_TRANSPORT + bool "Provisioning Transport" + default EXAMPLE_PROV_TRANSPORT_BLE + help + Wi-Fi provisioning component offers both, SoftAP and BLE transports. Choose any one. + + config EXAMPLE_PROV_TRANSPORT_BLE + bool "BLE" + select BT_ENABLED + depends on IDF_TARGET_ESP32 + config EXAMPLE_PROV_TRANSPORT_SOFTAP + bool "Soft AP" + endchoice + + config EXAMPLE_PROV_TRANSPORT + int + default 1 if EXAMPLE_PROV_TRANSPORT_BLE + default 2 if EXAMPLE_PROV_TRANSPORT_SOFTAP + +endmenu diff --git a/examples/provisioning/wifi_prov_mgr/main/app_main.c b/examples/provisioning/wifi_prov_mgr/main/app_main.c index 53ea813ea..109fffac1 100644 --- a/examples/provisioning/wifi_prov_mgr/main/app_main.c +++ b/examples/provisioning/wifi_prov_mgr/main/app_main.c @@ -20,8 +20,14 @@ #include #include + +#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_BLE #include +#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_BLE */ + +#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP #include +#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP */ static const char *TAG = "app"; @@ -93,6 +99,27 @@ static void get_device_service_name(char *service_name, size_t max) ssid_prefix, eth_mac[3], eth_mac[4], eth_mac[5]); } +/* Handler for the optional provisioning endpoint registered by the application. + * The data format can be chosen by applications. Here, we are using plain ascii text. + * Applications can choose to use other formats like protobuf, JSON, XML, etc. + */ +esp_err_t custom_prov_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, + uint8_t **outbuf, ssize_t *outlen, void *priv_data) +{ + if (inbuf) { + ESP_LOGI(TAG, "Received data: %.*s", inlen, (char *)inbuf); + } + char response[] = "SUCCESS"; + *outbuf = (uint8_t *)strdup(response); + if (*outbuf == NULL) { + ESP_LOGE(TAG, "System out of memory"); + return ESP_ERR_NO_MEM; + } + *outlen = strlen(response) + 1; /* +1 for NULL terminating byte */ + + return ESP_OK; +} + void app_main(void) { /* Initialize NVS partition */ @@ -120,6 +147,9 @@ void app_main(void) /* Initialize Wi-Fi including netif with default config */ esp_netif_create_default_wifi_sta(); +#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP + esp_netif_create_default_wifi_ap(); +#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP */ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); @@ -127,7 +157,12 @@ void app_main(void) 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_EXAMPLE_PROV_TRANSPORT_BLE .scheme = wifi_prov_scheme_ble, +#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_BLE */ +#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP + .scheme = wifi_prov_scheme_softap, +#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP */ /* Any default scheme specific event handler that you would * like to choose. Since our example application requires @@ -137,7 +172,12 @@ void app_main(void) * 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_EXAMPLE_PROV_TRANSPORT_BLE .scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM +#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_BLE */ +#ifdef CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP + .scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE +#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_SOFTAP */ }; /* Initialize provisioning manager with the @@ -181,6 +221,7 @@ void app_main(void) */ const char *service_key = NULL; +#ifdef CONFIG_EXAMPLE_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 @@ -197,10 +238,23 @@ void app_main(void) 0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12 }; wifi_prov_scheme_ble_set_service_uuid(custom_service_uuid); +#endif /* CONFIG_EXAMPLE_PROV_TRANSPORT_BLE */ + /* An optional endpoint that applications can create if they expect to + * get some additional custom data during provisioning workflow. + * The endpoint name can be anything of your choice. + * This call must be made before starting the provisioning. + */ + wifi_prov_mgr_endpoint_create("custom-data"); /* Start provisioning service */ ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning(security, pop, service_name, service_key)); + /* The handler for the optional endpoint created above. + * This call must be made after starting the provisioning, and only if the endpoint + * has already been created above. + */ + wifi_prov_mgr_endpoint_register("custom-data", custom_prov_data_handler, NULL); + /* Uncomment the following to wait for the provisioning to finish and then release * the resources of the manager. Since in this case de-initialization is triggered * by the default event loop handler, we don't need to call the following */ diff --git a/examples/provisioning/wifi_prov_mgr/wifi_prov_mgr_test.py b/examples/provisioning/wifi_prov_mgr/wifi_prov_mgr_test.py index 881fa9d60..c0f4770f2 100644 --- a/examples/provisioning/wifi_prov_mgr/wifi_prov_mgr_test.py +++ b/examples/provisioning/wifi_prov_mgr/wifi_prov_mgr_test.py @@ -29,7 +29,7 @@ esp_prov.config_throw_except = True @ttfw_idf.idf_example_test(env_tag="Example_WIFI_BT") def test_examples_wifi_prov_mgr(env, extra_data): # Acquire DUT - dut1 = env.get_dut("wifi_prov_mgr", "examples/provisioning/manager", dut_class=ttfw_idf.ESP32DUT) + dut1 = env.get_dut("wifi_prov_mgr", "examples/provisioning/wifi_prov_mgr", dut_class=ttfw_idf.ESP32DUT) # Get binary file binary_file = os.path.join(dut1.app.binary_path, "wifi_prov_mgr.bin") @@ -78,6 +78,10 @@ def test_examples_wifi_prov_mgr(env, extra_data): if not esp_prov.establish_session(transport, security): raise RuntimeError("Failed to start session") + print("Sending Custom Data") + if not esp_prov.custom_data(transport, security, "My Custom Data"): + raise RuntimeError("Failed to send custom data") + print("Sending Wifi credential to DUT") if not esp_prov.send_wifi_config(transport, security, ap_ssid, ap_password): raise RuntimeError("Failed to send Wi-Fi config")