1
6
7
8
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
99
100
106
107
120
121
122
123
124
125
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
156
157
158
160
161
162
163
164
165
166
167
168
169
170
171
172
175
176
177
178
179
180
181
182
183
184
185
190
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
217
220
221
222
223
224
228
229
234
235
236
243
248
249
254
255
256
257
258
259
260
271
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
303
304
305
306
308
309
314
317
323
329
333
341
345
349
350
351
352
353
354
355
356
357
358
359
360
361
362
367
368
369
370
371
375
378
384
395
396
401
402
403
404
405
406
407
408
413
414
415
416
417
418
419
430
438
446
454
467
471
474
477
480
483
486
489
491
492
493
494
495
496
497
498
499
500
504
505
506
507
508
509
515
516
517
521
522
523
/* ... */
/* ... */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_mac.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"12 includes
#if CONFIG_BT_CONTROLLER_ENABLED || !CONFIG_BT_NIMBLE_ENABLED
#include "esp_bt.h"
#endif
#include "esp_blufi_api.h"
#include "blufi_example.h"
#include "esp_blufi.h"
#define EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY CONFIG_EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY
#define EXAMPLE_INVALID_REASON 255
#define EXAMPLE_INVALID_RSSI -128
#if CONFIG_ESP_WIFI_AUTH_OPEN
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
#elif CONFIG_ESP_WIFI_AUTH_WEP
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
#elif CONFIG_ESP_WIFI_AUTH_WPA_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA2_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA3_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
#elif CONFIG_ESP_WIFI_AUTH_WAPI_PSK
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
#endif
static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);
#define WIFI_LIST_NUM 10
static wifi_config_t sta_config;
static wifi_config_t ap_config;
static EventGroupHandle_t wifi_event_group;
/* ... */
const int CONNECTED_BIT = BIT0;
static uint8_t example_wifi_retry = 0;
static bool gl_sta_connected = false;
static bool gl_sta_got_ip = false;
static bool ble_is_connected = false;
static uint8_t gl_sta_bssid[6];
static uint8_t gl_sta_ssid[32];
static int gl_sta_ssid_len;
static wifi_sta_list_t gl_sta_list;
static bool gl_sta_is_connecting = false;
static esp_blufi_extra_info_t gl_sta_conn_info;
static void example_record_wifi_conn_info(int rssi, uint8_t reason)
{
memset(&gl_sta_conn_info, 0, sizeof(esp_blufi_extra_info_t));
if (gl_sta_is_connecting) {
gl_sta_conn_info.sta_max_conn_retry_set = true;
gl_sta_conn_info.sta_max_conn_retry = EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY;
}{...} else {
gl_sta_conn_info.sta_conn_rssi_set = true;
gl_sta_conn_info.sta_conn_rssi = rssi;
gl_sta_conn_info.sta_conn_end_reason_set = true;
gl_sta_conn_info.sta_conn_end_reason = reason;
}{...}
}{ ... }
static void example_wifi_connect(void)
{
example_wifi_retry = 0;
gl_sta_is_connecting = (esp_wifi_connect() == ESP_OK);
example_record_wifi_conn_info(EXAMPLE_INVALID_RSSI, EXAMPLE_INVALID_REASON);
}{ ... }
static bool example_wifi_reconnect(void)
{
bool ret;
if (gl_sta_is_connecting && example_wifi_retry++ < EXAMPLE_WIFI_CONNECTION_MAXIMUM_RETRY) {
BLUFI_INFO("BLUFI WiFi starts reconnection\n");
gl_sta_is_connecting = (esp_wifi_connect() == ESP_OK);
example_record_wifi_conn_info(EXAMPLE_INVALID_RSSI, EXAMPLE_INVALID_REASON);
ret = true;
}{...} else {
ret = false;
}{...}
return ret;
}{ ... }
static int softap_get_current_connection_number(void)
{
esp_err_t ret;
ret = esp_wifi_ap_get_sta_list(&gl_sta_list);
if (ret == ESP_OK)
{
return gl_sta_list.num;
}{...}
return 0;
}{ ... }
static void ip_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
wifi_mode_t mode;
switch (event_id) {
case IP_EVENT_STA_GOT_IP: {
esp_blufi_extra_info_t info;
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
esp_wifi_get_mode(&mode);
memset(&info, 0, sizeof(esp_blufi_extra_info_t));
memcpy(info.sta_bssid, gl_sta_bssid, 6);
info.sta_bssid_set = true;
info.sta_ssid = gl_sta_ssid;
info.sta_ssid_len = gl_sta_ssid_len;
gl_sta_got_ip = true;
if (ble_is_connected == true) {
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_SUCCESS, softap_get_current_connection_number(), &info);
}{...} else {
BLUFI_INFO("BLUFI BLE is not connected yet\n");
}{...}
break;
}{...}
... default:
break;...
}{...}
return;
}{ ... }
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
wifi_event_sta_connected_t *event;
wifi_event_sta_disconnected_t *disconnected_event;
wifi_mode_t mode;
switch (event_id) {
case WIFI_EVENT_STA_START:
example_wifi_connect();
break;...
case WIFI_EVENT_STA_CONNECTED:
gl_sta_connected = true;
gl_sta_is_connecting = false;
event = (wifi_event_sta_connected_t*) event_data;
memcpy(gl_sta_bssid, event->bssid, 6);
memcpy(gl_sta_ssid, event->ssid, event->ssid_len);
gl_sta_ssid_len = event->ssid_len;
break;...
case WIFI_EVENT_STA_DISCONNECTED:
if (gl_sta_connected == false && example_wifi_reconnect() == false) {
gl_sta_is_connecting = false;
disconnected_event = (wifi_event_sta_disconnected_t*) event_data;
example_record_wifi_conn_info(disconnected_event->rssi, disconnected_event->reason);
}{...}
/* ... */
gl_sta_connected = false;
gl_sta_got_ip = false;
memset(gl_sta_ssid, 0, 32);
memset(gl_sta_bssid, 0, 6);
gl_sta_ssid_len = 0;
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;...
case WIFI_EVENT_AP_START:
esp_wifi_get_mode(&mode);
if (ble_is_connected == true) {
if (gl_sta_connected) {
esp_blufi_extra_info_t info;
memset(&info, 0, sizeof(esp_blufi_extra_info_t));
memcpy(info.sta_bssid, gl_sta_bssid, 6);
info.sta_bssid_set = true;
info.sta_ssid = gl_sta_ssid;
info.sta_ssid_len = gl_sta_ssid_len;
esp_blufi_send_wifi_conn_report(mode, gl_sta_got_ip ? ESP_BLUFI_STA_CONN_SUCCESS : ESP_BLUFI_STA_NO_IP, softap_get_current_connection_number(), &info);
}{...} else if (gl_sta_is_connecting) {
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONNECTING, softap_get_current_connection_number(), &gl_sta_conn_info);
}{...} else {
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL, softap_get_current_connection_number(), &gl_sta_conn_info);
}{...}
}{...} else {
BLUFI_INFO("BLUFI BLE is not connected yet\n");
}{...}
break;...
case WIFI_EVENT_SCAN_DONE: {
uint16_t apCount = 0;
esp_wifi_scan_get_ap_num(&apCount);
if (apCount == 0) {
BLUFI_INFO("Nothing AP found");
break;
}{...}
wifi_ap_record_t *ap_list = (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * apCount);
if (!ap_list) {
BLUFI_ERROR("malloc error, ap_list is NULL");
esp_wifi_clear_ap_list();
break;
}{...}
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&apCount, ap_list));
esp_blufi_ap_record_t * blufi_ap_list = (esp_blufi_ap_record_t *)malloc(apCount * sizeof(esp_blufi_ap_record_t));
if (!blufi_ap_list) {
if (ap_list) {
free(ap_list);
}{...}
BLUFI_ERROR("malloc error, blufi_ap_list is NULL");
break;
}{...}
for (int i = 0; i < apCount; ++i)
{
blufi_ap_list[i].rssi = ap_list[i].rssi;
memcpy(blufi_ap_list[i].ssid, ap_list[i].ssid, sizeof(ap_list[i].ssid));
}{...}
if (ble_is_connected == true) {
esp_blufi_send_wifi_list(apCount, blufi_ap_list);
}{...} else {
BLUFI_INFO("BLUFI BLE is not connected yet\n");
}{...}
esp_wifi_scan_stop();
free(ap_list);
free(blufi_ap_list);
break;
}{...}
... case WIFI_EVENT_AP_STACONNECTED: {
wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
BLUFI_INFO("station "MACSTR" join, AID=%d", MAC2STR(event->mac), event->aid);
break;
}{...}
... case WIFI_EVENT_AP_STADISCONNECTED: {
wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
BLUFI_INFO("station "MACSTR" leave, AID=%d, reason=%d", MAC2STR(event->mac), event->aid, event->reason);
break;
}{...}
...
default:
break;...
}{...}
return;
}{ ... }
static void initialise_wifi(void)
{
ESP_ERROR_CHECK(esp_netif_init());
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
assert(ap_netif);
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
example_record_wifi_conn_info(EXAMPLE_INVALID_RSSI, EXAMPLE_INVALID_REASON);
ESP_ERROR_CHECK( esp_wifi_start() );
}{ ... }
static esp_blufi_callbacks_t example_callbacks = {
.event_cb = example_event_callback,
.negotiate_data_handler = blufi_dh_negotiate_data_handler,
.encrypt_func = blufi_aes_encrypt,
.decrypt_func = blufi_aes_decrypt,
.checksum_func = blufi_crc_checksum,
}{...};
static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param)
{
/* ... */
switch (event) {
case ESP_BLUFI_EVENT_INIT_FINISH:
BLUFI_INFO("BLUFI init finish\n");
esp_blufi_adv_start();
break;...
case ESP_BLUFI_EVENT_DEINIT_FINISH:
BLUFI_INFO("BLUFI deinit finish\n");
break;...
case ESP_BLUFI_EVENT_BLE_CONNECT:
BLUFI_INFO("BLUFI ble connect\n");
ble_is_connected = true;
esp_blufi_adv_stop();
blufi_security_init();
break;...
case ESP_BLUFI_EVENT_BLE_DISCONNECT:
BLUFI_INFO("BLUFI ble disconnect\n");
ble_is_connected = false;
blufi_security_deinit();
esp_blufi_adv_start();
break;...
case ESP_BLUFI_EVENT_SET_WIFI_OPMODE:
BLUFI_INFO("BLUFI Set WIFI opmode %d\n", param->wifi_mode.op_mode);
ESP_ERROR_CHECK( esp_wifi_set_mode(param->wifi_mode.op_mode) );
break;...
case ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP:
BLUFI_INFO("BLUFI request wifi connect to AP\n");
/* ... */
esp_wifi_disconnect();
example_wifi_connect();
break;...
case ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP:
BLUFI_INFO("BLUFI request wifi disconnect from AP\n");
esp_wifi_disconnect();
break;...
case ESP_BLUFI_EVENT_REPORT_ERROR:
BLUFI_ERROR("BLUFI report error, error code %d\n", param->report_error.state);
esp_blufi_send_error_info(param->report_error.state);
break;...
case ESP_BLUFI_EVENT_GET_WIFI_STATUS: {
wifi_mode_t mode;
esp_blufi_extra_info_t info;
esp_wifi_get_mode(&mode);
if (gl_sta_connected) {
memset(&info, 0, sizeof(esp_blufi_extra_info_t));
memcpy(info.sta_bssid, gl_sta_bssid, 6);
info.sta_bssid_set = true;
info.sta_ssid = gl_sta_ssid;
info.sta_ssid_len = gl_sta_ssid_len;
esp_blufi_send_wifi_conn_report(mode, gl_sta_got_ip ? ESP_BLUFI_STA_CONN_SUCCESS : ESP_BLUFI_STA_NO_IP, softap_get_current_connection_number(), &info);
}{...} else if (gl_sta_is_connecting) {
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONNECTING, softap_get_current_connection_number(), &gl_sta_conn_info);
}{...} else {
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL, softap_get_current_connection_number(), &gl_sta_conn_info);
}{...}
BLUFI_INFO("BLUFI get wifi status from AP\n");
break;
}{...}
... case ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE:
BLUFI_INFO("blufi close a gatt connection");
esp_blufi_disconnect();
break;...
case ESP_BLUFI_EVENT_DEAUTHENTICATE_STA:
break;...
case ESP_BLUFI_EVENT_RECV_STA_BSSID:
memcpy(sta_config.sta.bssid, param->sta_bssid.bssid, 6);
sta_config.sta.bssid_set = 1;
esp_wifi_set_config(WIFI_IF_STA, &sta_config);
BLUFI_INFO("Recv STA BSSID %s\n", sta_config.sta.ssid);
break;...
case ESP_BLUFI_EVENT_RECV_STA_SSID:
if (param->sta_ssid.ssid_len >= sizeof(sta_config.sta.ssid)/sizeof(sta_config.sta.ssid[0])) {
esp_blufi_send_error_info(ESP_BLUFI_DATA_FORMAT_ERROR);
BLUFI_INFO("Invalid STA SSID\n");
break;
}{...}
strncpy((char *)sta_config.sta.ssid, (char *)param->sta_ssid.ssid, param->sta_ssid.ssid_len);
sta_config.sta.ssid[param->sta_ssid.ssid_len] = '\0';
esp_wifi_set_config(WIFI_IF_STA, &sta_config);
BLUFI_INFO("Recv STA SSID %s\n", sta_config.sta.ssid);
break;...
case ESP_BLUFI_EVENT_RECV_STA_PASSWD:
if (param->sta_passwd.passwd_len >= sizeof(sta_config.sta.password)/sizeof(sta_config.sta.password[0])) {
esp_blufi_send_error_info(ESP_BLUFI_DATA_FORMAT_ERROR);
BLUFI_INFO("Invalid STA PASSWORD\n");
break;
}{...}
strncpy((char *)sta_config.sta.password, (char *)param->sta_passwd.passwd, param->sta_passwd.passwd_len);
sta_config.sta.password[param->sta_passwd.passwd_len] = '\0';
sta_config.sta.threshold.authmode = EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD;
esp_wifi_set_config(WIFI_IF_STA, &sta_config);
BLUFI_INFO("Recv STA PASSWORD %s\n", sta_config.sta.password);
break;...
case ESP_BLUFI_EVENT_RECV_SOFTAP_SSID:
if (param->softap_ssid.ssid_len >= sizeof(ap_config.ap.ssid)/sizeof(ap_config.ap.ssid[0])) {
esp_blufi_send_error_info(ESP_BLUFI_DATA_FORMAT_ERROR);
BLUFI_INFO("Invalid SOFTAP SSID\n");
break;
}{...}
strncpy((char *)ap_config.ap.ssid, (char *)param->softap_ssid.ssid, param->softap_ssid.ssid_len);
ap_config.ap.ssid[param->softap_ssid.ssid_len] = '\0';
ap_config.ap.ssid_len = param->softap_ssid.ssid_len;
esp_wifi_set_config(WIFI_IF_AP, &ap_config);
BLUFI_INFO("Recv SOFTAP SSID %s, ssid len %d\n", ap_config.ap.ssid, ap_config.ap.ssid_len);
break;...
case ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD:
if (param->softap_passwd.passwd_len >= sizeof(ap_config.ap.password)/sizeof(ap_config.ap.password[0])) {
esp_blufi_send_error_info(ESP_BLUFI_DATA_FORMAT_ERROR);
BLUFI_INFO("Invalid SOFTAP PASSWD\n");
break;
}{...}
strncpy((char *)ap_config.ap.password, (char *)param->softap_passwd.passwd, param->softap_passwd.passwd_len);
ap_config.ap.password[param->softap_passwd.passwd_len] = '\0';
esp_wifi_set_config(WIFI_IF_AP, &ap_config);
BLUFI_INFO("Recv SOFTAP PASSWORD %s len = %d\n", ap_config.ap.password, param->softap_passwd.passwd_len);
break;...
case ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM:
if (param->softap_max_conn_num.max_conn_num > 4) {
return;
}{...}
ap_config.ap.max_connection = param->softap_max_conn_num.max_conn_num;
esp_wifi_set_config(WIFI_IF_AP, &ap_config);
BLUFI_INFO("Recv SOFTAP MAX CONN NUM %d\n", ap_config.ap.max_connection);
break;...
case ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE:
if (param->softap_auth_mode.auth_mode >= WIFI_AUTH_MAX) {
return;
}{...}
ap_config.ap.authmode = param->softap_auth_mode.auth_mode;
esp_wifi_set_config(WIFI_IF_AP, &ap_config);
BLUFI_INFO("Recv SOFTAP AUTH MODE %d\n", ap_config.ap.authmode);
break;...
case ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL:
if (param->softap_channel.channel > 13) {
return;
}{...}
ap_config.ap.channel = param->softap_channel.channel;
esp_wifi_set_config(WIFI_IF_AP, &ap_config);
BLUFI_INFO("Recv SOFTAP CHANNEL %d\n", ap_config.ap.channel);
break;...
case ESP_BLUFI_EVENT_GET_WIFI_LIST:{
wifi_scan_config_t scanConf = {
.ssid = NULL,
.bssid = NULL,
.channel = 0,
.show_hidden = false
}{...};
esp_err_t ret = esp_wifi_scan_start(&scanConf, true);
if (ret != ESP_OK) {
esp_blufi_send_error_info(ESP_BLUFI_WIFI_SCAN_FAIL);
}{...}
break;
}{...}
case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA:
BLUFI_INFO("Recv Custom Data %" PRIu32 "\n", param->custom_data.data_len);
ESP_LOG_BUFFER_HEX("Custom Data", param->custom_data.data, param->custom_data.data_len);
break;...
case ESP_BLUFI_EVENT_RECV_USERNAME:
break;...
case ESP_BLUFI_EVENT_RECV_CA_CERT:
break;...
case ESP_BLUFI_EVENT_RECV_CLIENT_CERT:
break;...
case ESP_BLUFI_EVENT_RECV_SERVER_CERT:
break;...
case ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY:
break;;...
case ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY:
break;...
default:
break;...
}{...}
}{ ... }
void app_main(void)
{
esp_err_t ret;
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}{...}
ESP_ERROR_CHECK( ret );
initialise_wifi();
#if CONFIG_BT_CONTROLLER_ENABLED || !CONFIG_BT_NIMBLE_ENABLED
ret = esp_blufi_controller_init();
if (ret) {
BLUFI_ERROR("%s BLUFI controller init failed: %s\n", __func__, esp_err_to_name(ret));
return;
}{...}
#endif/* ... */
ret = esp_blufi_host_and_cb_init(&example_callbacks);
if (ret) {
BLUFI_ERROR("%s initialise failed: %s\n", __func__, esp_err_to_name(ret));
return;
}{...}
BLUFI_INFO("BLUFI VERSION %04x\n", esp_blufi_get_version());
}{ ... }