简介:枚举全部服务需要按照下面三个步骤来进行,完整代码直接看第四点。
一.枚举出PrimaryServices的uuid和handle范围:
1.库函数
GATT_DiscAllPrimaryServices(centralConnHandle,centralTaskId );
2.从机返回数据处理
case BLE_DISC_STATE_SVC:
// 处理服务发现结果
if (pMsg->method == ATT_READ_BY_GRP_TYPE_RSP) {
if (pMsg->msg.readByGrpTypeRsp.numGrps > 0) {
uint8_t len = pMsg->msg.readByGrpTypeRsp.len;
uint8_t *pData = pMsg->msg.readByGrpTypeRsp.pDataList;
for (uint8_t i = 0; i < pMsg->msg.readByGrpTypeRsp.numGrps; i++) {
uint16_t startHandle = BUILD_UINT16(pData[len * i], pData[len * i + 1]);
uint16_t endHandle = BUILD_UINT16(pData[len * i + 2], pData[len * i + 3]);
uint8_t uuidLen = len - 4;
uint8_t *uuid = &pData[len * i + 4];
PRINT("服务 #%d:\r\n", i+1);
PRINT(" 起始句柄: 0x%04X\r\n", startHandle);
PRINT(" 结束句柄: 0x%04X\r\n", endHandle);
PRINT(" UUID长度: %d 字节\r\n", uuidLen);
PRINT(" UUID: ");
hex_dump(uuid, uuidLen);
// 可选:检查特定服务UUID并存储句柄
if (uuidLen == 2 && uuid[0] == LO_UINT16(SIMPLEPROFILE_SERV_UUID) &&
uuid[1] == HI_UINT16(SIMPLEPROFILE_SERV_UUID)) {
centralSvcStartHdl = startHandle;
centralSvcEndHdl = endHandle;
PRINT("找到SimpleProfile服务!\r\n");
}
}
}
// 服务发现完成,开始发现特征
if (pMsg->hdr.status == bleProcedureComplete) {
centralDiscState = BLE_DISC_STATE_CHAR;
uint16_t startHdl = 0x01;
uint16_t endHdl = 0xFFFF;
// 使用实际服务范围(优化:避免全范围搜索)
// uint16_t startHdl = (centralSvcStartHdl > 0) ? centralSvcStartHdl : 0x01;
// uint16_t endHdl = (centralSvcEndHdl > 0) ? centralSvcEndHdl : 0xFFFF;
result = GATT_DiscAllChars(centralConnHandle, startHdl, endHdl, centralTaskId);
PRINT("GATT_DiscAllChars = 0x%02X\r\n", result);
if (result != SUCCESS) {
PRINT("错误: 启动特征发现失败 (0x%02X)\r\n", result);
centralDiscState = BLE_DISC_STATE_IDLE;
}
}
} else if (pMsg->method == ATT_ERROR_RSP) {
PRINT("错误: 服务发现失败 (0x%02X)\r\n", pMsg->hdr.status);
centralDiscState = BLE_DISC_STATE_IDLE;
}
break;
3.代码输出详解
每次最多只能返回2个PrimaryServices,Peripheral例程有四个PrimaryServices,分两次获取到所有的四个PrimaryServices;分别获取到了每个PrimaryService的起始句柄,结束句柄和UUID。
GATT_DiscAllPrimaryServices = 0x00
服务 #1:
起始句柄: 0x0001
结束句柄: 0x0009
UUID长度: 2 字节
UUID: 00 18
服务 #2:
起始句柄: 0x000A
结束句柄: 0x000D
UUID长度: 2 字节
UUID: 01 18
服务 #1:
起始句柄: 0x000E
结束句柄: 0x0020
UUID长度: 2 字节
UUID: 0a 18
服务 #2:
起始句柄: 0x0021
结束句柄: 0x0031
UUID长度: 2 字节
UUID: e0 ff
找到SimpleProfile服务!
GATT_DiscAllChars = 0x00
二.枚举出每次主服务下的chars:
1.库函数
GATT_DiscAllChars(centralConnHandle,0x01,0xFFFF,centralTaskId);
2.从机返回数据处理
case BLE_DISC_STATE_CHAR:
// 处理特征发现结果
if (pMsg->method == ATT_READ_BY_TYPE_RSP) {
if (pMsg->msg.readByTypeRsp.numPairs > 0) {
uint8_t len = pMsg->msg.readByTypeRsp.len;
uint8_t *pData = pMsg->msg.readByTypeRsp.pDataList;
for (uint8_t i = 0; i < pMsg->msg.readByTypeRsp.numPairs; i++) {
uint8_t properties = pData[len * i + 2];
uint16_t valueHandle = BUILD_UINT16(pData[len * i + 3], pData[len * i + 4]);
uint8_t uuidLen = len - 5;
uint8_t *uuid = &pData[len * i + 5];
PRINT("特征 #%d:\r\n", i+1);
PRINT(" 属性: 0x%02X\r\n", properties);
PRINT(" 值句柄: 0x%04X\r\n", valueHandle);
PRINT(" UUID长度: %d 字节\r\n", uuidLen);
PRINT(" UUID: ");
hex_dump(uuid, uuidLen);
// 存储可写特征句柄
if (properties & (GATT_PROP_WRITE | GATT_PROP_WRITE_NO_RSP)) {
centralCharHdl = valueHandle;
PRINT(" 可写特征句柄: 0x%04X\r\n", valueHandle);
}
// 存储可通知特征的CCCD句柄 (值句柄+1)
if (properties & GATT_PROP_NOTIFY) {
centralCCCDHdl = valueHandle + 1;
PRINT(" 通知CCCD句柄: 0x%04X\r\n", centralCCCDHdl);
}
}
}
// 特征发现完成,开始发现描述符
if (pMsg->hdr.status == bleProcedureComplete) {
centralDiscState = BLE_DISC_STATE_DESC;
uint16_t startHdl = 0x01;
uint16_t endHdl = 0xFFFF;
// 使用实际特征范围(优化:避免全范围搜索)
// uint16_t startHdl = (centralSvcStartHdl > 0) ? centralSvcStartHdl : 0x01;
// uint16_t endHdl = (centralSvcEndHdl > 0) ? centralSvcEndHdl : 0xFFFF;
result = GATT_DiscAllCharDescs(centralConnHandle, startHdl, endHdl, centralTaskId);
PRINT("GATT_DiscAllCharDescs = 0x%02X\r\n", result);
if (result != SUCCESS) {
PRINT("错误: 启动描述符发现失败 (0x%02X)\r\n", result);
centralDiscState = BLE_DISC_STATE_IDLE;
}
}
} else if (pMsg->method == ATT_ERROR_RSP) {
PRINT("错误: 特征发现失败 (0x%02X)\r\n", pMsg->hdr.status);
centralDiscState = BLE_DISC_STATE_IDLE;
}
break;
3.代码输出详解
每次最多只能返回3个Chars,Peripheral例程有19个Chars,分7次获取到所有的19个Chars;分别获取到了每个Char的属性,属性值句柄和UUID。
GATT_DiscAllChars = 0x00
PHY Update 0...
RSSI : -46 dB
特征 #1:
属性: 0x02
值句柄: 0x0003
UUID长度: 2 字节
UUID: 00 2a
特征 #2:
属性: 0x02
值句柄: 0x0005
UUID长度: 2 字节
UUID: 01 2a
特征 #3:
属性: 0x02
值句柄: 0x0007
UUID长度: 2 字节
UUID: 04 2a
特征 #1:
属性: 0x02
值句柄: 0x0009
UUID长度: 2 字节
UUID: a6 2a
特征 #2:
属性: 0x20
值句柄: 0x000C
UUID长度: 2 字节
UUID: 05 2a
特征 #3:
属性: 0x02
值句柄: 0x0010
UUID长度: 2 字节
UUID: 23 2a
特征 #1:
属性: 0x02
值句柄: 0x0012
UUID长度: 2 字节
UUID: 24 2a
特征 #2:
属性: 0x02
值句柄: 0x0014
UUID长度: 2 字节
UUID: 25 2a
特征 #3:
属性: 0x02
值句柄: 0x0016
UUID长度: 2 字节
UUID: 26 2a
PHY Update...
特征 #1:
属性: 0x02
值句柄: 0x0018
UUID长度: 2 字节
UUID: 27 2a
特征 #2:
属性: 0x02
值句柄: 0x001A
UUID长度: 2 字节
UUID: 28 2a
特征 #3:
属性: 0x02
值句柄: 0x001C
UUID长度: 2 字节
UUID: 29 2a
特征 #1:
属性: 0x02
值句柄: 0x001E
UUID长度: 2 字节
UUID: 2a 2a
特征 #2:
属性: 0x02
值句柄: 0x0020
UUID长度: 2 字节
UUID: 50 2a
特征 #3:
属性: 0x0A
值句柄: 0x0023
UUID长度: 2 字节
UUID: e1 ff
可写特征句柄: 0x0023
特征 #1:
属性: 0x02
值句柄: 0x0026
UUID长度: 2 字节
UUID: e2 ff
特征 #2:
属性: 0x08
值句柄: 0x0029
UUID长度: 2 字节
UUID: e3 ff
可写特征句柄: 0x0029
特征 #3:
属性: 0x10
值句柄: 0x002C
UUID长度: 2 字节
UUID: e4 ff
通知CCCD句柄: 0x002D
RSSI : -49 dB
Param Update...
特征 #1:
属性: 0x02
值句柄: 0x0030
UUID长度: 2 字节
UUID: e5 ff
三.枚举处每个char的Declarations和Descriptors:
1.库函数
GATT_DiscAllCharDescs(centralConnHandle,0x01,0xFFFF,centralTaskId);
2.从机返回数据处理
case BLE_DISC_STATE_DESC:
// 处理描述符发现结果
if (pMsg->method == ATT_FIND_INFO_RSP) {
if (pMsg->msg.findInfoRsp.numInfo > 0) {
uint16_t numInfo = pMsg->msg.findInfoRsp.numInfo;
uint8_t format = pMsg->msg.findInfoRsp.format;
uint8_t *pInfo = pMsg->msg.findInfoRsp.pInfo;
PRINT("找到 %d 个描述符\r\n", numInfo);
PRINT("找到 %d 个描述符\r\n", format);
// 验证格式和数据长度
uint8_t entrySize = (format == 0x01) ? 4 : 18; // 16位或128位UUID
if (1) {
for (uint16_t i = 0; i < numInfo; i++) {
uint16_t handle = BUILD_UINT16(pInfo[i * entrySize], pInfo[i * entrySize + 1]);
PRINT("描述符 #%d:\r\n", i+1);
PRINT(" 句柄: 0x%04X\r\n", handle);
if (format == 0x01) { // 16位UUID
uint16_t uuid = BUILD_UINT16(pInfo[i * entrySize + 2], pInfo[i * entrySize + 3]);
PRINT(" UUID: 0x%04X\r\n", uuid);
// 检查是否为CCCD (0x2902)
if (uuid == GATT_CLIENT_CHAR_CFG_UUID) {
PRINT(" 找到CCCD描述符!\r\n");
centralCCCDHdl = handle; // 更新CCCD句柄
}
} else { // 128位UUID
PRINT(" UUID: 128位 (省略显示)\r\n");
// 可扩展:添加128位UUID处理逻辑
}
}
} else {
PRINT("错误: 描述符数据长度不匹配!\r\n");
}
}
// 描述符发现完成
if (pMsg->hdr.status == bleProcedureComplete) {
PRINT("描述符发现完成!\r\n");
centralDiscState = BLE_DISC_STATE_COMPLETE;
// 启动下一步操作(例如启用通知)仅是演示,当服务中发现多个centralCCCDHdl时只会开启最后一个
if (centralCCCDHdl != 0) {
tmos_start_task(centralTaskId, START_WRITE_CCCD_EVT, 1600);
}
}
} else if (pMsg->method == ATT_ERROR_RSP) {
PRINT("错误: 描述符发现失败 (0x%02X)\r\n", pMsg->hdr.status);
centralDiscState = BLE_DISC_STATE_IDLE;
}
break;
default:
break;
}
3.代码输出详解
每次最多只能返回5个描述符,Peripheral例程有49个Chars,分8次获取到所有的49个Chars;分别获取到了每个描述符的句柄和UUID。
GATT_DiscAllCharDescs = 0x00
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0001
UUID: 0x2800
描述符 #2:
句柄: 0x0002
UUID: 0x2803
描述符 #3:
句柄: 0x0003
UUID: 0x2A00
描述符 #4:
句柄: 0x0004
UUID: 0x2803
描述符 #5:
句柄: 0x0005
UUID: 0x2A01
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0006
UUID: 0x2803
描述符 #2:
句柄: 0x0007
UUID: 0x2A04
描述符 #3:
句柄: 0x0008
UUID: 0x2803
描述符 #4:
句柄: 0x0009
UUID: 0x2AA6
描述符 #5:
句柄: 0x000A
UUID: 0x2800
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x000B
UUID: 0x2803
描述符 #2:
句柄: 0x000C
UUID: 0x2A05
描述符 #3:
句柄: 0x000D
UUID: 0x2902
找到CCCD描述符!
描述符 #4:
句柄: 0x000E
UUID: 0x2800
描述符 #5:
句柄: 0x000F
UUID: 0x2803
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0010
UUID: 0x2A23
描述符 #2:
句柄: 0x0011
UUID: 0x2803
描述符 #3:
句柄: 0x0012
UUID: 0x2A24
描述符 #4:
句柄: 0x0013
UUID: 0x2803
描述符 #5:
句柄: 0x0014
UUID: 0x2A25
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0015
UUID: 0x2803
描述符 #2:
句柄: 0x0016
UUID: 0x2A26
描述符 #3:
句柄: 0x0017
UUID: 0x2803
描述符 #4:
句柄: 0x0018
UUID: 0x2A27
描述符 #5:
句柄: 0x0019
UUID: 0x2803
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x001A
UUID: 0x2A28
描述符 #2:
句柄: 0x001B
UUID: 0x2803
描述符 #3:
句柄: 0x001C
UUID: 0x2A29
描述符 #4:
句柄: 0x001D
UUID: 0x2803
描述符 #5:
句柄: 0x001E
UUID: 0x2A2A
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x001F
UUID: 0x2803
描述符 #2:
句柄: 0x0020
UUID: 0x2A50
描述符 #3:
句柄: 0x0021
UUID: 0x2800
描述符 #4:
句柄: 0x0022
UUID: 0x2803
描述符 #5:
句柄: 0x0023
UUID: 0xFFE1
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0024
UUID: 0x2901
描述符 #2:
句柄: 0x0025
UUID: 0x2803
描述符 #3:
句柄: 0x0026
UUID: 0xFFE2
描述符 #4:
句柄: 0x0027
UUID: 0x2901
描述符 #5:
句柄: 0x0028
UUID: 0x2803
RSSI : -46 dB
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0029
UUID: 0xFFE3
描述符 #2:
句柄: 0x002A
UUID: 0x2901
描述符 #3:
句柄: 0x002B
UUID: 0x2803
描述符 #4:
句柄: 0x002C
UUID: 0xFFE4
描述符 #5:
句柄: 0x002D
UUID: 0x2902
找到CCCD描述符!
找到 4 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x002E
UUID: 0x2901
描述符 #2:
句柄: 0x002F
UUID: 0x2803
描述符 #3:
句柄: 0x0030
UUID: 0xFFE5
描述符 #4:
句柄: 0x0031
UUID: 0x2901
描述符发现完成!
四.完整代码展示:
将下面两个函数直接替换主机例程里的同名函数便可使用,hex_dump为方便打印输出的函数,
void hex_dump(uint8_t* data,uint32_t length) {
for(uint32_t i=0;i<length;i++) {
PRINT("%02x ",*data);
data++;
}
PRINT("\r\n");
}
static void centralStartDiscovery(void)
{
uint8_t result;
// 初始化缓存的句柄
centralSvcStartHdl = centralSvcEndHdl = centralCharHdl = 0;
centralCCCDHdl = 0; // 新增CCCD句柄初始化
centralDiscState = BLE_DISC_STATE_SVC;
// 发现所有主服务
result = GATT_DiscAllPrimaryServices(centralConnHandle, centralTaskId);
PRINT("GATT_DiscAllPrimaryServices = 0x%02X\r\n", result);
if (result != SUCCESS) {
PRINT("错误: 启动服务发现失败 (0x%02X)\r\n", result);
centralDiscState = BLE_DISC_STATE_IDLE;
}
}
static void centralGATTDiscoveryEvent(gattMsgEvent_t *pMsg)
{
uint8_t result;
if (pMsg == NULL) return; //检查空指针
switch (centralDiscState) {
case BLE_DISC_STATE_SVC:
// 处理服务发现结果
if (pMsg->method == ATT_READ_BY_GRP_TYPE_RSP) {
if (pMsg->msg.readByGrpTypeRsp.numGrps > 0) {
uint8_t len = pMsg->msg.readByGrpTypeRsp.len;
uint8_t *pData = pMsg->msg.readByGrpTypeRsp.pDataList;
for (uint8_t i = 0; i < pMsg->msg.readByGrpTypeRsp.numGrps; i++) {
uint16_t startHandle = BUILD_UINT16(pData[len * i], pData[len * i + 1]);
uint16_t endHandle = BUILD_UINT16(pData[len * i + 2], pData[len * i + 3]);
uint8_t uuidLen = len - 4;
uint8_t *uuid = &pData[len * i + 4];
PRINT("服务 #%d:\r\n", i+1);
PRINT(" 起始句柄: 0x%04X\r\n", startHandle);
PRINT(" 结束句柄: 0x%04X\r\n", endHandle);
PRINT(" UUID长度: %d 字节\r\n", uuidLen);
PRINT(" UUID: ");
hex_dump(uuid, uuidLen);
// 可选:检查特定服务UUID并存储句柄
if (uuidLen == 2 && uuid[0] == LO_UINT16(SIMPLEPROFILE_SERV_UUID) &&
uuid[1] == HI_UINT16(SIMPLEPROFILE_SERV_UUID)) {
centralSvcStartHdl = startHandle;
centralSvcEndHdl = endHandle;
PRINT("找到SimpleProfile服务!\r\n");
}
}
}
// 服务发现完成,开始发现特征
if (pMsg->hdr.status == bleProcedureComplete) {
centralDiscState = BLE_DISC_STATE_CHAR;
uint16_t startHdl = 0x01;
uint16_t endHdl = 0xFFFF;
// 使用实际服务范围(优化:避免全范围搜索)
// uint16_t startHdl = (centralSvcStartHdl > 0) ? centralSvcStartHdl : 0x01;
// uint16_t endHdl = (centralSvcEndHdl > 0) ? centralSvcEndHdl : 0xFFFF;
result = GATT_DiscAllChars(centralConnHandle, startHdl, endHdl, centralTaskId);
PRINT("GATT_DiscAllChars = 0x%02X\r\n", result);
if (result != SUCCESS) {
PRINT("错误: 启动特征发现失败 (0x%02X)\r\n", result);
centralDiscState = BLE_DISC_STATE_IDLE;
}
}
} else if (pMsg->method == ATT_ERROR_RSP) {
PRINT("错误: 服务发现失败 (0x%02X)\r\n", pMsg->hdr.status);
centralDiscState = BLE_DISC_STATE_IDLE;
}
break;
case BLE_DISC_STATE_CHAR:
// 处理特征发现结果
if (pMsg->method == ATT_READ_BY_TYPE_RSP) {
if (pMsg->msg.readByTypeRsp.numPairs > 0) {
uint8_t len = pMsg->msg.readByTypeRsp.len;
uint8_t *pData = pMsg->msg.readByTypeRsp.pDataList;
for (uint8_t i = 0; i < pMsg->msg.readByTypeRsp.numPairs; i++) {
uint8_t properties = pData[len * i + 2];
uint16_t valueHandle = BUILD_UINT16(pData[len * i + 3], pData[len * i + 4]);
uint8_t uuidLen = len - 5;
uint8_t *uuid = &pData[len * i + 5];
PRINT("特征 #%d:\r\n", i+1);
PRINT(" 属性: 0x%02X\r\n", properties);
PRINT(" 值句柄: 0x%04X\r\n", valueHandle);
PRINT(" UUID长度: %d 字节\r\n", uuidLen);
PRINT(" UUID: ");
hex_dump(uuid, uuidLen);
// 存储可写特征句柄
if (properties & (GATT_PROP_WRITE | GATT_PROP_WRITE_NO_RSP)) {
centralCharHdl = valueHandle;
PRINT(" 可写特征句柄: 0x%04X\r\n", valueHandle);
}
// 存储可通知特征的CCCD句柄 (值句柄+1)
if (properties & GATT_PROP_NOTIFY) {
centralCCCDHdl = valueHandle + 1;
PRINT(" 通知CCCD句柄: 0x%04X\r\n", centralCCCDHdl);
}
}
}
// 特征发现完成,开始发现描述符
if (pMsg->hdr.status == bleProcedureComplete) {
centralDiscState = BLE_DISC_STATE_DESC;
uint16_t startHdl = 0x01;
uint16_t endHdl = 0xFFFF;
// 使用实际特征范围(优化:避免全范围搜索)
// uint16_t startHdl = (centralSvcStartHdl > 0) ? centralSvcStartHdl : 0x01;
// uint16_t endHdl = (centralSvcEndHdl > 0) ? centralSvcEndHdl : 0xFFFF;
result = GATT_DiscAllCharDescs(centralConnHandle, startHdl, endHdl, centralTaskId);
PRINT("GATT_DiscAllCharDescs = 0x%02X\r\n", result);
if (result != SUCCESS) {
PRINT("错误: 启动描述符发现失败 (0x%02X)\r\n", result);
centralDiscState = BLE_DISC_STATE_IDLE;
}
}
} else if (pMsg->method == ATT_ERROR_RSP) {
PRINT("错误: 特征发现失败 (0x%02X)\r\n", pMsg->hdr.status);
centralDiscState = BLE_DISC_STATE_IDLE;
}
break;
case BLE_DISC_STATE_DESC:
// 处理描述符发现结果
if (pMsg->method == ATT_FIND_INFO_RSP) {
if (pMsg->msg.findInfoRsp.numInfo > 0) {
uint16_t numInfo = pMsg->msg.findInfoRsp.numInfo;
uint8_t format = pMsg->msg.findInfoRsp.format;
uint8_t *pInfo = pMsg->msg.findInfoRsp.pInfo;
PRINT("找到 %d 个描述符\r\n", numInfo);
PRINT("找到 %d 个描述符\r\n", format);
// 验证格式和数据长度
uint8_t entrySize = (format == 0x01) ? 4 : 18; // 16位或128位UUID
if (1) {
for (uint16_t i = 0; i < numInfo; i++) {
uint16_t handle = BUILD_UINT16(pInfo[i * entrySize], pInfo[i * entrySize + 1]);
PRINT("描述符 #%d:\r\n", i+1);
PRINT(" 句柄: 0x%04X\r\n", handle);
if (format == 0x01) { // 16位UUID
uint16_t uuid = BUILD_UINT16(pInfo[i * entrySize + 2], pInfo[i * entrySize + 3]);
PRINT(" UUID: 0x%04X\r\n", uuid);
// 检查是否为CCCD (0x2902)
if (uuid == GATT_CLIENT_CHAR_CFG_UUID) {
PRINT(" 找到CCCD描述符!\r\n");
centralCCCDHdl = handle; // 更新CCCD句柄
}
} else { // 128位UUID
PRINT(" UUID: 128位 (省略显示)\r\n");
// 可扩展:添加128位UUID处理逻辑
}
}
} else {
PRINT("错误: 描述符数据长度不匹配!\r\n");
}
}
// 描述符发现完成
if (pMsg->hdr.status == bleProcedureComplete) {
PRINT("描述符发现完成!\r\n");
centralDiscState = BLE_DISC_STATE_COMPLETE;
// 启动下一步操作(例如启用通知)仅是演示,当服务中发现多个centralCCCDHdl时只会开启最后一个
if (centralCCCDHdl != 0) {
tmos_start_task(centralTaskId, START_WRITE_CCCD_EVT, 1600);
}
}
} else if (pMsg->method == ATT_ERROR_RSP) {
PRINT("错误: 描述符发现失败 (0x%02X)\r\n", pMsg->hdr.status);
centralDiscState = BLE_DISC_STATE_IDLE;
}
break;
default:
break;
}
}
五.完整的打印输出
GATT_DiscAllPrimaryServices = 0x00
服务 #1:
起始句柄: 0x0001
结束句柄: 0x0009
UUID长度: 2 字节
UUID: 00 18
服务 #2:
起始句柄: 0x000A
结束句柄: 0x000D
UUID长度: 2 字节
UUID: 01 18
服务 #1:
起始句柄: 0x000E
结束句柄: 0x0020
UUID长度: 2 字节
UUID: 0a 18
服务 #2:
起始句柄: 0x0021
结束句柄: 0x0031
UUID长度: 2 字节
UUID: e0 ff
找到SimpleProfile服务!
GATT_DiscAllChars = 0x00
PHY Update 0...
RSSI : -46 dB
特征 #1:
属性: 0x02
值句柄: 0x0003
UUID长度: 2 字节
UUID: 00 2a
特征 #2:
属性: 0x02
值句柄: 0x0005
UUID长度: 2 字节
UUID: 01 2a
特征 #3:
属性: 0x02
值句柄: 0x0007
UUID长度: 2 字节
UUID: 04 2a
特征 #1:
属性: 0x02
值句柄: 0x0009
UUID长度: 2 字节
UUID: a6 2a
特征 #2:
属性: 0x20
值句柄: 0x000C
UUID长度: 2 字节
UUID: 05 2a
特征 #3:
属性: 0x02
值句柄: 0x0010
UUID长度: 2 字节
UUID: 23 2a
特征 #1:
属性: 0x02
值句柄: 0x0012
UUID长度: 2 字节
UUID: 24 2a
特征 #2:
属性: 0x02
值句柄: 0x0014
UUID长度: 2 字节
UUID: 25 2a
特征 #3:
属性: 0x02
值句柄: 0x0016
UUID长度: 2 字节
UUID: 26 2a
PHY Update...
特征 #1:
属性: 0x02
值句柄: 0x0018
UUID长度: 2 字节
UUID: 27 2a
特征 #2:
属性: 0x02
值句柄: 0x001A
UUID长度: 2 字节
UUID: 28 2a
特征 #3:
属性: 0x02
值句柄: 0x001C
UUID长度: 2 字节
UUID: 29 2a
特征 #1:
属性: 0x02
值句柄: 0x001E
UUID长度: 2 字节
UUID: 2a 2a
特征 #2:
属性: 0x02
值句柄: 0x0020
UUID长度: 2 字节
UUID: 50 2a
特征 #3:
属性: 0x0A
值句柄: 0x0023
UUID长度: 2 字节
UUID: e1 ff
可写特征句柄: 0x0023
特征 #1:
属性: 0x02
值句柄: 0x0026
UUID长度: 2 字节
UUID: e2 ff
特征 #2:
属性: 0x08
值句柄: 0x0029
UUID长度: 2 字节
UUID: e3 ff
可写特征句柄: 0x0029
特征 #3:
属性: 0x10
值句柄: 0x002C
UUID长度: 2 字节
UUID: e4 ff
通知CCCD句柄: 0x002D
RSSI : -49 dB
Param Update...
特征 #1:
属性: 0x02
值句柄: 0x0030
UUID长度: 2 字节
UUID: e5 ff
GATT_DiscAllCharDescs = 0x00
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0001
UUID: 0x2800
描述符 #2:
句柄: 0x0002
UUID: 0x2803
描述符 #3:
句柄: 0x0003
UUID: 0x2A00
描述符 #4:
句柄: 0x0004
UUID: 0x2803
描述符 #5:
句柄: 0x0005
UUID: 0x2A01
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0006
UUID: 0x2803
描述符 #2:
句柄: 0x0007
UUID: 0x2A04
描述符 #3:
句柄: 0x0008
UUID: 0x2803
描述符 #4:
句柄: 0x0009
UUID: 0x2AA6
描述符 #5:
句柄: 0x000A
UUID: 0x2800
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x000B
UUID: 0x2803
描述符 #2:
句柄: 0x000C
UUID: 0x2A05
描述符 #3:
句柄: 0x000D
UUID: 0x2902
找到CCCD描述符!
描述符 #4:
句柄: 0x000E
UUID: 0x2800
描述符 #5:
句柄: 0x000F
UUID: 0x2803
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0010
UUID: 0x2A23
描述符 #2:
句柄: 0x0011
UUID: 0x2803
描述符 #3:
句柄: 0x0012
UUID: 0x2A24
描述符 #4:
句柄: 0x0013
UUID: 0x2803
描述符 #5:
句柄: 0x0014
UUID: 0x2A25
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0015
UUID: 0x2803
描述符 #2:
句柄: 0x0016
UUID: 0x2A26
描述符 #3:
句柄: 0x0017
UUID: 0x2803
描述符 #4:
句柄: 0x0018
UUID: 0x2A27
描述符 #5:
句柄: 0x0019
UUID: 0x2803
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x001A
UUID: 0x2A28
描述符 #2:
句柄: 0x001B
UUID: 0x2803
描述符 #3:
句柄: 0x001C
UUID: 0x2A29
描述符 #4:
句柄: 0x001D
UUID: 0x2803
描述符 #5:
句柄: 0x001E
UUID: 0x2A2A
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x001F
UUID: 0x2803
描述符 #2:
句柄: 0x0020
UUID: 0x2A50
描述符 #3:
句柄: 0x0021
UUID: 0x2800
描述符 #4:
句柄: 0x0022
UUID: 0x2803
描述符 #5:
句柄: 0x0023
UUID: 0xFFE1
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0024
UUID: 0x2901
描述符 #2:
句柄: 0x0025
UUID: 0x2803
描述符 #3:
句柄: 0x0026
UUID: 0xFFE2
描述符 #4:
句柄: 0x0027
UUID: 0x2901
描述符 #5:
句柄: 0x0028
UUID: 0x2803
RSSI : -46 dB
找到 5 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x0029
UUID: 0xFFE3
描述符 #2:
句柄: 0x002A
UUID: 0x2901
描述符 #3:
句柄: 0x002B
UUID: 0x2803
描述符 #4:
句柄: 0x002C
UUID: 0xFFE4
描述符 #5:
句柄: 0x002D
UUID: 0x2902
找到CCCD描述符!
找到 4 个描述符
找到 1 个描述符
描述符 #1:
句柄: 0x002E
UUID: 0x2901
描述符 #2:
句柄: 0x002F
UUID: 0x2803
描述符 #3:
句柄: 0x0030
UUID: 0xFFE5
描述符 #4:
句柄: 0x0031
UUID: 0x2901
描述符发现完成!
RSSI : -47 dB
Write success
Receive noti: 88
Receive noti: 88
RSSI : -47 dB