Job_SignsPads/ESP32/software/main/src/bsp_bleNet.c
2025-04-22 10:29:37 +08:00

1266 lines
54 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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);
}
}