blufi_example_main.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. /****************************************************************************
  7. * This is a demo for bluetooth config wifi connection to ap. You can config ESP32 to connect a softap
  8. * or config ESP32 as a softap to be connected by other device. APP can be downloaded from github
  9. * android source code: https://github.com/EspressifApp/EspBlufi
  10. * iOS source code: https://github.com/EspressifApp/EspBlufiForiOS
  11. ****************************************************************************/
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "freertos/FreeRTOS.h"
  16. #include "freertos/task.h"
  17. #include "freertos/event_groups.h"
  18. #include "esp_system.h"
  19. #include "esp_mac.h"
  20. #include "esp_wifi.h"
  21. #include "esp_event.h"
  22. #include "esp_log.h"
  23. #include "nvs_flash.h"
  24. #include "esp_bt.h"
  25. #include "esp_blufi_api.h"
  26. #include "blufi_example.h"
  27. #include "esp_blufi.h"
  28. static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);
  29. #define WIFI_LIST_NUM 10
  30. static wifi_config_t sta_config;
  31. static wifi_config_t ap_config;
  32. /* FreeRTOS event group to signal when we are connected & ready to make a request */
  33. static EventGroupHandle_t wifi_event_group;
  34. /* The event group allows multiple bits for each event,
  35. but we only care about one event - are we connected
  36. to the AP with an IP? */
  37. const int CONNECTED_BIT = BIT0;
  38. /* store the station info for send back to phone */
  39. static bool gl_sta_connected = false;
  40. static bool ble_is_connected = false;
  41. static uint8_t gl_sta_bssid[6];
  42. static uint8_t gl_sta_ssid[32];
  43. static int gl_sta_ssid_len;
  44. static wifi_sta_list_t gl_sta_list;
  45. static int softap_get_current_connection_number(void)
  46. {
  47. esp_err_t ret;
  48. ret = esp_wifi_ap_get_sta_list(&gl_sta_list);
  49. if (ret == ESP_OK)
  50. {
  51. return gl_sta_list.num;
  52. }
  53. return 0;
  54. }
  55. static void ip_event_handler(void* arg, esp_event_base_t event_base,
  56. int32_t event_id, void* event_data)
  57. {
  58. wifi_mode_t mode;
  59. switch (event_id) {
  60. case IP_EVENT_STA_GOT_IP: {
  61. esp_blufi_extra_info_t info;
  62. xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
  63. esp_wifi_get_mode(&mode);
  64. memset(&info, 0, sizeof(esp_blufi_extra_info_t));
  65. memcpy(info.sta_bssid, gl_sta_bssid, 6);
  66. info.sta_bssid_set = true;
  67. info.sta_ssid = gl_sta_ssid;
  68. info.sta_ssid_len = gl_sta_ssid_len;
  69. if (ble_is_connected == true) {
  70. esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_SUCCESS, softap_get_current_connection_number(), &info);
  71. } else {
  72. BLUFI_INFO("BLUFI BLE is not connected yet\n");
  73. }
  74. break;
  75. }
  76. default:
  77. break;
  78. }
  79. return;
  80. }
  81. static void wifi_event_handler(void* arg, esp_event_base_t event_base,
  82. int32_t event_id, void* event_data)
  83. {
  84. wifi_event_sta_connected_t *event;
  85. wifi_mode_t mode;
  86. switch (event_id) {
  87. case WIFI_EVENT_STA_START:
  88. esp_wifi_connect();
  89. break;
  90. case WIFI_EVENT_STA_CONNECTED:
  91. gl_sta_connected = true;
  92. event = (wifi_event_sta_connected_t*) event_data;
  93. memcpy(gl_sta_bssid, event->bssid, 6);
  94. memcpy(gl_sta_ssid, event->ssid, event->ssid_len);
  95. gl_sta_ssid_len = event->ssid_len;
  96. break;
  97. case WIFI_EVENT_STA_DISCONNECTED:
  98. /* This is a workaround as ESP32 WiFi libs don't currently
  99. auto-reassociate. */
  100. gl_sta_connected = false;
  101. memset(gl_sta_ssid, 0, 32);
  102. memset(gl_sta_bssid, 0, 6);
  103. gl_sta_ssid_len = 0;
  104. esp_wifi_connect();
  105. xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
  106. break;
  107. case WIFI_EVENT_AP_START:
  108. esp_wifi_get_mode(&mode);
  109. /* TODO: get config or information of softap, then set to report extra_info */
  110. if (ble_is_connected == true) {
  111. if (gl_sta_connected) {
  112. esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_SUCCESS, softap_get_current_connection_number(), NULL);
  113. } else {
  114. esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL, softap_get_current_connection_number(), NULL);
  115. }
  116. } else {
  117. BLUFI_INFO("BLUFI BLE is not connected yet\n");
  118. }
  119. break;
  120. case WIFI_EVENT_SCAN_DONE: {
  121. uint16_t apCount = 0;
  122. esp_wifi_scan_get_ap_num(&apCount);
  123. if (apCount == 0) {
  124. BLUFI_INFO("Nothing AP found");
  125. break;
  126. }
  127. wifi_ap_record_t *ap_list = (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * apCount);
  128. if (!ap_list) {
  129. BLUFI_ERROR("malloc error, ap_list is NULL");
  130. break;
  131. }
  132. ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&apCount, ap_list));
  133. esp_blufi_ap_record_t * blufi_ap_list = (esp_blufi_ap_record_t *)malloc(apCount * sizeof(esp_blufi_ap_record_t));
  134. if (!blufi_ap_list) {
  135. if (ap_list) {
  136. free(ap_list);
  137. }
  138. BLUFI_ERROR("malloc error, blufi_ap_list is NULL");
  139. break;
  140. }
  141. for (int i = 0; i < apCount; ++i)
  142. {
  143. blufi_ap_list[i].rssi = ap_list[i].rssi;
  144. memcpy(blufi_ap_list[i].ssid, ap_list[i].ssid, sizeof(ap_list[i].ssid));
  145. }
  146. if (ble_is_connected == true) {
  147. esp_blufi_send_wifi_list(apCount, blufi_ap_list);
  148. } else {
  149. BLUFI_INFO("BLUFI BLE is not connected yet\n");
  150. }
  151. esp_wifi_scan_stop();
  152. free(ap_list);
  153. free(blufi_ap_list);
  154. break;
  155. }
  156. case WIFI_EVENT_AP_STACONNECTED: {
  157. wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
  158. BLUFI_INFO("station "MACSTR" join, AID=%d", MAC2STR(event->mac), event->aid);
  159. break;
  160. }
  161. case WIFI_EVENT_AP_STADISCONNECTED: {
  162. wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
  163. BLUFI_INFO("station "MACSTR" leave, AID=%d", MAC2STR(event->mac), event->aid);
  164. break;
  165. }
  166. default:
  167. break;
  168. }
  169. return;
  170. }
  171. static void initialise_wifi(void)
  172. {
  173. ESP_ERROR_CHECK(esp_netif_init());
  174. wifi_event_group = xEventGroupCreate();
  175. ESP_ERROR_CHECK(esp_event_loop_create_default());
  176. esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
  177. assert(sta_netif);
  178. esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
  179. assert(ap_netif);
  180. ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
  181. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL));
  182. wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  183. ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
  184. ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
  185. ESP_ERROR_CHECK( esp_wifi_start() );
  186. }
  187. static esp_blufi_callbacks_t example_callbacks = {
  188. .event_cb = example_event_callback,
  189. .negotiate_data_handler = blufi_dh_negotiate_data_handler,
  190. .encrypt_func = blufi_aes_encrypt,
  191. .decrypt_func = blufi_aes_decrypt,
  192. .checksum_func = blufi_crc_checksum,
  193. };
  194. static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param)
  195. {
  196. /* actually, should post to blufi_task handle the procedure,
  197. * now, as a example, we do it more simply */
  198. switch (event) {
  199. case ESP_BLUFI_EVENT_INIT_FINISH:
  200. BLUFI_INFO("BLUFI init finish\n");
  201. esp_blufi_adv_start();
  202. break;
  203. case ESP_BLUFI_EVENT_DEINIT_FINISH:
  204. BLUFI_INFO("BLUFI deinit finish\n");
  205. break;
  206. case ESP_BLUFI_EVENT_BLE_CONNECT:
  207. BLUFI_INFO("BLUFI ble connect\n");
  208. ble_is_connected = true;
  209. esp_blufi_adv_stop();
  210. blufi_security_init();
  211. break;
  212. case ESP_BLUFI_EVENT_BLE_DISCONNECT:
  213. BLUFI_INFO("BLUFI ble disconnect\n");
  214. ble_is_connected = false;
  215. blufi_security_deinit();
  216. esp_blufi_adv_start();
  217. break;
  218. case ESP_BLUFI_EVENT_SET_WIFI_OPMODE:
  219. BLUFI_INFO("BLUFI Set WIFI opmode %d\n", param->wifi_mode.op_mode);
  220. ESP_ERROR_CHECK( esp_wifi_set_mode(param->wifi_mode.op_mode) );
  221. break;
  222. case ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP:
  223. BLUFI_INFO("BLUFI requset wifi connect to AP\n");
  224. /* there is no wifi callback when the device has already connected to this wifi
  225. so disconnect wifi before connection.
  226. */
  227. esp_wifi_disconnect();
  228. esp_wifi_connect();
  229. break;
  230. case ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP:
  231. BLUFI_INFO("BLUFI requset wifi disconnect from AP\n");
  232. esp_wifi_disconnect();
  233. break;
  234. case ESP_BLUFI_EVENT_REPORT_ERROR:
  235. BLUFI_ERROR("BLUFI report error, error code %d\n", param->report_error.state);
  236. esp_blufi_send_error_info(param->report_error.state);
  237. break;
  238. case ESP_BLUFI_EVENT_GET_WIFI_STATUS: {
  239. wifi_mode_t mode;
  240. esp_blufi_extra_info_t info;
  241. esp_wifi_get_mode(&mode);
  242. if (gl_sta_connected) {
  243. memset(&info, 0, sizeof(esp_blufi_extra_info_t));
  244. memcpy(info.sta_bssid, gl_sta_bssid, 6);
  245. info.sta_bssid_set = true;
  246. info.sta_ssid = gl_sta_ssid;
  247. info.sta_ssid_len = gl_sta_ssid_len;
  248. esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_SUCCESS, softap_get_current_connection_number(), &info);
  249. } else {
  250. esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL, softap_get_current_connection_number(), NULL);
  251. }
  252. BLUFI_INFO("BLUFI get wifi status from AP\n");
  253. break;
  254. }
  255. case ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE:
  256. BLUFI_INFO("blufi close a gatt connection");
  257. esp_blufi_disconnect();
  258. break;
  259. case ESP_BLUFI_EVENT_DEAUTHENTICATE_STA:
  260. /* TODO */
  261. break;
  262. case ESP_BLUFI_EVENT_RECV_STA_BSSID:
  263. memcpy(sta_config.sta.bssid, param->sta_bssid.bssid, 6);
  264. sta_config.sta.bssid_set = 1;
  265. esp_wifi_set_config(WIFI_IF_STA, &sta_config);
  266. BLUFI_INFO("Recv STA BSSID %s\n", sta_config.sta.ssid);
  267. break;
  268. case ESP_BLUFI_EVENT_RECV_STA_SSID:
  269. strncpy((char *)sta_config.sta.ssid, (char *)param->sta_ssid.ssid, param->sta_ssid.ssid_len);
  270. sta_config.sta.ssid[param->sta_ssid.ssid_len] = '\0';
  271. esp_wifi_set_config(WIFI_IF_STA, &sta_config);
  272. BLUFI_INFO("Recv STA SSID %s\n", sta_config.sta.ssid);
  273. break;
  274. case ESP_BLUFI_EVENT_RECV_STA_PASSWD:
  275. strncpy((char *)sta_config.sta.password, (char *)param->sta_passwd.passwd, param->sta_passwd.passwd_len);
  276. sta_config.sta.password[param->sta_passwd.passwd_len] = '\0';
  277. esp_wifi_set_config(WIFI_IF_STA, &sta_config);
  278. BLUFI_INFO("Recv STA PASSWORD %s\n", sta_config.sta.password);
  279. break;
  280. case ESP_BLUFI_EVENT_RECV_SOFTAP_SSID:
  281. strncpy((char *)ap_config.ap.ssid, (char *)param->softap_ssid.ssid, param->softap_ssid.ssid_len);
  282. ap_config.ap.ssid[param->softap_ssid.ssid_len] = '\0';
  283. ap_config.ap.ssid_len = param->softap_ssid.ssid_len;
  284. esp_wifi_set_config(WIFI_IF_AP, &ap_config);
  285. BLUFI_INFO("Recv SOFTAP SSID %s, ssid len %d\n", ap_config.ap.ssid, ap_config.ap.ssid_len);
  286. break;
  287. case ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD:
  288. strncpy((char *)ap_config.ap.password, (char *)param->softap_passwd.passwd, param->softap_passwd.passwd_len);
  289. ap_config.ap.password[param->softap_passwd.passwd_len] = '\0';
  290. esp_wifi_set_config(WIFI_IF_AP, &ap_config);
  291. BLUFI_INFO("Recv SOFTAP PASSWORD %s len = %d\n", ap_config.ap.password, param->softap_passwd.passwd_len);
  292. break;
  293. case ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM:
  294. if (param->softap_max_conn_num.max_conn_num > 4) {
  295. return;
  296. }
  297. ap_config.ap.max_connection = param->softap_max_conn_num.max_conn_num;
  298. esp_wifi_set_config(WIFI_IF_AP, &ap_config);
  299. BLUFI_INFO("Recv SOFTAP MAX CONN NUM %d\n", ap_config.ap.max_connection);
  300. break;
  301. case ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE:
  302. if (param->softap_auth_mode.auth_mode >= WIFI_AUTH_MAX) {
  303. return;
  304. }
  305. ap_config.ap.authmode = param->softap_auth_mode.auth_mode;
  306. esp_wifi_set_config(WIFI_IF_AP, &ap_config);
  307. BLUFI_INFO("Recv SOFTAP AUTH MODE %d\n", ap_config.ap.authmode);
  308. break;
  309. case ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL:
  310. if (param->softap_channel.channel > 13) {
  311. return;
  312. }
  313. ap_config.ap.channel = param->softap_channel.channel;
  314. esp_wifi_set_config(WIFI_IF_AP, &ap_config);
  315. BLUFI_INFO("Recv SOFTAP CHANNEL %d\n", ap_config.ap.channel);
  316. break;
  317. case ESP_BLUFI_EVENT_GET_WIFI_LIST:{
  318. wifi_scan_config_t scanConf = {
  319. .ssid = NULL,
  320. .bssid = NULL,
  321. .channel = 0,
  322. .show_hidden = false
  323. };
  324. esp_wifi_scan_start(&scanConf, true);
  325. break;
  326. }
  327. case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA:
  328. BLUFI_INFO("Recv Custom Data %d\n", param->custom_data.data_len);
  329. esp_log_buffer_hex("Custom Data", param->custom_data.data, param->custom_data.data_len);
  330. break;
  331. case ESP_BLUFI_EVENT_RECV_USERNAME:
  332. /* Not handle currently */
  333. break;
  334. case ESP_BLUFI_EVENT_RECV_CA_CERT:
  335. /* Not handle currently */
  336. break;
  337. case ESP_BLUFI_EVENT_RECV_CLIENT_CERT:
  338. /* Not handle currently */
  339. break;
  340. case ESP_BLUFI_EVENT_RECV_SERVER_CERT:
  341. /* Not handle currently */
  342. break;
  343. case ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY:
  344. /* Not handle currently */
  345. break;;
  346. case ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY:
  347. /* Not handle currently */
  348. break;
  349. default:
  350. break;
  351. }
  352. }
  353. void app_main(void)
  354. {
  355. esp_err_t ret;
  356. // Initialize NVS
  357. ret = nvs_flash_init();
  358. if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  359. ESP_ERROR_CHECK(nvs_flash_erase());
  360. ret = nvs_flash_init();
  361. }
  362. ESP_ERROR_CHECK( ret );
  363. initialise_wifi();
  364. ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
  365. esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
  366. ret = esp_bt_controller_init(&bt_cfg);
  367. if (ret) {
  368. BLUFI_ERROR("%s initialize bt controller failed: %s\n", __func__, esp_err_to_name(ret));
  369. }
  370. ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
  371. if (ret) {
  372. BLUFI_ERROR("%s enable bt controller failed: %s\n", __func__, esp_err_to_name(ret));
  373. return;
  374. }
  375. ret = esp_blufi_host_and_cb_init(&example_callbacks);
  376. if (ret) {
  377. BLUFI_ERROR("%s initialise failed: %s\n", __func__, esp_err_to_name(ret));
  378. return;
  379. }
  380. BLUFI_INFO("BLUFI VERSION %04x\n", esp_blufi_get_version());
  381. }