kopia lustrzana https://github.com/espressif/esp-idf
423 wiersze
15 KiB
C
423 wiersze
15 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
|
*/
|
|
|
|
|
|
/****************************************************************************
|
|
* This is a demo for bluetooth config wifi connection to ap. You can config ESP32 to connect a softap
|
|
* or config ESP32 as a softap to be connected by other device. APP can be downloaded from github
|
|
* android source code: https://github.com/EspressifApp/EspBlufi
|
|
* iOS source code: https://github.com/EspressifApp/EspBlufiForiOS
|
|
****************************************************************************/
|
|
|
|
#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"
|
|
#include "esp_bt.h"
|
|
|
|
#include "esp_blufi_api.h"
|
|
#include "blufi_example.h"
|
|
|
|
#include "esp_blufi.h"
|
|
|
|
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;
|
|
|
|
/* FreeRTOS event group to signal when we are connected & ready to make a request */
|
|
static EventGroupHandle_t wifi_event_group;
|
|
|
|
/* The event group allows multiple bits for each event,
|
|
but we only care about one event - are we connected
|
|
to the AP with an IP? */
|
|
const int CONNECTED_BIT = BIT0;
|
|
|
|
/* store the station info for send back to phone */
|
|
static bool gl_sta_connected = 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 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;
|
|
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_mode_t mode;
|
|
|
|
switch (event_id) {
|
|
case WIFI_EVENT_STA_START:
|
|
esp_wifi_connect();
|
|
break;
|
|
case WIFI_EVENT_STA_CONNECTED:
|
|
gl_sta_connected = true;
|
|
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:
|
|
/* This is a workaround as ESP32 WiFi libs don't currently
|
|
auto-reassociate. */
|
|
gl_sta_connected = false;
|
|
memset(gl_sta_ssid, 0, 32);
|
|
memset(gl_sta_bssid, 0, 6);
|
|
gl_sta_ssid_len = 0;
|
|
esp_wifi_connect();
|
|
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
|
break;
|
|
case WIFI_EVENT_AP_START:
|
|
esp_wifi_get_mode(&mode);
|
|
|
|
/* TODO: get config or information of softap, then set to report extra_info */
|
|
if (ble_is_connected == true) {
|
|
if (gl_sta_connected) {
|
|
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_SUCCESS, softap_get_current_connection_number(), NULL);
|
|
} else {
|
|
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL, softap_get_current_connection_number(), NULL);
|
|
}
|
|
} 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");
|
|
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", MAC2STR(event->mac), event->aid);
|
|
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) );
|
|
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)
|
|
{
|
|
/* actually, should post to blufi_task handle the procedure,
|
|
* now, as a example, we do it more simply */
|
|
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 requset wifi connect to AP\n");
|
|
/* there is no wifi callback when the device has already connected to this wifi
|
|
so disconnect wifi before connection.
|
|
*/
|
|
esp_wifi_disconnect();
|
|
esp_wifi_connect();
|
|
break;
|
|
case ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP:
|
|
BLUFI_INFO("BLUFI requset 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, ESP_BLUFI_STA_CONN_SUCCESS, softap_get_current_connection_number(), &info);
|
|
} else {
|
|
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL, softap_get_current_connection_number(), NULL);
|
|
}
|
|
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:
|
|
/* TODO */
|
|
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:
|
|
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:
|
|
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';
|
|
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:
|
|
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:
|
|
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_wifi_scan_start(&scanConf, true);
|
|
break;
|
|
}
|
|
case ESP_BLUFI_EVENT_RECV_CUSTOM_DATA:
|
|
BLUFI_INFO("Recv Custom Data %d\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:
|
|
/* Not handle currently */
|
|
break;
|
|
case ESP_BLUFI_EVENT_RECV_CA_CERT:
|
|
/* Not handle currently */
|
|
break;
|
|
case ESP_BLUFI_EVENT_RECV_CLIENT_CERT:
|
|
/* Not handle currently */
|
|
break;
|
|
case ESP_BLUFI_EVENT_RECV_SERVER_CERT:
|
|
/* Not handle currently */
|
|
break;
|
|
case ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY:
|
|
/* Not handle currently */
|
|
break;;
|
|
case ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY:
|
|
/* Not handle currently */
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void app_main(void)
|
|
{
|
|
esp_err_t ret;
|
|
|
|
// Initialize NVS
|
|
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();
|
|
|
|
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
|
|
|
|
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
|
ret = esp_bt_controller_init(&bt_cfg);
|
|
if (ret) {
|
|
BLUFI_ERROR("%s initialize bt controller failed: %s\n", __func__, esp_err_to_name(ret));
|
|
}
|
|
|
|
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
|
|
if (ret) {
|
|
BLUFI_ERROR("%s enable bt controller failed: %s\n", __func__, esp_err_to_name(ret));
|
|
return;
|
|
}
|
|
|
|
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());
|
|
}
|