Skip to content

Commit 82227e6

Browse files
authored
Provisioning fix and upgrades (#8209)
* Added printQR function to library * Upgraded example * Upgraded README * Safegueard for qrcode.h include * Updated Safegueard for qrcode.h include
1 parent 0034a43 commit 82227e6

File tree

4 files changed

+151
-84
lines changed

4 files changed

+151
-84
lines changed

Diff for: libraries/WiFiProv/examples/WiFiProv/README.md

+71-67
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,120 @@
11
# Provisioning for Arduino
22

3-
This sketch implements provisioning using various IDF components
3+
This sketch implements provisioning using various IDF components.
44

5-
# Description
5+
## Description
66

7-
This example allows Arduino user to choose either BLE or SOFTAP as a 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).
7+
This example allows Arduino users to choose either BLE or SOFTAP as the mode of transport for provisioning-related communication between the device (to be provisioned) and the client (owner of the device).
88

9-
# APIs introduced for provisioning
9+
## APIs introduced for provisioning
1010

11-
## WiFi.onEvent()
11+
### WiFi.onEvent()
1212

13-
Using this API user can register to receive WiFi Events and Provisioning Events
13+
Using this API, users can register to receive WiFi Events and Provisioning Events.
1414

15-
## WiFi.beginProvision()
15+
### WiFi.beginProvision()
1616

17-
WiFi.beginProvision(void ( * scheme_cb)(), wifi_prov_scheme_event_handler_t scheme_event_handler, wifi_prov_security_t security, char * pop, char * service_name, char * service_key, uint8_t * uuid);
17+
```
18+
WiFi.beginProvision(void (*scheme_cb)(), wifi_prov_scheme_event_handler_t scheme_event_handler, wifi_prov_security_t security, char *pop, char *service_name, char *service_key, uint8_t *uuid);
19+
```
1820

1921
#### Parameters passed
2022

21-
* function pointer : choose the mode of transfer
22-
* provSchemeBLE - Using BLE
23-
* provSchemeSoftAP - Using SoftAP
24-
25-
* security : choose security type
26-
* WIFI_PROV_SECURITY_1 - It allows secure communication which consists of secure handshake using key exchange and proof of possession (pop) and encryption/decryption of messages.
23+
- Function pointer: Choose the mode of transfer
24+
- `provSchemeBLE` - Using BLE
25+
- `provSchemeSoftAP` - Using SoftAP
26+
27+
- `security`: Choose the security type
28+
- `WIFI_PROV_SECURITY_1` - Enables secure communication with a secure handshake using key exchange and proof of possession (pop), and encryption/decryption of messages.
29+
- `WIFI_PROV_SECURITY_0` - Does not provide application-level security, allowing plain text communication.
2730

28-
* WIFI_PROV_SECURITY_0 - It do not provide application level security, it involve simply plain text communication.
31+
- `scheme_event_handler`: Specify the handlers according to the chosen mode
32+
- BLE:
33+
- `WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM` - Used when the application doesn't need BT and BLE after provisioning is finished.
34+
- `WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE` - Used when the application doesn't need BLE to be active after provisioning is finished.
35+
- `WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT` - Used when the application doesn't need BT to be active after provisioning is finished.
2936

30-
* scheme_event_handler : specify the handlers according to the mode chosen
31-
* BLE :
32-
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM - This scheme event handler is used when application doesn't need BT and BLE after provisioning is finised
33-
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE - This scheme event handler is used when application doesn't need BLE to be active after provisioning is finised
34-
- WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT - This scheme event handler is used when application doesn't need BT to be active after provisioning is finised
37+
- SoftAP:
38+
- `WIFI_PROV_EVENT_HANDLER_NONE`
3539

36-
* SoftAp :
37-
- WIFI_PROV_EVENT_HANDLER_NONE
40+
- `pop`: String used for authentication.
3841

39-
* pop : It is the string that is used to provide the authentication.
42+
- `service_name`: Specify the service name for the device. If not specified, the default chosen name is `PROV_XXX`, where XXX represents the last 3 bytes of the MAC address.
4043

41-
* service_name : Specify service name for the device, if it is not specified then default chosen name is PROV_XXX where XXX are the last 3 bytes of the MAC address.
44+
- `service_key`: Specify the service key. If the chosen mode of provisioning is BLE, the `service_key` is always NULL.
4245

43-
* service_key : Specify service key, if chosen mode of provisioning is BLE then service_key is always NULL
46+
- `uuid`: Users can specify their own 128-bit UUID while provisioning using BLE. If not specified, the default value is:
4447

45-
* uuid : user can specify there own 128 bit UUID while provisioning using BLE, if not specified then default value taken is
46-
- { 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,
47-
0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02, }
48+
```
49+
{ 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf, 0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02 }
50+
```
4851

