OVMS3-idf/examples/provisioning/manager
Anurag Kar f94db7bba7 wifi_provisioning : Added Wi-Fi Scan list feature to Provisioning Manager
List of changes in components/wifi_provisioning:
* Manager version is now v1.1
* .proto files and protocomm handler added for sending Wi-Fi scan command and receiving scan results
* Implemented handlers for wifi_scan protocomm endpoint
* Update manager context data structure to hold scan state and results
* scheme_softap now runs Wi-Fi in APSTA mode
* Wi-Fi is started in AP mode when provisioning is started. This is necessary for scan list to work
* Docs updates with information about new wifi_scan endpoint

List of changes in tools/esp_prov:
* Added functions for sending and receiving protobuf messages compatible with wifi_scan protocomm endpoint
* Added feature to display/refresh scan results and accept user selection at runtime
* New functions:
  * get_version() : only returns the protocol version string
  * has_capability() : check is a capability is present according to proto-ver response
* wifi_scan feature is provided only if the `wifi_scan` capability is present

Other changes:
* Replace recursive mutex with plain mutex
* assert on return value of mutex give / take calls
* replace all calls with macros ACQUIRE_LOCK and RELEASE_LOCK
* some checks added in scanning related private APIs
* free and nullify scanning context and state if service is stopped while ongoing scan
2019-06-28 07:49:03 +00:00
..
main Provisioning : Added Wi-Fi Provisioning Manager example and test script 2019-06-28 07:49:03 +00:00
CMakeLists.txt Provisioning : Added Wi-Fi Provisioning Manager example and test script 2019-06-28 07:49:03 +00:00
Makefile Provisioning : Added Wi-Fi Provisioning Manager example and test script 2019-06-28 07:49:03 +00:00
partitions.csv Provisioning : Added Wi-Fi Provisioning Manager example and test script 2019-06-28 07:49:03 +00:00
README.md Provisioning : Added Wi-Fi Provisioning Manager example and test script 2019-06-28 07:49:03 +00:00
sdkconfig.defaults Provisioning : Added Wi-Fi Provisioning Manager example and test script 2019-06-28 07:49:03 +00:00
wifi_prov_mgr_test.py wifi_provisioning : Added Wi-Fi Scan list feature to Provisioning Manager 2019-06-28 07:49:03 +00:00

Wi-Fi Provisioning Manager Example

(See the README.md file in the upper level 'examples' directory for more information about examples.)

wifi_prov_mgr example demonstrates the usage of wifi_provisioning manager component for building a provisioning application.

For this example BLE is chosen as the mode of transport, over which the provisioning related communication is to take place, between the device (to be provisioned) and the client (owner of the device).

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 stack intact in their own application.

wifi_prov_mgr uses the following components :

  • wifi_provisioning : provides manager, 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

Platform : iOS

For iOS, a provisioning application along with source code is available on GitHub : 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

make menuconfig
  • Set serial port under Serial Flasher Options.

Build and Flash

Build the project and flash it to the board, then run monitor tool to view serial output:

make -j4 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 (445) app: Starting provisioning
I (1035) app: Provisioning started
I (1045) wifi_prov_mgr: Provisioning started with service name : 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 --ssid myssid --passphrase mypassword --sec_ver 1 --pop abcd1234 --transport ble --ble_devname PROV_261FCC

Above command will perform the provisioning steps, and the monitor log should display something like this :

I (39725) app: Received Wi-Fi credentials
    SSID     : myssid
    Password : mypassword
.
.
.
I (45335) tcpip_adapter: sta ip: 192.168.43.243, mask: 255.255.255.0, gw: 192.168.43.1
I (45345) app: Provisioning successful
I (45345) app: Connected with IP Address:192.168.43.243
I (46355) app: Hello World!
I (47355) app: Hello World!
I (48355) app: Hello World!
I (49355) app: Hello World!
.
.
.
I (52315) wifi_prov_mgr: Provisioning stopped
.
.
.
I (52355) app: Hello World!
I (53355) app: Hello World!
I (54355) app: Hello World!
I (55355) app: Hello World!

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). Serial monitor log will display the failure along with disconnect reason :

E (367015) app: Provisioning failed!
    Reason : Wi-Fi AP password incorrect
    Please reset to factory and retry provisioning

Once credentials have been applied, even though wrong credentials were provided, the device will no longer go into provisioning mode on subsequent reboots until NVS is erased (see following section).

Provisioning does not start

If the serial monitor log shows the following :

I (465) app: Already provisioned, starting Wi-Fi STA

it means either the device has been provisioned earlier with or without success (e.g. scenario covered in above section), or that the Wi-Fi credentials were already set by some other application flashed previously onto your device. On setting the log level to DEBUG this is clearly evident :

D (455) wifi_prov_mgr: Found Wi-Fi SSID     : myssid
D (465) wifi_prov_mgr: Found Wi-Fi Password : m********d
I (465) app: Already provisioned, starting Wi-Fi STA

To fix this we simple need to erase the NVS partition from flash. First we need to find out its address and size. This can be seen from the monitor log on the top right after reboot.

I (47) boot: Partition Table:
I (50) boot: ## Label            Usage          Type ST Offset   Length
I (58) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (65) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (73) boot:  2 factory          factory app      00 00 00010000 00124f80
I (80) boot: End of partition table

Now erase NVS partition by running the following commands :

$IDF_PATH/components/esptool_py/esptool/esptool.py erase_region 0x9000 0x6000

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 :

==== Esp_Prov Version: v1.0 ====
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.