【WCH蓝牙系列芯片】-基于CH585开发板—蓝牙主机直接获取蓝牙从机的handle,建立通信
------------------------------------------------------------------------------------------------------------------------------------

在默认的例程中,centralStartDiscovery函数中,将主机的“发现状态机”切换到 BLE_DISC_STATE_SVC(正在发现主服务)状态,然后直接利用GATT_DiscAllPrimaryServices函数对蓝牙从机的所有服务进行读取。并且将函数返回值打印出来,这个可以通过返回值判断,是否枚举成功,如果枚举不成功,就重新再开启TMOS任务事件,再从头开启枚举。
在centralGATTDiscoveryEvent函数中,替换成下面新的函数
static void centralGATTDiscoveryEvent(gattMsgEvent_t *pMsg) { attReadByTypeReq_t req; uint8_t result; if(centralDiscState == BLE_DISC_STATE_SVC) //判断当前的中央设备的状态是否为服务发现状态 { // Service found, store handles PRINT("method1=%x numGrps1=%04x \n", pMsg->method, pMsg->msg.readByGrpTypeRsp.numGrps); //判断接收到的消息是否是按组类型读取响应(ATT_READ_BY_GRP_TYPE_RSP),并且返回的组数量大于0 if(pMsg->method == ATT_READ_BY_GRP_TYPE_RSP &&pMsg->msg.readByGrpTypeRsp.numGrps > 0) { for(unsigned char i = 0 ; i < pMsg->msg.readByGrpTypeRsp.numGrps;i++) { // Attribute LEN 当前属性的长度 PRINT("current att len:%04d\r\n",pMsg->msg.readByGrpTypeRsp.len); // Attribute start Handle 当前属性的起始句柄 PRINT("current att start handle:%04x\r\n", BUILD_UINT16( pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i], \ pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i + 1])); // Attribute End Group Handle 当前属性的结束句柄 PRINT("current att end handle:%04x\r\n", BUILD_UINT16( pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i+2], \ pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i + 3])); //Primary Service UUID Length 当前服务UUID的长度 PRINT("current service uuid len:%04d\r\n",pMsg->msg.readByGrpTypeRsp.len - 4); // uuid 打印UUID PRINT("uuid:"); //指向当前UUID的指针位置 uint8_t *p_uuid = &(pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i + 4]); //计算UUID的长度 uint8_t uuid_length = pMsg->msg.readByGrpTypeRsp.len - 4; //打印UUID的内容 hex_dump(p_uuid,uuid_length); printf("\r\n"); } } // If procedure complete PRINT("method=%x status=%x centralSvcStartHdl=%x\r\n",pMsg->method,pMsg->hdr.status,centralSvcStartHdl); //收到的消息是否是按组类型读取响应(ATT_READ_BY_GRP_TYPE_RSP) //过程状态为完成状态(bleProcedureComplete) //消息的方法为错误响应(ATT_ERROR_RSP) if((pMsg->method == ATT_READ_BY_GRP_TYPE_RSP && pMsg->hdr.status == bleProcedureComplete) || (pMsg->method == ATT_ERROR_RSP)) { // Discover characteristic 即将开始发现特征 centralDiscState = BLE_DISC_STATE_CHAR; //发现所有特征 result = GATT_DiscAllChars(centralConnHandle,0x01,0xFFFF,centralTaskId); PRINT("GATT_DiscAllChars:%02x\r\n",result); } } else if(centralDiscState == BLE_DISC_STATE_CHAR) //是否为特征发现状态 { // Characteristic found, store handle //检查收到的消息是否是按类型读取响应(ATT_READ_BY_TYPE_RSP)并且消息中包含的特征数量大于0 if(pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0) { for(unsigned char i = 0; i < pMsg->msg.readByTypeRsp.numPairs ; i++) { //characteristic properties //提取特征的属性,例如读、写、通知 uint8_t char_properties = pMsg->msg.readByTypeRsp.pDataList[pMsg->msg.readByTypeRsp.len * i + 2]; //提取特征的值句柄 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 特征UUID的长度 uint8_t char_uuid_length = pMsg->msg.readByGrpTypeRsp.len - 5; //uuid 提取特征UUID的值 uint8_t *char_uuid = &(pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i + 5]); //如果具有写属性,则打印"write handle" PRINT("char_properties :%02x,%s\r\n",char_properties,(char_properties&(GATT_PROP_WRITE|GATT_PROP_WRITE_NO_RSP))?"wite handle":""); PRINT("char_value_handle:%04x\r\n",char_value_handle); //特征的值句柄 PRINT("char_uuid_length :%02d\r\n",char_uuid_length); //特征UUID的长度 PRINT("char_uuid :"); //打印特征UUID的值 hex_dump(char_uuid,char_uuid_length); //对写和读属性 if (char_value_handle == 0x26) { centralCharHdl = 0x26; centralProcedureInProgress = FALSE; tmos_start_task(centralTaskId, START_READ_OR_WRITE_EVT, 1600); } //具有通知属性 if (char_value_handle == 0x23) { centralCCCDHdl = char_value_handle+1; centralProcedureInProgress = FALSE; PRINT("notify handle:%04x\r\n",char_value_handle); tmos_start_task(centralTaskId, START_WRITE_CCCD_EVT, 1600); } printf("\r\n"); } } } }
在前面调用了 GATT_DiscAllPrimaryServices (寻找所有服务)后,这段函数将服务中的么据特征值全部打印出来,底层协议栈拿到从机发来的数据,就会不断地触发这个回调函数。
这两个部分修改完之后,可以利用BLE_UART的程序进行配合使用,通过打印可以看到,



通过打印可以看到可以看到枚举BLE_UART中的读写数据的服务对应的服务和对应的hanlde值,这样可以直接对handle值来开启任务。


浙公网安备 33010602011771号