1266 lines
54 KiB
C
1266 lines
54 KiB
C
|
||
#include "main.h"
|
||
#include "drv_nvs.h"
|
||
#include "drv_usart.h"
|
||
#include "bsp_bleNet.h"
|
||
|
||
#define TAG "JsonPrase_Task"
|
||
#define GATTS_TAG "GATTS_DEMOS"
|
||
//----------------------------------------------------------------
|
||
// 任务
|
||
//----------------------------------------------------------------
|
||
#define TASK1_TASK_PRIO 1 // 任务优先级
|
||
#define TASK1_STK_SIZE 4096 // 任务堆栈大小
|
||
TaskHandle_t ParseTaskHandle; // 任务句柄
|
||
void ParseTask(void *pvParameters); // 任务函数
|
||
|
||
#define BLE_NET_TASK_PRIO 2 // 任务优先级
|
||
#define BLE_NET_STK_SIZE 4096 // 任务堆栈大小
|
||
TaskHandle_t BLE_NetTasks_TaskHandle; // 任务句柄
|
||
void BLE_NetTask(void *pvParameters); // 任务函数
|
||
|
||
//----------------------------------------------------------------
|
||
// 信号量
|
||
//----------------------------------------------------------------
|
||
SemaphoreHandle_t xSemaphore_BLE_Connect; // 蓝牙链接成功二值
|
||
SemaphoreHandle_t xSemaphore_WIFI_ConnectDone; // WiFi链接成功二值
|
||
SemaphoreHandle_t xSemaphore_WIFI_ConnectFail; // WiFi链接失败二值
|
||
SemaphoreHandle_t xSemaphore_WIFI_Json_PraseDone; // 配网json解析二值
|
||
|
||
//----------------------------------------------------------------
|
||
// 队列
|
||
//----------------------------------------------------------------
|
||
QueueHandle_t xQueue_WIFI_STA_Json;
|
||
|
||
/// Declare the static function
|
||
static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
|
||
// static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
|
||
|
||
#define GATTS_SERVICE_LOCAL_UUID_A 0xA55A
|
||
|
||
#define GATTS_CHAR_UUID_TEST_A 0xFF01
|
||
|
||
#define GATTS_NUM_HANDLE_TEST_A 10
|
||
|
||
// #define GATTS_SERVICE_UUID_TEST_B 0x00EE
|
||
// #define GATTS_CHAR_UUID_TEST_B 0xEE01
|
||
// #define GATTS_DESCR_UUID_TEST_B 0x2222
|
||
// #define GATTS_NUM_HANDLE_TEST_B 4
|
||
|
||
#define TEST_DEVICE_NAME "BW"
|
||
#define TEST_MANUFACTURER_DATA_LEN 17
|
||
|
||
#define GATTS_DEMO_CHAR_VAL_LEN_MAX 0x40
|
||
|
||
#define PREPARE_BUF_MAX_SIZE 1024
|
||
|
||
static uint8_t char1_str[] = {0x11, 0x22, 0x33};
|
||
static esp_gatt_char_prop_t a_property = 0;
|
||
// static esp_gatt_char_prop_t b_property = 0;
|
||
|
||
static esp_attr_value_t gatts_demo_char1_val =
|
||
{
|
||
.attr_max_len = GATTS_DEMO_CHAR_VAL_LEN_MAX,
|
||
.attr_len = sizeof(char1_str),
|
||
.attr_value = char1_str,
|
||
};
|
||
|
||
// extern char BLE_ConnectDoneFlg;
|
||
|
||
extern char WifiScanMsg[1024 * 6];
|
||
|
||
static uint8_t adv_config_done = 0;
|
||
#define adv_config_flag (1 << 0)
|
||
#define scan_rsp_config_flag (1 << 1)
|
||
|
||
#ifdef CONFIG_SET_RAW_ADV_DATA
|
||
static uint8_t raw_adv_data[] = {
|
||
0x02, 0x01, 0x06, // BLE的设置
|
||
0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd}; // TX强度以及其他
|
||
static uint8_t raw_scan_rsp_data[] = {
|
||
0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, 0x53, 0x5f, 0x44,
|
||
0x45, 0x4d, 0x4f};
|
||
#else
|
||
|
||
void BLE_WifiScanner(void);
|
||
static uint8_t adv_service_uuid128[16] = {
|
||
/* LSB <--------------------------------------------------------------------------------> MSB */
|
||
// first uuid, 16bit, [12],[13] is the value
|
||
0xfb,
|
||
0x34,
|
||
0x9b,
|
||
0x5f,
|
||
0x80,
|
||
0x00,
|
||
0x00,
|
||
0x80,
|
||
0x00,
|
||
0x10,
|
||
0x00,
|
||
0x00,
|
||
(GATTS_SERVICE_LOCAL_UUID_A & 0xff),
|
||
(GATTS_SERVICE_LOCAL_UUID_A >> 8),
|
||
0x00,
|
||
0x00,
|
||
// second uuid, 16bit, [12], [13], [14], [15] is the value
|
||
// 0xfb,
|
||
// 0x34,
|
||
// 0x9b,
|
||
// 0x5f,
|
||
// 0x80,
|
||
// 0x00,
|
||
// 0x00,
|
||
// 0x80,
|
||
// 0x00,
|
||
// 0x10,
|
||
// 0x00,
|
||
// 0x00,
|
||
// 0x1A,
|
||
// 0x18,
|
||
// 0x00,
|
||
// 0x00,
|
||
};
|
||
|
||
// The length of adv data must be less than 31 bytes
|
||
// static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, 0x45, 0x56};
|
||
// adv data
|
||
static esp_ble_adv_data_t adv_data = {
|
||
.set_scan_rsp = false,
|
||
.include_name = true,
|
||
.include_txpower = false,
|
||
.min_interval = 0x0050, // slave connection min interval, Time = min_interval * 1.25 msec
|
||
.max_interval = 0x0060, // slave connection max interval, Time = max_interval * 1.25 msec
|
||
.appearance = 0x00,
|
||
.manufacturer_len = 0, // TEST_MANUFACTURER_DATA_LEN,
|
||
.p_manufacturer_data = NULL, //&test_manufacturer[0],
|
||
.service_data_len = 0,
|
||
.p_service_data = NULL,
|
||
.service_uuid_len = sizeof(adv_service_uuid128),
|
||
.p_service_uuid = adv_service_uuid128,
|
||
.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
|
||
};
|
||
// scan response data
|
||
static esp_ble_adv_data_t scan_rsp_data = {
|
||
.set_scan_rsp = true,
|
||
.include_name = true,
|
||
.include_txpower = true,
|
||
//.min_interval = 0x0006,
|
||
//.max_interval = 0x0010,
|
||
.appearance = 0x00,
|
||
.manufacturer_len = 0, // TEST_MANUFACTURER_DATA_LEN,
|
||
.p_manufacturer_data = NULL, //&test_manufacturer[0],
|
||
.service_data_len = 0,
|
||
.p_service_data = NULL,
|
||
.service_uuid_len = sizeof(adv_service_uuid128),
|
||
.p_service_uuid = adv_service_uuid128,
|
||
.flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT),
|
||
};
|
||
|
||
#endif /* CONFIG_SET_RAW_ADV_DATA */
|
||
|
||
static esp_ble_adv_params_t adv_params = {
|
||
.adv_int_min = 0x50,
|
||
.adv_int_max = 0x50,
|
||
.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 PROFILE_NUM 1
|
||
#define PROFILE_A_APP_ID 0
|
||
// #define PROFILE_B_APP_ID 1
|
||
|
||
struct gatts_profile_inst
|
||
{
|
||
esp_gatts_cb_t gatts_cb;
|
||
uint16_t gatts_if;
|
||
uint16_t app_id;
|
||
uint16_t conn_id;
|
||
uint16_t service_handle;
|
||
esp_gatt_srvc_id_t service_id;
|
||
uint16_t char_handle;
|
||
esp_bt_uuid_t char_uuid;
|
||
esp_gatt_perm_t perm;
|
||
esp_gatt_char_prop_t property;
|
||
uint16_t descr_handle;
|
||
esp_bt_uuid_t descr_uuid;
|
||
};
|
||
|
||
/* One gatt-based profile one app_id and one gatts_if, this array will store the gatts_if returned by ESP_GATTS_REG_EVT */
|
||
static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = {
|
||
[PROFILE_A_APP_ID] = {
|
||
.gatts_cb = gatts_profile_a_event_handler,
|
||
.gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
|
||
},
|
||
// [PROFILE_B_APP_ID] = {
|
||
// .gatts_cb = gatts_profile_b_event_handler, /* This demo does not implement, similar as profile A */
|
||
// .gatts_if = ESP_GATT_IF_NONE, /* Not get the gatt_if, so initial is ESP_GATT_IF_NONE */
|
||
// },
|
||
};
|
||
|
||
typedef struct
|
||
{
|
||
uint8_t *prepare_buf;
|
||
int prepare_len;
|
||
} prepare_type_env_t;
|
||
|
||
static prepare_type_env_t a_prepare_write_env;
|
||
// static prepare_type_env_t b_prepare_write_env;
|
||
|
||
void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param);
|
||
void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param);
|
||
|
||
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
|
||
{
|
||
switch (event)
|
||
{
|
||
#ifdef CONFIG_SET_RAW_ADV_DATA
|
||
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
|
||
adv_config_done &= (~adv_config_flag);
|
||
if (adv_config_done == 0)
|
||
{
|
||
esp_ble_gap_start_advertising(&adv_params);
|
||
}
|
||
break;
|
||
case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
|
||
adv_config_done &= (~scan_rsp_config_flag);
|
||
if (adv_config_done == 0)
|
||
{
|
||
esp_ble_gap_start_advertising(&adv_params);
|
||
}
|
||
break;
|
||
#else
|
||
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
|
||
adv_config_done &= (~adv_config_flag);
|
||
if (adv_config_done == 0)
|
||
{
|
||
esp_ble_gap_start_advertising(&adv_params);
|
||
}
|
||
break;
|
||
case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:
|
||
adv_config_done &= (~scan_rsp_config_flag);
|
||
if (adv_config_done == 0)
|
||
{
|
||
esp_ble_gap_start_advertising(&adv_params);
|
||
}
|
||
break;
|
||
#endif
|
||
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
|
||
// advertising start complete event to indicate advertising start successfully or failed
|
||
if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "Advertising start failed\n");
|
||
}
|
||
break;
|
||
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
|
||
if (param->adv_stop_cmpl.status != ESP_BT_STATUS_SUCCESS)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "Advertising stop failed\n");
|
||
}
|
||
else
|
||
{
|
||
ESP_LOGI(GATTS_TAG, "Stop adv successfully\n");
|
||
}
|
||
break;
|
||
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
|
||
ESP_LOGI(GATTS_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d",
|
||
param->update_conn_params.status,
|
||
param->update_conn_params.min_int,
|
||
param->update_conn_params.max_int,
|
||
param->update_conn_params.conn_int,
|
||
param->update_conn_params.latency,
|
||
param->update_conn_params.timeout);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
|
||
{
|
||
esp_gatt_status_t status = ESP_GATT_OK;
|
||
if (param->write.need_rsp)
|
||
{
|
||
if (param->write.is_prep)
|
||
{
|
||
if (prepare_write_env->prepare_buf == NULL)
|
||
{
|
||
prepare_write_env->prepare_buf = (uint8_t *)malloc(PREPARE_BUF_MAX_SIZE * sizeof(uint8_t));
|
||
prepare_write_env->prepare_len = 0;
|
||
if (prepare_write_env->prepare_buf == NULL)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "Gatt_server prep no mem\n");
|
||
status = ESP_GATT_NO_RESOURCES;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (param->write.offset > PREPARE_BUF_MAX_SIZE)
|
||
{
|
||
status = ESP_GATT_INVALID_OFFSET;
|
||
}
|
||
else if ((param->write.offset + param->write.len) > PREPARE_BUF_MAX_SIZE)
|
||
{
|
||
status = ESP_GATT_INVALID_ATTR_LEN;
|
||
}
|
||
}
|
||
|
||
esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t));
|
||
gatt_rsp->attr_value.len = param->write.len;
|
||
gatt_rsp->attr_value.handle = param->write.handle;
|
||
gatt_rsp->attr_value.offset = param->write.offset;
|
||
gatt_rsp->attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
|
||
memcpy(gatt_rsp->attr_value.value, param->write.value, param->write.len);
|
||
esp_err_t response_err = esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, gatt_rsp);
|
||
if (response_err != ESP_OK)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "Send response error\n");
|
||
}
|
||
free(gatt_rsp);
|
||
if (status != ESP_GATT_OK)
|
||
{
|
||
return;
|
||
}
|
||
memcpy(prepare_write_env->prepare_buf + param->write.offset,
|
||
param->write.value,
|
||
param->write.len);
|
||
prepare_write_env->prepare_len += param->write.len;
|
||
}
|
||
else
|
||
{
|
||
// DONE: 可以发送队列 param->write.value -> STA_net_param_queue
|
||
ESP_LOGI(GATTS_TAG, "Prepare Send Response Write Event:%s", param->write.value);
|
||
xQueueSend(xQueue_WIFI_STA_Json, param->write.value, portMAX_DELAY);
|
||
esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, status, NULL);
|
||
}
|
||
}
|
||
}
|
||
#include "string.h"
|
||
void example_exec_write_event_env(prepare_type_env_t *prepare_write_env, esp_ble_gatts_cb_param_t *param)
|
||
{
|
||
if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC)
|
||
{
|
||
esp_log_buffer_hex(GATTS_TAG, prepare_write_env->prepare_buf, prepare_write_env->prepare_len);
|
||
for (int i = 0; i < strlen((char *)prepare_write_env->prepare_buf); i++)
|
||
{
|
||
printf("%x ", prepare_write_env->prepare_buf[i]);
|
||
}
|
||
|
||
// TODO: 接收到数据之后处理 esp_ble_gatts_send_indicate 发送ACK
|
||
}
|
||
else
|
||
{
|
||
ESP_LOGI(GATTS_TAG, "ESP_GATT_PREP_WRITE_CANCEL");
|
||
}
|
||
if (prepare_write_env->prepare_buf)
|
||
{
|
||
// DONE: 可以发送队列 (超过MTU)
|
||
ESP_LOGI(GATTS_TAG, "Prepare Send Response EXEC Write Event:%s", prepare_write_env->prepare_buf);
|
||
xQueueSend(xQueue_WIFI_STA_Json, prepare_write_env->prepare_buf, portMAX_DELAY);
|
||
free(prepare_write_env->prepare_buf);
|
||
prepare_write_env->prepare_buf = NULL;
|
||
}
|
||
prepare_write_env->prepare_len = 0;
|
||
}
|
||
/*
|
||
在没有连接之前:注册->创建->启动->添加特征->添加特征描述:
|
||
|
||
ESP_GATTS_REG_EVT—> ESP_GATTS_CREATE_EVT—> ESP_GATTS_START_EVT—> ESP_GATTS_ADD_CHAR_EVT—> ESP_GATTS_ADD_CHAR_DESCR_EVT
|
||
|
||
在连接之后:
|
||
|
||
CONNECT_EVT—> ESP_GATTS_MTU_EVT—> GATT_WRITE_EVT—> ESP_GATTS_CONF_EVT—> GATT_READ_EVT
|
||
*/
|
||
static char BLE_Connect_Flag = 0;
|
||
static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
|
||
{
|
||
// static uint16_t characteristic_id = 0;
|
||
char BLE_NameBuffer[32] = {0};
|
||
switch (event)
|
||
{
|
||
case ESP_GATTS_REG_EVT:
|
||
ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id);
|
||
gl_profile_tab[PROFILE_A_APP_ID].service_id.is_primary = true;
|
||
gl_profile_tab[PROFILE_A_APP_ID].service_id.id.inst_id = 0x00;
|
||
gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16;
|
||
// 此处修改之后更改service的名称,有的是SIG的BLE目录里面就有的。
|
||
gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_LOCAL_UUID_A;
|
||
ESP_LOGI(GATTS_TAG, "Service ID:------- %x", gl_profile_tab[PROFILE_A_APP_ID].service_id.id.uuid.uuid.uuid16);
|
||
// 设置蓝牙的名称
|
||
strcat(BLE_NameBuffer, TEST_DEVICE_NAME);
|
||
strcat(BLE_NameBuffer, (const char *)network_Config.serialNumber);
|
||
printf("BLE Name: %s\n", BLE_NameBuffer);
|
||
esp_err_t set_dev_name_ret = esp_ble_gap_set_device_name(BLE_NameBuffer);
|
||
if (set_dev_name_ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "set device name failed, error code = %x", set_dev_name_ret);
|
||
}
|
||
#ifdef CONFIG_SET_RAW_ADV_DATA
|
||
// 调用此函数以设置原始广播数据
|
||
esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data));
|
||
if (raw_adv_ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "config raw adv data failed, error code = %x ", raw_adv_ret);
|
||
}
|
||
adv_config_done |= adv_config_flag;
|
||
// 调用此函数以设置原始扫描响应数据。
|
||
esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw(raw_scan_rsp_data, sizeof(raw_scan_rsp_data));
|
||
if (raw_scan_ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "config raw scan rsp data failed, error code = %x", raw_scan_ret);
|
||
}
|
||
adv_config_done |= scan_rsp_config_flag;
|
||
#else
|
||
// config adv data
|
||
esp_err_t ret = esp_ble_gap_config_adv_data(&adv_data);
|
||
if (ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "config adv data failed, error code = %x", ret);
|
||
}
|
||
adv_config_done |= adv_config_flag;
|
||
// config scan response data
|
||
ret = esp_ble_gap_config_adv_data(&scan_rsp_data);
|
||
if (ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "config scan response data failed, error code = %x", ret);
|
||
}
|
||
adv_config_done |= scan_rsp_config_flag;
|
||
|
||
#endif
|
||
esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_A_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_A);
|
||
break;
|
||
case ESP_GATTS_READ_EVT:
|
||
{ // GATT读取事件,手机读取开发板的数据
|
||
// todo: 此处用于获取配网的时候的LOG,链接的密码账号以及其他
|
||
// ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, param->read.trans_id, param->read.handle);
|
||
esp_gatt_rsp_t rsp;
|
||
memset(&rsp, 0, sizeof(esp_gatt_rsp_t));
|
||
rsp.attr_value.handle = param->read.handle;
|
||
|
||
// char Test_buf[100] = {0};
|
||
// memcpy(Test_buf, "1234567890QWERTYUIOPASDFGHJKL;ZXCVBNM,./", 40);
|
||
// memcpy(rsp.attr_value.value, Test_buf, 100);
|
||
// rsp.attr_value.len = 40;
|
||
|
||
sprintf((char *)rsp.attr_value.value, "{\"wifi_ssid\":\"%s\"}\r\n", "F1");
|
||
rsp.attr_value.len = strlen((char *)rsp.attr_value.value);
|
||
|
||
esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id,
|
||
ESP_GATT_OK, &rsp);
|
||
break;
|
||
}
|
||
case ESP_GATTS_WRITE_EVT:
|
||
{ // GATT写事件,手机给开发板的发送数据,不需要回复
|
||
// ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %ld, handle %d", param->write.conn_id, param->write.trans_id, param->write.handle);
|
||
if (!param->write.is_prep)
|
||
{
|
||
ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len);
|
||
esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len);
|
||
if (gl_profile_tab[PROFILE_A_APP_ID].descr_handle == param->write.handle && param->write.len == 2)
|
||
{
|
||
uint16_t descr_value = param->write.value[1] << 8 | param->write.value[0];
|
||
if (descr_value == 0x0001)
|
||
{
|
||
if (a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY)
|
||
{
|
||
ESP_LOGI(GATTS_TAG, "notify enable");
|
||
uint8_t notify_data[15];
|
||
for (int i = 0; i < sizeof(notify_data); ++i)
|
||
{
|
||
notify_data[i] = i % 0xff;
|
||
}
|
||
// the size of notify_data[] need less than MTU size
|
||
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
|
||
sizeof(notify_data), notify_data, false);
|
||
}
|
||
}
|
||
else if (descr_value == 0x0002)
|
||
{
|
||
if (a_property & ESP_GATT_CHAR_PROP_BIT_INDICATE)
|
||
{
|
||
ESP_LOGI(GATTS_TAG, "indicate enable");
|
||
uint8_t indicate_data[15];
|
||
for (int i = 0; i < sizeof(indicate_data); ++i)
|
||
{
|
||
indicate_data[i] = i % 0xff;
|
||
}
|
||
// the size of indicate_data[] need less than MTU size
|
||
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
|
||
sizeof(indicate_data), indicate_data, true);
|
||
}
|
||
}
|
||
else if (descr_value == 0x0000)
|
||
{
|
||
ESP_LOGI(GATTS_TAG, "notify/indicate disable ");
|
||
}
|
||
else
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "unknown descr value");
|
||
esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len);
|
||
}
|
||
}
|
||
}
|
||
example_write_event_env(gatts_if, &a_prepare_write_env, param);
|
||
break;
|
||
}
|
||
case ESP_GATTS_EXEC_WRITE_EVT:
|
||
{ // GATT写事件,手机给开发板的发送数据,需要回复
|
||
ESP_LOGI(GATTS_TAG, "ESP_GATTS_EXEC_WRITE_EVT");
|
||
esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
|
||
example_exec_write_event_env(&a_prepare_write_env, param);
|
||
break;
|
||
}
|
||
case ESP_GATTS_MTU_EVT:
|
||
ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
|
||
break;
|
||
case ESP_GATTS_UNREG_EVT:
|
||
break;
|
||
// 创建 GATT事件,基本参数的设置,将Characteristic加到service中,完成触发下面事件
|
||
case ESP_GATTS_CREATE_EVT:
|
||
ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, param->create.service_handle);
|
||
gl_profile_tab[PROFILE_A_APP_ID].service_handle = param->create.service_handle;
|
||
gl_profile_tab[PROFILE_A_APP_ID].char_uuid.len = ESP_UUID_LEN_16;
|
||
gl_profile_tab[PROFILE_A_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_A;
|
||
|
||
// 启动 GATT 服务。
|
||
esp_ble_gatts_start_service(gl_profile_tab[PROFILE_A_APP_ID].service_handle);
|
||
a_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
|
||
// 来添加特性(特征的UUID, 特征值描述符属性权限, 特征属性、特征值、属性响应控制字节)。
|
||
esp_err_t add_char_ret = esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].char_uuid,
|
||
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
|
||
a_property,
|
||
&gatts_demo_char1_val, NULL);
|
||
if (add_char_ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "add char failed, error code =%x", add_char_ret);
|
||
}
|
||
break;
|
||
case ESP_GATTS_ADD_INCL_SRVC_EVT:
|
||
break;
|
||
// 添加Characteristic事件,添加Characteristic的Descriptor,完成触发下面事件
|
||
case ESP_GATTS_ADD_CHAR_EVT:
|
||
{
|
||
uint16_t length = 0;
|
||
const uint8_t *prf_char;
|
||
ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n",
|
||
param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
|
||
gl_profile_tab[PROFILE_A_APP_ID].char_handle = param->add_char.attr_handle;
|
||
gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.len = ESP_UUID_LEN_16;
|
||
// 此处修改DESCR的UUID
|
||
gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
|
||
esp_err_t get_attr_ret = esp_ble_gatts_get_attr_value(param->add_char.attr_handle, &length, &prf_char);
|
||
if (get_attr_ret == ESP_FAIL)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "ILLEGAL HANDLE");
|
||
}
|
||
ESP_LOGI(GATTS_TAG, "the gatts demo char length = %x\n", length);
|
||
for (int i = 0; i < length; i++)
|
||
{
|
||
ESP_LOGI(GATTS_TAG, "prf_char[%x] =%x\n", i, prf_char[i]);
|
||
}
|
||
// characteristic_id = param->add_char.char_uuid.uuid.uuid16;
|
||
ESP_LOGI(GATTS_TAG, "char uuid: ----- %x\n", param->add_char.char_uuid.uuid.uuid16);
|
||
if (param->add_char.char_uuid.len == ESP_UUID_LEN_16 && param->add_char.char_uuid.uuid.uuid16 == GATTS_CHAR_UUID_TEST_A)
|
||
{
|
||
ESP_LOGI(GATTS_TAG, "descr uuid: ----- %x\n", gl_profile_tab[PROFILE_A_APP_ID].descr_uuid.uuid.uuid16);
|
||
esp_err_t add_descr_ret = esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid,
|
||
ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
|
||
if (add_descr_ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "add char descr failed, error code =%x", add_descr_ret);
|
||
}
|
||
// NOTE:此处用于 新增一个 描述
|
||
// esp_bt_uuid_t c_char_uuid;
|
||
// c_char_uuid.len = ESP_UUID_LEN_16;
|
||
// c_char_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
|
||
// esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &c_char_uuid,
|
||
// ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
|
||
break;
|
||
}
|
||
// NOTE:针对另外一个特征点增加描述
|
||
// else if (param->add_char.char_uuid.len == ESP_UUID_LEN_16 && param->add_char.char_uuid.uuid.uuid16 == GATTS_CHAR_UUID_TEST_A + 1)
|
||
// {
|
||
// esp_err_t add_descr_ret = esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &gl_profile_tab[PROFILE_A_APP_ID].descr_uuid,
|
||
// ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
|
||
// if (add_descr_ret)
|
||
// {
|
||
// ESP_LOGE(GATTS_TAG, "add char descr failed, error code =%x", add_descr_ret);
|
||
// }
|
||
// esp_bt_uuid_t c_char_uuid;
|
||
// c_char_uuid.len = ESP_UUID_LEN_16;
|
||
// c_char_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
|
||
// add_descr_ret = esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &c_char_uuid,
|
||
// ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, NULL, NULL);
|
||
// }
|
||
break;
|
||
}
|
||
case ESP_GATTS_ADD_CHAR_DESCR_EVT: // 添加描述事件
|
||
gl_profile_tab[PROFILE_A_APP_ID].descr_handle = param->add_char_descr.attr_handle;
|
||
ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",
|
||
param->add_char_descr.status, param->add_char_descr.attr_handle, param->add_char_descr.service_handle);
|
||
// NOTE:增加一个特征点
|
||
// if (param->add_char_descr.descr_uuid.uuid.uuid16 == ESP_GATT_UUID_CHAR_CLIENT_CONFIG && characteristic_id == GATTS_CHAR_UUID_TEST_A)
|
||
// {
|
||
// esp_bt_uuid_t d_char_uuid;
|
||
// d_char_uuid.len = ESP_UUID_LEN_16;
|
||
// d_char_uuid.uuid.uuid16 = 0xFF02;
|
||
// esp_ble_gatts_add_char(gl_profile_tab[PROFILE_A_APP_ID].service_handle, &d_char_uuid,
|
||
// ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
|
||
// a_property,
|
||
// &gatts_demo_char1_val, NULL);
|
||
// }
|
||
|
||
break;
|
||
case ESP_GATTS_DELETE_EVT:
|
||
break;
|
||
case ESP_GATTS_START_EVT:
|
||
ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n",
|
||
param->start.status, param->start.service_handle);
|
||
break;
|
||
case ESP_GATTS_STOP_EVT:
|
||
break;
|
||
case ESP_GATTS_CONNECT_EVT: // GATT 连接事件
|
||
{
|
||
esp_ble_conn_update_params_t conn_params = {0};
|
||
memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
|
||
/* For the IOS system, please reference the apple official documents about the ble connection parameters restrictions. */
|
||
conn_params.latency = 0;
|
||
conn_params.max_int = 0x40; // max_int = 0x20*1.25ms = 40ms
|
||
conn_params.min_int = 0x20; // min_int = 0x10*1.25ms = 20ms
|
||
conn_params.timeout = 1000; // timeout = 400*10ms = 4000ms
|
||
ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:",
|
||
param->connect.conn_id,
|
||
param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2],
|
||
param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5]);
|
||
gl_profile_tab[PROFILE_A_APP_ID].conn_id = param->connect.conn_id;
|
||
// start sent the update connection parameters to the peer device.
|
||
esp_ble_gap_update_conn_params(&conn_params);
|
||
BLE_Connect_Flag = 1;
|
||
printf("Connection is %d\n", BLE_Connect_Flag);
|
||
BLE_WifiScanner();
|
||
xSemaphoreGive(xSemaphore_BLE_Connect); // 给蓝牙链接成功二值
|
||
break;
|
||
}
|
||
case ESP_GATTS_DISCONNECT_EVT: // 断开连接事件
|
||
ESP_LOGI(GATTS_TAG, "ESP_GATTS_DISCONNECT_EVT, disconnect reason 0x%x", param->disconnect.reason);
|
||
esp_ble_gap_start_advertising(&adv_params);
|
||
xTimerStart(NetConfig_timer, 0);
|
||
BLE_Connect_Flag = 0;
|
||
break;
|
||
case ESP_GATTS_CONF_EVT: // GATT配置事件
|
||
ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONF_EVT, status %d attr_handle %d", param->conf.status, param->conf.handle);
|
||
if (param->conf.status != ESP_GATT_OK)
|
||
{
|
||
esp_log_buffer_hex(GATTS_TAG, param->conf.value, param->conf.len);
|
||
}
|
||
break;
|
||
case ESP_GATTS_OPEN_EVT:
|
||
case ESP_GATTS_CANCEL_OPEN_EVT:
|
||
case ESP_GATTS_CLOSE_EVT:
|
||
case ESP_GATTS_LISTEN_EVT:
|
||
case ESP_GATTS_CONGEST_EVT:
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
// static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
|
||
// {
|
||
// switch (event)
|
||
// {
|
||
// case ESP_GATTS_REG_EVT:
|
||
// ESP_LOGI(GATTS_TAG, "REGISTER_APP_EVT, status %d, app_id %d\n", param->reg.status, param->reg.app_id);
|
||
// gl_profile_tab[PROFILE_B_APP_ID].service_id.is_primary = true;
|
||
// gl_profile_tab[PROFILE_B_APP_ID].service_id.id.inst_id = 0x00;
|
||
// gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.len = ESP_UUID_LEN_16;
|
||
// gl_profile_tab[PROFILE_B_APP_ID].service_id.id.uuid.uuid.uuid16 = GATTS_SERVICE_UUID_TEST_B;
|
||
// esp_ble_gatts_create_service(gatts_if, &gl_profile_tab[PROFILE_B_APP_ID].service_id, GATTS_NUM_HANDLE_TEST_B);
|
||
// break;
|
||
// case ESP_GATTS_READ_EVT:
|
||
// {
|
||
// ESP_LOGI(GATTS_TAG, "GATT_READ_EVT, conn_id %d, trans_id %d, handle %d\n", param->read.conn_id, param->read.trans_id, param->read.handle);
|
||
// esp_gatt_rsp_t rsp;
|
||
// memset(&rsp, 0, sizeof(esp_gatt_rsp_t));
|
||
// rsp.attr_value.handle = param->read.handle;
|
||
// rsp.attr_value.len = 4;
|
||
// rsp.attr_value.value[0] = 0xde;
|
||
// rsp.attr_value.value[1] = 0xed;
|
||
// rsp.attr_value.value[2] = 0xbe;
|
||
// rsp.attr_value.value[3] = 0xef;
|
||
// esp_ble_gatts_send_response(gatts_if, param->read.conn_id, param->read.trans_id,
|
||
// ESP_GATT_OK, &rsp);
|
||
// break;
|
||
// }
|
||
// case ESP_GATTS_WRITE_EVT:
|
||
// {
|
||
// ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, conn_id %d, trans_id %d, handle %d\n", param->write.conn_id, param->write.trans_id, param->write.handle);
|
||
// if (!param->write.is_prep)
|
||
// {
|
||
// ESP_LOGI(GATTS_TAG, "GATT_WRITE_EVT, value len %d, value :", param->write.len);
|
||
// esp_log_buffer_hex(GATTS_TAG, param->write.value, param->write.len);
|
||
// if (gl_profile_tab[PROFILE_B_APP_ID].descr_handle == param->write.handle && param->write.len == 2)
|
||
// {
|
||
// uint16_t descr_value = param->write.value[1] << 8 | param->write.value[0];
|
||
// if (descr_value == 0x0001)
|
||
// {
|
||
// if (b_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY)
|
||
// {
|
||
// ESP_LOGI(GATTS_TAG, "notify enable");
|
||
// uint8_t notify_data[15];
|
||
// for (int i = 0; i < sizeof(notify_data); ++i)
|
||
// {
|
||
// notify_data[i] = i % 0xff;
|
||
// }
|
||
// // the size of notify_data[] need less than MTU size
|
||
// esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_B_APP_ID].char_handle,
|
||
// sizeof(notify_data), notify_data, false);
|
||
// }
|
||
// }
|
||
// else if (descr_value == 0x0002)
|
||
// {
|
||
// if (b_property & ESP_GATT_CHAR_PROP_BIT_INDICATE)
|
||
// {
|
||
// ESP_LOGI(GATTS_TAG, "indicate enable");
|
||
// uint8_t indicate_data[15];
|
||
// for (int i = 0; i < sizeof(indicate_data); ++i)
|
||
// {
|
||
// indicate_data[i] = i % 0xff;
|
||
// }
|
||
// // the size of indicate_data[] need less than MTU size
|
||
// esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, gl_profile_tab[PROFILE_B_APP_ID].char_handle,
|
||
// sizeof(indicate_data), indicate_data, true);
|
||
// }
|
||
// }
|
||
// else if (descr_value == 0x0000)
|
||
// {
|
||
// ESP_LOGI(GATTS_TAG, "notify/indicate disable ");
|
||
// }
|
||
// else
|
||
// {
|
||
// ESP_LOGE(GATTS_TAG, "unknown value");
|
||
// }
|
||
// }
|
||
// }
|
||
// example_write_event_env(gatts_if, &b_prepare_write_env, param);
|
||
// break;
|
||
// }
|
||
// case ESP_GATTS_EXEC_WRITE_EVT:
|
||
// ESP_LOGI(GATTS_TAG, "ESP_GATTS_EXEC_WRITE_EVT");
|
||
// esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL);
|
||
// example_exec_write_event_env(&b_prepare_write_env, param);
|
||
// break;
|
||
// case ESP_GATTS_MTU_EVT:
|
||
// ESP_LOGI(GATTS_TAG, "ESP_GATTS_MTU_EVT, MTU %d", param->mtu.mtu);
|
||
// break;
|
||
// case ESP_GATTS_UNREG_EVT:
|
||
// break;
|
||
// case ESP_GATTS_CREATE_EVT:
|
||
// ESP_LOGI(GATTS_TAG, "CREATE_SERVICE_EVT, status %d, service_handle %d\n", param->create.status, param->create.service_handle);
|
||
// gl_profile_tab[PROFILE_B_APP_ID].service_handle = param->create.service_handle;
|
||
// gl_profile_tab[PROFILE_B_APP_ID].char_uuid.len = ESP_UUID_LEN_16;
|
||
// gl_profile_tab[PROFILE_B_APP_ID].char_uuid.uuid.uuid16 = GATTS_CHAR_UUID_TEST_B;
|
||
// esp_ble_gatts_start_service(gl_profile_tab[PROFILE_B_APP_ID].service_handle);
|
||
// b_property = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | ESP_GATT_CHAR_PROP_BIT_NOTIFY;
|
||
// esp_err_t add_char_ret = esp_ble_gatts_add_char(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].char_uuid,
|
||
// ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
|
||
// b_property,
|
||
// NULL, NULL);
|
||
// if (add_char_ret)
|
||
// {
|
||
// ESP_LOGE(GATTS_TAG, "add char failed, error code =%x", add_char_ret);
|
||
// }
|
||
// break;
|
||
// case ESP_GATTS_ADD_INCL_SRVC_EVT:
|
||
// break;
|
||
// case ESP_GATTS_ADD_CHAR_EVT:
|
||
// ESP_LOGI(GATTS_TAG, "ADD_CHAR_EVT, status %d, attr_handle %d, service_handle %d\n",
|
||
// param->add_char.status, param->add_char.attr_handle, param->add_char.service_handle);
|
||
// gl_profile_tab[PROFILE_B_APP_ID].char_handle = param->add_char.attr_handle;
|
||
// gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.len = ESP_UUID_LEN_16;
|
||
// gl_profile_tab[PROFILE_B_APP_ID].descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG;
|
||
// esp_ble_gatts_add_char_descr(gl_profile_tab[PROFILE_B_APP_ID].service_handle, &gl_profile_tab[PROFILE_B_APP_ID].descr_uuid,
|
||
// ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE,
|
||
// NULL, NULL);
|
||
// break;
|
||
// case ESP_GATTS_ADD_CHAR_DESCR_EVT:
|
||
// gl_profile_tab[PROFILE_B_APP_ID].descr_handle = param->add_char_descr.attr_handle;
|
||
// ESP_LOGI(GATTS_TAG, "ADD_DESCR_EVT, status %d, attr_handle %d, service_handle %d\n",
|
||
// param->add_char_descr.status, param->add_char_descr.attr_handle, param->add_char_descr.service_handle);
|
||
// break;
|
||
// case ESP_GATTS_DELETE_EVT:
|
||
// break;
|
||
// case ESP_GATTS_START_EVT:
|
||
// ESP_LOGI(GATTS_TAG, "SERVICE_START_EVT, status %d, service_handle %d\n",
|
||
// param->start.status, param->start.service_handle);
|
||
// break;
|
||
// case ESP_GATTS_STOP_EVT:
|
||
// break;
|
||
// case ESP_GATTS_CONNECT_EVT:
|
||
// ESP_LOGI(GATTS_TAG, "CONNECT_EVT, conn_id %d, remote %02x:%02x:%02x:%02x:%02x:%02x:",
|
||
// param->connect.conn_id,
|
||
// param->connect.remote_bda[0], param->connect.remote_bda[1], param->connect.remote_bda[2],
|
||
// param->connect.remote_bda[3], param->connect.remote_bda[4], param->connect.remote_bda[5]);
|
||
// gl_profile_tab[PROFILE_B_APP_ID].conn_id = param->connect.conn_id;
|
||
// break;
|
||
// case ESP_GATTS_CONF_EVT:
|
||
// ESP_LOGI(GATTS_TAG, "ESP_GATTS_CONF_EVT status %d attr_handle %d", param->conf.status, param->conf.handle);
|
||
// if (param->conf.status != ESP_GATT_OK)
|
||
// {
|
||
// esp_log_buffer_hex(GATTS_TAG, param->conf.value, param->conf.len);
|
||
// }
|
||
// break;
|
||
// case ESP_GATTS_DISCONNECT_EVT:
|
||
// case ESP_GATTS_OPEN_EVT:
|
||
// case ESP_GATTS_CANCEL_OPEN_EVT:
|
||
// case ESP_GATTS_CLOSE_EVT:
|
||
// case ESP_GATTS_LISTEN_EVT:
|
||
// case ESP_GATTS_CONGEST_EVT:
|
||
// default:
|
||
// break;
|
||
// }
|
||
// }
|
||
|
||
static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
|
||
{
|
||
/* If event is register event, store the gatts_if for each profile */
|
||
if (event == ESP_GATTS_REG_EVT)
|
||
{
|
||
if (param->reg.status == ESP_GATT_OK)
|
||
{
|
||
gl_profile_tab[param->reg.app_id].gatts_if = gatts_if;
|
||
}
|
||
else
|
||
{
|
||
ESP_LOGI(GATTS_TAG, "Reg app failed, app_id %04x, status %d\n",
|
||
param->reg.app_id,
|
||
param->reg.status);
|
||
return;
|
||
}
|
||
}
|
||
|
||
/* If the gatts_if equal to profile A, call profile A cb handler,
|
||
* so here call each profile's callback */
|
||
do
|
||
{
|
||
int idx;
|
||
for (idx = 0; idx < PROFILE_NUM; idx++)
|
||
{
|
||
if (gatts_if == ESP_GATT_IF_NONE || /* ESP_GATT_IF_NONE, not specify a certain gatt_if, need to call every profile cb function */
|
||
gatts_if == gl_profile_tab[idx].gatts_if)
|
||
{
|
||
if (gl_profile_tab[idx].gatts_cb)
|
||
{
|
||
gl_profile_tab[idx].gatts_cb(event, gatts_if, param);
|
||
}
|
||
}
|
||
}
|
||
} while (0);
|
||
}
|
||
|
||
void RTOS_Port_Init(void)
|
||
{
|
||
/* 创建信号量 */
|
||
xSemaphore_BLE_Connect = xSemaphoreCreateBinary();
|
||
xSemaphore_WIFI_ConnectDone = xSemaphoreCreateBinary();
|
||
xSemaphore_WIFI_ConnectFail = xSemaphoreCreateBinary();
|
||
xSemaphore_WIFI_Json_PraseDone = xSemaphoreCreateBinary();
|
||
/* 创建队列 */
|
||
xQueue_WIFI_STA_Json = xQueueCreate(10, 500);
|
||
}
|
||
|
||
void ble_NetWorkConnect_Init(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);
|
||
|
||
// 防止当前蓝牙工作在经典蓝牙模式,先释放一下classic bt 资源
|
||
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)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
|
||
return;
|
||
}
|
||
|
||
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
|
||
if (ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
|
||
return;
|
||
}
|
||
// 初始化BLE的协议栈
|
||
ret = esp_bluedroid_init();
|
||
if (ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "%s init bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
|
||
return;
|
||
}
|
||
ret = esp_bluedroid_enable();
|
||
if (ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "%s enable bluetooth failed: %s\n", __func__, esp_err_to_name(ret));
|
||
return;
|
||
}
|
||
|
||
// 注册gatt 回调函数 , 导入gatt的profiles.
|
||
ret = esp_ble_gatts_register_callback(gatts_event_handler);
|
||
if (ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "gatts register error, error code = %x", ret);
|
||
return;
|
||
}
|
||
// 注册GAP事件回调函数,定义了在广播期间蓝牙设备的一些操作
|
||
ret = esp_ble_gap_register_callback(gap_event_handler);
|
||
if (ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "gap register error, error code = %x", ret);
|
||
return;
|
||
}
|
||
// 注册 profile 注册2个service A和B
|
||
ret = esp_ble_gatts_app_register(PROFILE_A_APP_ID);
|
||
if (ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret);
|
||
return;
|
||
}
|
||
// ret = esp_ble_gatts_app_register(PROFILE_B_APP_ID);
|
||
// if (ret)
|
||
// {
|
||
// ESP_LOGE(GATTS_TAG, "gatts app register error, error code = %x", ret);
|
||
// return;
|
||
// }
|
||
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9);
|
||
// 设置 mtu
|
||
esp_err_t local_mtu_ret = esp_ble_gatt_set_local_mtu(500);
|
||
if (local_mtu_ret)
|
||
{
|
||
ESP_LOGE(GATTS_TAG, "set local MTU failed, error code = %x", local_mtu_ret);
|
||
}
|
||
return;
|
||
}
|
||
|
||
void app_BLE_ConnectNet(void)
|
||
{
|
||
// 新建控制任务
|
||
xTaskCreate(BLE_NetTask, "BLE_NetTask", BLE_NET_STK_SIZE, NULL,
|
||
BLE_NET_TASK_PRIO, &BLE_NetTasks_TaskHandle);
|
||
}
|
||
//----------------------------------------------------------------
|
||
// BLE 配网的逻辑处理(接收到WIFI链接成功之后删除任务并且复位)
|
||
//----------------------------------------------------------------
|
||
char BLE_WifiScanner_NoScanFlg = 0;
|
||
extern esp_netif_t *sta_netif;
|
||
// extern TaskHandle_t UartRxHandle;
|
||
// extern TaskHandle_t UartPushHandle;
|
||
// extern esp_mqtt_client_handle_t user_client;
|
||
void BLE_NetTask(void *pvParameters)
|
||
{
|
||
char tx_buffer[100] = {[0 ... 99] = 0};
|
||
uint8_t device_mac[6] = {0};
|
||
char MAC[18] = {0};
|
||
// 初始化 操作系统的接口
|
||
RTOS_Port_Init();
|
||
// 初始 建立BLE
|
||
ble_NetWorkConnect_Init();
|
||
// 获取MAC
|
||
esp_base_mac_addr_get(device_mac);
|
||
sprintf(MAC, "%x:%x:%x:%x:%x:%x",
|
||
device_mac[0], device_mac[1], device_mac[2],
|
||
device_mac[3], device_mac[4], device_mac[5]);
|
||
printf("device_mac IS %s\n", MAC);
|
||
// 新建解析任务
|
||
xTaskCreate(ParseTask, "ParseTask_task", TASK1_STK_SIZE, NULL,
|
||
TASK1_TASK_PRIO, &ParseTaskHandle);
|
||
while (1)
|
||
{
|
||
vTaskDelay(pdMS_TO_TICKS(100));
|
||
if (BLE_Connect_Flag)
|
||
{
|
||
// 如果蓝牙链接成功则Log上报
|
||
if (xSemaphoreTake(xSemaphore_BLE_Connect, 50) == pdTRUE)
|
||
{
|
||
xTimerStop(NetConfig_timer, 0);
|
||
//------------------------------------------------------------ 清理现场
|
||
// if (UartRxHandle != NULL && BLE_WifiScanner_NoScanFlg == 0)
|
||
// vTaskDelete(UartRxHandle);
|
||
// if (UartPushHandle != NULL && BLE_WifiScanner_NoScanFlg == 0)
|
||
// vTaskDelete(UartPushHandle);
|
||
// BLE_WifiScanner_NoScanFlg = 1;
|
||
// ESP_LOGI(TAG, "vTaskDelete.....");
|
||
// vTaskDelay(pdMS_TO_TICKS(500));
|
||
// if (user_client != NULL)
|
||
//{
|
||
// ESP_ERROR_CHECK(esp_mqtt_client_disconnect(user_client));
|
||
// ESP_ERROR_CHECK(esp_mqtt_client_stop(user_client));
|
||
// ESP_ERROR_CHECK(esp_mqtt_client_destroy(user_client));
|
||
//}
|
||
// ESP_LOGI(TAG, "esp_mqtt_client_stop.....");
|
||
// vTaskDelay(pdMS_TO_TICKS(500));
|
||
// if (sta_netif != NULL && esp_wifi_disconnect() == ESP_OK)
|
||
//{
|
||
// ESP_ERROR_CHECK(esp_wifi_scan_stop());
|
||
// ESP_ERROR_CHECK(esp_wifi_stop());
|
||
// ESP_ERROR_CHECK(esp_wifi_deinit());
|
||
// ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(sta_netif)); // <-add this!
|
||
// esp_netif_destroy(sta_netif);
|
||
//}
|
||
// ESP_LOGI(TAG, "esp_wifi_stop.....");
|
||
// vTaskDelay(pdMS_TO_TICKS(500));
|
||
//------------------------------------------------------------
|
||
BLE_WifiScanner();
|
||
// BLE_ConnectDoneFlg = 1;
|
||
ESP_LOGI("BLE CONFIG", "BLE Connect Done!!!!!!!!!!");
|
||
}
|
||
// json 如果解析成功则发消息
|
||
if (xSemaphoreTake(xSemaphore_WIFI_Json_PraseDone, 50) == pdTRUE)
|
||
{
|
||
ESP_LOGI("BLE CONFIG", "Json Prase Done!");
|
||
// DONE: 保存配网信息
|
||
nvs_write_netConfig(&network_Config, sizeof(network_Config));
|
||
}
|
||
// 如果WIFI链接成功则上报对应的json
|
||
if (xSemaphoreTake(xSemaphore_WIFI_ConnectDone, 50) == pdTRUE)
|
||
{
|
||
ESP_LOGI("BLE CONFIG", "WIFI Connect Done!");
|
||
sprintf(tx_buffer, "{\"MAC\":\"%s\"}\r\n", MAC);
|
||
esp_ble_gatts_send_indicate(gl_profile_tab[PROFILE_A_APP_ID].gatts_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
|
||
strlen(tx_buffer), (uint8_t *)tx_buffer, false);
|
||
sprintf(tx_buffer, "{\"wifi status\":\"connected\"}\r\n");
|
||
esp_ble_gatts_send_indicate(gl_profile_tab[PROFILE_A_APP_ID].gatts_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
|
||
strlen(tx_buffer), (uint8_t *)tx_buffer, false);
|
||
// DONE: 完成之后需要复位
|
||
Device_System_StartReset(); // STM32部分的复位指令
|
||
// ESP32复位
|
||
esp_restart();
|
||
vTaskDelete(NULL);
|
||
}
|
||
// 如果WIFI链接失败则上报对应的json
|
||
if (xSemaphoreTake(xSemaphore_WIFI_ConnectFail, 50) == pdTRUE)
|
||
{
|
||
ESP_LOGI("BLE CONFIG", "WIFI Connect Fail!");
|
||
sprintf(tx_buffer, "{\"MAC\":\"%s\"}\r\n", MAC);
|
||
esp_ble_gatts_send_indicate(gl_profile_tab[PROFILE_A_APP_ID].gatts_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
|
||
strlen(tx_buffer), (uint8_t *)tx_buffer, false);
|
||
sprintf(tx_buffer, "{\"wifi status\":\"connect fail\"}\r\n");
|
||
esp_ble_gatts_send_indicate(gl_profile_tab[PROFILE_A_APP_ID].gatts_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
|
||
strlen(tx_buffer), (uint8_t *)tx_buffer, false);
|
||
// DONE: 完成之后需要复位
|
||
for (char i = 5; i > 0; i--)
|
||
{
|
||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||
printf("Ready to Reboot!....%d\r\n", i);
|
||
}
|
||
// ESP 复位
|
||
esp_restart();
|
||
vTaskDelete(NULL);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//----------------------------------------------------------------
|
||
// 解析线程
|
||
//----------------------------------------------------------------
|
||
void ParseTask(void *pvParameters)
|
||
{
|
||
char PraseDoneCount = 0;
|
||
char TestBuffer[512] = {0};
|
||
while (true)
|
||
{
|
||
// 测试代码,模拟接收成功且解析正常
|
||
if (xQueueReceive(xQueue_WIFI_STA_Json, TestBuffer, 10) == pdTRUE && strlen(TestBuffer) > 16)
|
||
{
|
||
printf("xQueueReceive is successful \r\ndata received is \r\n%s\r\n", TestBuffer);
|
||
cJSON *pJsonRoot = cJSON_Parse(TestBuffer);
|
||
if (!pJsonRoot)
|
||
{
|
||
ESP_LOGE(TAG, "Couldn't parse JSON Data %s", TestBuffer);
|
||
printf("Error before: [%s]\n", cJSON_GetErrorPtr());
|
||
}
|
||
else
|
||
{
|
||
char *s = cJSON_Print(pJsonRoot);
|
||
ESP_LOGI(TAG, "pJsonRoot: %s\r\n", s);
|
||
cJSON_free((void *)s);
|
||
// 解析SERIAL_NUMBER字段
|
||
cJSON *pSerialNumber = cJSON_GetObjectItem(pJsonRoot, "SERIAL_NUMBER");
|
||
if (pSerialNumber)
|
||
{
|
||
if (cJSON_IsString(pSerialNumber) && (12 == strlen(pSerialNumber->valuestring)))
|
||
{
|
||
memcpy(network_Config.serialNumber, pSerialNumber->valuestring, strlen(pSerialNumber->valuestring));
|
||
ESP_LOGI(TAG, "SerialNumber:%s \n", network_Config.serialNumber);
|
||
PraseDoneCount = 1;
|
||
}
|
||
else
|
||
{
|
||
ESP_LOGI(TAG, "SerialNumber:format error");
|
||
}
|
||
}
|
||
// 解析password字段
|
||
cJSON *pPassWord = cJSON_GetObjectItem(pJsonRoot, "PASSWORD");
|
||
if (pPassWord)
|
||
{
|
||
if (cJSON_IsString(pPassWord))
|
||
{
|
||
memset(network_Config.wifi_password, 0, sizeof(network_Config.wifi_password));
|
||
memcpy(network_Config.wifi_password, pPassWord->valuestring, strlen(pPassWord->valuestring));
|
||
}
|
||
ESP_LOGI(TAG, "password:%s \n", network_Config.wifi_password);
|
||
PraseDoneCount++;
|
||
}
|
||
// 解析ssid字段
|
||
cJSON *pSSID = cJSON_GetObjectItem(pJsonRoot, "SSID");
|
||
if (pSSID)
|
||
{
|
||
if (cJSON_IsString(pSSID))
|
||
{
|
||
memset(network_Config.wifi_ssid, 0, sizeof(network_Config.wifi_ssid));
|
||
memcpy(network_Config.wifi_ssid, pSSID->valuestring, strlen(pSSID->valuestring));
|
||
}
|
||
ESP_LOGI(TAG, "ssid:%s \n", network_Config.wifi_ssid);
|
||
PraseDoneCount++;
|
||
}
|
||
// 解析serverip字段
|
||
cJSON *pServerIP = cJSON_GetObjectItem(pJsonRoot, "SERVER_IP");
|
||
if (pServerIP)
|
||
{
|
||
if (cJSON_IsString(pServerIP))
|
||
{
|
||
memset(network_Config.mqtt_ip, 0, sizeof(network_Config.mqtt_ip));
|
||
memcpy(network_Config.mqtt_ip, pServerIP->valuestring, strlen(pServerIP->valuestring));
|
||
}
|
||
ESP_LOGI(TAG, "server_ip:%s \n", network_Config.mqtt_ip);
|
||
PraseDoneCount++;
|
||
}
|
||
// 解析port字段
|
||
cJSON *pPort = cJSON_GetObjectItem(pJsonRoot, "SERVER_PORT");
|
||
if (pPort)
|
||
{
|
||
if (cJSON_IsString(pPort))
|
||
{
|
||
network_Config.mqtt_port = 0;
|
||
network_Config.mqtt_port = atoi(pPort->valuestring);
|
||
}
|
||
ESP_LOGI(TAG, "port:%d \n", network_Config.mqtt_port);
|
||
PraseDoneCount++;
|
||
}
|
||
// 解析MQTT USERNAME字段
|
||
cJSON *pMQTT_UserName = cJSON_GetObjectItem(pJsonRoot, "MQTT_USERNAME");
|
||
if (pMQTT_UserName)
|
||
{
|
||
if (cJSON_IsString(pMQTT_UserName))
|
||
{
|
||
memset(network_Config.mqtt_username, 0, sizeof(network_Config.mqtt_username));
|
||
memcpy(network_Config.mqtt_username, pMQTT_UserName->valuestring, strlen(pMQTT_UserName->valuestring));
|
||
}
|
||
ESP_LOGI(TAG, "MQTT UserName:%s \n", network_Config.mqtt_username);
|
||
PraseDoneCount++;
|
||
}
|
||
else
|
||
{
|
||
ESP_LOGI(TAG, "MQTT UserName: NULL \n");
|
||
memset(network_Config.mqtt_username, 0, sizeof(network_Config.mqtt_username));
|
||
memcpy(network_Config.mqtt_username, "NULL", 4);
|
||
}
|
||
// 解析MQTT USERNAME字段
|
||
cJSON *pMQTT_PassWord = cJSON_GetObjectItem(pJsonRoot, "MQTT_PASSWORD");
|
||
if (pMQTT_PassWord)
|
||
{
|
||
if (cJSON_IsString(pMQTT_PassWord))
|
||
{
|
||
memset(network_Config.mqtt_password, 0, sizeof(network_Config.mqtt_password));
|
||
memcpy(network_Config.mqtt_password, pMQTT_PassWord->valuestring, strlen(pMQTT_PassWord->valuestring));
|
||
}
|
||
ESP_LOGI(TAG, "MQTT PassWord:%s \n", network_Config.mqtt_password);
|
||
PraseDoneCount++;
|
||
}
|
||
else
|
||
{
|
||
ESP_LOGI(TAG, "MQTT PassWord: NULL \n");
|
||
memset(network_Config.mqtt_password, 0, sizeof(network_Config.mqtt_password));
|
||
memcpy(network_Config.mqtt_password, "NULL", 4);
|
||
}
|
||
cJSON_Delete(pJsonRoot); // 释放内存
|
||
}
|
||
printf("PraseDoneCount is %d\n", PraseDoneCount);
|
||
// 超过四个或者只配置了SN 表示解析成功
|
||
if (PraseDoneCount >= 4 || PraseDoneCount == 1)
|
||
{
|
||
printf("xSemaphore_WIFI_Json_PraseDone Send!!!!!\n");
|
||
xSemaphoreGive(xSemaphore_WIFI_Json_PraseDone);
|
||
}
|
||
vTaskDelay(500 / portTICK_PERIOD_MS); // 等待1s
|
||
// 尝试链接WIFI
|
||
xSemaphoreGive(xSemaphore_WIFI_ConnectDone);
|
||
}
|
||
vTaskDelay(100 / portTICK_PERIOD_MS); // 等待1s
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @function: BLE_WifiScanner
|
||
* @brief: None
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
char EmptyBuffer[100] = {"{\"wifi\" : [],\"Number\" : 0, \"DeviseType\" : \"Elder\"}"};
|
||
void BLE_WifiScanner(void)
|
||
{
|
||
vTaskDelay(1500 / portTICK_PERIOD_MS); // 等待1s
|
||
// 不需要扫描
|
||
ESP_LOGW(TAG, "WifiScanMsg : %s", WifiScanMsg);
|
||
if (WifiScanMsg[0] == 0x00)
|
||
{
|
||
memcpy(WifiScanMsg, EmptyBuffer, sizeof(EmptyBuffer));
|
||
ESP_LOGW(TAG, "EmptyBuffer : %s", EmptyBuffer);
|
||
}
|
||
esp_ble_gatts_send_indicate(gl_profile_tab[PROFILE_A_APP_ID].gatts_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id, gl_profile_tab[PROFILE_A_APP_ID].char_handle,
|
||
strlen(WifiScanMsg), (uint8_t *)WifiScanMsg, false);
|
||
}
|
||
|
||
/**
|
||
* @function: BLE_RetryConnectNetwork
|
||
* @brief 配网完成之后上报是否成功
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void BLE_RetryConnectNetwork(void)
|
||
{
|
||
}
|
||
|
||
/**
|
||
* @description: app_BLE_StopNetConfigEvent
|
||
* @return {*}
|
||
*/
|
||
void app_BLE_StopNetConfigEvent(void)
|
||
{
|
||
ESP_LOGI(TAG, "TimeOut Stop BLE Config EVENT");
|
||
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_ENABLED)
|
||
{
|
||
esp_bluedroid_disable();
|
||
esp_bluedroid_deinit();
|
||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||
esp_bt_controller_disable();
|
||
esp_bt_controller_deinit();
|
||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||
esp_bt_mem_release(ESP_BT_MODE_BTDM);
|
||
// 关闭配网线程
|
||
vTaskDelete(BLE_NetTasks_TaskHandle);
|
||
// 关闭解析线程
|
||
vTaskDelete(ParseTaskHandle);
|
||
}
|
||
}
|