49-
# NOTE
52+
- `reset_provisioned`: Resets previously provisioned data before initializing. Using this prevents problem when the device automatically connects to previously connected WiFi and therefore cannot be found.
5053

51-
* If none of the parameters are specified in beginProvision then default provisioning takes place using SoftAP with
52-
* scheme = WIFI_PROV_SCHEME_SOFTAP
53-
* scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE
54-
* security = WIFI_PROV_SECURITY_1
55-
* pop = "abcd1234"
56-
* service_name = "PROV_XXX"
57-
* service_key = NULL
58-
* uuid = NULL
54+
**NOTE:** If none of the parameters are specified in `beginProvision`, default provisioning takes place using SoftAP with the following settings:
55+
- `scheme = WIFI_PROV_SCHEME_SOFTAP`
56+
- `scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE`
57+
- `security = WIFI_PROV_SECURITY_1`
58+
- `pop = "abcd1234"`
59+
- `service_name = "PROV_XXX"`
60+
- `service_key = NULL`
61+
- `uuid = NULL`
62+
- `reset_provisioned = false`
5963

60-
# Log Output
61-
* Enable debuger : [ Tools -> Core Debug Level -> Info ]
64+
## Flashing
65+
This sketch takes up a lot of space for the app and may not be able to flash with default setting on some chips.
66+
If you see Error like this: "Sketch too big"
67+
In Arduino IDE go to: Tools > Partition scheme > chose anything that has more than 1.4MB APP for example `No OTA (2MB APP/2MB SPIFFS)`
6268

63-
# Provisioning Tools
64-
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/provisioning/wifi_provisioning.html#provisioning-tools
69+
## Log Output
70+
- To enable debugging: Go to Tools -> Core Debug Level -> Info.
6571

