蓝牙连上后,一般来说 要先进行服务和特征发现,
拿到对应uuid 对应的handle,
然后根据handle去操作,诸如使能cccd,和读写数据
如下面是一个发现服务,发现char 和获取cccd 对应的handle的api:
void central_db_dis_process(void){
uint8_t result = 0;
attReadByTypeReq_t req;
switch(ble_db_dis_state){
case BLE_DISC_STATE_IDLE:
break;
case BLE_DISC_STATE_SVC:
result = GATT_DiscPrimaryServiceByUUID( centralConnHandle,
service_uuid,
16,
centralTaskId );
PRINT("GATT_DiscPrimaryServiceByUUID:%xrn",result);
break;
case BLE_DISC_STATE_CHAR:
result = GATT_DiscAllChars(centralConnHandle,centralSvcStartHdl,centralSvcEndHdl,centralTaskId);
break;
case BLE_DISC_STATE_CCCD:
req.startHandle = centralSvcStartHdl;
req.endHandle = centralSvcEndHdl;
req.type.len = ATT_BT_UUID_SIZE;
req.type.uuid[0] = LO_UINT16(GATT_CLIENT_CHAR_CFG_UUID);
req.type.uuid[1] = HI_UINT16(GATT_CLIENT_CHAR_CFG_UUID);
result = GATT_ReadUsingCharUUID( centralConnHandle, &req, centralTaskId );
break;
default:
break;
}
if(result != SUCCESS){
if(centralConnHandle != BLE_STATE_IDLE){
tmos_start_task(centralTaskId,START_SVC_DISCOVERY_EVT,1600);
}else{
PRINT("conntection has been disconnectedrn");
}
}
}
其中处理函数为:
/*********************************************************************
* @fn centralGATTDiscoveryEvent
*
* @brief Process GATT discovery event
*
* @return none
*/
static void centralGATTDiscoveryEvent( gattMsgEvent_t *pMsg ){
PRINT("centralGATTDiscoveryEventrn");
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);
}
}
}
break;
case BLE_DISC_STATE_CHAR:
// Characteristic found, store handle
if ( pMsg->method == ATT_READ_BY_TYPE_RSP ){
if(pMsg->msg.readByTypeRsp.numPairs > 0 ){
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:%02xrn",char_value_handle);
}else if(tmos_memcmp(notify_uuid,chat_uuid,char_uuid_length)){
PRINT("notify uuid found,handle:%02xrn",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 donern");
}
}
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);
}
ble_db_dis_state = BLE_DISC_STATE_IDLE;
}
break;
default:
break;
}
}
然后enable notify 可以是:
uint8_t central_gatt_write_char_value(uint16_t connection_handle,uint16_t char_handle,uint8_t *data,uint16_t length){
uint8_t result;
attWriteReq_t req;
req.cmd = FALSE;
req.sig = FALSE;
req.handle = char_handle;
req.len = length;
req.pValue = GATT_bm_alloc(connection_handle,ATT_WRITE_REQ,req.len,NULL,0);
if ( req.pValue != NULL ){
tmos_memcpy(req.pValue,data,length);
result = GATT_WriteCharValue(centralConnHandle,&req,centralTaskId);
if(SUCCESS == result){
return SUCCESS;
}else{
GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
write_data_when_failed.connection_handle = connection_handle;
write_data_when_failed.char_handle = char_handle;
write_data_when_failed.data_length = length;
tmos_memcpy(write_data_when_failed.data,data,write_data_when_failed.data_length);
PRINT("data0 data1=%02x %02x rn",write_data_when_failed.data[0],write_data_when_failed.data[1]);
tmos_start_task(centralTaskId,START_WRITE_EVT,80);
return result;
}
}
return 0xff;
}
uint8_t central_enbale_notify(uint16_t connection_handle,uint16_t notify_handle){
uint8_t data[2] = {0x01,0x00};
return central_gatt_write_char_value(connection_handle,notify_handle,data,2);
}
uint8_t central_disable_notify(uint16_t connection_handle,uint16_t notify_handle){
uint8_t data[2] = {0x00,0x00};
return central_gatt_write_char_value(connection_handle,notify_handle,data,2);
}
蓝牙连上后,一般来说 要先进行服务和特征发现,
拿到对应uuid 对应的handle,
然后根据handle去操作,诸如使能cccd,和读写数据
如下面是一个发现服务,发现char 和获取cccd 对应的handle的api:
void central_db_dis_process(void){
uint8_t result = 0;
attReadByTypeReq_t req;
switch(ble_db_dis_state){
case BLE_DISC_STATE_IDLE:
break;
case BLE_DISC_STATE_SVC:
result = GATT_DiscPrimaryServiceByUUID( centralConnHandle,
service_uuid,
16,
centralTaskId );
PRINT("GATT_DiscPrimaryServiceByUUID:%xrn",result);
break;
case BLE_DISC_STATE_CHAR:
result = GATT_DiscAllChars(centralConnHandle,centralSvcStartHdl,centralSvcEndHdl,centralTaskId);
break;
case BLE_DISC_STATE_CCCD:
req.startHandle = centralSvcStartHdl;
req.endHandle = centralSvcEndHdl;
req.type.len = ATT_BT_UUID_SIZE;
req.type.uuid[0] = LO_UINT16(GATT_CLIENT_CHAR_CFG_UUID);
req.type.uuid[1] = HI_UINT16(GATT_CLIENT_CHAR_CFG_UUID);
result = GATT_ReadUsingCharUUID( centralConnHandle, &req, centralTaskId );
break;
default:
break;
}
if(result != SUCCESS){
if(centralConnHandle != BLE_STATE_IDLE){
tmos_start_task(centralTaskId,START_SVC_DISCOVERY_EVT,1600);
}else{
PRINT("conntection has been disconnectedrn");
}
}
}
其中处理函数为:
/*********************************************************************
* @fn centralGATTDiscoveryEvent
*
* @brief Process GATT discovery event
*
* @return none
*/
static void centralGATTDiscoveryEvent( gattMsgEvent_t *pMsg ){
PRINT("centralGATTDiscoveryEventrn");
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);
}
}
}
break;
case BLE_DISC_STATE_CHAR:
// Characteristic found, store handle
if ( pMsg->method == ATT_READ_BY_TYPE_RSP ){
if(pMsg->msg.readByTypeRsp.numPairs > 0 ){
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:%02xrn",char_value_handle);
}else if(tmos_memcmp(notify_uuid,chat_uuid,char_uuid_length)){
PRINT("notify uuid found,handle:%02xrn",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 donern");
}
}
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);
}
ble_db_dis_state = BLE_DISC_STATE_IDLE;
}
break;
default:
break;
}
}
然后enable notify 可以是:
uint8_t central_gatt_write_char_value(uint16_t connection_handle,uint16_t char_handle,uint8_t *data,uint16_t length){
uint8_t result;
attWriteReq_t req;
req.cmd = FALSE;
req.sig = FALSE;
req.handle = char_handle;
req.len = length;
req.pValue = GATT_bm_alloc(connection_handle,ATT_WRITE_REQ,req.len,NULL,0);
if ( req.pValue != NULL ){
tmos_memcpy(req.pValue,data,length);
result = GATT_WriteCharValue(centralConnHandle,&req,centralTaskId);
if(SUCCESS == result){
return SUCCESS;
}else{
GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
write_data_when_failed.connection_handle = connection_handle;
write_data_when_failed.char_handle = char_handle;
write_data_when_failed.data_length = length;
tmos_memcpy(write_data_when_failed.data,data,write_data_when_failed.data_length);
PRINT("data0 data1=%02x %02x rn",write_data_when_failed.data[0],write_data_when_failed.data[1]);
tmos_start_task(centralTaskId,START_WRITE_EVT,80);
return result;
}
}
return 0xff;
}
uint8_t central_enbale_notify(uint16_t connection_handle,uint16_t notify_handle){
uint8_t data[2] = {0x01,0x00};
return central_gatt_write_char_value(connection_handle,notify_handle,data,2);
}
uint8_t central_disable_notify(uint16_t connection_handle,uint16_t notify_handle){
uint8_t data[2] = {0x00,0x00};
return central_gatt_write_char_value(connection_handle,notify_handle,data,2);
}
举报