蓝牙BLE主机Central讲解三(服务枚举)

前言:

CH582EVT中Central例程修改待连接MAC地址即可与对应的从机建立连接。实现数据传输则是通过枚举特定UUID进而获取透传的handle值。UUID是获取handle值的一种方式,只要能够获取到handle值即可。以下提供两种方式获取handle并进行数据传输。

  1. 直接抓包已有主机或手机与从机的连接,并进行数据收发,可以获取到收发的handle值;
  2. 主机枚举从机所有服务并列表对应handle值;

一、抓包获取handle值

 

二、枚举UUID或者handle值

以下两个函数替换central.c的原有函数

static void centralStartDiscovery(void)
{
    centralSvcStartHdl = centralSvcEndHdl = centralCharHdl = 0;
    centralDiscState = BLE_DISC_STATE_SVC;

    uint8_t ret = 0;
    ret = GATT_DiscAllPrimaryServices(centralConnHandle, centralTaskId);
    printf("GATT_DiscAllPrimaryServices ret = %x\n", ret);
}

static void centralGATTDiscoveryEvent(gattMsgEvent_t *pMsg)
{
    attReadByTypeReq_t req;
    if(centralDiscState == BLE_DISC_STATE_SVC)
    {
        // Service found, store handles
        if(pMsg->method == ATT_READ_BY_GRP_TYPE_RSP &&//ATT_FIND_BY_TYPE_VALUE_RSP &&
           pMsg->msg.findByTypeValueRsp.numInfo > 0)
        {
#if 0
            for(uint16_t i = 0; i < pMsg->msg.readByGrpTypeRsp.numGrps; i++)
            {
              // uuid
              printf("uuid = %x", BUILD_UINT16(
                  pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i +4], \
                  pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i +5]));

              //Primary Service UUID Length
              printf("%02d bit x",pMsg->msg.readByGrpTypeRsp.len - 4);

              // printf("att len = %d\n", pMsg->msg.readByGrpTypeRsp.len);
              printf("start handle:%04x",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
              printf("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]));
            }
#endif
        }

        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;
            uint8_t ret = GATT_DiscAllChars(centralConnHandle,0x01,0xFFFF,centralTaskId);
            PRINT("GATT_DiscAllChars:%02x\r\n",ret);
        }
    }
    else if(centralDiscState == BLE_DISC_STATE_CHAR)
    {
        // Characteristic found, store handle
        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
                uint8_t char_uuid_length = pMsg->msg.readByGrpTypeRsp.len - 5;
                //uuid
                uint8_t *char_uuid = &(pMsg->msg.readByGrpTypeRsp.pDataList[pMsg->msg.readByGrpTypeRsp.len * i + 5]);
                PRINT("______________________________\n");
                PRINT("char_uuid        :");
                for(uint8_t i = 0; i < char_uuid_length; i++ ){
                  printf("%02x ", char_uuid[i]);
                }printf("\n");
//                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        :%02d bit\r\n",char_uuid_length);

                if(char_properties&(GATT_PROP_WRITE|GATT_PROP_WRITE_NO_RSP)) {
                    centralCharHdl = char_value_handle;
                    PRINT("Write handle:%04x\r\n",char_value_handle);
                    tmos_start_task(centralTaskId, START_READ_OR_WRITE_EVT, 1600);
                }
                if(char_properties&GATT_PROP_NOTIFY) {
                    centralCCCDHdl = char_value_handle+1;                //通过GATT_DiscAllChars或者handle,noti/indi的handle值需要+1
                    PRINT("Notify handle:%04x\r\n",char_value_handle);
                    tmos_start_task(centralTaskId, START_WRITE_CCCD_EVT, 1600);
               }
                if(char_properties&GATT_PROP_INDICATE) {
                    centralCCCDHdl = char_value_handle+1;                //通过GATT_DiscAllChars或者handle,noti/indi的handle值需要+1
                    PRINT("Indicate handle:%04x\r\n",char_value_handle);
                    tmos_start_task(centralTaskId, START_WRITE_CCCD_EVT, 800);
               }
            }
        }
    }
}

注意:

使用GATT_DiscAllChars函数或者蓝牙分析仪抓包获取到的noti/indi的handle值需要+1才可以使能成功,write/read没有这方面的限制。使用GATT_ReadUsingCharUUID获取到的handle值直接使能填写使能就可以。

因此在使用枚举的时候,建议失败的时候可以手动+1尝试使能测试。

 

posted @ 2023-11-21 11:22  SweetTea_lllpc  阅读(699)  评论(0编辑  收藏  举报