66-
# Example output
72+
## Provisioning Tools
73+
[Provisioning Tools](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/provisioning/wifi_provisioning.html#provisioning-tools)
6774

68-
## Provisioning using SoftAP
75+
## Example Output
6976

77+
### Provisioning using SoftAP
7078
```
7179
[I][WiFiProv.cpp:117] beginProvision(): Starting AP using SOFTAP
72-
service_name : PROV_XXX
73-
password : 123456789
74-
pop : abcd1234
80+
service_name: PROV_XXX
81+
password: 123456789
82+
pop: abcd1234
7583
7684
Provisioning started
77-
Give Credentials of your access point using " Android app "
85+
Give Credentials of your access point using "Android app"
7886
7987
Received Wi-Fi credentials
80-
SSID : GIONEE M2
81-
Password : 123456789
88+
SSID: GIONEE M2
89+
Password: 123456789
8290
83-
Connected IP address : 192.168.43.120
91+
Connected IP address: 192.168.43.120
8492
Provisioning Successful
8593
Provisioning Ends
86-
8794
```
8895

89-
## Provisioning using BLE
90-
96+
### Provisioning using BLE
9197
```
9298
[I][WiFiProv.cpp:115] beginProvision(): Starting AP using BLE
93-
service_name : PROV_XXX
94-
pop : abcd1234
99+
service_name: PROV_XXX
100+
pop: abcd1234
95101
96102
Provisioning started
97-
Give Credentials of your access point using " Android app "
103+
Give Credentials of your access point using "Android app"
98104
99105
Received Wi-Fi credentials
100-
SSID : GIONEE M2
101-
Password : 123456789
106+
SSID: GIONEE M2
107+
Password: 123456789
102108
103-
Connected IP address : 192.168.43.120
109+
Connected IP address: 192.168.43.120
104110
Provisioning Successful
105111
Provisioning Ends
106-
107112
```
108113

109-
## Credentials are available on device
110-
111-
```
112-
[I][WiFiProv.cpp:146] beginProvision(): Aleardy Provisioned, starting Wi-Fi STA
113-
[I][WiFiProv.cpp:150] beginProvision(): SSID : Wce*****
114-
[I][WiFiProv.cpp:152] beginProvision(): CONNECTING TO THE ACCESS POINT :
115-
Connected IP address : 192.168.43.120
114+
### Credentials are available on the device
116115
```
116+
[I][WiFiProv.cpp:146] beginProvision(): Already Provisioned, starting Wi-Fi STA
117+
[I][WiFiProv.cpp:150] beginProvision(): SSID: Wce*****
118+
[I][WiFiProv.cpp:152] beginProvision(): CONNECTING TO THE ACCESS POINT:
119+
Connected IP address: 192.168.43.120
120+
```

Diff for: libraries/WiFiProv/examples/WiFiProv/WiFiProv.ino

+40-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
1+
/*
2+
Please read README.md file in this folder, or on the web:
3+
https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFiProv/examples/WiFiProv
4+
5+
Note: This sketch takes up a lot of space for the app and may not be able to flash with default setting on some chips.
6+
If you see Error like this: "Sketch too big"
7+
In Arduino IDE go to: Tools > Partition scheme > chose anything that has more than 1.4MB APP
8+
- for example "No OTA (2MB APP/2MB SPIFFS)"
9+
*/
10+
111
#include "WiFiProv.h"
212
#include "WiFi.h"
13+
14+
// #define USE_SOFT_AP // Uncomment if you want to enforce using Soft AP method instead of BLE
15+
16+
const char * pop = "abcd1234"; // Proof of possession - otherwise called a PIN - string provided by the device, entered by user in the phone app
17+
const char * service_name = "PROV_123"; // Name of your device (the Espressif apps expects by default device name starting with "Prov_")
18+
const char * service_key = NULL; // Password used for SofAP method (NULL = no password needed)
19+
bool reset_provisioned = true; // When true the library will automatically delete previously provisioned data.
20+
321
void SysProvEvent(arduino_event_t *sys_event)
422
{
523
switch (sys_event->event_id) {
@@ -11,22 +29,22 @@ void SysProvEvent(arduino_event_t *sys_event)
1129
Serial.println("\nDisconnected. Connecting to the AP again... ");
1230
break;
1331
case ARDUINO_EVENT_PROV_START:
14-
Serial.println("\nProvisioning started\nGive Credentials of your access point using \" Android app \"");
32+
Serial.println("\nProvisioning started\nGive Credentials of your access point using smartphone app");
1533
break;
16-
case ARDUINO_EVENT_PROV_CRED_RECV: {
34+
case ARDUINO_EVENT_PROV_CRED_RECV: {
1735
Serial.println("\nReceived Wi-Fi credentials");
1836
Serial.print("\tSSID : ");
1937
Serial.println((const char *) sys_event->event_info.prov_cred_recv.ssid);
2038
Serial.print("\tPassword : ");
2139
Serial.println((char const *) sys_event->event_info.prov_cred_recv.password);
2240
break;
2341
}
24-
case ARDUINO_EVENT_PROV_CRED_FAIL: {
42+
case ARDUINO_EVENT_PROV_CRED_FAIL: {
2543
Serial.println("\nProvisioning failed!\nPlease reset to factory and retry provisioning\n");
26-
if(sys_event->event_info.prov_fail_reason == WIFI_PROV_STA_AUTH_ERROR)
44+
if(sys_event->event_info.prov_fail_reason == WIFI_PROV_STA_AUTH_ERROR)
2745
Serial.println("\nWi-Fi AP password incorrect");
2846
else
29-
Serial.println("\nWi-Fi AP not found....Add API \" nvs_flash_erase() \" before beginProvision()");
47+
Serial.println("\nWi-Fi AP not found....Add API \" nvs_flash_erase() \" before beginProvision()");
3048
break;
3149
}
3250
case ARDUINO_EVENT_PROV_CRED_SUCCESS:
@@ -42,15 +60,26 @@ void SysProvEvent(arduino_event_t *sys_event)
4260

4361
void setup() {
4462
Serial.begin(115200);
45-
//Sample uuid that user can pass during provisioning using BLE
46-
/* uint8_t uuid[16] = {0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,
47-
0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02 };*/
4863
WiFi.onEvent(SysProvEvent);
49-
#if CONFIG_IDF_TARGET_ESP32 && CONFIG_BLUEDROID_ENABLED
50-
WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, "abcd1234", "Prov_123");
64+
65+
#if CONFIG_IDF_TARGET_ESP32 && CONFIG_BLUEDROID_ENABLED && not USE_SOFT_AP
66+
Serial.println("Begin Provisioning using BLE");
67+
// Sample uuid that user can pass during provisioning using BLE
68+
uint8_t uuid[16] = {0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,
69+
0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02 };
70+
WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name, service_key, uuid, reset_provisioned);
5171
#else
52-
WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, "abcd1234", "Prov_123");
72+
Serial.println("Begin Provisioning using Soft AP");
73+
WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name, service_key);
5374
#endif
75+
76+
#if CONFIG_BLUEDROID_ENABLED && not USE_SOFT_AP
77+
log_d("ble qr");
78+
WiFiProv.printQR(service_name, pop, "ble");
79+
#else
80+
log_d("wifi qr");
81+
WiFiProv.printQR(service_name, pop, "softap");
82+
#endif
5483
}
5584

5685
void loop() {

Diff for: libraries/WiFiProv/src/WiFiProv.cpp

+37-5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
#include <esp_wifi.h>
2727
#include <esp_event.h>
2828
#include <esp32-hal.h>
29+
#if __has_include("qrcode.h")
30+
#include "qrcode.h"
31+
#endif
2932

3033
#include <nvs_flash.h>
3134
#if CONFIG_BLUEDROID_ENABLED
@@ -66,7 +69,7 @@ static void get_device_service_name(prov_scheme_t prov_scheme, char *service_nam
6669
#endif
6770
}
6871

69-
void WiFiProvClass :: beginProvision(prov_scheme_t prov_scheme, scheme_handler_t scheme_handler, wifi_prov_security_t security, const char * pop, const char *service_name, const char *service_key, uint8_t * uuid)
72+
void WiFiProvClass :: beginProvision(prov_scheme_t prov_scheme, scheme_handler_t scheme_handler, wifi_prov_security_t security, const char * pop, const char *service_name, const char *service_key, uint8_t * uuid, bool reset_provisioned)
7073
{
7174
bool provisioned = false;
7275
static char service_name_temp[32];
@@ -107,10 +110,13 @@ void WiFiProvClass :: beginProvision(prov_scheme_t prov_scheme, scheme_handler_t
107110
log_e("wifi_prov_mgr_init failed!");
108111
return;
109112
}
110-
if(wifi_prov_mgr_is_provisioned(&provisioned) != ESP_OK){
111-
log_e("wifi_prov_mgr_is_provisioned failed!");
112-
wifi_prov_mgr_deinit();
113-
return;
113+
if(reset_provisioned){
114+
log_i("Resetting provisioned data.");
115+
wifi_prov_mgr_reset_provisioning();
116+
}else if(wifi_prov_mgr_is_provisioned(&provisioned) != ESP_OK){
117+
log_e("wifi_prov_mgr_is_provisioned failed!");
118+
wifi_prov_mgr_deinit();
119+
return;
114120
}
115121
if(provisioned == false) {
116122
#if CONFIG_BLUEDROID_ENABLED
@@ -158,4 +164,30 @@ void WiFiProvClass :: beginProvision(prov_scheme_t prov_scheme, scheme_handler_t
158164
}
159165
}
160166

167+
// Copied from IDF example
168+
void WiFiProvClass :: printQR(const char *name, const char *pop, const char *transport){
169+
if (!name || !transport) {
170+
log_w("Cannot generate QR code payload. Data missing.");
171+
return;
172+
}
173+
char payload[150] = {0};
174+
if (pop) {
175+
snprintf(payload, sizeof(payload), "{\"ver\":\"%s\",\"name\":\"%s\"" \
176+
",\"pop\":\"%s\",\"transport\":\"%s\"}",
177+
"v1", name, pop, transport);
178+
} else {
179+
snprintf(payload, sizeof(payload), "{\"ver\":\"%s\",\"name\":\"%s\"" \
180+
",\"transport\":\"%s\"}",
181+
"v1", name, transport);
182+
}
183+
#if __has_include("qrcode.h")
184+
log_i("Scan this QR code from the provisioning application for Provisioning.");
185+
esp_qrcode_config_t cfg = ESP_QRCODE_CONFIG_DEFAULT();
186+
esp_qrcode_generate(&cfg, payload);
187+
#else
188+
log_i("If QR code is not visible, copy paste the below URL in a browser.\n%s?data=%s", "https://espressif.github.io/esp-jumpstart/qrcode.html", payload);
189+
log_i("If you are using Arduino as IDF component, install ESP Rainmaker:\nhttps://github.com/espressif/esp-rainmaker");
190+
#endif
191+
}
192+
161193
WiFiProvClass WiFiProv;

Diff for: libraries/WiFiProv/src/WiFiProv.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ class WiFiProvClass
4747
public:
4848

4949
void beginProvision(prov_scheme_t prov_scheme = WIFI_PROV_SCHEME_SOFTAP, scheme_handler_t scheme_handler = WIFI_PROV_SCHEME_HANDLER_NONE,
50-
wifi_prov_security_t security = WIFI_PROV_SECURITY_1, const char * pop = "abcd1234", const char * service_name = NULL, const char * service_key = NULL, uint8_t *uuid = NULL);
50+
wifi_prov_security_t security = WIFI_PROV_SECURITY_1, const char * pop = "abcd1234", const char * service_name = NULL,
51+
const char * service_key = NULL, uint8_t *uuid = NULL, bool reset_provisioned = false);
52+
void printQR(const char *name, const char *pop, const char *transport);
5153
};
5254

5355
extern WiFiProvClass WiFiProv;

0 commit comments

Comments
 (0)