ble_spp_client(连接我家的手环)
2018-12-13 本文已影响83人
昨天剩下的一杯冷茶
1、 手环的服务和特征值
1.1、 服务UUID 0xFFC0
1.2、 0xFFC2 Properties:Notify
1.3、 0xFFC1 Properties:Write
2、 在ble_spp_client修改
2.1 修改服务特征值
#define ESP_GATT_SPP_SERVICE_UUID 0xFFC0
enum
{
SPP_IDX_SVC,
SPP_IDX_SPP_DATA_NTY_VAL,
SPP_IDX_SPP_DATA_NTF_CFG,
SPP_IDX_SPP_DATA_RECV_VAL,
#if 0
SPP_IDX_SPP_COMMAND_VAL,
SPP_IDX_SPP_STATUS_VAL,
SPP_IDX_SPP_STATUS_CFG,
#endif
#ifdef SUPPORT_HEARTBEAT
SPP_IDX_SPP_HEARTBEAT_VAL,
SPP_IDX_SPP_HEARTBEAT_CFG,
#endif
SPP_IDX_NB,
};
2.2在广播设置过滤条件
case ESP_GAP_SEARCH_INQ_RES_EVT:
//CD:FF:18:D8:8A:D5
adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len);
if (adv_name_len && (strncmp((char *)adv_name, "H701", adv_name_len) == 0) )
{
if ( (scan_result->scan_rst.bda[4] == 0x8a) && (scan_result->scan_rst.bda[5] == 0xd5) )
{
esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6);
ESP_LOGI(GATTC_TAG, "%02X-%02X-%02X-%02X-%02X-%02X\n",\
scan_result->scan_rst.bda[0],scan_result->scan_rst.bda[1],scan_result->scan_rst.bda[2],\
scan_result->scan_rst.bda[3],scan_result->scan_rst.bda[4],scan_result->scan_rst.bda[5]);
ESP_LOGI(GATTC_TAG, "Searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len);
ESP_LOGI(GATTC_TAG, "Searched Device Name Len %d", adv_name_len);
esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len);
ESP_LOGI(GATTC_TAG, "\n");
memcpy(&(scan_rst), scan_result, sizeof(esp_ble_gap_cb_param_t));
esp_ble_gap_stop_scanning();
if (adv_name != NULL)
{
if ( strncmp((char *)adv_name, device_name, adv_name_len) == 0)
{
memcpy(&(scan_rst), scan_result, sizeof(esp_ble_gap_cb_param_t));
esp_ble_gap_stop_scanning();
}
}
}
}
2.3 添加一个变量,判断是否打开通知&&将下面部分语句屏蔽
case ESP_GATTC_WRITE_DESCR_EVT:
ESP_LOGI(GATTC_TAG,"ESP_GATTC_WRITE_DESCR_EVT: status =%d,handle = %d \n", p_data->write.status, p_data->write.handle);
if(p_data->write.status != ESP_GATT_OK)
{
ESP_LOGE(GATTC_TAG, "ESP_GATTC_WRITE_DESCR_EVT, error status = %d", p_data->write.status);
break;
}
else
{
is_notify_ok = true;
ESP_LOGI(GATTC_TAG, "is_notify_ok = true\n");
}
switch(cmd)
{
case SPP_IDX_SPP_DATA_NTY_VAL:
//cmd = SPP_IDX_SPP_STATUS_VAL;
//xQueueSend(cmd_reg_queue, &cmd,10/portTICK_PERIOD_MS);
break;
#if 0
case SPP_IDX_SPP_STATUS_VAL:
#ifdef SUPPORT_HEARTBEAT
cmd = SPP_IDX_SPP_HEARTBEAT_VAL;
xQueueSend(cmd_reg_queue, &cmd, 10/portTICK_PERIOD_MS);
#endif
break;
#endif
2.4、将spp_client_reg_task任务函数改为如下
void spp_client_reg_task(void* arg)
{
uint16_t cmd_id;
for(;;)
{
vTaskDelay(100 / portTICK_PERIOD_MS);
if(xQueueReceive(cmd_reg_queue, &cmd_id, portMAX_DELAY))
{
if(cmd_id == SPP_IDX_SPP_DATA_NTY_VAL)
{
ESP_LOGI(GATTC_TAG,"Index = %d,UUID = 0x%04x, handle = %d \n", cmd_id, (db+SPP_IDX_SPP_DATA_NTY_VAL)->uuid.uuid.uuid16, (db+SPP_IDX_SPP_DATA_NTY_VAL)->attribute_handle);
esp_ble_gattc_register_for_notify(spp_gattc_if, gl_profile_tab[PROFILE_APP_ID].remote_bda, (db+SPP_IDX_SPP_DATA_NTY_VAL)->attribute_handle);
}
#if 0
else if(cmd_id == SPP_IDX_SPP_STATUS_VAL)
{
ESP_LOGI(GATTC_TAG,"Index = %d,UUID = 0x%04x, handle = %d \n", cmd_id, (db+SPP_IDX_SPP_STATUS_VAL)->uuid.uuid.uuid16, (db+SPP_IDX_SPP_STATUS_VAL)->attribute_handle);
esp_ble_gattc_register_for_notify(spp_gattc_if, gl_profile_tab[PROFILE_APP_ID].remote_bda, (db+SPP_IDX_SPP_STATUS_VAL)->attribute_handle);
}
#endif
#ifdef SUPPORT_HEARTBEAT
else if(cmd_id == SPP_IDX_SPP_HEARTBEAT_VAL)
{
ESP_LOGI(GATTC_TAG,"Index = %d,UUID = 0x%04x, handle = %d \n", cmd_id, (db+SPP_IDX_SPP_HEARTBEAT_VAL)->uuid.uuid.uuid16, (db+SPP_IDX_SPP_HEARTBEAT_VAL)->attribute_handle);
esp_ble_gattc_register_for_notify(spp_gattc_if, gl_profile_tab[PROFILE_APP_ID].remote_bda, (db+SPP_IDX_SPP_HEARTBEAT_VAL)->attribute_handle);
}
#endif
}
}
}
2.5、将串口任务改为如下:
//17 00 02 02 02
uint8_t motor_buf[5] = {0x17,0x00,0x02,0x02,0x02};//是我公司定义的协议
void uart_task(void *pvParameters)
{
uart_event_t event;
for (;;)
{
if (is_notify_ok && ((db+SPP_IDX_SPP_DATA_RECV_VAL)->properties & (ESP_GATT_CHAR_PROP_BIT_WRITE_NR | ESP_GATT_CHAR_PROP_BIT_WRITE)) )
{
ESP_LOGE(GATTC_TAG, "---------->send motor data\n");
esp_ble_gattc_write_char( spp_gattc_if,
spp_conn_id,
(db+SPP_IDX_SPP_DATA_RECV_VAL)->attribute_handle,
5,
motor_buf,
ESP_GATT_WRITE_TYPE_RSP,
ESP_GATT_AUTH_REQ_NONE);
is_notify_ok = false;
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
//vTaskDelete(NULL);
}
2.6将通知处理函数改为如下(已经知道手环的MAC为CD:FF:18:D8:8A:D5)
static void notify_event_handler(esp_ble_gattc_cb_param_t * p_data)
{
uint8_t handle = 0;
if(p_data->notify.is_notify == true)
{
ESP_LOGI(GATTC_TAG,"+NOTIFY:handle = %d,length = %d ", p_data->notify.handle, p_data->notify.value_len);
}
else
{
ESP_LOGI(GATTC_TAG,"+INDICATE:handle = %d,length = %d ", p_data->notify.handle, p_data->notify.value_len);
}
handle = p_data->notify.handle;
if(handle == db[SPP_IDX_SPP_DATA_NTY_VAL].attribute_handle)
{
esp_log_buffer_char(GATTC_TAG, (char *)p_data->notify.value, p_data->notify.value_len);
ESP_LOGI(GATTC_TAG,"%02X-%02X-%02X-%02X-\n",p_data->notify.value[0],p_data->notify.value[1],\
p_data->notify.value[2],p_data->notify.value[3]);
}
else
{
esp_log_buffer_char(GATTC_TAG, (char *)p_data->notify.value, p_data->notify.value_len);
}
}
效果如下:
image.png
当客户端连接上手环后,发送震动命令(0X1700020202),手环回复(0X9617)。