使用GATT_ReadUsingCharUUID()查找句柄,无法获取write属性的UUID句柄(返回0x01),获取read属性正常
可以通过下面方式 在service 发现后的,通过传入service 的起始结束handle调用下面代码去查询:
result = GATT_DiscAllChars(centralConnHandle,centralSvcStartHdl,centralSvcEndHdl,centralTaskId);
static void centralGATTDiscoveryEvent( gattMsgEvent_t *pMsg ){ uint8_t result ; PRINT("centralGATTDiscoveryEvent\r\n"); switch(ble_db_dis_state){ case BLE_DISC_STATE_SVC: // Service found, store handles if ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP ){ if( pMsg->msg.findByTypeValueRsp.numInfo > 0 ){ centralSvcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo,0); centralSvcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo,0); // Display Profile Service handle range PRINT("Found Profile Service handle : %x ~ %x \n",centralSvcStartHdl,centralSvcEndHdl); } if( ( pMsg->hdr.status == bleProcedureComplete )||( pMsg->method == ATT_ERROR_RSP ) ){ if ( centralSvcStartHdl != 0 ){ //central_db_dis_change_state(BLE_DISC_STATE_CHAR); result = GATT_DiscAllChars(centralConnHandle,centralSvcStartHdl,centralSvcEndHdl,centralTaskId); PRINT("GATT_DiscAllChars:%02x\r\n",result); } } } break; case BLE_DISC_STATE_CHAR: // Characteristic found, store handle if ( pMsg->method == ATT_READ_BY_TYPE_RSP ){ if(pMsg->msg.readByTypeRsp.numPairs > 0 ){ //centralCharHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.pDataList[0], // pMsg->msg.readByTypeRsp.pDataList[1] ); //PRINT("Found Characteristic 1 handle : %x \n",centralCharHdl); // Iterate through all three pairs found. for(unsigned char i = 0; i < pMsg->msg.readByTypeRsp.numPairs ; i++){ #if 0 //characteristic properties uint8_t char_properties = pMsg->msg.readByTypeRsp.pDataList[pMsg->msg.readByTypeRsp.len * i + 2]; #endif uint16_t char_value_handle = BUILD_UINT16(pMsg->msg.readByTypeRsp.pDataList[pMsg->msg.readByTypeRsp.len * i+3], \ pMsg->msg.readByTypeRsp.pDataList[pMsg->msg.readByTypeRsp.len * i + 4]); //characteristic uuid length uint8_t char_uuid_length = pMsg->msg.readByGrpTypeRsp.len - 5; //uuid uint8_t *chat_uuid = &(pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i + 5]); if(sizeof(write_uuid) == char_uuid_length){ if(tmos_memcmp(write_uuid,chat_uuid,char_uuid_length)){ PRINT("write_uuid found,handle:%02x\r\n",char_value_handle); }else if(tmos_memcmp(notify_uuid,chat_uuid,char_uuid_length)){ PRINT("notify uuid found,handle:%02x\r\n",char_value_handle); } } } } if((pMsg->hdr.status == bleProcedureComplete ) || ( pMsg->method == ATT_ERROR_RSP ) ){ central_db_dis_change_state(BLE_DISC_STATE_CCCD); PRINT("BLE_DISC_STATE_CHAR done\r\n"); } } break; case BLE_DISC_STATE_CCCD: if ( pMsg->method == ATT_READ_BY_TYPE_RSP){ if(pMsg->msg.readByTypeRsp.numPairs > 0 ){ centralCCCDHdl = BUILD_UINT16( pMsg->msg.readByTypeRsp.pDataList[0], pMsg->msg.readByTypeRsp.pDataList[1] ); PRINT("Found client characteristic configuration handle : %x \n",centralCCCDHdl); central_enbale_notify(centralConnHandle,centralCCCDHdl); } //centralDiscState = BLE_DISC_STATE_IDLE; ble_db_dis_state = BLE_DISC_STATE_IDLE; } break; default: break; } }
void pv_drv_ble_center_gatt_discovery_event( gattMsgEvent_t *pMsg )
{
attReadByTypeReq_t req;
struct pv_ble_center_uuid_st uuid;
// pv_printf("-> %d, %02X, %04X/%04X\r\n", centralDiscState, pMsg->method, pMsg->msg.handleValueNoti.handle, pMsg->msg.handleValueInd.handle);
pv_ble_center_control(PV_BLE_CENTER_PORT(1), PV_BLE_CENTER_CTRL_GET_UUID, &uuid);
if ( pv_drv_ble_center.discovery_state == BLE_DISC_STATE_SVC )
{
// Service found, store handles
if ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP &&
pMsg->msg.findByTypeValueRsp.numInfo > 0 )
{
pv_drv_ble_center.svc_start_handle = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo,0);
pv_drv_ble_center.svc_end_handle = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo,0);
// Display Profile Service handle range
PV_LOG_D("Found Profile Service, UUID handle range: %x ~ %x\r\n",pv_drv_ble_center.svc_start_handle, pv_drv_ble_center.svc_end_handle);
pv_drv_ble_center.discovery_state = BLE_DISC_STATE_UUID;
}
else
{
PV_LOG_W("Not Found Profile Service handle: %04X\r\n", uuid.server_uuid);
}
}
else if (pv_drv_ble_center.discovery_state == BLE_DISC_STATE_UUID)
{
// If procedure complete
if (pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->hdr.status == bleProcedureComplete)
{
if (pv_drv_ble_center.svc_start_handle != 0)
{
PV_ASSERT(uuid.uuid_cnt);
// Discover characteristic
pv_drv_ble_center.discovery_state = 0;
req.startHandle = pv_drv_ble_center.svc_start_handle;
req.endHandle = pv_drv_ble_center.svc_end_handle;
req.type.len = ATT_BT_UUID_SIZE;
req.type.uuid[0] = LO_UINT16(uuid.uuid[pv_drv_ble_center.discovery_state].uuid);
req.type.uuid[1] = HI_UINT16(uuid.uuid[pv_drv_ble_center.discovery_state].uuid);
GATT_DiscCharsByUUID( pv_drv_ble_center.connect_handle, &req, centralTaskId );
PV_LOG_D("Set Fonud UUID (%02X%02X)\r\n", req.type.uuid[1], req.type.uuid[0]);
}
}
}
else if (pv_drv_ble_center.discovery_state < uuid.uuid_cnt)
{
// Characteristic found, store handle
if ( pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0 )
{
pv_drv_ble_center_uuid[pv_drv_ble_center.discovery_state].uuid = uuid.uuid[pv_drv_ble_center.discovery_state].uuid;
pv_drv_ble_center_uuid[pv_drv_ble_center.discovery_state].event = PV_BIT(pv_drv_ble_center.discovery_state);
pv_drv_ble_center_uuid[pv_drv_ble_center.discovery_state].cb = uuid.uuid[pv_drv_ble_center.discovery_state].cb;
pv_drv_ble_center_uuid[pv_drv_ble_center.discovery_state].permission = uuid.uuid[pv_drv_ble_center.discovery_state].permission;
pv_drv_ble_center_uuid[pv_drv_ble_center.discovery_state].handle = BUILD_UINT16( pMsg->msg.readByTypeRsp.pDataList[0], pMsg->msg.readByTypeRsp.pDataList[1] );
// Start do read or write
tmos_start_task( centralTaskId, pv_drv_ble_center_uuid[pv_drv_ble_center.discovery_state].event, DEFAULT_READ_OR_WRITE_DELAY);
// Display uuid handle
PV_LOG_D("Found uuid (%04X) handle : %04x\r\n", uuid.uuid[pv_drv_ble_center.discovery_state].uuid, pv_drv_ble_center_uuid[pv_drv_ble_center.discovery_state].handle);
// PV_LOG_D("permission: %d, %d/%d\r\n", uuid.uuid[centralDiscState].permission, centralDiscState, uuid.uuid_cnt);
if (++pv_drv_ble_center.discovery_state >= uuid.uuid_cnt)
{
pv_drv_ble_center.lock = FALSE;
}
}
// Found next uuid handle
else if ((pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->hdr.status == bleProcedureComplete) ||
pMsg->method == ATT_ERROR_RSP)
{
// Discover characteristic
req.startHandle = pv_drv_ble_center.svc_start_handle;
req.endHandle = pv_drv_ble_center.svc_end_handle;
req.type.len = ATT_BT_UUID_SIZE;
req.type.uuid[0] = LO_UINT16(uuid.uuid[pv_drv_ble_center.discovery_state].uuid);
req.type.uuid[1] = HI_UINT16(uuid.uuid[pv_drv_ble_center.discovery_state].uuid);
GATT_DiscCharsByUUID( pv_drv_ble_center.connect_handle, &req, centralTaskId );
PV_LOG_D("Set Fonud UUID (%02X%02X)\r\n", req.type.uuid[1], req.type.uuid[0]);
}
}
}
结论:
GATT_DiscCharsByUUID(), 可以拿到UUID句柄,可参考开源项目:https://gitee.com/zhsing/pvt/tree/wch/