mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-20 09:55:54 +08:00
添加智能灯固件代码
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(blufi_demo)
|
||||
@@ -0,0 +1,10 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := blufi_demo
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := components/include
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
@@ -0,0 +1,21 @@
|
||||
| Supported Targets | ESP32 |
|
||||
| ----------------- | ----- |
|
||||
|
||||
ESP-IDF Blufi demo
|
||||
=======================
|
||||
|
||||
This is the demo for bluetooth config wifi connection to ap.
|
||||
|
||||
To test this demo, you need to prepare a mobile phone with blufi application installed. You can download the blufi application from [Android version](https://github.com/EspressifApp/EspBlufi) and [iOS version](https://itunes.apple.com/cn/app/espblufi/id1450614082?mt=8).
|
||||
|
||||
Blufi is completely open source, here is the download link:
|
||||
|
||||
* [blufi source code](https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/bluedroid/ble/blufi)
|
||||
|
||||
* [BluFi protocol](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/blufi.html?highlight=blufi#the-frame-formats-defined-in-blufi)
|
||||
|
||||
* [iOS source code](https://github.com/EspressifApp/EspBlufiForiOS)
|
||||
|
||||
* [Android source code](https://github.com/EspressifApp/EspBlufi)
|
||||
|
||||
* [Bluetooth Network User Guide CN](https://www.espressif.com/sites/default/files/documentation/esp32_bluetooth_networking_user_guide_cn.pdf)
|
||||
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "blufi_example_main.c"
|
||||
"blufi_security.c"
|
||||
INCLUDE_DIRS ".")
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#define BLUFI_EXAMPLE_TAG "BLUFI_EXAMPLE"
|
||||
#define BLUFI_INFO(fmt, ...) ESP_LOGI(BLUFI_EXAMPLE_TAG, fmt, ##__VA_ARGS__)
|
||||
#define BLUFI_ERROR(fmt, ...) ESP_LOGE(BLUFI_EXAMPLE_TAG, fmt, ##__VA_ARGS__)
|
||||
|
||||
void blufi_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free);
|
||||
int blufi_aes_encrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
|
||||
int blufi_aes_decrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
|
||||
uint16_t blufi_crc_checksum(uint8_t iv8, uint8_t *data, int len);
|
||||
|
||||
int blufi_security_init(void);
|
||||
void blufi_security_deinit(void);
|
||||
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* 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_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_bt.h"
|
||||
|
||||
#include "esp_blufi_api.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gap_ble_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_bt_device.h"
|
||||
#include "blufi_example.h"
|
||||
|
||||
static void example_event_callback(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);
|
||||
|
||||
#define BLUFI_DEVICE_NAME "BLUFI_DEVICE"
|
||||
static uint8_t example_service_uuid128[32] = {
|
||||
/* LSB <--------------------------------------------------------------------------------> MSB */
|
||||
//first uuid, 16bit, [12],[13] is the value
|
||||
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
|
||||
};
|
||||
|
||||
//static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, 0x45, 0x56};
|
||||
static esp_ble_adv_data_t example_adv_data = {
|
||||
.set_scan_rsp = false,
|
||||
.include_name = true,
|
||||
.include_txpower = true,
|
||||
.min_interval = 0x0006, //slave connection min interval, Time = min_interval * 1.25 msec
|
||||
.max_interval = 0x0010, //slave connection max interval, Time = max_interval * 1.25 msec
|
||||
.appearance = 0x00,
|
||||
.manufacturer_len = 0,
|
||||
.p_manufacturer_data = NULL,
|
||||
.service_data_len = 0,
|
||||
.p_service_data = NULL,
|
||||
.service_uuid_len = 16,
|
||||
.p_service_uuid = example_service_uuid128,
|
||||
.flag = 0x6,
|
||||
};
|
||||
|
||||
static esp_ble_adv_params_t example_adv_params = {
|
||||
.adv_int_min = 0x100,
|
||||
.adv_int_max = 0x100,
|
||||
.adv_type = ADV_TYPE_IND,
|
||||
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
|
||||
//.peer_addr =
|
||||
//.peer_addr_type =
|
||||
.channel_map = ADV_CHNL_ALL,
|
||||
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
|
||||
};
|
||||
|
||||
#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;
|
||||
|
||||
/* connect infor*/
|
||||
static uint8_t server_if;
|
||||
static uint16_t conn_id;
|
||||
|
||||
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, 0, &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, 0, NULL);
|
||||
} else {
|
||||
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL, 0, 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;
|
||||
}
|
||||
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_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_ble_gap_set_device_name(BLUFI_DEVICE_NAME);
|
||||
esp_ble_gap_config_adv_data(&example_adv_data);
|
||||
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;
|
||||
server_if = param->connect.server_if;
|
||||
conn_id = param->connect.conn_id;
|
||||
esp_ble_gap_stop_advertising();
|
||||
blufi_security_init();
|
||||
break;
|
||||
case ESP_BLUFI_EVENT_BLE_DISCONNECT:
|
||||
BLUFI_INFO("BLUFI ble disconnect\n");
|
||||
ble_is_connected = false;
|
||||
blufi_security_deinit();
|
||||
esp_ble_gap_start_advertising(&example_adv_params);
|
||||
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, 0, &info);
|
||||
} else {
|
||||
esp_blufi_send_wifi_conn_report(mode, ESP_BLUFI_STA_CONN_FAIL, 0, 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_close(server_if, conn_id);
|
||||
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_ERROR_CHECK(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;
|
||||
}
|
||||
}
|
||||
|
||||
static void example_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
|
||||
{
|
||||
switch (event) {
|
||||
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
|
||||
esp_ble_gap_start_advertising(&example_adv_params);
|
||||
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_bluedroid_init();
|
||||
if (ret) {
|
||||
BLUFI_ERROR("%s init bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
ret = esp_bluedroid_enable();
|
||||
if (ret) {
|
||||
BLUFI_ERROR("%s init bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
BLUFI_INFO("BD ADDR: "ESP_BD_ADDR_STR"\n", ESP_BD_ADDR_HEX(esp_bt_dev_get_address()));
|
||||
|
||||
BLUFI_INFO("BLUFI VERSION %04x\n", esp_blufi_get_version());
|
||||
|
||||
ret = esp_ble_gap_register_callback(example_gap_event_handler);
|
||||
if(ret){
|
||||
BLUFI_ERROR("%s gap register failed, error code = %x\n", __func__, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = esp_blufi_register_callbacks(&example_callbacks);
|
||||
if(ret){
|
||||
BLUFI_ERROR("%s blufi register failed, error code = %x\n", __func__, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
esp_blufi_profile_init();
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#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_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_bt.h"
|
||||
|
||||
#include "esp_blufi_api.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gap_ble_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "blufi_example.h"
|
||||
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/dhm.h"
|
||||
#include "mbedtls/md5.h"
|
||||
#include "esp_crc.h"
|
||||
|
||||
/*
|
||||
The SEC_TYPE_xxx is for self-defined packet data type in the procedure of "BLUFI negotiate key"
|
||||
If user use other negotiation procedure to exchange(or generate) key, should redefine the type by yourself.
|
||||
*/
|
||||
#define SEC_TYPE_DH_PARAM_LEN 0x00
|
||||
#define SEC_TYPE_DH_PARAM_DATA 0x01
|
||||
#define SEC_TYPE_DH_P 0x02
|
||||
#define SEC_TYPE_DH_G 0x03
|
||||
#define SEC_TYPE_DH_PUBLIC 0x04
|
||||
|
||||
|
||||
struct blufi_security {
|
||||
#define DH_SELF_PUB_KEY_LEN 128
|
||||
#define DH_SELF_PUB_KEY_BIT_LEN (DH_SELF_PUB_KEY_LEN * 8)
|
||||
uint8_t self_public_key[DH_SELF_PUB_KEY_LEN];
|
||||
#define SHARE_KEY_LEN 128
|
||||
#define SHARE_KEY_BIT_LEN (SHARE_KEY_LEN * 8)
|
||||
uint8_t share_key[SHARE_KEY_LEN];
|
||||
size_t share_len;
|
||||
#define PSK_LEN 16
|
||||
uint8_t psk[PSK_LEN];
|
||||
uint8_t *dh_param;
|
||||
int dh_param_len;
|
||||
uint8_t iv[16];
|
||||
mbedtls_dhm_context dhm;
|
||||
mbedtls_aes_context aes;
|
||||
};
|
||||
static struct blufi_security *blufi_sec;
|
||||
|
||||
static int myrand( void *rng_state, unsigned char *output, size_t len )
|
||||
{
|
||||
esp_fill_random(output, len);
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
extern void btc_blufi_report_error(esp_blufi_error_state_t state);
|
||||
|
||||
void blufi_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free)
|
||||
{
|
||||
int ret;
|
||||
uint8_t type = data[0];
|
||||
|
||||
if (blufi_sec == NULL) {
|
||||
BLUFI_ERROR("BLUFI Security is not initialized");
|
||||
btc_blufi_report_error(ESP_BLUFI_INIT_SECURITY_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SEC_TYPE_DH_PARAM_LEN:
|
||||
blufi_sec->dh_param_len = ((data[1]<<8)|data[2]);
|
||||
if (blufi_sec->dh_param) {
|
||||
free(blufi_sec->dh_param);
|
||||
blufi_sec->dh_param = NULL;
|
||||
}
|
||||
blufi_sec->dh_param = (uint8_t *)malloc(blufi_sec->dh_param_len);
|
||||
if (blufi_sec->dh_param == NULL) {
|
||||
btc_blufi_report_error(ESP_BLUFI_DH_MALLOC_ERROR);
|
||||
BLUFI_ERROR("%s, malloc failed\n", __func__);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SEC_TYPE_DH_PARAM_DATA:{
|
||||
if (blufi_sec->dh_param == NULL) {
|
||||
BLUFI_ERROR("%s, blufi_sec->dh_param == NULL\n", __func__);
|
||||
btc_blufi_report_error(ESP_BLUFI_DH_PARAM_ERROR);
|
||||
return;
|
||||
}
|
||||
uint8_t *param = blufi_sec->dh_param;
|
||||
memcpy(blufi_sec->dh_param, &data[1], blufi_sec->dh_param_len);
|
||||
ret = mbedtls_dhm_read_params(&blufi_sec->dhm, ¶m, ¶m[blufi_sec->dh_param_len]);
|
||||
if (ret) {
|
||||
BLUFI_ERROR("%s read param failed %d\n", __func__, ret);
|
||||
btc_blufi_report_error(ESP_BLUFI_READ_PARAM_ERROR);
|
||||
return;
|
||||
}
|
||||
free(blufi_sec->dh_param);
|
||||
blufi_sec->dh_param = NULL;
|
||||
ret = mbedtls_dhm_make_public(&blufi_sec->dhm, (int) mbedtls_mpi_size( &blufi_sec->dhm.P ), blufi_sec->self_public_key, blufi_sec->dhm.len, myrand, NULL);
|
||||
if (ret) {
|
||||
BLUFI_ERROR("%s make public failed %d\n", __func__, ret);
|
||||
btc_blufi_report_error(ESP_BLUFI_MAKE_PUBLIC_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
mbedtls_dhm_calc_secret( &blufi_sec->dhm,
|
||||
blufi_sec->share_key,
|
||||
SHARE_KEY_BIT_LEN,
|
||||
&blufi_sec->share_len,
|
||||
NULL, NULL);
|
||||
|
||||
mbedtls_md5(blufi_sec->share_key, blufi_sec->share_len, blufi_sec->psk);
|
||||
|
||||
mbedtls_aes_setkey_enc(&blufi_sec->aes, blufi_sec->psk, 128);
|
||||
|
||||
/* alloc output data */
|
||||
*output_data = &blufi_sec->self_public_key[0];
|
||||
*output_len = blufi_sec->dhm.len;
|
||||
*need_free = false;
|
||||
|
||||
}
|
||||
break;
|
||||
case SEC_TYPE_DH_P:
|
||||
break;
|
||||
case SEC_TYPE_DH_G:
|
||||
break;
|
||||
case SEC_TYPE_DH_PUBLIC:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int blufi_aes_encrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
|
||||
{
|
||||
int ret;
|
||||
size_t iv_offset = 0;
|
||||
uint8_t iv0[16];
|
||||
|
||||
memcpy(iv0, blufi_sec->iv, sizeof(blufi_sec->iv));
|
||||
iv0[0] = iv8; /* set iv8 as the iv0[0] */
|
||||
|
||||
ret = mbedtls_aes_crypt_cfb128(&blufi_sec->aes, MBEDTLS_AES_ENCRYPT, crypt_len, &iv_offset, iv0, crypt_data, crypt_data);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return crypt_len;
|
||||
}
|
||||
|
||||
int blufi_aes_decrypt(uint8_t iv8, uint8_t *crypt_data, int crypt_len)
|
||||
{
|
||||
int ret;
|
||||
size_t iv_offset = 0;
|
||||
uint8_t iv0[16];
|
||||
|
||||
memcpy(iv0, blufi_sec->iv, sizeof(blufi_sec->iv));
|
||||
iv0[0] = iv8; /* set iv8 as the iv0[0] */
|
||||
|
||||
ret = mbedtls_aes_crypt_cfb128(&blufi_sec->aes, MBEDTLS_AES_DECRYPT, crypt_len, &iv_offset, iv0, crypt_data, crypt_data);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return crypt_len;
|
||||
}
|
||||
|
||||
uint16_t blufi_crc_checksum(uint8_t iv8, uint8_t *data, int len)
|
||||
{
|
||||
/* This iv8 ignore, not used */
|
||||
return esp_crc16_be(0, data, len);
|
||||
}
|
||||
|
||||
esp_err_t blufi_security_init(void)
|
||||
{
|
||||
blufi_sec = (struct blufi_security *)malloc(sizeof(struct blufi_security));
|
||||
if (blufi_sec == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
memset(blufi_sec, 0x0, sizeof(struct blufi_security));
|
||||
|
||||
mbedtls_dhm_init(&blufi_sec->dhm);
|
||||
mbedtls_aes_init(&blufi_sec->aes);
|
||||
|
||||
memset(blufi_sec->iv, 0x0, 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void blufi_security_deinit(void)
|
||||
{
|
||||
if (blufi_sec == NULL) {
|
||||
return;
|
||||
}
|
||||
if (blufi_sec->dh_param){
|
||||
free(blufi_sec->dh_param);
|
||||
blufi_sec->dh_param = NULL;
|
||||
}
|
||||
mbedtls_dhm_free(&blufi_sec->dhm);
|
||||
mbedtls_aes_free(&blufi_sec->aes);
|
||||
|
||||
memset(blufi_sec, 0x0, sizeof(struct blufi_security));
|
||||
|
||||
free(blufi_sec);
|
||||
blufi_sec = NULL;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
@@ -0,0 +1,31 @@
|
||||
# Override some defaults so BT stack is enabled
|
||||
# in this example
|
||||
|
||||
#
|
||||
# BT config
|
||||
#
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
|
||||
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
|
||||
CONFIG_BTDM_CTRL_MODE_BTDM=n
|
||||
CONFIG_BTDM_CTRL_PINNED_TO_CORE_0=y
|
||||
CONFIG_BTDM_CTRL_PINNED_TO_CORE_1=n
|
||||
CONFIG_BTDM_CTRL_PINNED_TO_CORE=0
|
||||
CONFIG_BTDM_CTRL_HCI_MODE_VHCI=y
|
||||
CONFIG_BTDM_CTRL_HCI_MODE_UART_H4=n
|
||||
CONFIG_BT_BLUEDROID_ENABLED=y
|
||||
CONFIG_BT_BLUEDROID_PINNED_TO_CORE_0=y
|
||||
CONFIG_BT_BLUEDROID_PINNED_TO_CORE_1=n
|
||||
CONFIG_BT_BLUEDROID_PINNED_TO_CORE=0
|
||||
CONFIG_BT_BTC_TASK_STACK_SIZE=3072
|
||||
CONFIG_BT_BLUEDROID_MEM_DEBUG=n
|
||||
CONFIG_BT_CLASSIC_ENABLED=n
|
||||
CONFIG_BT_GATTS_ENABLE=y
|
||||
CONFIG_BT_GATTC_ENABLE=n
|
||||
CONFIG_BT_BLE_SMP_ENABLE=n
|
||||
CONFIG_BL_ENABLE_SRVCHG_REG=y
|
||||
CONFIG_BT_STACK_NO_LOG=n
|
||||
CONFIG_BT_ACL_CONNECTIONS=4
|
||||
CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=n
|
||||
CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=n
|
||||
CONFIG_BT_SMP_ENABLE=n
|
||||
Reference in New Issue
Block a user