1 /* DPP Enrollee Example
2
3 This example code is in the Public Domain (or CC0 licensed, at your option.)
4
5 Unless required by applicable law or agreed to in writing, this
6 software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7 CONDITIONS OF ANY KIND, either express or implied.
8 */
9 #include <string.h>
10 #include "freertos/FreeRTOS.h"
11 #include "freertos/task.h"
12 #include "freertos/event_groups.h"
13 #include "esp_system.h"
14 #include "esp_wifi.h"
15 #include "esp_event.h"
16 #include "esp_dpp.h"
17 #include "esp_log.h"
18 #include "nvs_flash.h"
19 #include "qrcode.h"
20
21 #ifdef CONFIG_ESP_DPP_LISTEN_CHANNEL
22 #define EXAMPLE_DPP_LISTEN_CHANNEL_LIST CONFIG_ESP_DPP_LISTEN_CHANNEL_LIST
23 #else
24 #define EXAMPLE_DPP_LISTEN_CHANNEL_LIST "6"
25 #endif
26
27 #ifdef CONFIG_ESP_DPP_BOOTSTRAPPING_KEY
28 #define EXAMPLE_DPP_BOOTSTRAPPING_KEY CONFIG_ESP_DPP_BOOTSTRAPPING_KEY
29 #else
30 #define EXAMPLE_DPP_BOOTSTRAPPING_KEY 0
31 #endif
32
33 #ifdef CONFIG_ESP_DPP_DEVICE_INFO
34 #define EXAMPLE_DPP_DEVICE_INFO CONFIG_ESP_DPP_DEVICE_INFO
35 #else
36 #define EXAMPLE_DPP_DEVICE_INFO 0
37 #endif
38
39 static const char *TAG = "wifi dpp-enrollee";
40 wifi_config_t s_dpp_wifi_config;
41
42 static int s_retry_num = 0;
43
44 /* FreeRTOS event group to signal when we are connected*/
45 static EventGroupHandle_t s_dpp_event_group;
46
47 #define DPP_CONNECTED_BIT BIT0
48 #define DPP_CONNECT_FAIL_BIT BIT1
49 #define DPP_AUTH_FAIL_BIT BIT2
50
event_handler(void * arg,esp_event_base_t event_base,int32_t event_id,void * event_data)51 static void event_handler(void *arg, esp_event_base_t event_base,
52 int32_t event_id, void *event_data)
53 {
54 if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
55 ESP_ERROR_CHECK(esp_supp_dpp_start_listen());
56 ESP_LOGI(TAG, "Started listening for DPP Authentication");
57 } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
58 if (s_retry_num < 5) {
59 esp_wifi_connect();
60 s_retry_num++;
61 ESP_LOGI(TAG, "retry to connect to the AP");
62 } else {
63 xEventGroupSetBits(s_dpp_event_group, DPP_CONNECT_FAIL_BIT);
64 }
65 ESP_LOGI(TAG, "connect to the AP fail");
66 } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
67 ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
68 ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
69 s_retry_num = 0;
70 xEventGroupSetBits(s_dpp_event_group, DPP_CONNECTED_BIT);
71 }
72 }
73
dpp_enrollee_event_cb(esp_supp_dpp_event_t event,void * data)74 void dpp_enrollee_event_cb(esp_supp_dpp_event_t event, void *data)
75 {
76 switch (event) {
77 case ESP_SUPP_DPP_URI_READY:
78 if (data != NULL) {
79 esp_qrcode_config_t cfg = ESP_QRCODE_CONFIG_DEFAULT();
80
81 ESP_LOGI(TAG, "Scan below QR Code to configure the enrollee:\n");
82 esp_qrcode_generate(&cfg, (const char *)data);
83 }
84 break;
85 case ESP_SUPP_DPP_CFG_RECVD:
86 memcpy(&s_dpp_wifi_config, data, sizeof(s_dpp_wifi_config));
87 esp_wifi_set_config(ESP_IF_WIFI_STA, &s_dpp_wifi_config);
88 ESP_LOGI(TAG, "DPP Authentication successful, connecting to AP : %s",
89 s_dpp_wifi_config.sta.ssid);
90 s_retry_num = 0;
91 esp_wifi_connect();
92 break;
93 case ESP_SUPP_DPP_FAIL:
94 if (s_retry_num < 5) {
95 ESP_LOGI(TAG, "DPP Auth failed (Reason: %s), retry...", esp_err_to_name((int)data));
96 ESP_ERROR_CHECK(esp_supp_dpp_start_listen());
97 s_retry_num++;
98 } else {
99 xEventGroupSetBits(s_dpp_event_group, DPP_AUTH_FAIL_BIT);
100 }
101 break;
102 default:
103 break;
104 }
105 }
106
dpp_enrollee_init(void)107 void dpp_enrollee_init(void)
108 {
109 s_dpp_event_group = xEventGroupCreate();
110
111 ESP_ERROR_CHECK(esp_netif_init());
112
113 ESP_ERROR_CHECK(esp_event_loop_create_default());
114 esp_netif_create_default_wifi_sta();
115
116 ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
117 ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
118
119 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
120 ESP_ERROR_CHECK(esp_wifi_init(&cfg));
121
122 ESP_ERROR_CHECK(esp_supp_dpp_init(dpp_enrollee_event_cb));
123 /* Currently only supported method is QR Code */
124 ESP_ERROR_CHECK(esp_supp_dpp_bootstrap_gen(EXAMPLE_DPP_LISTEN_CHANNEL_LIST, DPP_BOOTSTRAP_QR_CODE,
125 EXAMPLE_DPP_BOOTSTRAPPING_KEY, EXAMPLE_DPP_DEVICE_INFO));
126
127 ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
128 ESP_ERROR_CHECK(esp_wifi_start());
129
130 /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
131 * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
132 EventBits_t bits = xEventGroupWaitBits(s_dpp_event_group,
133 DPP_CONNECTED_BIT | DPP_CONNECT_FAIL_BIT | DPP_AUTH_FAIL_BIT,
134 pdFALSE,
135 pdFALSE,
136 portMAX_DELAY);
137
138 /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
139 * happened. */
140 if (bits & DPP_CONNECTED_BIT) {
141 ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
142 s_dpp_wifi_config.sta.ssid, s_dpp_wifi_config.sta.password);
143 } else if (bits & DPP_CONNECT_FAIL_BIT) {
144 ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
145 s_dpp_wifi_config.sta.ssid, s_dpp_wifi_config.sta.password);
146 } else if (bits & DPP_AUTH_FAIL_BIT) {
147 ESP_LOGI(TAG, "DPP Authentication failed after %d retries", s_retry_num);
148 } else {
149 ESP_LOGE(TAG, "UNEXPECTED EVENT");
150 }
151
152 esp_supp_dpp_deinit();
153 ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler));
154 ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler));
155 vEventGroupDelete(s_dpp_event_group);
156 }
157
app_main(void)158 void app_main(void)
159 {
160 //Initialize NVS
161 esp_err_t ret = nvs_flash_init();
162 if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
163 ESP_ERROR_CHECK(nvs_flash_erase());
164 ret = nvs_flash_init();
165 }
166 ESP_ERROR_CHECK(ret);
167
168 dpp_enrollee_init();
169 }
170