diff --git a/examples/provisioning/legacy/ble_prov/CMakeLists.txt b/examples/provisioning/legacy/ble_prov/CMakeLists.txt deleted file mode 100644 index d4924bb7c7..0000000000 --- a/examples/provisioning/legacy/ble_prov/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# The following lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) -set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/qrcode) -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(ble_prov) diff --git a/examples/provisioning/legacy/ble_prov/README.md b/examples/provisioning/legacy/ble_prov/README.md deleted file mode 100644 index 3e6afa8879..0000000000 --- a/examples/provisioning/legacy/ble_prov/README.md +++ /dev/null @@ -1,243 +0,0 @@ -| Supported Targets | ESP32 | -| ----------------- | ----- | - -# BLE based Provisioning Example (Legacy) - -> Note: It is recommended to use the new `wifi_prov_mgr` example which is based on the simpler `wifi_provisioning` APIs. Check this example only if you wish to use lower level provisioning and protocomm APIs and want more control over the handlers. - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - -`ble_prov` example demonstrates the implementation and integration of various IDF components 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). - -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. - -Right after provisioning is complete, BLE is turned off and disabled to free the memory used by the BLE stack. Though, that is specific to this example, and the user can choose to keep BLE on in their own application. - -`ble_prov` uses the following components : -* `wifi_provisioning` : provides data structures and protocomm endpoint handlers for Wi-Fi configuration -* `protocomm` : for protocol based communication and secure session establishment -* `protobuf` : Google's protocol buffer library for serialization of protocomm data structures -* `bt` : ESP32 BLE stack for transport of protobuf packets - -This example can be used, as it is, for adding a provisioning service to any application intended for IoT. - -## How to use example - -### Hardware Required - -Example should be able to run on any commonly available ESP32 development board. - -### Application Required - -Provisioning applications are available for various platforms. See below - -#### Platform : Android - -For Android, a provisioning application along with source code is available on GitHub : [esp-idf-provisioning-android](https://github.com/espressif/esp-idf-provisioning-android) - -#### Platform : iOS - -For iOS, a provisioning application along with source code is available on GitHub : [esp-idf-provisioning-ios](https://github.com/espressif/esp-idf-provisioning-ios) - -#### Platform : Linux / Windows / macOS - -To provision the device running this example, the `esp_prov.py` script needs to be run (found under `$IDF_PATH/tools/esp_prov`). Make sure to satisfy all the dependencies prior to running the script. - -Presently, `esp_prov` supports BLE transport only for Linux platform. For Windows/macOS it falls back to console mode and requires another application (for BLE) through which the communication can take place. - -There are various applications, specific to Windows and macOS platform which can be used. The `esp_prov` console will guide you through the provisioning process of locating the correct BLE GATT services and characteristics, the values to write, and input read values. - -### Configure the project - -``` -idf.py menuconfig -``` - -* Under Example Configuration set the following : - * Security Version (default 1) - * Proof of Possession (default "abcd1234") - -### Build and Flash - -Build the project and flash it to the board, then run monitor tool to view serial output: - -``` -idf.py -p PORT flash monitor -``` - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -``` -I (550) app: Starting BLE provisioning -I (1130) app_prov: Provisioning started with BLE devname : PROV_261FCC -``` - -Make sure to note down the BLE device name (starting with PROV_) displayed in the serial monitor log (eg. PROV_261FCC). This will depend on the MAC ID and will be unique for every device. - -In a separate terminal run the `esp_prov.py` script under `$IDP_PATH/tools/esp_prov` directory (please replace `myssid` and `mypassword` with the credentials of the AP to which the device is supposed to connect to after provisioning). Assuming default example configuration : - -``` -python esp_prov.py --transport ble --service_name PROV_261FCC --sec_ver 1 --pop abcd1234 --ssid myssid --passphrase mypassword -``` - -Above command will perform the provisioning steps, and the monitor log should display something like this : - -``` -I (682950) app_prov_handler: WiFi Credentials Received : - ssid : myssid - password : mypassword -. -. -. -I (683130) app_prov: STA Start -I (683130) app_prov_handler: WiFi Credentials Applied -. -. -. -I (688270) app_prov_handler: Connecting state -. -. -. -I (688390) app_prov: STA Got IP -I (688390) app: got ip:192.168.43.220 -I (693410) app_prov_handler: Connected state -``` - -After sometime the provisioning app will exit and BLE will be turned off - -``` -I (718390) app_prov: Stopping provisioning -I (718670) app_prov: Provisioning stopped -``` - -## QR Code Scanning - -Enabling `CONFIG_EXAMPLE_PROV_SHOW_QR` will display a QR code on the serial terminal, which can be scanned from the ESP Provisioning phone apps to start the Wi-Fi provisioning process. - -The monitor log should display something like this : - -``` -I (1640) app_prov: SoftAP Provisioning started with SSID 'PROV_EA69FC', Password 'PROV_PASS' -I (1640) app: Scan this QR code from the provisioning application for Provisioning. -I (1650) QRCODE: Encoding below text with ECC LVL 0 & QR Code Version 10 -I (1660) QRCODE: {"ver":"v1","name":"PROV_EA69FC","pop":"abcd1234","transport":"ble"} - - █▀▀▀▀▀█ ▄▀ ▄█ ▄█▄▄█▀▄ ██ █▀▀▀▀▀█ - █ ███ █ ▀███▀ ██▀▀█ ▀█▀ █ ███ █ - █ ▀▀▀ █ █▄ ▄ ▀███ ▄▄█▀ ▄ █ ▀▀▀ █ - ▀▀▀▀▀▀▀ █▄▀ █ ▀ ▀▄█▄▀▄▀▄█ ▀▀▀▀▀▀▀ - ▀▀▄▀▄▄▀█ █▄ ▀▄▀█▄█ ▄▄ ██▄█▀▀▄▀▀▄ - ███ █▀▀ ▄▀▀ ▄█▄ ▀▀█▄█▀▄▄ ▄█ █ - ▄▀▀ ▀▀▀█▀▄▄▄█▀▀ ██▄█▄▄█▄▀█ ▄▄ ▀█ - ▄█▄█ ▀▀▄█ ██ ▄█ ██▀█▀ ▄█ █▄ - ▄█▀█▀ █▄▀▀▄ █▀█▀██ ▄█▀ ▀▀▄ ▀ - █▄▄█▄▀█▄▄▀▄▄▀█ ▀▄ ▄▀██ ▄ █▄▄▄ ▀█ - ▀▄▀▄▀▀▀█ ▄ ▄▀▀▀█▄▀▀▀▀▀▄█ ▄▄ █ ▄▄ - ▀█▄▀██▀▄▄ ▄▄▀▄ ▄▀▀▀▀█▄▀▄▀█ ▄▄ ▀▀ - ▀ ▀ ▀ ▀▀█▄▀ ▀▀ ▀▀▀▄▀██ █▀▀▀█▀ ▄▄ - █▀▀▀▀▀█ ▀▀██▀█▀ ▀█ ▄ █▀▀█ ▀ ██ ▀▄ - █ ███ █ ▄█▀▄▄▄ █▀▀▀ ██ ▀████▀ ▄█ - █ ▀▀▀ █ ▄▀▄▄ ▄▀█▀▄▄▄█ ▀ ▄▀█▀▀▀ - ▀▀▀▀▀▀▀ ▀ ▀▀▀▀ ▀ ▀ ▀ ▀ ▀▀ ▀ - - -I (1870) app: If QR code is not visible, copy paste the below URL in a browser. -https://espressif.github.io/esp-jumpstart/qrcode.html?data={"ver":"v1","name":"PROV_EA69FC","pop":"abcd1234","transport":"ble"} -``` - -## Troubleshooting - -### Provisioning failed - -It is possible that the Wi-Fi credentials provided were incorrect, or the device was not able to establish connection to the network, in which the the `esp_prov` script will notify failure (with reason) and the provisioning app will continue running, allowing the user to retry the process. Serial monitor log will display the failure along with disconnect reason : - -``` -E (39291) app_prov: STA Disconnected -E (39291) app_prov: Disconnect reason : 201 -I (39291) app_prov: STA AP Not found -I (42021) app_prov_handler: Disconnected state -``` - -### Provisioning does not start - -If the serial monitor log is different, as shown below : - -``` -I (539) app_prov: Found ssid myssid -I (539) app_prov: Found password mypassword -I (549) app: Starting WiFi station -``` - -It means the Wi-Fi credentials were already set by some other application flashed previously to your device. To erase these credentials either do full erase and then flash the example - -``` -make erase_flash -idf.py -p PORT flash monitor -``` - -Or, enable `Reset Provisioning` option under `Example Configuration` under menuconfig. But this will erase the saved Wi-Fi credentials every time the device boots, so this is not the preferred solution. - -### Unsupported platform - -If the platform requirement, for running `esp_prov` is not satisfied, then the script execution will fallback to console mode, in which case the full process (involving user inputs) will look like this : - -``` -BLE client is running in console mode - This could be due to your platform not being supported or dependencies not being met - Please ensure all pre-requisites are met to run the full fledged client -BLECLI >> Please connect to BLE device `PROV_261FCC` manually using your tool of choice -BLECLI >> Was the device connected successfully? [y/n] y -BLECLI >> List available attributes of the connected device -BLECLI >> Is the service UUID '0000ffff-0000-1000-8000-00805f9b34fb' listed among available attributes? [y/n] y -BLECLI >> Is the characteristic UUID '0000ff53-0000-1000-8000-00805f9b34fb' listed among available attributes? [y/n] y -BLECLI >> Is the characteristic UUID '0000ff51-0000-1000-8000-00805f9b34fb' listed among available attributes? [y/n] y -BLECLI >> Is the characteristic UUID '0000ff52-0000-1000-8000-00805f9b34fb' listed among available attributes? [y/n] y - -==== Verifying protocol version ==== -BLECLI >> Write following data to characteristic with UUID '0000ff53-0000-1000-8000-00805f9b34fb' : - >> 56302e31 -BLECLI >> Enter data read from characteristic (in hex) : - << 53554343455353 -==== Verified protocol version successfully ==== - -==== Starting Session ==== -BLECLI >> Write following data to characteristic with UUID '0000ff51-0000-1000-8000-00805f9b34fb' : - >> 10015a25a201220a20ae6d9d5d1029f8c366892252d2d5a0ffa7ce1ee5829312545dd5f2aba057294d -BLECLI >> Enter data read from characteristic (in hex) : - << 10015a390801aa0134122048008bfc365fad4753dc75912e0c764d60749cb26dd609595b6fbc72e12614031a1089733af233c7448e7d7fb7963682c6d8 -BLECLI >> Write following data to characteristic with UUID '0000ff51-0000-1000-8000-00805f9b34fb' : - >> 10015a270802b2012212204051088dc294fe4621fac934a8ea22e948fcc3e8ac458aac088ce705c65dbfb9 -BLECLI >> Enter data read from characteristic (in hex) : - << 10015a270803ba01221a20c8d38059d5206a3d92642973ac6ba8ac2f6ecf2b7a3632964eb35a0f20133adb -==== Session Established ==== - -==== Sending Wifi credential to esp32 ==== -BLECLI >> Write following data to characteristic with UUID '0000ff52-0000-1000-8000-00805f9b34fb' : - >> 98471ac4019a46765c28d87df8c8ae71c1ae6cfe0bc9c615bc6d2c -BLECLI >> Enter data read from characteristic (in hex) : - << 3271f39a -==== Wifi Credentials sent successfully ==== - -==== Applying config to esp32 ==== -BLECLI >> Write following data to characteristic with UUID '0000ff52-0000-1000-8000-00805f9b34fb' : - >> 5355 -BLECLI >> Enter data read from characteristic (in hex) : - << 1664db24 -==== Apply config sent successfully ==== - -==== Wifi connection state ==== -BLECLI >> Write following data to characteristic with UUID '0000ff52-0000-1000-8000-00805f9b34fb' : - >> 290d -BLECLI >> Enter data read from characteristic (in hex) : - << 505f72a9f8521025c1964d7789c4d7edc56aedebd144e1b667bc7c0975757b80cc091aa9f3e95b06eaefbc30290fa1 -++++ WiFi state: connected ++++ -==== Provisioning was successful ==== -``` - -The write data is to be copied from the console output ```>>``` to the platform specific application and the data read from the application is to be pasted at the user input prompt ```<<``` of the console, in the format (hex) indicated in above sample log. diff --git a/examples/provisioning/legacy/ble_prov/ble_prov_test.py b/examples/provisioning/legacy/ble_prov/ble_prov_test.py deleted file mode 100644 index ba09b9ee2f..0000000000 --- a/examples/provisioning/legacy/ble_prov/ble_prov_test.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2018 Espressif Systems (Shanghai) PTE LTD -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import print_function - -import os -import re - -import esp_prov -import ttfw_idf - -# Have esp_prov throw exception -esp_prov.config_throw_except = True - - -@ttfw_idf.idf_example_test(env_tag='Example_WIFI_BT') -def test_examples_provisioning_ble(env, extra_data): - # Acquire DUT - dut1 = env.get_dut('ble_prov', 'examples/provisioning/legacy/ble_prov', dut_class=ttfw_idf.ESP32DUT) - - # Get binary file - binary_file = os.path.join(dut1.app.binary_path, 'ble_prov.bin') - bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance('ble_prov_bin_size', '{}KB'.format(bin_size // 1024)) - - # Upload binary and start testing - dut1.start_app() - - # Parse BLE devname - devname = dut1.expect(re.compile(r"Provisioning started with BLE devname : '(PROV_\S\S\S\S\S\S)'"), timeout=60)[0] - print('BLE Device Alias for DUT :', devname) - - # Match additional headers sent in the request - dut1.expect('BLE Provisioning started', timeout=30) - - print('Starting Provisioning') - verbose = False - protover = 'V0.1' - secver = 1 - pop = 'abcd1234' - provmode = 'ble' - ap_ssid = 'myssid' - ap_password = 'mypassword' - - print('Getting security') - security = esp_prov.get_security(secver, pop, verbose) - if security is None: - raise RuntimeError('Failed to get security') - - print('Getting transport') - transport = esp_prov.get_transport(provmode, devname) - if transport is None: - raise RuntimeError('Failed to get transport') - - print('Verifying protocol version') - if not esp_prov.version_match(transport, protover): - raise RuntimeError('Mismatch in protocol version') - - print('Starting Session') - if not esp_prov.establish_session(transport, security): - raise RuntimeError('Failed to start session') - - 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') - - print('Applying config') - if not esp_prov.apply_wifi_config(transport, security): - raise RuntimeError('Failed to send apply config') - - if not esp_prov.wait_wifi_connected(transport, security): - raise RuntimeError('Provisioning failed') - - -if __name__ == '__main__': - test_examples_provisioning_ble() diff --git a/examples/provisioning/legacy/ble_prov/main/CMakeLists.txt b/examples/provisioning/legacy/ble_prov/main/CMakeLists.txt deleted file mode 100644 index dae207e87f..0000000000 --- a/examples/provisioning/legacy/ble_prov/main/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -idf_component_register(SRCS "app_main.c" - "app_prov.c" - "app_prov_handlers.c" - INCLUDE_DIRS ".") diff --git a/examples/provisioning/legacy/ble_prov/main/Kconfig.projbuild b/examples/provisioning/legacy/ble_prov/main/Kconfig.projbuild deleted file mode 100644 index a4dbb7fbbb..0000000000 --- a/examples/provisioning/legacy/ble_prov/main/Kconfig.projbuild +++ /dev/null @@ -1,53 +0,0 @@ -menu "Example Configuration" - - config EXAMPLE_USE_SEC_1 - bool - default y - prompt "Use Security Version 1" - help - Security version 1 used Curve25519 key exchange for establishing - secure session between device and client during provisioning - - config EXAMPLE_USE_POP - bool - depends on EXAMPLE_USE_SEC_1 - default y - prompt "Use proof-of-possession" - help - Proof-of-possession can be optionally used to prove that the device is indeed - in possession of the user who is provisioning the device. This proof-of-possession - is internally used to generate the shared secret through key exchange. - - config EXAMPLE_POP - string "Proof-of-possession" - default "abcd1234" - depends on EXAMPLE_USE_POP - - config EXAMPLE_RESET_PROVISIONED - bool - default n - prompt "Reset provisioned status of the device" - help - This erases the NVS to reset provisioned status of the device on every reboot. - Provisioned status is determined by the Wi-Fi STA configuration, saved on the NVS. - - config EXAMPLE_AP_RECONN_ATTEMPTS - int "Maximum AP connection attempts" - default 5 - help - Set the maximum connection attempts to perform when connecting to a Wi-Fi AP. - - config EXAMPLE_PROV_SHOW_QR - bool "Show provisioning QR code" - default y - help - Show the QR code for provisioning. - - config EXAMPLE_PROV_USING_BLUEDROID - bool - depends on (BT_BLUEDROID_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3)) - select BT_BLE_42_FEATURES_SUPPORTED - default y - help - This enables BLE 4.2 features for Bluedroid. -endmenu diff --git a/examples/provisioning/legacy/ble_prov/main/app_main.c b/examples/provisioning/legacy/ble_prov/main/app_main.c deleted file mode 100644 index efa5f72679..0000000000 --- a/examples/provisioning/legacy/ble_prov/main/app_main.c +++ /dev/null @@ -1,185 +0,0 @@ -/* BLE based Provisioning Example - - 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "app_prov.h" -#include "qrcode.h" - -#define EXAMPLE_AP_RECONN_ATTEMPTS CONFIG_EXAMPLE_AP_RECONN_ATTEMPTS -#define PROV_QR_VERSION "v1" -#define PROV_TRANSPORT_BLE "ble" -#define QRCODE_BASE_URL "https://espressif.github.io/esp-jumpstart/qrcode.html" - -static const char *TAG = "app"; - -static void start_ble_provisioning(void); - -static void event_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) -{ - static int s_retry_num_ap_not_found = 0; - static int s_retry_num_ap_auth_fail = 0; - - 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) { - wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; - switch (disconnected->reason) { - case WIFI_REASON_AUTH_EXPIRE: - case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: - case WIFI_REASON_BEACON_TIMEOUT: - case WIFI_REASON_AUTH_FAIL: - case WIFI_REASON_ASSOC_FAIL: - case WIFI_REASON_HANDSHAKE_TIMEOUT: - ESP_LOGW(TAG, "connect to the AP fail : auth Error"); - if (s_retry_num_ap_auth_fail < EXAMPLE_AP_RECONN_ATTEMPTS) { - s_retry_num_ap_auth_fail++; - esp_wifi_connect(); - ESP_LOGI(TAG, "retry connecting to the AP..."); - } else { - /* Restart provisioning if authentication fails */ - start_ble_provisioning(); - } - break; - case WIFI_REASON_NO_AP_FOUND: - ESP_LOGW(TAG, "connect to the AP fail : not found"); - if (s_retry_num_ap_not_found < EXAMPLE_AP_RECONN_ATTEMPTS) { - s_retry_num_ap_not_found++; - esp_wifi_connect(); - ESP_LOGI(TAG, "retry to connecting to the AP..."); - } - break; - default: - /* None of the expected reasons */ - esp_wifi_connect(); - break; - } - } 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, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); - s_retry_num_ap_not_found = 0; - s_retry_num_ap_auth_fail = 0; - } -} - -static void wifi_init_sta(void) -{ - /* Set our event handling */ - 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)); - - /* Start Wi-Fi in station mode with credentials set during provisioning */ - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -static void start_ble_provisioning(void) -{ - /* Security version */ - int security = 0; - /* Proof of possession */ - const protocomm_security_pop_t *pop = NULL; - -#ifdef CONFIG_EXAMPLE_USE_SEC_1 - security = 1; -#endif - - /* Having proof of possession is optional */ -#ifdef CONFIG_EXAMPLE_USE_POP - const static protocomm_security_pop_t app_pop = { - .data = (uint8_t *) CONFIG_EXAMPLE_POP, - .len = (sizeof(CONFIG_EXAMPLE_POP)-1) - }; - pop = &app_pop; -#endif - - ESP_ERROR_CHECK(app_prov_start_ble_provisioning(security, pop)); -} - -static void get_device_service_name(char *service_name, size_t max) -{ - uint8_t eth_mac[6]; - const char *ssid_prefix = "PROV_"; - 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]); -} - -static void ble_prov_print_qr(void) -{ - char payload[150] = {0}; - char name[12] = {0}; - char *pop = NULL; -#ifdef CONFIG_EXAMPLE_USE_POP - pop = CONFIG_EXAMPLE_POP; -#endif - get_device_service_name(name, sizeof(name)); - if (pop) { - snprintf(payload, sizeof(payload), "{\"ver\":\"%s\",\"name\":\"%s\"" \ - ",\"pop\":\"%s\",\"transport\":\"%s\"}", - PROV_QR_VERSION, name, pop, PROV_TRANSPORT_BLE); - } else { - snprintf(payload, sizeof(payload), "{\"ver\":\"%s\",\"name\":\"%s\"" \ - ",\"transport\":\"%s\"}", - PROV_QR_VERSION, name, PROV_TRANSPORT_BLE); - } -#ifdef CONFIG_EXAMPLE_PROV_SHOW_QR - ESP_LOGI(TAG, "Scan this QR code from the provisioning application for Provisioning."); - esp_qrcode_config_t cfg = ESP_QRCODE_CONFIG_DEFAULT(); - esp_qrcode_generate(&cfg, 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); -} - -void app_main(void) -{ - /* Initialize networking stack */ - ESP_ERROR_CHECK(esp_netif_init()); - - /* Create default event loop needed by the - * main app and the provisioning service */ - ESP_ERROR_CHECK(esp_event_loop_create_default()); - - /* Initialize NVS needed by Wi-Fi */ - ESP_ERROR_CHECK(nvs_flash_init()); - - /* Initialize Wi-Fi including netif with default config */ - esp_netif_create_default_wifi_sta(); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - - /* Check if device is provisioned */ - bool provisioned; - if (app_prov_is_provisioned(&provisioned) != ESP_OK) { - ESP_LOGE(TAG, "Error getting device provisioning state"); - return; - } - - if (provisioned == false) { - /* If not provisioned, start provisioning via BLE */ - ESP_LOGI(TAG, "Starting BLE provisioning"); - start_ble_provisioning(); - ble_prov_print_qr(); - } else { - /* Else start as station with credentials set during provisioning */ - ESP_LOGI(TAG, "Starting WiFi station"); - wifi_init_sta(); - } -} diff --git a/examples/provisioning/legacy/ble_prov/main/app_prov.c b/examples/provisioning/legacy/ble_prov/main/app_prov.c deleted file mode 100644 index 5c0b0e13b6..0000000000 --- a/examples/provisioning/legacy/ble_prov/main/app_prov.c +++ /dev/null @@ -1,389 +0,0 @@ -/* BLE based Provisioning Example - - 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_BT_NIMBLE_ENABLED -#include "esp_nimble_hci.h" -#include "nimble/nimble_port.h" -#include "nimble/nimble_port_freertos.h" -#include "host/ble_hs.h" -#endif - -#include -#include -#include -#include -#include - -#include "app_prov.h" - -static const char *TAG = "app_prov"; -static const char *ssid_prefix = "PROV_"; - -/* Handler for catching WiFi events */ -static void app_prov_event_handler(void* handler_arg, esp_event_base_t base, int32_t id, void* data); - -/* Handlers for wifi_config provisioning endpoint */ -extern wifi_prov_config_handlers_t wifi_prov_handlers; - -/** - * @brief Data relevant to provisioning application - */ -struct app_prov_data { - protocomm_t *pc; /*!< Protocomm handler */ - int security; /*!< Type of security to use with protocomm */ - const protocomm_security_pop_t *pop; /*!< Pointer to proof of possession */ - esp_timer_handle_t timer; /*!< Handle to timer */ - - /* State of WiFi Station */ - wifi_prov_sta_state_t wifi_state; - - /* Code for WiFi station disconnection (if disconnected) */ - wifi_prov_sta_fail_reason_t wifi_disconnect_reason; -}; - -/* Pointer to provisioning application data */ -static struct app_prov_data *g_prov; - -static esp_err_t app_prov_start_service(void) -{ - /* Create new protocomm instance */ - g_prov->pc = protocomm_new(); - if (g_prov->pc == NULL) { - ESP_LOGE(TAG, "Failed to create new protocomm instance"); - return ESP_FAIL; - } - - /* Endpoint UUIDs */ - protocomm_ble_name_uuid_t nu_lookup_table[] = { - {"prov-session", 0x0001}, - {"prov-config", 0x0002}, - {"proto-ver", 0x0003}, - }; - - /* Config for protocomm_ble_start() */ - protocomm_ble_config_t config = { - .service_uuid = { - /* LSB <--------------------------------------- - * ---------------------------------------> MSB */ - 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf, - 0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02, - }, - .nu_lookup_count = sizeof(nu_lookup_table)/sizeof(nu_lookup_table[0]), - .nu_lookup = nu_lookup_table - }; - - /* With the above selection of 128bit primary service UUID and - * 16bit endpoint UUIDs, the 128bit characteristic UUIDs will be - * formed by replacing the 12th and 13th bytes of the service UUID - * with the 16bit endpoint UUID, i.e. : - * service UUID : 021a9004-0382-4aea-bff4-6b3f1c5adfb4 - * masked base : 021a____-0382-4aea-bff4-6b3f1c5adfb4 - * ------------------------------------------------------ - * resulting characteristic UUIDs : - * 1) prov-session : 021a0001-0382-4aea-bff4-6b3f1c5adfb4 - * 2) prov-config : 021a0002-0382-4aea-bff4-6b3f1c5adfb4 - * 3) proto-ver : 021a0003-0382-4aea-bff4-6b3f1c5adfb4 - * - * Also, note that each endpoint (characteristic) will have - * an associated "Characteristic User Description" descriptor - * with 16bit UUID 0x2901, each containing the corresponding - * endpoint name. These descriptors can be used by a client - * side application to figure out which characteristic is - * mapped to which endpoint, without having to hardcode the - * UUIDs */ - - uint8_t eth_mac[6]; - esp_wifi_get_mac(WIFI_IF_STA, eth_mac); - snprintf(config.device_name, sizeof(config.device_name), "%s%02X%02X%02X", - ssid_prefix, eth_mac[3], eth_mac[4], eth_mac[5]); - - /* Release BT memory, as we need only BLE */ - esp_err_t err = esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); - if (err) { - ESP_LOGE(TAG, "bt_controller_mem_release failed %d", err); - if (err != ESP_ERR_INVALID_STATE) { - return err; - } - } - - /* Start protocomm layer on top of BLE */ - if (protocomm_ble_start(g_prov->pc, &config) != ESP_OK) { - ESP_LOGE(TAG, "Failed to start BLE provisioning"); - return ESP_FAIL; - } - - /* Set protocomm version verification endpoint for protocol */ - protocomm_set_version(g_prov->pc, "proto-ver", "V0.1"); - - /* Set protocomm security type for endpoint */ - if (g_prov->security == 0) { - protocomm_set_security(g_prov->pc, "prov-session", &protocomm_security0, NULL); - } else if (g_prov->security == 1) { - protocomm_set_security(g_prov->pc, "prov-session", &protocomm_security1, g_prov->pop); - } - - /* Add endpoint for provisioning to set wifi station config */ - if (protocomm_add_endpoint(g_prov->pc, "prov-config", - wifi_prov_config_data_handler, - (void *) &wifi_prov_handlers) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set provisioning endpoint"); - protocomm_ble_stop(g_prov->pc); - return ESP_FAIL; - } - - ESP_LOGI(TAG, "Provisioning started with BLE devname : '%s'", config.device_name); - return ESP_OK; -} - -static void app_prov_stop_service(void) -{ - /* Remove provisioning endpoint */ - protocomm_remove_endpoint(g_prov->pc, "prov-config"); - /* Unset provisioning security */ - protocomm_unset_security(g_prov->pc, "prov-session"); - /* Unset provisioning version endpoint */ - protocomm_unset_version(g_prov->pc, "proto-ver"); - /* Stop protocomm ble service */ - protocomm_ble_stop(g_prov->pc); - /* Delete protocomm instance */ - protocomm_delete(g_prov->pc); - - /* Remove event handler */ - esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler); - esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, app_prov_event_handler); - - /* Release memory used by BT stack */ - esp_bt_mem_release(ESP_BT_MODE_BTDM); -} - -/* Task spawned by timer callback */ -static void stop_prov_task(void * arg) -{ - ESP_LOGI(TAG, "Stopping provisioning"); - app_prov_stop_service(); - - /* Timer not needed anymore */ - esp_timer_handle_t timer = g_prov->timer; - esp_timer_delete(timer); - g_prov->timer = NULL; - - /* Free provisioning process data */ - free(g_prov); - g_prov = NULL; - ESP_LOGI(TAG, "Provisioning stopped"); - - vTaskDelete(NULL); -} - -/* Callback to be invoked by timer */ -static void _stop_prov_cb(void * arg) -{ - xTaskCreate(&stop_prov_task, "stop_prov", 2048, NULL, tskIDLE_PRIORITY, NULL); -} - -/* Event handler for starting/stopping provisioning */ -static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) -{ - /* If pointer to provisioning application data is NULL - * then provisioning is not running */ - if (!g_prov) { - return; - } - - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - ESP_LOGI(TAG, "STA Start"); - /* Once configuration is received through protocomm, - * device is started as station. Once station starts, - * wait for connection to establish with configured - * host SSID and password */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - ESP_LOGI(TAG, "STA Got IP"); - /* Station got IP. That means configuration is successful. - * Schedule timer to stop provisioning app after 30 seconds. */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTED; - if (g_prov && g_prov->timer) { - esp_timer_start_once(g_prov->timer, 30000*1000U); - } - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - ESP_LOGE(TAG, "STA Disconnected"); - /* Station couldn't connect to configured host SSID */ - g_prov->wifi_state = WIFI_PROV_STA_DISCONNECTED; - - wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; - ESP_LOGE(TAG, "Disconnect reason : %d", disconnected->reason); - - /* Set code corresponding to the reason for disconnection */ - switch (disconnected->reason) { - case WIFI_REASON_AUTH_EXPIRE: - case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: - case WIFI_REASON_BEACON_TIMEOUT: - case WIFI_REASON_AUTH_FAIL: - case WIFI_REASON_ASSOC_FAIL: - case WIFI_REASON_HANDSHAKE_TIMEOUT: - ESP_LOGI(TAG, "STA Auth Error"); - g_prov->wifi_disconnect_reason = WIFI_PROV_STA_AUTH_ERROR; - break; - case WIFI_REASON_NO_AP_FOUND: - ESP_LOGI(TAG, "STA AP Not found"); - g_prov->wifi_disconnect_reason = WIFI_PROV_STA_AP_NOT_FOUND; - break; - default: - /* If none of the expected reasons, - * retry connecting to host SSID */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } - esp_wifi_connect(); - } -} - -esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state) -{ - if (g_prov == NULL || state == NULL) { - return ESP_FAIL; - } - - *state = g_prov->wifi_state; - return ESP_OK; -} - -esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason) -{ - if (g_prov == NULL || reason == NULL) { - return ESP_FAIL; - } - - if (g_prov->wifi_state != WIFI_PROV_STA_DISCONNECTED) { - return ESP_FAIL; - } - - *reason = g_prov->wifi_disconnect_reason; - return ESP_OK; -} - -esp_err_t app_prov_is_provisioned(bool *provisioned) -{ - *provisioned = false; - -#ifdef CONFIG_EXAMPLE_RESET_PROVISIONED - esp_wifi_restore(); - return ESP_OK; -#endif - - /* Get WiFi Station configuration */ - wifi_config_t wifi_cfg; - if (esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) { - return ESP_FAIL; - } - - if (strlen((const char*) wifi_cfg.sta.ssid)) { - *provisioned = true; - ESP_LOGI(TAG, "Found ssid %s", (const char*) wifi_cfg.sta.ssid); - ESP_LOGI(TAG, "Found password %s", (const char*) wifi_cfg.sta.password); - } - return ESP_OK; -} - -esp_err_t app_prov_configure_sta(wifi_config_t *wifi_cfg) -{ - /* Configure WiFi as station */ - if (esp_wifi_set_mode(WIFI_MODE_STA) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi mode"); - return ESP_FAIL; - } - /* Configure WiFi station with host credentials - * provided during provisioning */ - if (esp_wifi_set_config(WIFI_IF_STA, wifi_cfg) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi configuration"); - return ESP_FAIL; - } - /* Start WiFi */ - if (esp_wifi_start() != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi configuration"); - return ESP_FAIL; - } - /* Connect to AP */ - if (esp_wifi_connect() != ESP_OK) { - ESP_LOGE(TAG, "Failed to connect WiFi"); - return ESP_FAIL; - } - - if (g_prov) { - /* Reset wifi station state for provisioning app */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } - return ESP_OK; -} - -esp_err_t app_prov_start_ble_provisioning(int security, const protocomm_security_pop_t *pop) -{ - /* If provisioning app data present, - * means provisioning app is already running */ - if (g_prov) { - ESP_LOGI(TAG, "Invalid provisioning state"); - return ESP_FAIL; - } - - /* Allocate memory for provisioning app data */ - g_prov = (struct app_prov_data *) calloc(1, sizeof(struct app_prov_data)); - if (!g_prov) { - ESP_LOGI(TAG, "Unable to allocate prov data"); - return ESP_ERR_NO_MEM; - } - - /* Initialize app data */ - g_prov->pop = pop; - g_prov->security = security; - - /* Create timer object as a member of app data */ - esp_timer_create_args_t timer_conf = { - .callback = _stop_prov_cb, - .arg = NULL, - .dispatch_method = ESP_TIMER_TASK, - .name = "stop_ble_tm" - }; - esp_err_t err = esp_timer_create(&timer_conf, &g_prov->timer); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to create timer"); - return err; - } - - err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to register WiFi event handler"); - return err; - } - - err = esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, app_prov_event_handler, NULL); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to register IP event handler"); - return err; - } - - /* Start provisioning service through BLE */ - err = app_prov_start_service(); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Provisioning failed to start"); - return err; - } - - ESP_LOGI(TAG, "BLE Provisioning started"); - return ESP_OK; -} diff --git a/examples/provisioning/legacy/ble_prov/main/app_prov.h b/examples/provisioning/legacy/ble_prov/main/app_prov.h deleted file mode 100644 index 64e4dbe3ad..0000000000 --- a/examples/provisioning/legacy/ble_prov/main/app_prov.h +++ /dev/null @@ -1,79 +0,0 @@ -/* BLE based Provisioning Example - - 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 -#include - -/** - * @brief Get state of WiFi Station during provisioning - * - * @note WiFi is initially configured as AP, when - * provisioning starts. After provisioning data - * is provided by user, the WiFi is reconfigured - * to run as both AP and Station. - * - * @param[out] state Pointer to wifi_prov_sta_state_t variable to be filled - * - * @return - * - ESP_OK : Successfully retrieved wifi state - * - ESP_FAIL : Provisioning app not running - */ -esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state); - -/** - * @brief Get reason code in case of WiFi station - * disconnection during provisioning - * -* @param[out] reason Pointer to wifi_prov_sta_fail_reason_t variable to be filled - * - * @return - * - ESP_OK : Successfully retrieved wifi disconnect reason - * - ESP_FAIL : Provisioning app not running - */ -esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason); - -/** - * @brief Checks if device is provisioned - * * - * @param[out] provisioned True if provisioned, else false - * - * @return - * - ESP_OK : Retrieved provision state successfully - * - ESP_FAIL : Failed to retrieve provision state - */ -esp_err_t app_prov_is_provisioned(bool *provisioned); - -/** - * @brief Runs WiFi as Station - * - * Configures the WiFi station mode to connect to the - * SSID and password specified in config structure, - * and starts WiFi to run as station - * - * @param[in] wifi_cfg Pointer to WiFi cofiguration structure - * - * @return - * - ESP_OK : WiFi configured and started successfully - * - ESP_FAIL : Failed to set configuration - */ -esp_err_t app_prov_configure_sta(wifi_config_t *wifi_cfg); - -/** - * @brief Start provisioning via Bluetooth - * - * @param[in] security Security mode - * @param[in] pop Pointer to proof of possession (NULL if not present) - * - * @return - * - ESP_OK : Provisioning started successfully - * - ESP_FAIL : Failed to start - */ -esp_err_t app_prov_start_ble_provisioning(int security, const protocomm_security_pop_t *pop); diff --git a/examples/provisioning/legacy/ble_prov/main/app_prov_handlers.c b/examples/provisioning/legacy/ble_prov/main/app_prov_handlers.c deleted file mode 100644 index b5d5d868c8..0000000000 --- a/examples/provisioning/legacy/ble_prov/main/app_prov_handlers.c +++ /dev/null @@ -1,135 +0,0 @@ -/* SoftAP based Provisioning Example - - 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. -*/ - -/* This file is mostly a boiler-plate code that applications can use without much change */ - -#include -#include -#include -#include - -#include -#include - -#include - -#include "app_prov.h" - -static const char* TAG = "app_prov_handler"; - -/* Provide definition of wifi_prov_ctx_t */ -struct wifi_prov_ctx { - wifi_config_t wifi_cfg; -}; - -static wifi_config_t *get_config(wifi_prov_ctx_t **ctx) -{ - return (*ctx ? &(*ctx)->wifi_cfg : NULL); -} - -static wifi_config_t *new_config(wifi_prov_ctx_t **ctx) -{ - free(*ctx); - (*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t)); - return get_config(ctx); -} - -static void free_config(wifi_prov_ctx_t **ctx) -{ - free(*ctx); - *ctx = NULL; -} - -static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx) -{ - /* Initialize to zero */ - memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t)); - - if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) { - ESP_LOGW(TAG, "Prov app not running"); - return ESP_FAIL; - } - - if (resp_data->wifi_state == WIFI_PROV_STA_CONNECTED) { - ESP_LOGI(TAG, "Connected state"); - - /* IP Addr assigned to STA */ - esp_netif_ip_info_t ip_info; - esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info); - esp_ip4addr_ntoa(&ip_info.ip, resp_data->conn_info.ip_addr, sizeof(resp_data->conn_info.ip_addr)); - - /* AP information to which STA is connected */ - wifi_ap_record_t ap_info; - esp_wifi_sta_get_ap_info(&ap_info); - memcpy(resp_data->conn_info.bssid, (char *)ap_info.bssid, sizeof(ap_info.bssid)); - memcpy(resp_data->conn_info.ssid, (char *)ap_info.ssid, sizeof(ap_info.ssid)); - resp_data->conn_info.channel = ap_info.primary; - resp_data->conn_info.auth_mode = ap_info.authmode; - } else if (resp_data->wifi_state == WIFI_PROV_STA_DISCONNECTED) { - ESP_LOGI(TAG, "Disconnected state"); - - /* If disconnected, convey reason */ - app_prov_get_wifi_disconnect_reason(&resp_data->fail_reason); - } else { - ESP_LOGI(TAG, "Connecting state"); - } - return ESP_OK; -} - -static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx) -{ - wifi_config_t *wifi_cfg = get_config(ctx); - if (wifi_cfg) { - free_config(ctx); - } - - wifi_cfg = new_config(ctx); - if (!wifi_cfg) { - ESP_LOGE(TAG, "Unable to alloc wifi config"); - return ESP_FAIL; - } - - ESP_LOGI(TAG, "WiFi Credentials Received : \n\tssid %s \n\tpassword %s", - req_data->ssid, req_data->password); - - /* Using memcpy allows the max SSID length to be 32 bytes (as per 802.11 standard). - * But this doesn't guarantee that the saved SSID will be null terminated, because - * wifi_cfg->sta.ssid is also 32 bytes long (without extra 1 byte for null character). - * Although, this is not a matter for concern because esp_wifi library reads the SSID - * upto 32 bytes in absence of null termination */ - const size_t ssid_len = strnlen(req_data->ssid, sizeof(wifi_cfg->sta.ssid)); - /* Ensure SSID less than 32 bytes is null terminated */ - memset(wifi_cfg->sta.ssid, 0, sizeof(wifi_cfg->sta.ssid)); - memcpy(wifi_cfg->sta.ssid, req_data->ssid, ssid_len); - - strlcpy((char *) wifi_cfg->sta.password, req_data->password, sizeof(wifi_cfg->sta.password)); - return ESP_OK; -} - -static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx) -{ - wifi_config_t *wifi_cfg = get_config(ctx); - if (!wifi_cfg) { - ESP_LOGE(TAG, "WiFi config not set"); - return ESP_FAIL; - } - - app_prov_configure_sta(wifi_cfg); - ESP_LOGI(TAG, "WiFi Credentials Applied"); - - free_config(ctx); - return ESP_OK; -} - -wifi_prov_config_handlers_t wifi_prov_handlers = { - .get_status_handler = get_status_handler, - .set_config_handler = set_config_handler, - .apply_config_handler = apply_config_handler, - .ctx = NULL -}; diff --git a/examples/provisioning/legacy/ble_prov/partitions.csv b/examples/provisioning/legacy/ble_prov/partitions.csv deleted file mode 100644 index d01414b8a9..0000000000 --- a/examples/provisioning/legacy/ble_prov/partitions.csv +++ /dev/null @@ -1,5 +0,0 @@ -# Name, Type, SubType, Offset, Size, Flags -# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap -nvs, data, nvs, 0x9000, 0x6000, -phy_init, data, phy, 0xf000, 0x1000, -factory, app, factory, 0x10000, 1200000, diff --git a/examples/provisioning/legacy/ble_prov/sdkconfig.defaults b/examples/provisioning/legacy/ble_prov/sdkconfig.defaults deleted file mode 100644 index 37eeb5f8ed..0000000000 --- a/examples/provisioning/legacy/ble_prov/sdkconfig.defaults +++ /dev/null @@ -1,10 +0,0 @@ -# Override some defaults so BT stack is enabled and -CONFIG_BT_ENABLED=y -CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y -CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n -CONFIG_BTDM_CTRL_MODE_BTDM=n - -# Binary is larger than default size -CONFIG_PARTITION_TABLE_CUSTOM=y -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" diff --git a/examples/provisioning/legacy/console_prov/CMakeLists.txt b/examples/provisioning/legacy/console_prov/CMakeLists.txt deleted file mode 100644 index 6542005886..0000000000 --- a/examples/provisioning/legacy/console_prov/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# The following lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(console_prov) diff --git a/examples/provisioning/legacy/console_prov/README.md b/examples/provisioning/legacy/console_prov/README.md deleted file mode 100644 index 01b50cb18e..0000000000 --- a/examples/provisioning/legacy/console_prov/README.md +++ /dev/null @@ -1,208 +0,0 @@ -# Console based Provisioning Example (Legacy) - -> Check this example only if you wish to use console based provisioning. For any real applications, it is recommended to use the new `wifi_prov_mgr` example which is based on the simpler `wifi_provisioning` APIs. - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - -`console_prov` example demonstrates the implementation and integration of various IDF components for building a console based provisioning application. - -For this example UART console 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). - -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. - -Right after provisioning is complete, the UART console is deactivated. - -`console_prov` uses the following components : -* `wifi_provisioning` : provides data structures and protocomm endpoint handlers for Wi-Fi configuration -* `protocomm` : for protocol based communication and secure session establishment -* `protobuf` : Google's protocol buffer library for serialization of protocomm data structures - -This example can be used, as it is, for adding a provisioning service to any application intended for IoT. But it is more suitable for debugging protocomm and provisioning related components and feature additions. - -## How to use example - -### Hardware Required - -Example should be able to run on any commonly available ESP32 development board. - -### Application Required - -To provision the device running this example, the `esp_prov.py` script needs to be run (found under `$IDF_PATH/tools/esp_prov`). This feature of `esp_prov` should work on all platforms, given the dependencies are satisfied. - -### Configure the project - -``` -idf.py menuconfig -``` - -* Under Example Configuration set the following : - * Security Version (default 1) - * Proof of Possession (default "abcd1234") - -### Build and Flash - -Build the project and flash it to the board, then run monitor tool to view serial output: - -``` -idf.py -p PORT flash monitor -``` - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -``` -I (388) app: Starting console provisioning -I (398) app_prov: Console provisioning started -. -. -. ->> -``` - -In a separate terminal run the `esp_prov.py` script under `$IDP_PATH/tools/esp_prov` directory (please replace `myssid` and `mypassword` with the credentials of the AP to which the device is supposed to connect to after provisioning). Assuming default example configuration, the script should be run as follows : - -``` -python esp_prov.py --transport console --proto_ver "V0.1" --sec_ver 1 --pop abcd1234 --ssid myssid --passphrase mypassword -``` - -A console will open up and the `Client->Device` commands have to be copied manually to the serial monitor console prompt : - -``` -==== Verifying protocol version ==== -Client->Device msg : proto-ver 0 56302e31 -Enter device->client msg : -``` - -On pasting the command on the serial monitor console, a `Device->Client` message will appear for each command : - -``` ->> proto-ver 0 56302e31 -53554343455353 -``` - -Copy this message back to the `esp_prov` console for proceeding to the next command : - -``` -==== Verifying protocol version ==== -Client->Device msg : proto-ver 0 56302e31 -Enter device->client msg : 53554343455353 -==== Verified protocol version successfully ==== - -==== Starting Session ==== -Client->Device msg : prov-session 0 10015a25a201220a20677106cc2f5b2acb5d8da26f0ad443df006daa1cd5bb3d75a8324d81ec5ef970 -Enter device->client msg : -``` - -This process keeps on till the device gets provisioned. - -Note that the commands are in the following format : - -``` - -``` - -This is helpful in understanding the provisioning process and the order in which the endpoints are communicated with. - -The full execution sequence of `esp_prov`, as seen on the console, is shown here : - -``` -==== Verifying protocol version ==== -Client->Device msg : proto-ver 0 56302e31 -Enter device->client msg : 53554343455353 -==== Verified protocol version successfully ==== - -==== Starting Session ==== -Client->Device msg : prov-session 0 10015a25a201220a20677106cc2f5b2acb5d8da26f0ad443df006daa1cd5bb3d75a8324d81ec5ef970 -Enter device->client msg : 10015a390801aa013412207566f4de191f600ea42de5c2b1df73f1f16685c2edb43d7c3ffc83d6b81ff61b1a103db6476536a88db10b7e0a172d4adef8 -Client->Device msg : prov-session 0 10015a270802b20122122084ca311e51c904a94f8a249c049f7aed33b39671cc11f0b92b15b299ef5653b7 -Enter device->client msg : 10015a270803ba01221a203246230190d5c1f5d94c01b56ac8cace1086cfb2d937a4a46cb6c79db7a35a8b -==== Session Established ==== - -==== Sending Wifi credential to esp32 ==== -Client->Device msg : prov-config 0 8f0c8cb6f2d53c4cc53b29be8ba1aac3edbb1dead39117c34687d6 -Enter device->client msg : 2e1f0eb0 -==== Wifi Credentials sent successfully ==== - -==== Applying config to esp32 ==== -Client->Device msg : prov-config 0 e8df -Enter device->client msg : 245c83f0 -==== Apply config sent successfully ==== - -==== Wifi connection state ==== -Client->Device msg : prov-config 0 2d36 -Enter device->client msg : 1b38a7411b6e2608aae50a6571807e04a6e90520b3b1e3c1e5b38cea4b9022e56485b92ff84289df218311972a42eb -++++ WiFi state: connected ++++ -==== Provisioning was successful ==== -``` - -The serial monitor console, for above sequence of commands, would look like : - -``` ->> proto-ver 0 56302e31 -53554343455353 ->> prov-session 0 10015a25a201220a20677106cc2f5b2acb5d8da26f0ad443df006daa1cd5bb3d75a8324d81ec5ef970 -10015a390801aa013412207566f4de191f600ea42de5c2b1df73f1f16685c2edb43d7c3ffc83d6b81ff61b1a103db6476536a88db10b7e0a172d4adef8 ->> prov-session 0 10015a270802b20122122084ca311e51c904a94f8a249c049f7aed33b39671cc11f0b92b15b299ef5653b7 -10015a270803ba01221a203246230190d5c1f5d94c01b56ac8cace1086cfb2d937a4a46cb6c79db7a35a8b ->> prov-config 0 8f0c8cb6f2d53c4cc53b29be8ba1aac3edbb1dead39117c34687d6 -I (1073738) app_prov_handler: WiFi Credentials Received : - ssid : myssid - password : mypassword - -2e1f0eb0 ->> prov-config 0 e8df -I (1084218) app_prov_handler: WiFi Credentials Applied - -245c83f0 ->> prov-config 0 2d36 -I (1089728) app_prov: STA Got IP -I (1089728) app: got ip:192.168.43.220 -I (1099698) app_prov_handler: Connected state - -1b38a7411b6e2608aae50a6571807e04a6e90520b3b1e3c1e5b38cea4b9022e56485b92ff84289df218311972a42eb ->> -``` - -After sometime the provisioning app will exit and UART console will be stopped - -``` -I (1119728) app_prov: Stopping provisioning -I (1119728) protocomm_console: Stopping console... -I (1119728) app_prov: Provisioning stopped -I (1119748) protocomm_console: Console stopped -``` - -## Troubleshooting - -### Provisioning failed - -It is possible that the Wi-Fi credentials provided were incorrect, or the device was not able to establish connection to the network, in which the the `esp_prov` script will notify failure (with reason) and the provisioning app will continue running, allowing the user to retry the process. Serial monitor log will display the failure along with disconnect reason : - -``` -E (39291) app_prov: STA Disconnected -E (39291) app_prov: Disconnect reason : 201 -I (39291) app_prov: STA AP Not found -I (42021) app_prov_handler: Disconnected state -``` - -### Provisioning does not start - -If the serial monitor log is different, as shown below : - -``` -I (539) app_prov: Found ssid myssid -I (539) app_prov: Found password mypassword -I (549) app: Starting WiFi station -``` - -It means the Wi-Fi credentials were already set by some other application flashed previously to your device. To erase these credentials either do full erase and then flash the example - -``` -make erase_flash -idf.py -p PORT flash monitor -``` - -Or, enable `Reset Provisioning` option under `Example Configuration` under menuconfig. But this will erase the saved Wi-Fi credentials every time the device boots, so this is not the preferred solution. diff --git a/examples/provisioning/legacy/console_prov/main/CMakeLists.txt b/examples/provisioning/legacy/console_prov/main/CMakeLists.txt deleted file mode 100644 index dae207e87f..0000000000 --- a/examples/provisioning/legacy/console_prov/main/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -idf_component_register(SRCS "app_main.c" - "app_prov.c" - "app_prov_handlers.c" - INCLUDE_DIRS ".") diff --git a/examples/provisioning/legacy/console_prov/main/Kconfig.projbuild b/examples/provisioning/legacy/console_prov/main/Kconfig.projbuild deleted file mode 100644 index b1578f84b3..0000000000 --- a/examples/provisioning/legacy/console_prov/main/Kconfig.projbuild +++ /dev/null @@ -1,40 +0,0 @@ -menu "Example Configuration" - - config EXAMPLE_USE_SEC_1 - bool - default y - prompt "Use Security Version 1" - help - Security version 1 used Curve25519 key exchange for establishing - secure session between device and client during provisioning - - config EXAMPLE_USE_POP - bool - depends on EXAMPLE_USE_SEC_1 - default y - prompt "Use proof-of-possession" - help - Proof-of-possession can be optionally used to prove that the device is indeed - in possession of the user who is provisioning the device. This proof-of-possession - is internally used to generate the shared secret through key exchange. - - config EXAMPLE_POP - string "Proof-of-possession" - default "abcd1234" - depends on EXAMPLE_USE_POP - - config EXAMPLE_RESET_PROVISIONED - bool - default n - prompt "Reset provisioned status of the device" - help - This erases the NVS to reset provisioned status of the device on every reboot. - Provisioned status is determined by the Wi-Fi STA configuration, saved on the NVS. - - config EXAMPLE_AP_RECONN_ATTEMPTS - int "Maximum AP connection attempts" - default 5 - help - Set the maximum connection attempts to perform when connecting to a Wi-Fi AP. - -endmenu diff --git a/examples/provisioning/legacy/console_prov/main/app_main.c b/examples/provisioning/legacy/console_prov/main/app_main.c deleted file mode 100644 index 55155f36a5..0000000000 --- a/examples/provisioning/legacy/console_prov/main/app_main.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Console based Provisioning Example - - 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "app_prov.h" - -#define EXAMPLE_AP_RECONN_ATTEMPTS CONFIG_EXAMPLE_AP_RECONN_ATTEMPTS - -static const char *TAG = "app"; - -static void event_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) -{ - static int s_retry_num = 0; - - 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) { - if (s_retry_num < EXAMPLE_AP_RECONN_ATTEMPTS) { - esp_wifi_connect(); - s_retry_num++; - ESP_LOGI(TAG, "retry to connect to the AP"); - } - ESP_LOGI(TAG,"connect to the AP fail"); - } 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, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); - s_retry_num = 0; - } -} - -static void wifi_init_sta(void) -{ - /* Set our event handling */ - 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)); - - /* Start Wi-Fi in station mode with credentials set during provisioning */ - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -static void start_console_provisioning(void) -{ - /* Security version */ - int security = 0; - /* Proof of possession */ - const protocomm_security_pop_t *pop = NULL; - -#ifdef CONFIG_EXAMPLE_USE_SEC_1 - security = 1; -#endif - - /* Having proof of possession is optional */ -#ifdef CONFIG_EXAMPLE_USE_POP - const static protocomm_security_pop_t app_pop = { - .data = (uint8_t *) CONFIG_EXAMPLE_POP, - .len = (sizeof(CONFIG_EXAMPLE_POP)-1) - }; - pop = &app_pop; -#endif - - ESP_ERROR_CHECK(app_prov_start_console_provisioning(security, pop)); -} - -void app_main(void) -{ - /* Initialize networking stack */ - ESP_ERROR_CHECK(esp_netif_init()); - - /* Create default event loop needed by the - * main app and the provisioning service */ - ESP_ERROR_CHECK(esp_event_loop_create_default()); - - /* Initialize NVS needed by Wi-Fi */ - ESP_ERROR_CHECK(nvs_flash_init()); - - /* Initialize Wi-Fi including netif with default config */ - esp_netif_create_default_wifi_sta(); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - - /* Check if device is provisioned */ - bool provisioned; - if (app_prov_is_provisioned(&provisioned) != ESP_OK) { - ESP_LOGE(TAG, "Error getting device provisioning state"); - return; - } - - if (provisioned == false) { - /* If not provisioned, start provisioning via console */ - ESP_LOGI(TAG, "Starting console provisioning"); - start_console_provisioning(); - } else { - /* Else start as station with credentials set during provisioning */ - ESP_LOGI(TAG, "Starting WiFi station"); - wifi_init_sta(); - } -} diff --git a/examples/provisioning/legacy/console_prov/main/app_prov.c b/examples/provisioning/legacy/console_prov/main/app_prov.c deleted file mode 100644 index 67d4560c0d..0000000000 --- a/examples/provisioning/legacy/console_prov/main/app_prov.c +++ /dev/null @@ -1,327 +0,0 @@ -/* Console based Provisioning Example - - 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "app_prov.h" - -static const char *TAG = "app_prov"; - -/* Handler for catching WiFi events */ -static void app_prov_event_handler(void* handler_arg, esp_event_base_t base, int32_t id, void* data); - -/* Handlers for wifi_config provisioning endpoint */ -extern wifi_prov_config_handlers_t wifi_prov_handlers; - -/** - * @brief Data relevant to provisioning application - */ -struct app_prov_data { - protocomm_t *pc; /*!< Protocomm handler */ - int security; /*!< Type of security to use with protocomm */ - const protocomm_security_pop_t *pop; /*!< Pointer to proof of possession */ - esp_timer_handle_t timer; /*!< Handle to timer */ - - /* State of WiFi Station */ - wifi_prov_sta_state_t wifi_state; - - /* Code for WiFi station disconnection (if disconnected) */ - wifi_prov_sta_fail_reason_t wifi_disconnect_reason; -}; - -/* Pointer to provisioning application data */ -static struct app_prov_data *g_prov; - -static esp_err_t app_prov_start_service(void) -{ - /* Create new protocomm instance */ - g_prov->pc = protocomm_new(); - if (g_prov->pc == NULL) { - ESP_LOGE(TAG, "Failed to create new protocomm instance"); - return ESP_FAIL; - } - - /* Config for protocomm_console_start() */ - protocomm_console_config_t config = PROTOCOMM_CONSOLE_DEFAULT_CONFIG(); - - /* Start protocomm using console */ - if (protocomm_console_start(g_prov->pc, &config) != ESP_OK) { - ESP_LOGE(TAG, "Failed to start console provisioning"); - return ESP_FAIL; - } - - /* Set protocomm version verification endpoint for protocol */ - protocomm_set_version(g_prov->pc, "proto-ver", "V0.1"); - - /* Set protocomm security type for endpoint */ - if (g_prov->security == 0) { - protocomm_set_security(g_prov->pc, "prov-session", &protocomm_security0, NULL); - } else if (g_prov->security == 1) { - protocomm_set_security(g_prov->pc, "prov-session", &protocomm_security1, g_prov->pop); - } - - /* Add endpoint for provisioning to set wifi station config */ - if (protocomm_add_endpoint(g_prov->pc, "prov-config", - wifi_prov_config_data_handler, - (void *) &wifi_prov_handlers) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set provisioning endpoint"); - protocomm_console_stop(g_prov->pc); - return ESP_FAIL; - } - - ESP_LOGI(TAG, "Provisioning started"); - return ESP_OK; -} - -static void app_prov_stop_service(void) -{ - /* Remove provisioning endpoint */ - protocomm_remove_endpoint(g_prov->pc, "prov-config"); - /* Unset provisioning security */ - protocomm_unset_security(g_prov->pc, "prov-session"); - /* Unset provisioning version endpoint */ - protocomm_unset_version(g_prov->pc, "proto-ver"); - /* Stop protocomm console service */ - protocomm_console_stop(g_prov->pc); - /* Delete protocomm instance */ - protocomm_delete(g_prov->pc); - - /* Remove event handler */ - esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler); - esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, app_prov_event_handler); -} - -/* Task spawned by timer callback */ -static void stop_prov_task(void * arg) -{ - ESP_LOGI(TAG, "Stopping provisioning"); - app_prov_stop_service(); - - /* Timer not needed anymore */ - esp_timer_handle_t timer = g_prov->timer; - esp_timer_delete(timer); - g_prov->timer = NULL; - - /* Free provisioning process data */ - free(g_prov); - g_prov = NULL; - ESP_LOGI(TAG, "Provisioning stopped"); - - vTaskDelete(NULL); -} - -/* Callback to be invoked by timer */ -static void _stop_prov_cb(void * arg) -{ - xTaskCreate(&stop_prov_task, "stop_prov", 2048, NULL, tskIDLE_PRIORITY, NULL); -} - -/* Event handler for starting/stopping provisioning */ -static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) -{ - /* If pointer to provisioning application data is NULL - * then provisioning is not running */ - if (!g_prov) { - return; - } - - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - ESP_LOGI(TAG, "STA Start"); - /* Once configuration is received through protocomm, - * device is started as station. Once station starts, - * wait for connection to establish with configured - * host SSID and password */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - ESP_LOGI(TAG, "STA Got IP"); - /* Station got IP. That means configuration is successful. - * Schedule timer to stop provisioning app after 30 seconds. */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTED; - if (g_prov && g_prov->timer) { - esp_timer_start_once(g_prov->timer, 30000*1000U); - } - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - ESP_LOGE(TAG, "STA Disconnected"); - /* Station couldn't connect to configured host SSID */ - g_prov->wifi_state = WIFI_PROV_STA_DISCONNECTED; - - wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; - ESP_LOGE(TAG, "Disconnect reason : %d", disconnected->reason); - - /* Set code corresponding to the reason for disconnection */ - switch (disconnected->reason) { - case WIFI_REASON_AUTH_EXPIRE: - case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: - case WIFI_REASON_BEACON_TIMEOUT: - case WIFI_REASON_AUTH_FAIL: - case WIFI_REASON_ASSOC_FAIL: - case WIFI_REASON_HANDSHAKE_TIMEOUT: - ESP_LOGI(TAG, "STA Auth Error"); - g_prov->wifi_disconnect_reason = WIFI_PROV_STA_AUTH_ERROR; - break; - case WIFI_REASON_NO_AP_FOUND: - ESP_LOGI(TAG, "STA AP Not found"); - g_prov->wifi_disconnect_reason = WIFI_PROV_STA_AP_NOT_FOUND; - break; - default: - /* If none of the expected reasons, - * retry connecting to host SSID */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } - esp_wifi_connect(); - } -} - -esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state) -{ - if (g_prov == NULL || state == NULL) { - return ESP_FAIL; - } - - *state = g_prov->wifi_state; - return ESP_OK; -} - -esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason) -{ - if (g_prov == NULL || reason == NULL) { - return ESP_FAIL; - } - - if (g_prov->wifi_state != WIFI_PROV_STA_DISCONNECTED) { - return ESP_FAIL; - } - - *reason = g_prov->wifi_disconnect_reason; - return ESP_OK; -} - -esp_err_t app_prov_is_provisioned(bool *provisioned) -{ - *provisioned = false; - -#ifdef CONFIG_EXAMPLE_RESET_PROVISIONED - esp_wifi_restore(); - return ESP_OK; -#endif - - /* Get WiFi Station configuration */ - wifi_config_t wifi_cfg; - if (esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) { - return ESP_FAIL; - } - - if (strlen((const char*) wifi_cfg.sta.ssid)) { - *provisioned = true; - ESP_LOGI(TAG, "Found ssid %s", (const char*) wifi_cfg.sta.ssid); - ESP_LOGI(TAG, "Found password %s", (const char*) wifi_cfg.sta.password); - } - return ESP_OK; -} - -esp_err_t app_prov_configure_sta(wifi_config_t *wifi_cfg) -{ - /* Configure WiFi as station */ - if (esp_wifi_set_mode(WIFI_MODE_STA) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi mode"); - return ESP_FAIL; - } - /* Configure WiFi station with host credentials - * provided during provisioning */ - if (esp_wifi_set_config(WIFI_IF_STA, wifi_cfg) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi configuration"); - return ESP_FAIL; - } - /* Start WiFi */ - if (esp_wifi_start() != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi configuration"); - return ESP_FAIL; - } - /* Connect to AP */ - if (esp_wifi_connect() != ESP_OK) { - ESP_LOGE(TAG, "Failed to connect WiFi"); - return ESP_FAIL; - } - - if (g_prov) { - /* Reset wifi station state for provisioning app */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } - return ESP_OK; -} - -esp_err_t app_prov_start_console_provisioning(int security, const protocomm_security_pop_t *pop) -{ - /* If provisioning app data present, - * means provisioning app is already running */ - if (g_prov) { - ESP_LOGI(TAG, "Invalid provisioning state"); - return ESP_FAIL; - } - - /* Allocate memory for provisioning app data */ - g_prov = (struct app_prov_data *) calloc(1, sizeof(struct app_prov_data)); - if (!g_prov) { - ESP_LOGI(TAG, "Unable to allocate prov data"); - return ESP_ERR_NO_MEM; - } - - /* Initialize app data */ - g_prov->pop = pop; - g_prov->security = security; - - /* Create timer object as a member of app data */ - esp_timer_create_args_t timer_conf = { - .callback = _stop_prov_cb, - .arg = NULL, - .dispatch_method = ESP_TIMER_TASK, - .name = "stop_console_tm" - }; - esp_err_t err = esp_timer_create(&timer_conf, &g_prov->timer); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to create timer"); - return err; - } - - err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to register WiFi event handler"); - return err; - } - - err = esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, app_prov_event_handler, NULL); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to register IP event handler"); - return err; - } - - /* Start provisioning service through console */ - err = app_prov_start_service(); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Provisioning failed to start"); - return err; - } - - ESP_LOGI(TAG, "Console provisioning started"); - return ESP_OK; -} diff --git a/examples/provisioning/legacy/console_prov/main/app_prov.h b/examples/provisioning/legacy/console_prov/main/app_prov.h deleted file mode 100644 index 5e6d884741..0000000000 --- a/examples/provisioning/legacy/console_prov/main/app_prov.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Console based Provisioning Example - - 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 -#include - -/** - * @brief Get state of WiFi Station during provisioning - * - * @note WiFi is initially configured as AP, when - * provisioning starts. After provisioning data - * is provided by user, the WiFi is reconfigured - * to run as both AP and Station. - * - * @param[out] state Pointer to wifi_prov_sta_state_t variable to be filled - * - * @return - * - ESP_OK : Successfully retrieved wifi state - * - ESP_FAIL : Provisioning app not running - */ -esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state); - -/** - * @brief Get reason code in case of WiFi station - * disconnection during provisioning - * -* @param[out] reason Pointer to wifi_prov_sta_fail_reason_t variable to be filled - * - * @return - * - ESP_OK : Successfully retrieved wifi disconnect reason - * - ESP_FAIL : Provisioning app not running - */ -esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason); - -/** - * @brief Checks if device is provisioned - * * - * @param[out] provisioned True if provisioned, else false - * - * @return - * - ESP_OK : Retrieved provision state successfully - * - ESP_FAIL : Failed to retrieve provision state - */ -esp_err_t app_prov_is_provisioned(bool *provisioned); - -/** - * @brief Runs WiFi as Station - * - * Configures the WiFi station mode to connect to the - * SSID and password specified in config structure, - * and starts WiFi to run as station - * - * @param[in] wifi_cfg Pointer to WiFi cofiguration structure - * - * @return - * - ESP_OK : WiFi configured and started successfully - * - ESP_FAIL : Failed to set configuration - */ -esp_err_t app_prov_configure_sta(wifi_config_t *wifi_cfg); - -/** - * @brief Start provisioning via Console - * - * @param[in] security Security mode - * @param[in] pop Pointer to proof of possession (NULL if not present) - * - * @return - * - ESP_OK : Provisioning started successfully - * - ESP_FAIL : Failed to start - */ -esp_err_t app_prov_start_console_provisioning(int security, const protocomm_security_pop_t *pop); diff --git a/examples/provisioning/legacy/console_prov/main/app_prov_handlers.c b/examples/provisioning/legacy/console_prov/main/app_prov_handlers.c deleted file mode 100644 index 26c3ba5f0f..0000000000 --- a/examples/provisioning/legacy/console_prov/main/app_prov_handlers.c +++ /dev/null @@ -1,135 +0,0 @@ -/* Console based Provisioning Example - - 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. -*/ - -/* This file is mostly a boiler-plate code that applications can use without much change */ - -#include -#include -#include -#include - -#include -#include - -#include - -#include "app_prov.h" - -static const char* TAG = "app_prov_handler"; - -/* Provide definition of wifi_prov_ctx_t */ -struct wifi_prov_ctx { - wifi_config_t wifi_cfg; -}; - -static wifi_config_t *get_config(wifi_prov_ctx_t **ctx) -{ - return (*ctx ? &(*ctx)->wifi_cfg : NULL); -} - -static wifi_config_t *new_config(wifi_prov_ctx_t **ctx) -{ - free(*ctx); - (*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t)); - return get_config(ctx); -} - -static void free_config(wifi_prov_ctx_t **ctx) -{ - free(*ctx); - *ctx = NULL; -} - -static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx) -{ - /* Initialize to zero */ - memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t)); - - if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) { - ESP_LOGW(TAG, "Prov app not running"); - return ESP_FAIL; - } - - if (resp_data->wifi_state == WIFI_PROV_STA_CONNECTED) { - ESP_LOGI(TAG, "Connected state"); - - /* IP Addr assigned to STA */ - esp_netif_ip_info_t ip_info; - esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info); - esp_ip4addr_ntoa(&ip_info.ip, resp_data->conn_info.ip_addr, sizeof(resp_data->conn_info.ip_addr)); - - /* AP information to which STA is connected */ - wifi_ap_record_t ap_info; - esp_wifi_sta_get_ap_info(&ap_info); - memcpy(resp_data->conn_info.bssid, (char *)ap_info.bssid, sizeof(ap_info.bssid)); - memcpy(resp_data->conn_info.ssid, (char *)ap_info.ssid, sizeof(ap_info.ssid)); - resp_data->conn_info.channel = ap_info.primary; - resp_data->conn_info.auth_mode = ap_info.authmode; - } else if (resp_data->wifi_state == WIFI_PROV_STA_DISCONNECTED) { - ESP_LOGI(TAG, "Disconnected state"); - - /* If disconnected, convey reason */ - app_prov_get_wifi_disconnect_reason(&resp_data->fail_reason); - } else { - ESP_LOGI(TAG, "Connecting state"); - } - return ESP_OK; -} - -static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx) -{ - wifi_config_t *wifi_cfg = get_config(ctx); - if (wifi_cfg) { - free_config(ctx); - } - - wifi_cfg = new_config(ctx); - if (!wifi_cfg) { - ESP_LOGE(TAG, "Unable to alloc wifi config"); - return ESP_FAIL; - } - - ESP_LOGI(TAG, "WiFi Credentials Received : \n\tssid %s \n\tpassword %s", - req_data->ssid, req_data->password); - - /* Using memcpy allows the max SSID length to be 32 bytes (as per 802.11 standard). - * But this doesn't guarantee that the saved SSID will be null terminated, because - * wifi_cfg->sta.ssid is also 32 bytes long (without extra 1 byte for null character). - * Although, this is not a matter for concern because esp_wifi library reads the SSID - * upto 32 bytes in absence of null termination */ - const size_t ssid_len = strnlen(req_data->ssid, sizeof(wifi_cfg->sta.ssid)); - /* Ensure SSID less than 32 bytes is null terminated */ - memset(wifi_cfg->sta.ssid, 0, sizeof(wifi_cfg->sta.ssid)); - memcpy(wifi_cfg->sta.ssid, req_data->ssid, ssid_len); - - strlcpy((char *) wifi_cfg->sta.password, req_data->password, sizeof(wifi_cfg->sta.password)); - return ESP_OK; -} - -static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx) -{ - wifi_config_t *wifi_cfg = get_config(ctx); - if (!wifi_cfg) { - ESP_LOGE(TAG, "WiFi config not set"); - return ESP_FAIL; - } - - app_prov_configure_sta(wifi_cfg); - ESP_LOGI(TAG, "WiFi Credentials Applied"); - - free_config(ctx); - return ESP_OK; -} - -wifi_prov_config_handlers_t wifi_prov_handlers = { - .get_status_handler = get_status_handler, - .set_config_handler = set_config_handler, - .apply_config_handler = apply_config_handler, - .ctx = NULL -}; diff --git a/examples/provisioning/legacy/custom_config/CMakeLists.txt b/examples/provisioning/legacy/custom_config/CMakeLists.txt deleted file mode 100644 index ec9b0ce662..0000000000 --- a/examples/provisioning/legacy/custom_config/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# The following lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) - -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(custom_config) diff --git a/examples/provisioning/legacy/custom_config/README.md b/examples/provisioning/legacy/custom_config/README.md deleted file mode 100644 index 0af5006c8a..0000000000 --- a/examples/provisioning/legacy/custom_config/README.md +++ /dev/null @@ -1,144 +0,0 @@ -# SoftAP + HTTPD based Provisioning Example featuring Custom configuration (Legacy) - -> Note: It is recommended to use the new `wifi_prov_mgr` example which is based on the simpler `wifi_provisioning` APIs. Check this example only if you wish to use lower level provisioning and protocomm APIs and want more control over the handlers. - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - -(Please see the README.md under `softap_prov` example before this.) - -`custom_config` example demonstrates the implementation and integration of various IDF components for building a provisioning application. - -This is same as `softap_prov` example, with added feature for configuration of some custom data (just like Wi-Fi configuration) during provisioning. The custom data provided during provisioning is simply printed on the serial monitor. The rest of the program functions just like `softap_prov`, ie. the device is configured as Wi-Fi station with supplied AP credentials. - - -`custom_config` uses the following components : -* `wifi_provisioning` : provides data structures and protocomm endpoint handlers for Wi-Fi configuration -* `protocomm` : for protocol based communication and secure session establishment -* `protobuf` : Google's protocol buffer library for serialization of protocomm data structures - -Also, it uses a component provided with this example `custom_provisioning` which provides data structures and protocomm endpoint handlers for custom data configuration - -## How to use example - -### Hardware Required - -Example should be able to run on any commonly available ESP32 development board. - -### Application Required - -To provision the device running this example, the `esp_prov.py` script needs to be run (found under `$IDF_PATH/tools/esp_prov`). This feature of `esp_prov` should work on all platforms, given the dependencies are satisfied. - -### Configure the project - -``` -idf.py menuconfig -``` - -* Under Example Configuration set the following : - * SoftAP SSID (Defaults to PROV_) - * SoftAP Password (Defaults to PROV_PASS) - * Security Version (default 0) - * Proof of Possession (by default not needed for security version 0) - -### Build and Flash - -Build the project and flash it to the board, then run monitor tool to view serial output: - -``` -idf.py -p PORT flash monitor -``` - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -``` -I (1562) app: SoftAP started -I (1572) app_prov: SoftAP Provisioning started with SSID 'PROV_261FCC', Password 'PROV_PASS' -``` - -Make sure to connect the client computer to the SoftAP network, whose SSID and Password are displayed in the serial monitor log. On successful connection the monitor log will show : - -``` -I (519482) tcpip_adapter: softAP assign IP to station,IP is: 192.168.4.2 -``` - -In a separate terminal run the `esp_prov.py` script under `$IDP_PATH/tools/esp_prov` directory (please replace the values corresponding to the parameters `--custom_info` and `--custom_ver` with your desired values for the custom configuration). Assuming default example configuration, the script should be run as follows : - -``` -python esp_prov.py --transport softap --service_name "192.168.4.1:80" --sec_ver 0 --ssid myssid --passphrase mypassword --custom_config --custom_info "some string" --custom_ver 4321 -``` - -Above command will perform the provisioning steps, and the monitor log should display something like this : - -``` -I (92734) app_prov_handler: Custom config received : - Info : some string - Version : 4321 -. -. -. -I (634572) app_prov_handler: WiFi Credentials Received : - ssid : myssid - password : mypassword -. -. -. -I (634652) app_prov_handler: WiFi Credentials Applied -I (634652) app_prov: STA Start -. -. -. -I (688270) app_prov_handler: Connecting state -. -. -. -I (637732) app_prov: STA Got IP -I (637732) app: got ip:192.168.43.220 -. -. -. -I (654562) app_prov_handler: Connected state -``` - -After sometime the provisioning app will exit, SoftAP will be turned off and HTTP server will be stopped - -``` -I (667732) app_prov: Stopping provisioning -I (668732) app_prov: Provisioning stopped -I (668742) app: SoftAP stopped -``` - -## Troubleshooting - -### Provisioning failed - -It is possible that the Wi-Fi credentials provided were incorrect, or the device was not able to establish connection to the network, in which the the `esp_prov` script will notify failure (with reason) and the provisioning app will continue running, allowing the user to retry the process. Serial monitor log will display the failure along with disconnect reason : - -``` -E (39291) app_prov: STA Disconnected -E (39291) app_prov: Disconnect reason : 201 -I (39291) app_prov: STA AP Not found -I (42021) app_prov_handler: Disconnected state -``` - -### Provisioning does not start - -If the serial monitor log is different, as shown below : - -``` -I (539) app_prov: Found ssid myssid -I (539) app_prov: Found password mypassword -I (549) app: Starting WiFi station -``` - -It means the Wi-Fi credentials were already set by some other application flashed previously to your device. To erase these credentials either do full erase and then flash the example - -``` -make erase_flash -idf.py -p PORT flash monitor -``` - -Or, enable `Reset Provisioning` option under `Example Configuration` under menuconfig. But this will erase the saved Wi-Fi credentials every time the device boots, so this is not the preferred solution. diff --git a/examples/provisioning/legacy/custom_config/components/custom_provisioning/CMakeLists.txt b/examples/provisioning/legacy/custom_config/components/custom_provisioning/CMakeLists.txt deleted file mode 100644 index f758ee1819..0000000000 --- a/examples/provisioning/legacy/custom_config/components/custom_provisioning/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -idf_component_register(SRCS "src/custom_config.c" - "proto-c/custom_config.pb-c.c" - INCLUDE_DIRS include - PRIV_INCLUDE_DIRS proto-c - PRIV_REQUIRES protobuf-c) diff --git a/examples/provisioning/legacy/custom_config/components/custom_provisioning/include/custom_provisioning/custom_config.h b/examples/provisioning/legacy/custom_config/components/custom_provisioning/include/custom_provisioning/custom_config.h deleted file mode 100644 index a9b6214a80..0000000000 --- a/examples/provisioning/legacy/custom_config/components/custom_provisioning/include/custom_provisioning/custom_config.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef _CUSTOM_PROV_CONFIG_H_ -#define _CUSTOM_PROV_CONFIG_H_ - -/** - * @brief Custom config data received by device - */ -typedef struct { - char info[128]; - int version; -} custom_config_t; - -/** - * @brief Internal handler for receiving and responding to protocomm - * requests from master - * - * This is to be passed as priv_data for protocomm request handler - * (refer to `custom_prov_config_data_handler()`) when calling `protocomm_add_endpoint()`. - */ -typedef esp_err_t (*custom_prov_config_handler_t) (const custom_config_t *config); - -/** - * @brief Handler for receiving and responding to requests from master - * - * This is to be registered as the `wifi_config` endpoint handler - * (protocomm `protocomm_req_handler_t`) using `protocomm_add_endpoint()` - */ -esp_err_t custom_prov_config_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, - uint8_t **outbuf, ssize_t *outlen, void *priv_data); - -#endif diff --git a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto-c/custom_config.pb-c.c b/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto-c/custom_config.pb-c.c deleted file mode 100644 index 62640573d1..0000000000 --- a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto-c/custom_config.pb-c.c +++ /dev/null @@ -1,229 +0,0 @@ -/* Generated by the protocol buffer compiler. DO NOT EDIT! */ -/* Generated from: custom_config.proto */ - -/* Do not generate deprecated warnings for self */ -#ifndef PROTOBUF_C__NO_DEPRECATED -#define PROTOBUF_C__NO_DEPRECATED -#endif - -#include "custom_config.pb-c.h" -void custom_config_request__init - (CustomConfigRequest *message) -{ - static const CustomConfigRequest init_value = CUSTOM_CONFIG_REQUEST__INIT; - *message = init_value; -} -size_t custom_config_request__get_packed_size - (const CustomConfigRequest *message) -{ - assert(message->base.descriptor == &custom_config_request__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t custom_config_request__pack - (const CustomConfigRequest *message, - uint8_t *out) -{ - assert(message->base.descriptor == &custom_config_request__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t custom_config_request__pack_to_buffer - (const CustomConfigRequest *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &custom_config_request__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -CustomConfigRequest * - custom_config_request__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (CustomConfigRequest *) - protobuf_c_message_unpack (&custom_config_request__descriptor, - allocator, len, data); -} -void custom_config_request__free_unpacked - (CustomConfigRequest *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &custom_config_request__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} -void custom_config_response__init - (CustomConfigResponse *message) -{ - static const CustomConfigResponse init_value = CUSTOM_CONFIG_RESPONSE__INIT; - *message = init_value; -} -size_t custom_config_response__get_packed_size - (const CustomConfigResponse *message) -{ - assert(message->base.descriptor == &custom_config_response__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t custom_config_response__pack - (const CustomConfigResponse *message, - uint8_t *out) -{ - assert(message->base.descriptor == &custom_config_response__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t custom_config_response__pack_to_buffer - (const CustomConfigResponse *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &custom_config_response__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -CustomConfigResponse * - custom_config_response__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (CustomConfigResponse *) - protobuf_c_message_unpack (&custom_config_response__descriptor, - allocator, len, data); -} -void custom_config_response__free_unpacked - (CustomConfigResponse *message, - ProtobufCAllocator *allocator) -{ - if(!message) - return; - assert(message->base.descriptor == &custom_config_response__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} -static const ProtobufCFieldDescriptor custom_config_request__field_descriptors[2] = -{ - { - "info", - 1, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_STRING, - 0, /* quantifier_offset */ - offsetof(CustomConfigRequest, info), - NULL, - &protobuf_c_empty_string, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "version", - 2, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_INT32, - 0, /* quantifier_offset */ - offsetof(CustomConfigRequest, version), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned custom_config_request__field_indices_by_name[] = { - 0, /* field[0] = info */ - 1, /* field[1] = version */ -}; -static const ProtobufCIntRange custom_config_request__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 2 } -}; -const ProtobufCMessageDescriptor custom_config_request__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "CustomConfigRequest", - "CustomConfigRequest", - "CustomConfigRequest", - "", - sizeof(CustomConfigRequest), - 2, - custom_config_request__field_descriptors, - custom_config_request__field_indices_by_name, - 1, custom_config_request__number_ranges, - (ProtobufCMessageInit) custom_config_request__init, - NULL,NULL,NULL /* reserved[123] */ -}; -static const ProtobufCFieldDescriptor custom_config_response__field_descriptors[2] = -{ - { - "status", - 1, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_ENUM, - 0, /* quantifier_offset */ - offsetof(CustomConfigResponse, status), - &custom_config_status__descriptor, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, - { - "dummy", - 2, - PROTOBUF_C_LABEL_NONE, - PROTOBUF_C_TYPE_INT32, - 0, /* quantifier_offset */ - offsetof(CustomConfigResponse, dummy), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned custom_config_response__field_indices_by_name[] = { - 1, /* field[1] = dummy */ - 0, /* field[0] = status */ -}; -static const ProtobufCIntRange custom_config_response__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 2 } -}; -const ProtobufCMessageDescriptor custom_config_response__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "CustomConfigResponse", - "CustomConfigResponse", - "CustomConfigResponse", - "", - sizeof(CustomConfigResponse), - 2, - custom_config_response__field_descriptors, - custom_config_response__field_indices_by_name, - 1, custom_config_response__number_ranges, - (ProtobufCMessageInit) custom_config_response__init, - NULL,NULL,NULL /* reserved[123] */ -}; -static const ProtobufCEnumValue custom_config_status__enum_values_by_number[2] = -{ - { "ConfigSuccess", "CUSTOM_CONFIG_STATUS__ConfigSuccess", 0 }, - { "ConfigFail", "CUSTOM_CONFIG_STATUS__ConfigFail", 1 }, -}; -static const ProtobufCIntRange custom_config_status__value_ranges[] = { -{0, 0},{0, 2} -}; -static const ProtobufCEnumValueIndex custom_config_status__enum_values_by_name[2] = -{ - { "ConfigFail", 1 }, - { "ConfigSuccess", 0 }, -}; -const ProtobufCEnumDescriptor custom_config_status__descriptor = -{ - PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, - "CustomConfigStatus", - "CustomConfigStatus", - "CustomConfigStatus", - "", - 2, - custom_config_status__enum_values_by_number, - 2, - custom_config_status__enum_values_by_name, - 1, - custom_config_status__value_ranges, - NULL,NULL,NULL,NULL /* reserved[1234] */ -}; diff --git a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto-c/custom_config.pb-c.h b/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto-c/custom_config.pb-c.h deleted file mode 100644 index fe1e0e4530..0000000000 --- a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto-c/custom_config.pb-c.h +++ /dev/null @@ -1,113 +0,0 @@ -/* Generated by the protocol buffer compiler. DO NOT EDIT! */ -/* Generated from: custom_config.proto */ - -#ifndef PROTOBUF_C_custom_5fconfig_2eproto__INCLUDED -#define PROTOBUF_C_custom_5fconfig_2eproto__INCLUDED - -#include - -PROTOBUF_C__BEGIN_DECLS - -#if PROTOBUF_C_VERSION_NUMBER < 1003000 -# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. -#elif 1003000 < PROTOBUF_C_MIN_COMPILER_VERSION -# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. -#endif - - -typedef struct _CustomConfigRequest CustomConfigRequest; -typedef struct _CustomConfigResponse CustomConfigResponse; - - -/* --- enums --- */ - -typedef enum _CustomConfigStatus { - CUSTOM_CONFIG_STATUS__ConfigSuccess = 0, - CUSTOM_CONFIG_STATUS__ConfigFail = 1 - PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(CUSTOM_CONFIG_STATUS) -} CustomConfigStatus; - -/* --- messages --- */ - -struct _CustomConfigRequest -{ - ProtobufCMessage base; - char *info; - int32_t version; -}; -#define CUSTOM_CONFIG_REQUEST__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&custom_config_request__descriptor) \ - , (char *)protobuf_c_empty_string, 0 } - - -struct _CustomConfigResponse -{ - ProtobufCMessage base; - CustomConfigStatus status; - int32_t dummy; -}; -#define CUSTOM_CONFIG_RESPONSE__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&custom_config_response__descriptor) \ - , CUSTOM_CONFIG_STATUS__ConfigSuccess, 0 } - - -/* CustomConfigRequest methods */ -void custom_config_request__init - (CustomConfigRequest *message); -size_t custom_config_request__get_packed_size - (const CustomConfigRequest *message); -size_t custom_config_request__pack - (const CustomConfigRequest *message, - uint8_t *out); -size_t custom_config_request__pack_to_buffer - (const CustomConfigRequest *message, - ProtobufCBuffer *buffer); -CustomConfigRequest * - custom_config_request__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void custom_config_request__free_unpacked - (CustomConfigRequest *message, - ProtobufCAllocator *allocator); -/* CustomConfigResponse methods */ -void custom_config_response__init - (CustomConfigResponse *message); -size_t custom_config_response__get_packed_size - (const CustomConfigResponse *message); -size_t custom_config_response__pack - (const CustomConfigResponse *message, - uint8_t *out); -size_t custom_config_response__pack_to_buffer - (const CustomConfigResponse *message, - ProtobufCBuffer *buffer); -CustomConfigResponse * - custom_config_response__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void custom_config_response__free_unpacked - (CustomConfigResponse *message, - ProtobufCAllocator *allocator); -/* --- per-message closures --- */ - -typedef void (*CustomConfigRequest_Closure) - (const CustomConfigRequest *message, - void *closure_data); -typedef void (*CustomConfigResponse_Closure) - (const CustomConfigResponse *message, - void *closure_data); - -/* --- services --- */ - - -/* --- descriptors --- */ - -extern const ProtobufCEnumDescriptor custom_config_status__descriptor; -extern const ProtobufCMessageDescriptor custom_config_request__descriptor; -extern const ProtobufCMessageDescriptor custom_config_response__descriptor; - -PROTOBUF_C__END_DECLS - - -#endif /* PROTOBUF_C_custom_5fconfig_2eproto__INCLUDED */ diff --git a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/CMakeLists.txt b/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/CMakeLists.txt deleted file mode 100644 index 153cfdceca..0000000000 --- a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -cmake_minimum_required(VERSION 3.5) - -set(PROTO_COMPILER "protoc") -set(PROTO_C_COMPILER "protoc-c") -set(C_OUT_PATH "${CMAKE_CURRENT_LIST_DIR}/../proto-c") -set(PY_OUT_PATH "${CMAKE_CURRENT_LIST_DIR}/../python") - -set(PROTO_SRCS "custom_config.proto") - -add_custom_target(c_proto - COMMAND ${PROTO_C_COMPILER} --c_out=${C_OUT_PATH} -I . ${PROTO_SRCS} - VERBATIM - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - ) - -add_custom_target(python_proto - COMMAND ${PROTO_COMPILER} --python_out=${PY_OUT_PATH} -I . ${PROTO_SRCS} - VERBATIM - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - ) - -add_custom_target(proto ALL - DEPENDS c_proto python_proto - VERBATIM - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - ) diff --git a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/README.md b/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/README.md deleted file mode 100644 index 933e82cbab..0000000000 --- a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Protobuf files for defining custom config-data packet structures - -This is an example proto file defining custom configuration related data packet structures, namely - -1. CustomConfigRequest - for sending configuration data consisting of various fields (Info and Version) -2. CustomConfigResponse - for receiving configuration status (fail/success) - -Note : These proto files are not automatically compiled during the build process. - -# Compilation - -Compilation requires protoc (Protobuf Compiler) and protoc-c (Protobuf C Compiler) installed. Since the generated files are to remain the same, as long as the proto files are not modified, therefore the generated files are already available under `examples/provisioning/custom_config/components/custom_provisioning/proto-c` and `examples/provisioning/custom_config/components/custom_provisioning/python` directories, and thus running cmake / make (and installing the Protobuf compilers) is optional. - -If using `cmake` follow the below steps. If using `make`, jump to Step 2 directly. - -## Step 1 (Only for cmake) - -When using cmake, first create a build directory and call cmake from inside: - -``` -mkdir build -cd build -cmake .. -``` - -## Step 2 - -Simply run `make` to generate the respective C and Python files. The newly created files will overwrite those under `examples/provisioning/custom_config/components/custom_provisioning/proto-c` and `examples/provisioning/custom_config/components/custom_provisioning/python` diff --git a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/custom_config.proto b/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/custom_config.proto deleted file mode 100644 index c6ae82ead5..0000000000 --- a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/custom_config.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; - -enum CustomConfigStatus { - ConfigSuccess = 0; - ConfigFail = 1; -} - -message CustomConfigRequest { - string info = 1; - int32 version = 2; -} - -message CustomConfigResponse { - CustomConfigStatus status = 1; - int32 dummy = 2; -} diff --git a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/makefile b/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/makefile deleted file mode 100644 index d0da1dde6d..0000000000 --- a/examples/provisioning/legacy/custom_config/components/custom_provisioning/proto/makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: c_proto python_proto - -c_proto: *.proto - @protoc-c --c_out=../proto-c/ *.proto - -python_proto: *.proto - @protoc --python_out=../python/ *.proto diff --git a/examples/provisioning/legacy/custom_config/components/custom_provisioning/python/custom_config_pb2.py b/examples/provisioning/legacy/custom_config/components/custom_provisioning/python/custom_config_pb2.py deleted file mode 100644 index be6029305c..0000000000 --- a/examples/provisioning/legacy/custom_config/components/custom_provisioning/python/custom_config_pb2.py +++ /dev/null @@ -1,152 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: custom_config.proto - -import sys - -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import enum_type_wrapper - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='custom_config.proto', - package='', - syntax='proto3', - serialized_options=None, - serialized_pb=_b('\n\x13\x63ustom_config.proto\"4\n\x13\x43ustomConfigRequest\x12\x0c\n\x04info\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\x05\"J\n\x14\x43ustomConfigResponse\x12#\n\x06status\x18\x01 \x01(\x0e\x32\x13.CustomConfigStatus\x12\r\n\x05\x64ummy\x18\x02 \x01(\x05*7\n\x12\x43ustomConfigStatus\x12\x11\n\rConfigSuccess\x10\x00\x12\x0e\n\nConfigFail\x10\x01\x62\x06proto3') -) - -_CUSTOMCONFIGSTATUS = _descriptor.EnumDescriptor( - name='CustomConfigStatus', - full_name='CustomConfigStatus', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='ConfigSuccess', index=0, number=0, - serialized_options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='ConfigFail', index=1, number=1, - serialized_options=None, - type=None), - ], - containing_type=None, - serialized_options=None, - serialized_start=153, - serialized_end=208, -) -_sym_db.RegisterEnumDescriptor(_CUSTOMCONFIGSTATUS) - -CustomConfigStatus = enum_type_wrapper.EnumTypeWrapper(_CUSTOMCONFIGSTATUS) -ConfigSuccess = 0 -ConfigFail = 1 - - - -_CUSTOMCONFIGREQUEST = _descriptor.Descriptor( - name='CustomConfigRequest', - full_name='CustomConfigRequest', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='info', full_name='CustomConfigRequest.info', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b('').decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='version', full_name='CustomConfigRequest.version', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=23, - serialized_end=75, -) - - -_CUSTOMCONFIGRESPONSE = _descriptor.Descriptor( - name='CustomConfigResponse', - full_name='CustomConfigResponse', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='CustomConfigResponse.status', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='dummy', full_name='CustomConfigResponse.dummy', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=77, - serialized_end=151, -) - -_CUSTOMCONFIGRESPONSE.fields_by_name['status'].enum_type = _CUSTOMCONFIGSTATUS -DESCRIPTOR.message_types_by_name['CustomConfigRequest'] = _CUSTOMCONFIGREQUEST -DESCRIPTOR.message_types_by_name['CustomConfigResponse'] = _CUSTOMCONFIGRESPONSE -DESCRIPTOR.enum_types_by_name['CustomConfigStatus'] = _CUSTOMCONFIGSTATUS -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -CustomConfigRequest = _reflection.GeneratedProtocolMessageType('CustomConfigRequest', (_message.Message,), dict( - DESCRIPTOR = _CUSTOMCONFIGREQUEST, - __module__ = 'custom_config_pb2' - # @@protoc_insertion_point(class_scope:CustomConfigRequest) - )) -_sym_db.RegisterMessage(CustomConfigRequest) - -CustomConfigResponse = _reflection.GeneratedProtocolMessageType('CustomConfigResponse', (_message.Message,), dict( - DESCRIPTOR = _CUSTOMCONFIGRESPONSE, - __module__ = 'custom_config_pb2' - # @@protoc_insertion_point(class_scope:CustomConfigResponse) - )) -_sym_db.RegisterMessage(CustomConfigResponse) - - -# @@protoc_insertion_point(module_scope) diff --git a/examples/provisioning/legacy/custom_config/components/custom_provisioning/src/custom_config.c b/examples/provisioning/legacy/custom_config/components/custom_provisioning/src/custom_config.c deleted file mode 100644 index bf369aaec1..0000000000 --- a/examples/provisioning/legacy/custom_config/components/custom_provisioning/src/custom_config.c +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include -#include -#include - -#include - -#include "custom_config.pb-c.h" - -static const char *TAG = "custom_config"; - -int custom_prov_config_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, uint8_t **outbuf, ssize_t *outlen, void *priv_data) -{ - CustomConfigRequest *req; - CustomConfigResponse resp; - custom_prov_config_handler_t app_handler_custom_config = (custom_prov_config_handler_t) priv_data; - - req = custom_config_request__unpack(NULL, inlen, inbuf); - if (!req) { - ESP_LOGE(TAG, "Unable to unpack config data"); - return ESP_ERR_INVALID_ARG; - } - - custom_config_response__init(&resp); - resp.status = CUSTOM_CONFIG_STATUS__ConfigFail; - - if (app_handler_custom_config) { - custom_config_t config; - strlcpy(config.info, req->info, sizeof(config.info)); - config.version = req->version; - - esp_err_t err = app_handler_custom_config(&config); - resp.status = (err == ESP_OK) ? CUSTOM_CONFIG_STATUS__ConfigSuccess : - CUSTOM_CONFIG_STATUS__ConfigFail; - } - custom_config_request__free_unpacked(req, NULL); - - resp.dummy = 47; // Set a non zero value of dummy - - *outlen = custom_config_response__get_packed_size(&resp); - if (*outlen <= 0) { - ESP_LOGE(TAG, "Invalid encoding for response"); - return ESP_FAIL; - } - - *outbuf = (uint8_t *) malloc(*outlen); - if (*outbuf == NULL) { - ESP_LOGE(TAG, "System out of memory"); - return ESP_ERR_NO_MEM; - } - - custom_config_response__pack(&resp, *outbuf); - return ESP_OK; -} diff --git a/examples/provisioning/legacy/custom_config/main/CMakeLists.txt b/examples/provisioning/legacy/custom_config/main/CMakeLists.txt deleted file mode 100644 index dae207e87f..0000000000 --- a/examples/provisioning/legacy/custom_config/main/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -idf_component_register(SRCS "app_main.c" - "app_prov.c" - "app_prov_handlers.c" - INCLUDE_DIRS ".") diff --git a/examples/provisioning/legacy/custom_config/main/Kconfig.projbuild b/examples/provisioning/legacy/custom_config/main/Kconfig.projbuild deleted file mode 100644 index 0d353fdbb0..0000000000 --- a/examples/provisioning/legacy/custom_config/main/Kconfig.projbuild +++ /dev/null @@ -1,58 +0,0 @@ -menu "Example Configuration" - - config EXAMPLE_SSID - string "Wi-Fi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config EXAMPLE_PASS - string "Wi-Fi Password" - default "mypassword" - help - Wi-Fi password (WPA or WPA2) for the example to use. - - config EXAMPLE_USE_SEC_1 - bool - default n - prompt "Use Security Version 1" - help - Security version 1 used Curve25519 key exchange for establishing - secure session between device and client during provisioning - - config EXAMPLE_USE_POP - bool - depends on EXAMPLE_USE_SEC_1 - default n - prompt "Use proof-of-possession" - help - Proof-of-possession can be optionally used to prove that the device is indeed - in possession of the user who is provisioning the device. This proof-of-possession - is internally used to generate the shared secret through key exchange. - - config EXAMPLE_POP - string "Proof-of-possession" - default "abcd1234" - depends on EXAMPLE_USE_POP - - config EXAMPLE_PROTOCOMM_HTTPD_PORT - int "Protocomm HTTP Port" - default 80 - help - Port on which to run Protocomm HTTP based provisioning service - - config EXAMPLE_RESET_PROVISIONED - bool - default n - prompt "Reset provisioned status of the device" - help - This erases the NVS to reset provisioned status of the device on every reboot. - Provisioned status is determined by the Wi-Fi STA configuration, saved on the NVS. - - config EXAMPLE_AP_RECONN_ATTEMPTS - int "Maximum AP connection attempts" - default 5 - help - Set the maximum connection attempts to perform when connecting to a Wi-Fi AP. - -endmenu diff --git a/examples/provisioning/legacy/custom_config/main/app_main.c b/examples/provisioning/legacy/custom_config/main/app_main.c deleted file mode 100644 index f0f053daa4..0000000000 --- a/examples/provisioning/legacy/custom_config/main/app_main.c +++ /dev/null @@ -1,118 +0,0 @@ -/* SoftAP based Custom Provisioning Example - - 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "app_prov.h" - -#define EXAMPLE_AP_RECONN_ATTEMPTS CONFIG_EXAMPLE_AP_RECONN_ATTEMPTS - -static const char *TAG = "app"; - -static void event_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) -{ - static int s_retry_num = 0; - - 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) { - if (s_retry_num < EXAMPLE_AP_RECONN_ATTEMPTS) { - esp_wifi_connect(); - s_retry_num++; - ESP_LOGI(TAG, "retry to connect to the AP"); - } - ESP_LOGI(TAG,"connect to the AP fail"); - } 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, "got ip: " IPSTR, IP2STR(&event->ip_info.ip)); - s_retry_num = 0; - } -} - -static void wifi_init_sta(void) -{ - /* Set our event handling */ - 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)); - - /* Start Wi-Fi in station mode with credentials set during provisioning */ - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -static void start_softap_provisioning(void) -{ - /* Security version */ - int security = 0; - /* Proof of possession */ - const protocomm_security_pop_t *pop = NULL; - -#ifdef CONFIG_EXAMPLE_USE_SEC_1 - security = 1; -#endif - - /* Having proof of possession is optional */ -#ifdef CONFIG_EXAMPLE_USE_POP - const static protocomm_security_pop_t app_pop = { - .data = (uint8_t *) CONFIG_EXAMPLE_POP, - .len = (sizeof(CONFIG_EXAMPLE_POP)-1) - }; - pop = &app_pop; -#endif - - ESP_ERROR_CHECK(app_prov_start_softap_provisioning( - CONFIG_EXAMPLE_SSID, CONFIG_EXAMPLE_PASS, security, pop)); -} - -void app_main(void) -{ - /* Initialize networking stack */ - ESP_ERROR_CHECK(esp_netif_init()); - - /* Create default event loop needed by the - * main app and the provisioning service */ - ESP_ERROR_CHECK(esp_event_loop_create_default()); - - /* Initialize NVS needed by Wi-Fi */ - ESP_ERROR_CHECK(nvs_flash_init()); - - /* Initialize Wi-Fi including netif with default config */ - esp_netif_create_default_wifi_sta(); - esp_netif_create_default_wifi_ap(); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - - /* Check if device is provisioned */ - bool provisioned; - if (app_prov_is_provisioned(&provisioned) != ESP_OK) { - ESP_LOGE(TAG, "Error getting device provisioning state"); - return; - } - - if (provisioned == false) { - /* If not provisioned, start provisioning via soft AP */ - ESP_LOGI(TAG, "Starting WiFi SoftAP provisioning"); - start_softap_provisioning(); - } else { - /* Start WiFi station with credentials set during provisioning */ - ESP_LOGI(TAG, "Starting WiFi station"); - wifi_init_sta(); - } -} diff --git a/examples/provisioning/legacy/custom_config/main/app_prov.c b/examples/provisioning/legacy/custom_config/main/app_prov.c deleted file mode 100644 index 0fb4d2e763..0000000000 --- a/examples/provisioning/legacy/custom_config/main/app_prov.c +++ /dev/null @@ -1,399 +0,0 @@ -/* SoftAP based Custom Provisioning Example - - 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "app_prov.h" - -static const char *TAG = "app_prov"; - -/* Handler for catching WiFi events */ -static void app_prov_event_handler(void* handler_arg, esp_event_base_t base, int32_t id, void* data); - -/* Handlers for provisioning endpoints */ -extern wifi_prov_config_handlers_t wifi_prov_handlers; -extern custom_prov_config_handler_t custom_prov_handler; - -/** - * @brief Data relevant to provisioning application - */ -struct app_prov_data { - protocomm_t *pc; /*!< Protocomm handler */ - int security; /*!< Type of security to use with protocomm */ - const protocomm_security_pop_t *pop; /*!< Pointer to proof of possession */ - esp_timer_handle_t timer; /*!< Handle to timer */ - - /* State of WiFi Station */ - wifi_prov_sta_state_t wifi_state; - - /* Code for WiFi station disconnection (if disconnected) */ - wifi_prov_sta_fail_reason_t wifi_disconnect_reason; -}; - -/* Pointer to provisioning application data */ -static struct app_prov_data *g_prov; - -static esp_err_t app_prov_start_service(void) -{ - /* Create new protocomm instance */ - g_prov->pc = protocomm_new(); - if (g_prov->pc == NULL) { - ESP_LOGE(TAG, "Failed to create new protocomm instance"); - return ESP_FAIL; - } - - /* Config for protocomm_httpd_start() */ - protocomm_httpd_config_t pc_config = { - .data = { - .config = PROTOCOMM_HTTPD_DEFAULT_CONFIG() - } - }; - - /* Start protocomm server on top of HTTP */ - if (protocomm_httpd_start(g_prov->pc, &pc_config) != ESP_OK) { - ESP_LOGE(TAG, "Failed to start protocomm HTTP server"); - return ESP_FAIL; - } - - /* Set protocomm version verification endpoint for protocol */ - protocomm_set_version(g_prov->pc, "proto-ver", "V0.1"); - - /* Set protocomm security type for endpoint */ - if (g_prov->security == 0) { - protocomm_set_security(g_prov->pc, "prov-session", &protocomm_security0, NULL); - } else if (g_prov->security == 1) { - protocomm_set_security(g_prov->pc, "prov-session", &protocomm_security1, g_prov->pop); - } - - /* Add endpoint for provisioning to set WiFi STA config */ - if (protocomm_add_endpoint(g_prov->pc, "prov-config", - wifi_prov_config_data_handler, - (void *) &wifi_prov_handlers) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi provisioning endpoint"); - protocomm_httpd_stop(g_prov->pc); - return ESP_FAIL; - } - - /* Add endpoint for provisioning to set custom config */ - if (protocomm_add_endpoint(g_prov->pc, "custom-config", - custom_prov_config_data_handler, - (void *) custom_prov_handler) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set custom provisioning endpoint"); - protocomm_httpd_stop(g_prov->pc); - return ESP_FAIL; - } - return ESP_OK; -} - -static void app_prov_stop_service(void) -{ - /* Remove provisioning endpoint for custom config */ - protocomm_remove_endpoint(g_prov->pc, "custom-config"); - /* Remove provisioning endpoint for WiFi STA config */ - protocomm_remove_endpoint(g_prov->pc, "prov-config"); - /* Unset provisioning security */ - protocomm_unset_security(g_prov->pc, "prov-session"); - /* Unset provisioning version endpoint */ - protocomm_unset_version(g_prov->pc, "proto-ver"); - /* Stop protocomm server */ - protocomm_httpd_stop(g_prov->pc); - /* Delete protocomm instance */ - protocomm_delete(g_prov->pc); - - /* Remove event handler */ - esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler); - esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, app_prov_event_handler); -} - -/* Task spawned by timer callback */ -static void stop_prov_task(void * arg) -{ - ESP_LOGI(TAG, "Stopping provisioning"); - app_prov_stop_service(); - esp_wifi_set_mode(WIFI_MODE_STA); - - /* Timer not needed anymore */ - esp_timer_handle_t timer = g_prov->timer; - esp_timer_delete(timer); - g_prov->timer = NULL; - - /* Free provisioning process data */ - free(g_prov); - g_prov = NULL; - ESP_LOGI(TAG, "Provisioning stopped"); - - vTaskDelete(NULL); -} - -/* Callback to be invoked by timer */ -static void _stop_prov_cb(void * arg) -{ - xTaskCreate(&stop_prov_task, "stop_prov", 2048, NULL, tskIDLE_PRIORITY, NULL); -} - -/* Event handler for starting/stopping provisioning */ -static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) -{ - /* If pointer to provisioning application data is NULL - * then provisioning is not running */ - if (!g_prov) { - return; - } - - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - ESP_LOGI(TAG, "STA Start"); - /* Once configuration is received through protocomm, - * device is started as station. Once station starts, - * wait for connection to establish with configured - * host SSID and password */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - ESP_LOGI(TAG, "STA Got IP"); - /* Station got IP. That means configuration is successful. - * Schedule timer to stop provisioning app after 30 seconds. */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTED; - if (g_prov && g_prov->timer) { - /* Note that, after restarting the WiFi in Station + AP mode, the - * user gets disconnected from the AP for a while. But at the same - * time, the user app requests for status update from the device - * to verify that the provisioning was successful. Therefore, the - * turning off of the AP must be delayed long enough for the user - * to reconnect and get STA connection status from the device. - * Otherwise, the AP will be turned off before the user can - * reconnect and thus the user app will see connection timed out, - * signaling a failure in provisioning. */ - esp_timer_start_once(g_prov->timer, 30000*1000U); - } - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - ESP_LOGE(TAG, "STA Disconnected"); - /* Station couldn't connect to configured host SSID */ - g_prov->wifi_state = WIFI_PROV_STA_DISCONNECTED; - - wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; - ESP_LOGE(TAG, "Disconnect reason : %d", disconnected->reason); - - /* Set code corresponding to the reason for disconnection */ - switch (disconnected->reason) { - case WIFI_REASON_AUTH_EXPIRE: - case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: - case WIFI_REASON_BEACON_TIMEOUT: - case WIFI_REASON_AUTH_FAIL: - case WIFI_REASON_ASSOC_FAIL: - case WIFI_REASON_HANDSHAKE_TIMEOUT: - ESP_LOGI(TAG, "STA Auth Error"); - g_prov->wifi_disconnect_reason = WIFI_PROV_STA_AUTH_ERROR; - break; - case WIFI_REASON_NO_AP_FOUND: - ESP_LOGI(TAG, "STA AP Not found"); - g_prov->wifi_disconnect_reason = WIFI_PROV_STA_AP_NOT_FOUND; - break; - default: - /* If none of the expected reasons, - * retry connecting to host SSID */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } - esp_wifi_connect(); - } -} - -esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state) -{ - if (g_prov == NULL || state == NULL) { - return ESP_FAIL; - } - - *state = g_prov->wifi_state; - return ESP_OK; -} - -esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason) -{ - if (g_prov == NULL || reason == NULL) { - return ESP_FAIL; - } - - if (g_prov->wifi_state != WIFI_PROV_STA_DISCONNECTED) { - return ESP_FAIL; - } - - *reason = g_prov->wifi_disconnect_reason; - return ESP_OK; -} - -esp_err_t app_prov_is_provisioned(bool *provisioned) -{ - *provisioned = false; - -#ifdef CONFIG_EXAMPLE_RESET_PROVISIONED - esp_wifi_restore(); - return ESP_OK; -#endif - - /* Get WiFi Station configuration */ - wifi_config_t wifi_cfg; - if (esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) { - return ESP_FAIL; - } - - if (strlen((const char*) wifi_cfg.sta.ssid)) { - *provisioned = true; - ESP_LOGI(TAG, "Found ssid %s", (const char*) wifi_cfg.sta.ssid); - ESP_LOGI(TAG, "Found password %s", (const char*) wifi_cfg.sta.password); - } - return ESP_OK; -} - -esp_err_t app_prov_configure_sta(wifi_config_t *wifi_cfg) -{ - /* Configure WiFi as both AP and Station */ - if (esp_wifi_set_mode(WIFI_MODE_APSTA) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi mode"); - return ESP_FAIL; - } - /* Configure WiFi station with host credentials - * provided during provisioning */ - if (esp_wifi_set_config(WIFI_IF_STA, wifi_cfg) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi configuration"); - return ESP_FAIL; - } - /* Restart WiFi */ - if (esp_wifi_start() != ESP_OK) { - ESP_LOGE(TAG, "Failed to restart WiFi"); - return ESP_FAIL; - } - /* Connect to AP */ - if (esp_wifi_connect() != ESP_OK) { - ESP_LOGE(TAG, "Failed to connect WiFi"); - return ESP_FAIL; - } - - if (g_prov) { - /* Reset wifi station state for provisioning app */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } - return ESP_OK; -} - -static esp_err_t start_wifi_ap(const char *ssid, const char *pass) -{ - /* Build WiFi configuration for AP mode */ - wifi_config_t wifi_config = { - .ap = { - .max_connection = 5, - }, - }; - - strlcpy((char *) wifi_config.ap.ssid, ssid, sizeof(wifi_config.ap.ssid)); - - if (strlen(pass) == 0) { - memset(wifi_config.ap.password, 0, sizeof(wifi_config.ap.password)); - wifi_config.ap.authmode = WIFI_AUTH_OPEN; - } else { - strlcpy((char *) wifi_config.ap.password, pass, sizeof(wifi_config.ap.password)); - wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK; - } - - /* Start WiFi in AP mode with configuration built above */ - esp_err_t err = esp_wifi_set_mode(WIFI_MODE_AP); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi mode : %d", err); - return err; - } - err = esp_wifi_set_config(WIFI_IF_AP, &wifi_config); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi config : %d", err); - return err; - } - err = esp_wifi_start(); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to start WiFi : %d", err); - return err; - } - - return ESP_OK; -} - -esp_err_t app_prov_start_softap_provisioning(const char *ssid, const char *pass, - int security, const protocomm_security_pop_t *pop) -{ - /* If provisioning app data present, - * means provisioning app is already running */ - if (g_prov) { - ESP_LOGI(TAG, "Invalid provisioning state"); - return ESP_FAIL; - } - - /* Allocate memory for provisioning app data */ - g_prov = (struct app_prov_data *) calloc(1, sizeof(struct app_prov_data)); - if (!g_prov) { - ESP_LOGI(TAG, "Unable to allocate prov data"); - return ESP_ERR_NO_MEM; - } - - /* Initialize app data */ - g_prov->pop = pop; - g_prov->security = security; - - /* Create timer object as a member of app data */ - esp_timer_create_args_t timer_conf = { - .callback = _stop_prov_cb, - .arg = NULL, - .dispatch_method = ESP_TIMER_TASK, - .name = "stop_softap_tm" - }; - esp_err_t err = esp_timer_create(&timer_conf, &g_prov->timer); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to create timer"); - return err; - } - - err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to register WiFi event handler"); - return err; - } - - err = esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, app_prov_event_handler, NULL); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to register IP event handler"); - return err; - } - - /* Start WiFi softAP with specified ssid and password */ - err = start_wifi_ap(ssid, pass); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to start WiFi AP"); - return err; - } - - /* Start provisioning service through HTTP */ - err = app_prov_start_service(); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to start provisioning app"); - return err; - } - - ESP_LOGI(TAG, "SoftAP Provisioning started with SSID %s, Password %s", ssid, pass); - return ESP_OK; -} diff --git a/examples/provisioning/legacy/custom_config/main/app_prov.h b/examples/provisioning/legacy/custom_config/main/app_prov.h deleted file mode 100644 index be46b29451..0000000000 --- a/examples/provisioning/legacy/custom_config/main/app_prov.h +++ /dev/null @@ -1,88 +0,0 @@ -/* SoftAP based Custom Provisioning Example - - 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 - -#include -#include -#include - -/** - * @brief Get state of WiFi Station during provisioning - * - * @note WiFi is initially configured as AP, when - * provisioning starts. After provisioning data - * is provided by user, the WiFi is reconfigured - * to run as both AP and Station. - * - * @param[out] state Pointer to wifi_prov_sta_state_t variable to be filled - * - * @return - * - ESP_OK : Successfully retrieved wifi state - * - ESP_FAIL : Provisioning app not running - */ -esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state); - -/** - * @brief Get reason code in case of WiFi station - * disconnection during provisioning - * -* @param[out] reason Pointer to wifi_prov_sta_fail_reason_t variable to be filled - * - * @return - * - ESP_OK : Successfully retrieved wifi disconnect reason - * - ESP_FAIL : Provisioning app not running - */ -esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason); - -/** - * @brief Checks if device is provisioned - * * - * @param[out] provisioned True if provisioned, else false - * - * @return - * - ESP_OK : Retrieved provision state successfully - * - ESP_FAIL : Failed to retrieve provision state - */ -esp_err_t app_prov_is_provisioned(bool *provisioned); - -/** - * @brief Runs WiFi as both AP and Station - * - * Configures the WiFi station mode to connect to the - * SSID and password specified in config structure, - * and restarts WiFi to run as both AP and station - * - * @param[in] wifi_cfg Pointer to WiFi cofiguration structure - * - * @return - * - ESP_OK : WiFi configured and restarted successfully - * - ESP_FAIL : Failed to set configuration - */ -esp_err_t app_prov_configure_sta(wifi_config_t *wifi_cfg); - -/** - * @brief Start provisioning via softAP - * - * Starts the WiFi softAP with specified ssid and pass, provisioning - * security mode and proof of possession (if any). - * - * @param[in] ssid SSID for SoftAP - * @param[in] pass Password for SoftAP - * @param[in] security Security mode - * @param[in] pop Pointer to proof of possession (NULL if not present) - * - * @return - * - ESP_OK : Provisioning started successfully - * - ESP_FAIL : Failed to start - */ -esp_err_t app_prov_start_softap_provisioning(const char *ssid, const char *pass, - int security, const protocomm_security_pop_t *pop); diff --git a/examples/provisioning/legacy/custom_config/main/app_prov_handlers.c b/examples/provisioning/legacy/custom_config/main/app_prov_handlers.c deleted file mode 100644 index 067c1128ff..0000000000 --- a/examples/provisioning/legacy/custom_config/main/app_prov_handlers.c +++ /dev/null @@ -1,147 +0,0 @@ -/* SoftAP based Custom Provisioning Example - - 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. -*/ - -/* This file is mostly a boiler-plate code that applications can use without much change */ - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "app_prov.h" - -static const char* TAG = "app_prov_handler"; - -/* Provide definition of wifi_prov_ctx_t */ -struct wifi_prov_ctx { - wifi_config_t wifi_cfg; -}; - -static wifi_config_t *get_config(wifi_prov_ctx_t **ctx) -{ - return (*ctx ? &(*ctx)->wifi_cfg : NULL); -} - -static wifi_config_t *new_config(wifi_prov_ctx_t **ctx) -{ - free(*ctx); - (*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t)); - return get_config(ctx); -} - -static void free_config(wifi_prov_ctx_t **ctx) -{ - free(*ctx); - *ctx = NULL; -} - -/****************** Handler for Custom Configuration *******************/ -static esp_err_t custom_config_handler(const custom_config_t *config) -{ - ESP_LOGI(TAG, "Custom config received :\n\tInfo : %s\n\tVersion : %d", - config->info, config->version); - return ESP_OK; -} - -custom_prov_config_handler_t custom_prov_handler = custom_config_handler; - -/****************** Handlers for Wi-Fi Configuration *******************/ -static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx) -{ - /* Initialize to zero */ - memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t)); - - if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) { - ESP_LOGW(TAG, "Prov app not running"); - return ESP_FAIL; - } - - if (resp_data->wifi_state == WIFI_PROV_STA_CONNECTED) { - ESP_LOGI(TAG, "Connected state"); - - /* IP Addr assigned to STA */ - esp_netif_ip_info_t ip_info; - esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info); - esp_ip4addr_ntoa(&ip_info.ip, resp_data->conn_info.ip_addr, sizeof(resp_data->conn_info.ip_addr)); - - /* AP information to which STA is connected */ - wifi_ap_record_t ap_info; - esp_wifi_sta_get_ap_info(&ap_info); - memcpy(resp_data->conn_info.bssid, (char *)ap_info.bssid, sizeof(ap_info.bssid)); - memcpy(resp_data->conn_info.ssid, (char *)ap_info.ssid, sizeof(ap_info.ssid)); - resp_data->conn_info.channel = ap_info.primary; - resp_data->conn_info.auth_mode = ap_info.authmode; - } else if (resp_data->wifi_state == WIFI_PROV_STA_DISCONNECTED) { - ESP_LOGI(TAG, "Disconnected state"); - - /* If disconnected, convey reason */ - app_prov_get_wifi_disconnect_reason(&resp_data->fail_reason); - } else { - ESP_LOGI(TAG, "Connecting state"); - } - return ESP_OK; -} - -static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx) -{ - wifi_config_t *wifi_cfg = get_config(ctx); - if (wifi_cfg) { - free_config(ctx); - } - - wifi_cfg = new_config(ctx); - if (!wifi_cfg) { - ESP_LOGE(TAG, "Unable to alloc wifi config"); - return ESP_FAIL; - } - - ESP_LOGI(TAG, "WiFi Credentials Received : \n\tssid %s \n\tpassword %s", - req_data->ssid, req_data->password); - - /* Using memcpy allows the max SSID length to be 32 bytes (as per 802.11 standard). - * But this doesn't guarantee that the saved SSID will be null terminated, because - * wifi_cfg->sta.ssid is also 32 bytes long (without extra 1 byte for null character). - * Although, this is not a matter for concern because esp_wifi library reads the SSID - * upto 32 bytes in absence of null termination */ - const size_t ssid_len = strnlen(req_data->ssid, sizeof(wifi_cfg->sta.ssid)); - /* Ensure SSID less than 32 bytes is null terminated */ - memset(wifi_cfg->sta.ssid, 0, sizeof(wifi_cfg->sta.ssid)); - memcpy(wifi_cfg->sta.ssid, req_data->ssid, ssid_len); - - strlcpy((char *) wifi_cfg->sta.password, req_data->password, sizeof(wifi_cfg->sta.password)); - return ESP_OK; -} - -static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx) -{ - wifi_config_t *wifi_cfg = get_config(ctx); - if (!wifi_cfg) { - ESP_LOGE(TAG, "WiFi config not set"); - return ESP_FAIL; - } - - app_prov_configure_sta(wifi_cfg); - ESP_LOGI(TAG, "WiFi Credentials Applied"); - - free_config(ctx); - return ESP_OK; -} - -wifi_prov_config_handlers_t wifi_prov_handlers = { - .get_status_handler = get_status_handler, - .set_config_handler = set_config_handler, - .apply_config_handler = apply_config_handler, - .ctx = NULL -}; diff --git a/examples/provisioning/legacy/softap_prov/CMakeLists.txt b/examples/provisioning/legacy/softap_prov/CMakeLists.txt deleted file mode 100644 index ac08cea681..0000000000 --- a/examples/provisioning/legacy/softap_prov/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# The following lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) -set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/qrcode) -include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(softap_prov) diff --git a/examples/provisioning/legacy/softap_prov/README.md b/examples/provisioning/legacy/softap_prov/README.md deleted file mode 100644 index d2b1b7e9a8..0000000000 --- a/examples/provisioning/legacy/softap_prov/README.md +++ /dev/null @@ -1,186 +0,0 @@ -# SoftAP + HTTPD based Provisioning Example (Legacy) - -> Note: It is recommended to use the new `wifi_prov_mgr` example which is based on the simpler `wifi_provisioning` APIs. Check this example only if you wish to use lower level provisioning and protocomm APIs and want more control over the handlers. - -(See the README.md file in the upper level 'examples' directory for more information about examples.) - -`softap_prov` example demonstrates the implementation and integration of various IDF components for building a provisioning application. - -For this example Wi-Fi SoftAP 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). The provisioning service is hosted by an HTTP server which accepts requests to specific URIs corresponding to the available provisioning endpoints (eg. for session establishment, for Wi-Fi credentials configuration, etc.). - -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. - -Right after provisioning is complete, Wi-Fi SoftAP and the HTTP server are deactivated. Though, that is specific to this example, and the user can choose to keep SoftAP / HTTP server active in their own application. - -`softap_prov` uses the following components : -* `wifi_provisioning` : provides data structures and protocomm endpoint handlers for Wi-Fi configuration -* `protocomm` : for protocol based communication and secure session establishment -* `protobuf` : Google's protocol buffer library for serialization of protocomm data structures - -This example can be used, as it is, for adding a provisioning service to any application intended for IoT. - -## How to use example - -### Hardware Required - -Example should be able to run on any commonly available ESP32 development board. - -### Application Required - -Provisioning applications are available for various platforms. See below - -#### Platform : Android - -For Android, a provisioning application along with source code is available on GitHub : [esp-idf-provisioning-android](https://github.com/espressif/esp-idf-provisioning-android) - -#### Platform : iOS - -For iOS, a provisioning application along with source code is available on GitHub : [esp-idf-provisioning-ios](https://github.com/espressif/esp-idf-provisioning-ios) - -#### Platform : Linux / Windows / macOS - -To provision the device running this example, the `esp_prov.py` script needs to be run (found under `$IDF_PATH/tools/esp_prov`). This feature of `esp_prov` should work on all platforms, given the dependencies are satisfied. - -### Configure the project - -``` -idf.py menuconfig -``` - -* Under Example Configuration set the following : - * SoftAP SSID (Defaults to PROV_) - * SoftAP Password (Defaults to PROV_PASS) - * Security Version (default 1) - * Proof of Possession (default "abcd1234") - -### Build and Flash - -Build the project and flash it to the board, then run monitor tool to view serial output: - -``` -idf.py -p PORT flash monitor -``` - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -``` -I (1562) app: SoftAP started -I (1572) app_prov: SoftAP Provisioning started with SSID 'PROV_261FCC', Password 'PROV_PASS' -``` - -Make sure to connect the client computer to the SoftAP network, whose SSID and Password are displayed in the serial monitor log. On successful connection the monitor log will show : - -``` -I (519482) tcpip_adapter: softAP assign IP to station,IP is: 192.168.4.2 -``` - -In a separate terminal run the `esp_prov.py` script under `$IDP_PATH/tools/esp_prov` directory (please replace `myssid` and `mypassword` with the credentials of the AP to which the device is supposed to connect to after provisioning). The SoftAP endpoint corresponds to the IP and port of the device on the SoftAP network, but this is usually same as the default value and may be left out. Assuming default example configuration, the script should be run as follows : - -``` -python esp_prov.py --transport softap --service_name "192.168.4.1:80" --sec_ver 1 --pop abcd1234 --ssid myssid --passphrase mypassword -``` - -Above command will perform the provisioning steps, and the monitor log should display something like this : - -``` -I (634572) app_prov_handler: WiFi Credentials Received : - ssid : myssid - password : mypassword -. -. -. -I (634652) app_prov_handler: WiFi Credentials Applied -I (634652) app_prov: STA Start -. -. -. -I (688270) app_prov_handler: Connecting state -. -. -. -I (637732) app_prov: STA Got IP -I (637732) app: got ip:192.168.43.220 -. -. -. -I (654562) app_prov_handler: Connected state -``` - -After sometime the provisioning app will exit, SoftAP will be turned off and HTTP server will be stopped - -``` -I (667732) app_prov: Stopping provisioning -I (668732) app_prov: Provisioning stopped -I (668742) app: SoftAP stopped -``` - -## QR Code Scanning - -Enabling `CONFIG_EXAMPLE_PROV_SHOW_QR` will display a QR code on the serial terminal, which can be scanned from the ESP Provisioning phone apps to start the Wi-Fi provisioning process. - -The monitor log should display something like this : - -``` -I (1640) app_prov: SoftAP Provisioning started with SSID 'PROV_EA69FC', Password 'PROV_PASS' -I (1640) app: Scan this QR code from the provisioning application for Provisioning. -I (1650) QRCODE: Encoding below text with ECC LVL 0 & QR Code Version 10 -I (1660) QRCODE: {"ver":"v1","name":"PROV_EA69FC","pop":"abcd1234","transport":"softap"} - - █▀▀▀▀▀█ ▄▀ ▄█ ▄█▄▄█▀▄ ██ █▀▀▀▀▀█ - █ ███ █ ▀███▀ ██▀▀█ ▀█▀ █ ███ █ - █ ▀▀▀ █ █▄ ▄ ▀███ ▄▄█▀ ▄ █ ▀▀▀ █ - ▀▀▀▀▀▀▀ █▄▀ █ ▀ ▀▄█▄▀▄▀▄█ ▀▀▀▀▀▀▀ - ▀▀▄▀▄▄▀█ █▄ ▀▄▀█▄█ ▄▄ ██▄█▀▀▄▀▀▄ - ███ █▀▀ ▄▀▀ ▄█▄ ▀▀█▄█▀▄▄ ▄█ █ - ▄▀▀ ▀▀▀█▀▄▄▄█▀▀ ██▄█▄▄█▄▀█ ▄▄ ▀█ - ▄█▄█ ▀▀▄█ ██ ▄█ ██▀█▀ ▄█ █▄ - ▄█▀█▀ █▄▀▀▄ █▀█▀██ ▄█▀ ▀▀▄ ▀ - █▄▄█▄▀█▄▄▀▄▄▀█ ▀▄ ▄▀██ ▄ █▄▄▄ ▀█ - ▀▄▀▄▀▀▀█ ▄ ▄▀▀▀█▄▀▀▀▀▀▄█ ▄▄ █ ▄▄ - ▀█▄▀██▀▄▄ ▄▄▀▄ ▄▀▀▀▀█▄▀▄▀█ ▄▄ ▀▀ - ▀ ▀ ▀ ▀▀█▄▀ ▀▀ ▀▀▀▄▀██ █▀▀▀█▀ ▄▄ - █▀▀▀▀▀█ ▀▀██▀█▀ ▀█ ▄ █▀▀█ ▀ ██ ▀▄ - █ ███ █ ▄█▀▄▄▄ █▀▀▀ ██ ▀████▀ ▄█ - █ ▀▀▀ █ ▄▀▄▄ ▄▀█▀▄▄▄█ ▀ ▄▀█▀▀▀ - ▀▀▀▀▀▀▀ ▀ ▀▀▀▀ ▀ ▀ ▀ ▀ ▀▀ ▀ - - -I (1870) app: If QR code is not visible, copy paste the below URL in a browser. -https://espressif.github.io/esp-jumpstart/qrcode.html?data={"ver":"v1","name":"PROV_EA69FC","pop":"abcd1234","transport":"softap"} -``` - -## Troubleshooting - -### Provisioning failed - -It is possible that the Wi-Fi credentials provided were incorrect, or the device was not able to establish connection to the network, in which the the `esp_prov` script will notify failure (with reason) and the provisioning app will continue running, allowing the user to retry the process. Serial monitor log will display the failure along with disconnect reason : - -``` -E (39291) app_prov: STA Disconnected -E (39291) app_prov: Disconnect reason : 201 -I (39291) app_prov: STA AP Not found -I (42021) app_prov_handler: Disconnected state -``` - -### Provisioning does not start - -If the serial monitor log is different, as shown below : - -``` -I (539) app_prov: Found ssid myssid -I (539) app_prov: Found password mypassword -I (549) app: Starting WiFi station -``` - -It means the Wi-Fi credentials were already set by some other application flashed previously to your device. To erase these credentials either do full erase and then flash the example - -``` -make erase_flash -idf.py -p PORT flash monitor -``` - -Or, enable `Reset Provisioning` option under `Example Configuration` under menuconfig. But this will erase the saved Wi-Fi credentials every time the device boots, so this is not the preferred solution. diff --git a/examples/provisioning/legacy/softap_prov/main/CMakeLists.txt b/examples/provisioning/legacy/softap_prov/main/CMakeLists.txt deleted file mode 100644 index dae207e87f..0000000000 --- a/examples/provisioning/legacy/softap_prov/main/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -idf_component_register(SRCS "app_main.c" - "app_prov.c" - "app_prov_handlers.c" - INCLUDE_DIRS ".") diff --git a/examples/provisioning/legacy/softap_prov/main/Kconfig.projbuild b/examples/provisioning/legacy/softap_prov/main/Kconfig.projbuild deleted file mode 100644 index 97fee32dc4..0000000000 --- a/examples/provisioning/legacy/softap_prov/main/Kconfig.projbuild +++ /dev/null @@ -1,64 +0,0 @@ -menu "Example Configuration" - - config EXAMPLE_SSID_SET_MAC - bool "Use MAC as SSID" - default y - help - Set SoftAP SSID as PROV_. - - config EXAMPLE_SSID - string "Wi-Fi SSID" - default "PROV_SSID" - depends on !EXAMPLE_SSID_SET_MAC - help - SSID (network name) for the example to connect to. - - config EXAMPLE_PASS - string "Wi-Fi Password" - default "PROV_PASS" - help - Wi-Fi password (WPA or WPA2) for the example to use. - - config EXAMPLE_USE_SEC_1 - bool - default y - prompt "Use Security Version 1" - help - Security version 1 used Curve25519 key exchange for establishing - secure session between device and client during provisioning - - config EXAMPLE_USE_POP - bool - depends on EXAMPLE_USE_SEC_1 - default y - prompt "Use proof-of-possession" - help - Proof-of-possession can be optionally used to prove that the device is indeed - in possession of the user who is provisioning the device. This proof-of-possession - is internally used to generate the shared secret through key exchange. - - config EXAMPLE_POP - string "Proof-of-possession" - default "abcd1234" - depends on EXAMPLE_USE_POP - - config EXAMPLE_RESET_PROVISIONED - bool - default n - prompt "Reset provisioned status of the device" - help - This erases the NVS to reset provisioned status of the device on every reboot. - Provisioned status is determined by the Wi-Fi STA configuration, saved on the NVS. - - config EXAMPLE_AP_RECONN_ATTEMPTS - int "Maximum AP connection attempts" - default 5 - help - Set the maximum connection attempts to perform when connecting to a Wi-Fi AP. - - config EXAMPLE_PROV_SHOW_QR - bool "Show provisioning QR code" - default y - help - Show the QR code for provisioning. -endmenu diff --git a/examples/provisioning/legacy/softap_prov/main/app_main.c b/examples/provisioning/legacy/softap_prov/main/app_main.c deleted file mode 100644 index 97b30da024..0000000000 --- a/examples/provisioning/legacy/softap_prov/main/app_main.c +++ /dev/null @@ -1,173 +0,0 @@ -/* SoftAP based Provisioning Example - - 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "app_prov.h" -#include "qrcode.h" - -#define EXAMPLE_AP_RECONN_ATTEMPTS CONFIG_EXAMPLE_AP_RECONN_ATTEMPTS -#define PROV_QR_VERSION "v1" -#define PROV_TRANSPORT_SOFTAP "softap" -#define QRCODE_BASE_URL "https://espressif.github.io/esp-jumpstart/qrcode.html" - -static const char *TAG = "app"; - -static void event_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) -{ - static int s_retry_num = 0; - - 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) { - if (s_retry_num < EXAMPLE_AP_RECONN_ATTEMPTS) { - esp_wifi_connect(); - s_retry_num++; - ESP_LOGI(TAG, "retry to connect to the AP"); - } - ESP_LOGI(TAG,"connect to the AP fail"); - } 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, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); - s_retry_num = 0; - } -} - -static void wifi_init_sta(void) -{ - /* Set our event handling */ - 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)); - - /* Start Wi-Fi in station mode with credentials set during provisioning */ - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -static void start_softap_provisioning(void) -{ - /* Security version */ - int security = 0; - /* Proof of possession */ - const protocomm_security_pop_t *pop = NULL; - -#ifdef CONFIG_EXAMPLE_USE_SEC_1 - security = 1; -#endif - - /* Having proof of possession is optional */ -#ifdef CONFIG_EXAMPLE_USE_POP - const static protocomm_security_pop_t app_pop = { - .data = (uint8_t *) CONFIG_EXAMPLE_POP, - .len = (sizeof(CONFIG_EXAMPLE_POP)-1) - }; - pop = &app_pop; -#endif - - const char *ssid = NULL; - -#ifdef CONFIG_EXAMPLE_SSID - ssid = CONFIG_EXAMPLE_SSID; -#else - uint8_t eth_mac[6]; - esp_wifi_get_mac(WIFI_IF_STA, eth_mac); - - char ssid_with_mac[33]; - snprintf(ssid_with_mac, sizeof(ssid_with_mac), "PROV_%02X%02X%02X", - eth_mac[3], eth_mac[4], eth_mac[5]); - - ssid = ssid_with_mac; -#endif - - ESP_ERROR_CHECK(app_prov_start_softap_provisioning( - ssid, CONFIG_EXAMPLE_PASS, security, pop)); -} - -static void get_device_service_name(char *service_name, size_t max) -{ - uint8_t eth_mac[6]; - const char *ssid_prefix = "PROV_"; - 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]); -} - -static void softap_prov_print_qr(void) -{ - char payload[150] = {0}; - char name[12] = {0}; - char *pop = NULL; -#ifdef CONFIG_EXAMPLE_USE_POP - pop = CONFIG_EXAMPLE_POP; -#endif - get_device_service_name(name, sizeof(name)); - if (pop) { - snprintf(payload, sizeof(payload), "{\"ver\":\"%s\",\"name\":\"%s\"" \ - ",\"pop\":\"%s\",\"transport\":\"%s\"}", - PROV_QR_VERSION, name, pop, PROV_TRANSPORT_SOFTAP); - } else { - snprintf(payload, sizeof(payload), "{\"ver\":\"%s\",\"name\":\"%s\"" \ - ",\"transport\":\"%s\"}", - PROV_QR_VERSION, name, PROV_TRANSPORT_SOFTAP); - } -#ifdef CONFIG_EXAMPLE_PROV_SHOW_QR - ESP_LOGI(TAG, "Scan this QR code from the provisioning application for Provisioning."); - esp_qrcode_config_t cfg = ESP_QRCODE_CONFIG_DEFAULT(); - esp_qrcode_generate(&cfg, 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); -} - -void app_main(void) -{ - /* Initialize networking stack */ - ESP_ERROR_CHECK(esp_netif_init()); - - /* Create default event loop needed by the - * main app and the provisioning service */ - ESP_ERROR_CHECK(esp_event_loop_create_default()); - - /* Initialize NVS needed by Wi-Fi */ - ESP_ERROR_CHECK(nvs_flash_init()); - - /* Initialize Wi-Fi including netif with default config */ - esp_netif_create_default_wifi_sta(); - esp_netif_create_default_wifi_ap(); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - - /* Check if device is provisioned */ - bool provisioned; - if (app_prov_is_provisioned(&provisioned) != ESP_OK) { - ESP_LOGE(TAG, "Error getting device provisioning state"); - return; - } - - if (provisioned == false) { - /* If not provisioned, start provisioning via soft AP */ - ESP_LOGI(TAG, "Starting WiFi SoftAP provisioning"); - start_softap_provisioning(); - softap_prov_print_qr(); - } else { - /* Start WiFi station with credentials set during provisioning */ - ESP_LOGI(TAG, "Starting WiFi station"); - wifi_init_sta(); - } -} diff --git a/examples/provisioning/legacy/softap_prov/main/app_prov.c b/examples/provisioning/legacy/softap_prov/main/app_prov.c deleted file mode 100644 index 2ebb161264..0000000000 --- a/examples/provisioning/legacy/softap_prov/main/app_prov.c +++ /dev/null @@ -1,385 +0,0 @@ -/* SoftAP based Provisioning Example - - 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "app_prov.h" - -static const char *TAG = "app_prov"; - -/* Handler for catching WiFi events */ -static void app_prov_event_handler(void* handler_arg, esp_event_base_t base, int32_t id, void* data); - -/* Handlers for wifi_config provisioning endpoint */ -extern wifi_prov_config_handlers_t wifi_prov_handlers; - -/** - * @brief Data relevant to provisioning application - */ -struct app_prov_data { - protocomm_t *pc; /*!< Protocomm handler */ - int security; /*!< Type of security to use with protocomm */ - const protocomm_security_pop_t *pop; /*!< Pointer to proof of possession */ - esp_timer_handle_t timer; /*!< Handle to timer */ - - /* State of WiFi Station */ - wifi_prov_sta_state_t wifi_state; - - /* Code for WiFi station disconnection (if disconnected) */ - wifi_prov_sta_fail_reason_t wifi_disconnect_reason; -}; - -/* Pointer to provisioning application data */ -static struct app_prov_data *g_prov; - -static esp_err_t app_prov_start_service(void) -{ - /* Create new protocomm instance */ - g_prov->pc = protocomm_new(); - if (g_prov->pc == NULL) { - ESP_LOGE(TAG, "Failed to create new protocomm instance"); - return ESP_FAIL; - } - - /* Config for protocomm_httpd_start() */ - protocomm_httpd_config_t pc_config = { - .data = { - .config = PROTOCOMM_HTTPD_DEFAULT_CONFIG() - } - }; - /* Start protocomm server on top of HTTP */ - if (protocomm_httpd_start(g_prov->pc, &pc_config) != ESP_OK) { - ESP_LOGE(TAG, "Failed to start protocomm HTTP server"); - return ESP_FAIL; - } - - /* Set protocomm version verification endpoint for protocol */ - protocomm_set_version(g_prov->pc, "proto-ver", "V0.1"); - - /* Set protocomm security type for endpoint */ - if (g_prov->security == 0) { - protocomm_set_security(g_prov->pc, "prov-session", &protocomm_security0, NULL); - } else if (g_prov->security == 1) { - protocomm_set_security(g_prov->pc, "prov-session", &protocomm_security1, g_prov->pop); - } - - /* Add endpoint for provisioning to set wifi station config */ - if (protocomm_add_endpoint(g_prov->pc, "prov-config", - wifi_prov_config_data_handler, - (void *) &wifi_prov_handlers) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set provisioning endpoint"); - protocomm_httpd_stop(g_prov->pc); - return ESP_FAIL; - } - return ESP_OK; -} - -static void app_prov_stop_service(void) -{ - /* Remove provisioning endpoint */ - protocomm_remove_endpoint(g_prov->pc, "prov-config"); - /* Unset provisioning security */ - protocomm_unset_security(g_prov->pc, "prov-session"); - /* Unset provisioning version endpoint */ - protocomm_unset_version(g_prov->pc, "proto-ver"); - /* Stop protocomm server */ - protocomm_httpd_stop(g_prov->pc); - /* Delete protocomm instance */ - protocomm_delete(g_prov->pc); - - /* Remove event handler */ - esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler); - esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, app_prov_event_handler); -} - -/* Task spawned by timer callback */ -static void stop_prov_task(void * arg) -{ - ESP_LOGI(TAG, "Stopping provisioning"); - app_prov_stop_service(); - esp_wifi_set_mode(WIFI_MODE_STA); - - /* Timer not needed anymore */ - esp_timer_handle_t timer = g_prov->timer; - esp_timer_delete(timer); - g_prov->timer = NULL; - - /* Free provisioning process data */ - free(g_prov); - g_prov = NULL; - ESP_LOGI(TAG, "Provisioning stopped"); - - vTaskDelete(NULL); -} - -/* Callback to be invoked by timer */ -static void _stop_prov_cb(void * arg) -{ - xTaskCreate(&stop_prov_task, "stop_prov", 2048, NULL, tskIDLE_PRIORITY, NULL); -} - -/* Event handler for starting/stopping provisioning */ -static void app_prov_event_handler(void* handler_arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) -{ - /* If pointer to provisioning application data is NULL - * then provisioning is not running */ - if (!g_prov) { - return; - } - - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - ESP_LOGI(TAG, "STA Start"); - /* Once configuration is received through protocomm, - * device is started as station. Once station starts, - * wait for connection to establish with configured - * host SSID and password */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - ESP_LOGI(TAG, "STA Got IP"); - /* Station got IP. That means configuration is successful. - * Schedule timer to stop provisioning app after 30 seconds. */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTED; - if (g_prov && g_prov->timer) { - /* Note that, after restarting the WiFi in Station + AP mode, the - * user gets disconnected from the AP for a while. But at the same - * time, the user app requests for status update from the device - * to verify that the provisioning was successful. Therefore, the - * turning off of the AP must be delayed long enough for the user - * to reconnect and get STA connection status from the device. - * Otherwise, the AP will be turned off before the user can - * reconnect and thus the user app will see connection timed out, - * signaling a failure in provisioning. */ - esp_timer_start_once(g_prov->timer, 30000*1000U); - } - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - ESP_LOGE(TAG, "STA Disconnected"); - /* Station couldn't connect to configured host SSID */ - g_prov->wifi_state = WIFI_PROV_STA_DISCONNECTED; - - wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; - ESP_LOGE(TAG, "Disconnect reason : %d", disconnected->reason); - - /* Set code corresponding to the reason for disconnection */ - switch (disconnected->reason) { - case WIFI_REASON_AUTH_EXPIRE: - case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: - case WIFI_REASON_BEACON_TIMEOUT: - case WIFI_REASON_AUTH_FAIL: - case WIFI_REASON_ASSOC_FAIL: - case WIFI_REASON_HANDSHAKE_TIMEOUT: - ESP_LOGI(TAG, "STA Auth Error"); - g_prov->wifi_disconnect_reason = WIFI_PROV_STA_AUTH_ERROR; - break; - case WIFI_REASON_NO_AP_FOUND: - ESP_LOGI(TAG, "STA AP Not found"); - g_prov->wifi_disconnect_reason = WIFI_PROV_STA_AP_NOT_FOUND; - break; - default: - /* If none of the expected reasons, - * retry connecting to host SSID */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } - esp_wifi_connect(); - } -} - -esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state) -{ - if (g_prov == NULL || state == NULL) { - return ESP_FAIL; - } - - *state = g_prov->wifi_state; - return ESP_OK; -} - -esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason) -{ - if (g_prov == NULL || reason == NULL) { - return ESP_FAIL; - } - - if (g_prov->wifi_state != WIFI_PROV_STA_DISCONNECTED) { - return ESP_FAIL; - } - - *reason = g_prov->wifi_disconnect_reason; - return ESP_OK; -} - -esp_err_t app_prov_is_provisioned(bool *provisioned) -{ - *provisioned = false; - -#ifdef CONFIG_EXAMPLE_RESET_PROVISIONED - esp_wifi_restore(); - return ESP_OK; -#endif - - /* Get WiFi Station configuration */ - wifi_config_t wifi_cfg; - if (esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) { - return ESP_FAIL; - } - - if (strlen((const char*) wifi_cfg.sta.ssid)) { - *provisioned = true; - ESP_LOGI(TAG, "Found ssid %s", (const char*) wifi_cfg.sta.ssid); - ESP_LOGI(TAG, "Found password %s", (const char*) wifi_cfg.sta.password); - } - return ESP_OK; -} - -esp_err_t app_prov_configure_sta(wifi_config_t *wifi_cfg) -{ - /* Configure WiFi as both AP and Station */ - if (esp_wifi_set_mode(WIFI_MODE_APSTA) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi mode"); - return ESP_FAIL; - } - /* Configure WiFi station with host credentials - * provided during provisioning */ - if (esp_wifi_set_config(WIFI_IF_STA, wifi_cfg) != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi configuration"); - return ESP_FAIL; - } - /* Restart WiFi */ - if (esp_wifi_start() != ESP_OK) { - ESP_LOGE(TAG, "Failed to restart WiFi"); - return ESP_FAIL; - } - /* Connect to AP */ - if (esp_wifi_connect() != ESP_OK) { - ESP_LOGE(TAG, "Failed to connect WiFi"); - return ESP_FAIL; - } - - if (g_prov) { - /* Reset wifi station state for provisioning app */ - g_prov->wifi_state = WIFI_PROV_STA_CONNECTING; - } - return ESP_OK; -} - -static esp_err_t start_wifi_ap(const char *ssid, const char *pass) -{ - /* Build WiFi configuration for AP mode */ - wifi_config_t wifi_config = { - .ap = { - .max_connection = 5, - }, - }; - - strlcpy((char *) wifi_config.ap.ssid, ssid, sizeof(wifi_config.ap.ssid)); - - if (strlen(pass) == 0) { - memset(wifi_config.ap.password, 0, sizeof(wifi_config.ap.password)); - wifi_config.ap.authmode = WIFI_AUTH_OPEN; - } else { - strlcpy((char *) wifi_config.ap.password, pass, sizeof(wifi_config.ap.password)); - wifi_config.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK; - } - - /* Start WiFi in AP mode with configuration built above */ - esp_err_t err = esp_wifi_set_mode(WIFI_MODE_AP); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi mode : %d", err); - return err; - } - err = esp_wifi_set_config(WIFI_IF_AP, &wifi_config); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to set WiFi config : %d", err); - return err; - } - err = esp_wifi_start(); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to start WiFi : %d", err); - return err; - } - - return ESP_OK; -} - -esp_err_t app_prov_start_softap_provisioning(const char *ssid, const char *pass, - int security, const protocomm_security_pop_t *pop) -{ - /* If provisioning app data present, - * means provisioning app is already running */ - if (g_prov) { - ESP_LOGI(TAG, "Invalid provisioning state"); - return ESP_FAIL; - } - - /* Allocate memory for provisioning app data */ - g_prov = (struct app_prov_data *) calloc(1, sizeof(struct app_prov_data)); - if (!g_prov) { - ESP_LOGI(TAG, "Unable to allocate prov data"); - return ESP_ERR_NO_MEM; - } - - /* Initialize app data */ - g_prov->pop = pop; - g_prov->security = security; - - /* Create timer object as a member of app data */ - esp_timer_create_args_t timer_conf = { - .callback = _stop_prov_cb, - .arg = NULL, - .dispatch_method = ESP_TIMER_TASK, - .name = "stop_softap_tm" - }; - esp_err_t err = esp_timer_create(&timer_conf, &g_prov->timer); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to create timer"); - return err; - } - - err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, app_prov_event_handler, NULL); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to register WiFi event handler"); - return err; - } - - err = esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, app_prov_event_handler, NULL); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to register IP event handler"); - return err; - } - - /* Start WiFi softAP with specified ssid and password */ - err = start_wifi_ap(ssid, pass); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to start WiFi AP"); - return err; - } - - /* Start provisioning service through HTTP */ - err = app_prov_start_service(); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to start provisioning app"); - return err; - } - - ESP_LOGI(TAG, "SoftAP Provisioning started with SSID '%s', Password '%s'", ssid, pass); - return ESP_OK; -} diff --git a/examples/provisioning/legacy/softap_prov/main/app_prov.h b/examples/provisioning/legacy/softap_prov/main/app_prov.h deleted file mode 100644 index c87ff4f0b9..0000000000 --- a/examples/provisioning/legacy/softap_prov/main/app_prov.h +++ /dev/null @@ -1,87 +0,0 @@ -/* SoftAP based Provisioning Example - - 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 - -#include -#include - -/** - * @brief Get state of WiFi Station during provisioning - * - * @note WiFi is initially configured as AP, when - * provisioning starts. After provisioning data - * is provided by user, the WiFi is reconfigured - * to run as both AP and Station. - * - * @param[out] state Pointer to wifi_prov_sta_state_t variable to be filled - * - * @return - * - ESP_OK : Successfully retrieved wifi state - * - ESP_FAIL : Provisioning app not running - */ -esp_err_t app_prov_get_wifi_state(wifi_prov_sta_state_t* state); - -/** - * @brief Get reason code in case of WiFi station - * disconnection during provisioning - * -* @param[out] reason Pointer to wifi_prov_sta_fail_reason_t variable to be filled - * - * @return - * - ESP_OK : Successfully retrieved wifi disconnect reason - * - ESP_FAIL : Provisioning app not running - */ -esp_err_t app_prov_get_wifi_disconnect_reason(wifi_prov_sta_fail_reason_t* reason); - -/** - * @brief Checks if device is provisioned - * * - * @param[out] provisioned True if provisioned, else false - * - * @return - * - ESP_OK : Retrieved provision state successfully - * - ESP_FAIL : Failed to retrieve provision state - */ -esp_err_t app_prov_is_provisioned(bool *provisioned); - -/** - * @brief Runs WiFi as both AP and Station - * - * Configures the WiFi station mode to connect to the - * SSID and password specified in config structure, - * and restarts WiFi to run as both AP and station - * - * @param[in] wifi_cfg Pointer to WiFi cofiguration structure - * - * @return - * - ESP_OK : WiFi configured and restarted successfully - * - ESP_FAIL : Failed to set configuration - */ -esp_err_t app_prov_configure_sta(wifi_config_t *wifi_cfg); - -/** - * @brief Start provisioning via softAP - * - * Starts the WiFi softAP with specified ssid and pass, provisioning - * security mode and proof of possession (if any). - * - * @param[in] ssid SSID for SoftAP - * @param[in] pass Password for SoftAP - * @param[in] security Security mode - * @param[in] pop Pointer to proof of possession (NULL if not present) - * - * @return - * - ESP_OK : Provisioning started successfully - * - ESP_FAIL : Failed to start - */ -esp_err_t app_prov_start_softap_provisioning(const char *ssid, const char *pass, - int security, const protocomm_security_pop_t *pop); diff --git a/examples/provisioning/legacy/softap_prov/main/app_prov_handlers.c b/examples/provisioning/legacy/softap_prov/main/app_prov_handlers.c deleted file mode 100644 index b5d5d868c8..0000000000 --- a/examples/provisioning/legacy/softap_prov/main/app_prov_handlers.c +++ /dev/null @@ -1,135 +0,0 @@ -/* SoftAP based Provisioning Example - - 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. -*/ - -/* This file is mostly a boiler-plate code that applications can use without much change */ - -#include -#include -#include -#include - -#include -#include - -#include - -#include "app_prov.h" - -static const char* TAG = "app_prov_handler"; - -/* Provide definition of wifi_prov_ctx_t */ -struct wifi_prov_ctx { - wifi_config_t wifi_cfg; -}; - -static wifi_config_t *get_config(wifi_prov_ctx_t **ctx) -{ - return (*ctx ? &(*ctx)->wifi_cfg : NULL); -} - -static wifi_config_t *new_config(wifi_prov_ctx_t **ctx) -{ - free(*ctx); - (*ctx) = (wifi_prov_ctx_t *) calloc(1, sizeof(wifi_prov_ctx_t)); - return get_config(ctx); -} - -static void free_config(wifi_prov_ctx_t **ctx) -{ - free(*ctx); - *ctx = NULL; -} - -static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi_prov_ctx_t **ctx) -{ - /* Initialize to zero */ - memset(resp_data, 0, sizeof(wifi_prov_config_get_data_t)); - - if (app_prov_get_wifi_state(&resp_data->wifi_state) != ESP_OK) { - ESP_LOGW(TAG, "Prov app not running"); - return ESP_FAIL; - } - - if (resp_data->wifi_state == WIFI_PROV_STA_CONNECTED) { - ESP_LOGI(TAG, "Connected state"); - - /* IP Addr assigned to STA */ - esp_netif_ip_info_t ip_info; - esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info); - esp_ip4addr_ntoa(&ip_info.ip, resp_data->conn_info.ip_addr, sizeof(resp_data->conn_info.ip_addr)); - - /* AP information to which STA is connected */ - wifi_ap_record_t ap_info; - esp_wifi_sta_get_ap_info(&ap_info); - memcpy(resp_data->conn_info.bssid, (char *)ap_info.bssid, sizeof(ap_info.bssid)); - memcpy(resp_data->conn_info.ssid, (char *)ap_info.ssid, sizeof(ap_info.ssid)); - resp_data->conn_info.channel = ap_info.primary; - resp_data->conn_info.auth_mode = ap_info.authmode; - } else if (resp_data->wifi_state == WIFI_PROV_STA_DISCONNECTED) { - ESP_LOGI(TAG, "Disconnected state"); - - /* If disconnected, convey reason */ - app_prov_get_wifi_disconnect_reason(&resp_data->fail_reason); - } else { - ESP_LOGI(TAG, "Connecting state"); - } - return ESP_OK; -} - -static esp_err_t set_config_handler(const wifi_prov_config_set_data_t *req_data, wifi_prov_ctx_t **ctx) -{ - wifi_config_t *wifi_cfg = get_config(ctx); - if (wifi_cfg) { - free_config(ctx); - } - - wifi_cfg = new_config(ctx); - if (!wifi_cfg) { - ESP_LOGE(TAG, "Unable to alloc wifi config"); - return ESP_FAIL; - } - - ESP_LOGI(TAG, "WiFi Credentials Received : \n\tssid %s \n\tpassword %s", - req_data->ssid, req_data->password); - - /* Using memcpy allows the max SSID length to be 32 bytes (as per 802.11 standard). - * But this doesn't guarantee that the saved SSID will be null terminated, because - * wifi_cfg->sta.ssid is also 32 bytes long (without extra 1 byte for null character). - * Although, this is not a matter for concern because esp_wifi library reads the SSID - * upto 32 bytes in absence of null termination */ - const size_t ssid_len = strnlen(req_data->ssid, sizeof(wifi_cfg->sta.ssid)); - /* Ensure SSID less than 32 bytes is null terminated */ - memset(wifi_cfg->sta.ssid, 0, sizeof(wifi_cfg->sta.ssid)); - memcpy(wifi_cfg->sta.ssid, req_data->ssid, ssid_len); - - strlcpy((char *) wifi_cfg->sta.password, req_data->password, sizeof(wifi_cfg->sta.password)); - return ESP_OK; -} - -static esp_err_t apply_config_handler(wifi_prov_ctx_t **ctx) -{ - wifi_config_t *wifi_cfg = get_config(ctx); - if (!wifi_cfg) { - ESP_LOGE(TAG, "WiFi config not set"); - return ESP_FAIL; - } - - app_prov_configure_sta(wifi_cfg); - ESP_LOGI(TAG, "WiFi Credentials Applied"); - - free_config(ctx); - return ESP_OK; -} - -wifi_prov_config_handlers_t wifi_prov_handlers = { - .get_status_handler = get_status_handler, - .set_config_handler = set_config_handler, - .apply_config_handler = apply_config_handler, - .ctx = NULL -}; diff --git a/examples/provisioning/legacy/softap_prov/softap_prov_test.py b/examples/provisioning/legacy/softap_prov/softap_prov_test.py deleted file mode 100644 index 651eec66b8..0000000000 --- a/examples/provisioning/legacy/softap_prov/softap_prov_test.py +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2018 Espressif Systems (Shanghai) PTE LTD -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import print_function - -import os -import re - -import esp_prov -import tiny_test_fw -import ttfw_idf -import wifi_tools -from tiny_test_fw import Utility - -# Have esp_prov throw exception -esp_prov.config_throw_except = True - - -@ttfw_idf.idf_example_test(env_tag='Example_WIFI_BT') -def test_examples_provisioning_softap(env, extra_data): - # Acquire DUT - dut1 = env.get_dut('softap_prov', 'examples/provisioning/legacy/softap_prov', dut_class=ttfw_idf.ESP32DUT) - - # Get binary file - binary_file = os.path.join(dut1.app.binary_path, 'softap_prov.bin') - bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance('softap_prov_bin_size', '{}KB'.format(bin_size // 1024)) - - # Upload binary and start testing - dut1.start_app() - - # Parse IP address of STA - dut1.expect('Starting WiFi SoftAP provisioning', timeout=60) - [ssid, password] = dut1.expect(re.compile(r"SoftAP Provisioning started with SSID '(\S+)', Password '(\S+)'"), timeout=30) - - iface = wifi_tools.get_wiface_name() - if iface is None: - raise RuntimeError('Failed to get Wi-Fi interface on host') - print('Interface name : ' + iface) - print('SoftAP SSID : ' + ssid) - print('SoftAP Password : ' + password) - - try: - ctrl = wifi_tools.wpa_cli(iface, reset_on_exit=True) - print('Connecting to DUT SoftAP...') - try: - ip = ctrl.connect(ssid, password) - except RuntimeError as err: - Utility.console_log('error: {}'.format(err)) - try: - got_ip = dut1.expect(re.compile(r'DHCP server assigned IP to a station, IP is: (\d+.\d+.\d+.\d+)'), timeout=60) - Utility.console_log('got_ip: {}'.format(got_ip)) - got_ip = got_ip[0] - if ip != got_ip: - raise RuntimeError('SoftAP connected to another host! {} != {}'.format(ip, got_ip)) - except tiny_test_fw.DUT.ExpectTimeout: - # print what is happening on dut side - Utility.console_log('in exception tiny_test_fw.DUT.ExpectTimeout') - Utility.console_log(dut1.read()) - raise - print('Connected to DUT SoftAP') - - print('Starting Provisioning') - verbose = False - protover = 'V0.1' - secver = 1 - pop = 'abcd1234' - provmode = 'softap' - ap_ssid = 'myssid' - ap_password = 'mypassword' - softap_endpoint = '{}.{}.{}.1:80'.format(ip.split('.')[0], ip.split('.')[1], ip.split('.')[2]) - - print('Getting security') - security = esp_prov.get_security(secver, pop, verbose) - if security is None: - raise RuntimeError('Failed to get security') - - print('Getting transport') - transport = esp_prov.get_transport(provmode, softap_endpoint) - if transport is None: - raise RuntimeError('Failed to get transport') - - print('Verifying protocol version') - if not esp_prov.version_match(transport, protover): - raise RuntimeError('Mismatch in protocol version') - - print('Starting Session') - if not esp_prov.establish_session(transport, security): - raise RuntimeError('Failed to start session') - - 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') - - print('Applying config') - if not esp_prov.apply_wifi_config(transport, security): - raise RuntimeError('Failed to send apply config') - - if not esp_prov.wait_wifi_connected(transport, security): - raise RuntimeError('Provisioning failed') - finally: - ctrl.reset() - - -if __name__ == '__main__': - test_examples_provisioning_softap()