1| Supported Targets | ESP32 |
2| ----------------- | ----- |
3
4# BLE based Provisioning Example (Legacy)
5
6> 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.
7
8(See the README.md file in the upper level 'examples' directory for more information about examples.)
9
10`ble_prov` example demonstrates the implementation and integration of various IDF components for building a provisioning application.
11
12For 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).
13
14In 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.
15
16Right 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.
17
18`ble_prov` uses the following components :
19* `wifi_provisioning` : provides data structures and protocomm endpoint handlers for Wi-Fi configuration
20* `protocomm` : for protocol based communication and secure session establishment
21* `protobuf` : Google's protocol buffer library for serialization of protocomm data structures
22* `bt` : ESP32 BLE stack for transport of protobuf packets
23
24This example can be used, as it is, for adding a provisioning service to any application intended for IoT.
25
26## How to use example
27
28### Hardware Required
29
30Example should be able to run on any commonly available ESP32 development board.
31
32### Application Required
33
34Provisioning applications are available for various platforms. See below
35
36#### Platform : Android
37
38For Android, a provisioning application along with source code is available on GitHub : [esp-idf-provisioning-android](https://github.com/espressif/esp-idf-provisioning-android)
39
40#### Platform : iOS
41
42For iOS, a provisioning application along with source code is available on GitHub : [esp-idf-provisioning-ios](https://github.com/espressif/esp-idf-provisioning-ios)
43
44#### Platform : Linux / Windows / macOS
45
46To 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.
47
48Presently, `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.
49
50There 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.
51
52### Configure the project
53
54```
55idf.py menuconfig
56```
57
58* Under Example Configuration set the following :
59    * Security Version (default 1)
60    * Proof of Possession (default "abcd1234")
61
62### Build and Flash
63
64Build the project and flash it to the board, then run monitor tool to view serial output:
65
66```
67idf.py -p PORT flash monitor
68```
69
70(To exit the serial monitor, type ``Ctrl-]``.)
71
72See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
73
74## Example Output
75
76```
77I (550) app: Starting BLE provisioning
78I (1130) app_prov: Provisioning started with BLE devname : PROV_261FCC
79```
80
81Make 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.
82
83In 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 :
84
85```
86python esp_prov.py --transport ble --service_name PROV_261FCC --sec_ver 1 --pop abcd1234 --ssid myssid --passphrase mypassword
87```
88
89Above command will perform the provisioning steps, and the monitor log should display something like this :
90
91```
92I (682950) app_prov_handler: WiFi Credentials Received :
93    ssid     : myssid
94    password : mypassword
95.
96.
97.
98I (683130) app_prov: STA Start
99I (683130) app_prov_handler: WiFi Credentials Applied
100.
101.
102.
103I (688270) app_prov_handler: Connecting state
104.
105.
106.
107I (688390) app_prov: STA Got IP
108I (688390) app: got ip:192.168.43.220
109I (693410) app_prov_handler: Connected state
110```
111
112After sometime the provisioning app will exit and BLE will be turned off
113
114```
115I (718390) app_prov: Stopping provisioning
116I (718670) app_prov: Provisioning stopped
117```
118
119## QR Code Scanning
120
121Enabling `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.
122
123The monitor log should display something like this :
124
125```
126I (1640) app_prov: SoftAP Provisioning started with SSID 'PROV_EA69FC', Password 'PROV_PASS'
127I (1640) app: Scan this QR code from the provisioning application for Provisioning.
128I (1650) QRCODE: Encoding below text with ECC LVL 0 & QR Code Version 10
129I (1660) QRCODE: {"ver":"v1","name":"PROV_EA69FC","pop":"abcd1234","transport":"ble"}
130
131  █▀▀▀▀▀█ ▄▀ ▄█ ▄█▄▄█▀▄  ██ █▀▀▀▀▀█
132  █ ███ █ ▀███▀  ██▀▀█  ▀█▀ █ ███ █
133  █ ▀▀▀ █ █▄ ▄ ▀███  ▄▄█▀ ▄ █ ▀▀▀ █
134  ▀▀▀▀▀▀▀ █▄▀ █ ▀ ▀▄█▄▀▄▀▄█ ▀▀▀▀▀▀▀
135  ▀▀▄▀▄▄▀█  █▄ ▀▄▀█▄█ ▄▄ ██▄█▀▀▄▀▀▄
136  ███ █▀▀ ▄▀▀  ▄█▄ ▀▀█▄█▀▄▄ ▄█    █
137  ▄▀▀ ▀▀▀█▀▄▄▄█▀▀  ██▄█▄▄█▄▀█ ▄▄ ▀█
138   ▄█▄█ ▀▀▄█  ██   ▄█  ██▀█▀  ▄█ █▄
139    ▄█▀█▀  █▄▀▀▄  █▀█▀██  ▄█▀ ▀▀▄ ▀
140   █▄▄█▄▀█▄▄▀▄▄▀█ ▀▄ ▄▀██ ▄ █▄▄▄ ▀█
141  ▀▄▀▄▀▀▀█  ▄ ▄▀▀▀█▄▀▀▀▀▀▄█ ▄▄ █ ▄▄
142  ▀█▄▀██▀▄▄ ▄▄▀▄ ▄▀▀▀▀█▄▀▄▀█  ▄▄ ▀▀
143  ▀ ▀ ▀ ▀▀█▄▀ ▀▀  ▀▀▀▄▀██ █▀▀▀█▀ ▄▄
144  █▀▀▀▀▀█ ▀▀██▀█▀ ▀█ ▄ █▀▀█ ▀ ██ ▀▄
145  █ ███ █ ▄█▀▄▄▄  █▀▀▀ ██ ▀████▀ ▄█
146  █ ▀▀▀ █ ▄▀▄▄   ▄▀█▀▄▄▄█ ▀  ▄▀█▀▀▀
147  ▀▀▀▀▀▀▀ ▀  ▀▀▀▀    ▀ ▀  ▀ ▀ ▀▀ ▀
148
149
150I (1870) app: If QR code is not visible, copy paste the below URL in a browser.
151https://espressif.github.io/esp-jumpstart/qrcode.html?data={"ver":"v1","name":"PROV_EA69FC","pop":"abcd1234","transport":"ble"}
152```
153
154## Troubleshooting
155
156### Provisioning failed
157
158It 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 :
159
160```
161E (39291) app_prov: STA Disconnected
162E (39291) app_prov: Disconnect reason : 201
163I (39291) app_prov: STA AP Not found
164I (42021) app_prov_handler: Disconnected state
165```
166
167### Provisioning does not start
168
169If the serial monitor log is different, as shown below :
170
171```
172I (539) app_prov: Found ssid myssid
173I (539) app_prov: Found password mypassword
174I (549) app: Starting WiFi station
175```
176
177It 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
178
179```
180make erase_flash
181idf.py -p PORT flash monitor
182```
183
184Or, 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.
185
186### Unsupported platform
187
188If 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 :
189
190```
191BLE client is running in console mode
192    This could be due to your platform not being supported or dependencies not being met
193    Please ensure all pre-requisites are met to run the full fledged client
194BLECLI >> Please connect to BLE device `PROV_261FCC` manually using your tool of choice
195BLECLI >> Was the device connected successfully? [y/n] y
196BLECLI >> List available attributes of the connected device
197BLECLI >> Is the service UUID '0000ffff-0000-1000-8000-00805f9b34fb' listed among available attributes? [y/n] y
198BLECLI >> Is the characteristic UUID '0000ff53-0000-1000-8000-00805f9b34fb' listed among available attributes? [y/n] y
199BLECLI >> Is the characteristic UUID '0000ff51-0000-1000-8000-00805f9b34fb' listed among available attributes? [y/n] y
200BLECLI >> Is the characteristic UUID '0000ff52-0000-1000-8000-00805f9b34fb' listed among available attributes? [y/n] y
201
202==== Verifying protocol version ====
203BLECLI >> Write following data to characteristic with UUID '0000ff53-0000-1000-8000-00805f9b34fb' :
204    >> 56302e31
205BLECLI >> Enter data read from characteristic (in hex) :
206    << 53554343455353
207==== Verified protocol version successfully ====
208
209==== Starting Session ====
210BLECLI >> Write following data to characteristic with UUID '0000ff51-0000-1000-8000-00805f9b34fb' :
211    >> 10015a25a201220a20ae6d9d5d1029f8c366892252d2d5a0ffa7ce1ee5829312545dd5f2aba057294d
212BLECLI >> Enter data read from characteristic (in hex) :
213    << 10015a390801aa0134122048008bfc365fad4753dc75912e0c764d60749cb26dd609595b6fbc72e12614031a1089733af233c7448e7d7fb7963682c6d8
214BLECLI >> Write following data to characteristic with UUID '0000ff51-0000-1000-8000-00805f9b34fb' :
215    >> 10015a270802b2012212204051088dc294fe4621fac934a8ea22e948fcc3e8ac458aac088ce705c65dbfb9
216BLECLI >> Enter data read from characteristic (in hex) :
217    << 10015a270803ba01221a20c8d38059d5206a3d92642973ac6ba8ac2f6ecf2b7a3632964eb35a0f20133adb
218==== Session Established ====
219
220==== Sending Wifi credential to esp32 ====
221BLECLI >> Write following data to characteristic with UUID '0000ff52-0000-1000-8000-00805f9b34fb' :
222    >> 98471ac4019a46765c28d87df8c8ae71c1ae6cfe0bc9c615bc6d2c
223BLECLI >> Enter data read from characteristic (in hex) :
224    << 3271f39a
225==== Wifi Credentials sent successfully ====
226
227==== Applying config to esp32 ====
228BLECLI >> Write following data to characteristic with UUID '0000ff52-0000-1000-8000-00805f9b34fb' :
229    >> 5355
230BLECLI >> Enter data read from characteristic (in hex) :
231    << 1664db24
232==== Apply config sent successfully ====
233
234==== Wifi connection state  ====
235BLECLI >> Write following data to characteristic with UUID '0000ff52-0000-1000-8000-00805f9b34fb' :
236    >> 290d
237BLECLI >> Enter data read from characteristic (in hex) :
238    << 505f72a9f8521025c1964d7789c4d7edc56aedebd144e1b667bc7c0975757b80cc091aa9f3e95b06eaefbc30290fa1
239++++ WiFi state: connected ++++
240==== Provisioning was successful ====
241```
242
243The 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.
244