CH58X/CH59X/CH32V20X主机枚举所有服务,MTU交互(多连接版)

前言:

  现在提供的主机代码是直接通过从机的UUID去和指定的从机进行连接,获取对应特征值的handle值。只要能获取对应特征值的handle即可通信。

现在提供一种方式去获取对应的handle值进行通信。有时候在多连接的场景下需要对handle进行管理。

代码如下:

  

static void centralConnIistStartDiscovery_0(void)

{centralConnList[CONNECT0_ITEM].svcStartHdl = centralConnList[CONNECT0_ITEM].svcEndHdl = centralConnList[CONNECT0_ITEM].charHdl =0;
//    centralSvcStartHdl = centralSvcEndHdl = centralCharHdl = 0;
//    centralDiscState = BLE_DISC_STATE_SVC;
    centralConnList[CONNECT0_ITEM].discState = BLE_DISC_STATE_SVC;
    uint8_t ret = 0;
    ret = GATT_DiscAllPrimaryServices(centralConnList[CONNECT0_ITEM].connHandle, centralTaskId);
    printf("GATT_DiscAllPrimaryServices ret = %x\n", ret);
    if(ret ==0)
    {
        tmos_stop_task(centralConnList[CONNECT0_ITEM].taskID, START_SVC_DISCOVERY_EVT);
   }
}

static void centralGATTDiscoveryEvent(uint8_t connItem, gattMsgEvent_t *pMsg)
{
    attReadByTypeReq_t req;
    if(centralConnList[connItem].discState == 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
            centralConnList[connItem].discState = BLE_DISC_STATE_CHAR;
            uint8_t ret = GATT_DiscAllChars(centralConnList[connItem].connHandle,0x01,0xFFFF,centralTaskId);
            PRINT("GATT_DiscAllChars:%02x\r\n",ret);
        }
    }
    else if(centralConnList[connItem].discState == 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)) {
                    centralConnList[connItem].charHdl = char_value_handle;
                    PRINT("Write handle:%04x\r\n",char_value_handle);
                    tmos_start_task(centralConnList[connItem].taskID, START_READ_OR_WRITE_EVT, 1600);
                }
                if(char_properties&GATT_PROP_NOTIFY) {
                    centralConnList[connItem].cccHdl = char_value_handle+1;                //通过GATT_DiscAllChars或者handle,noti/indi的handle值需要+1
                    PRINT("Notify handle:%04x\r\n",char_value_handle);
                    tmos_start_task(centralConnList[connItem].taskID, START_WRITE_CCCD_EVT, 1600);
               }
                if(char_properties&GATT_PROP_INDICATE) {
                    centralConnList[connItem].cccHdl = char_value_handle+1;                //通过GATT_DiscAllChars或者handle,noti/indi的handle值需要+1
                    PRINT("Indicate handle:%04x\r\n",char_value_handle);
                    tmos_start_task(centralConnList[connItem].taskID, START_WRITE_CCCD_EVT, 800);
               }
            }
        }
    }
}

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

使用GATT_ReadUsingCharUUID获取到的handle值直接使能填写使能就可以。

这里更新MTU耗时较长可能会导致发现服务失败,程序中需要做些处理对GATT_DiscAllPrimaryServices的返回值进行判断如果返回值为0再停止这个任务。

当遇到write和write with no rsp的时候需要进行区分。相关实现代码如下:

    if(events & START_READ_OR_WRITE_EVT)
    {
        if(centralProcedureInProgress == FALSE)
        {
            if(centralDoWrite)
            {
                // Do a write
                attWriteReq_t req;

                req.cmd = FALSE;
                req.sig = FALSE;
                req.handle = centralCharHdl;
                req.len = 1;
               // req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_REQ, req.len, NULL, 0);
                //req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_CMD, req.len, NULL, 0);
                if(write_choose &0x08)
                {


                  PRINT("write_choose %02x\r\n",write_choose);
                  req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_REQ, req.len, NULL, 0);
                if(req.pValue != NULL)
                {

                    *req.pValue = centralCharVal;

                    if(GATT_WriteCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS)
                      //if(GATT_WriteNoRsp(centralConnHandle, &req) == SUCCESS)

                    {
                        //centralProcedureInProgress = TRUE;
                       // centralDoWrite = !centralDoWrite;
                        tmos_start_task(centralTaskId, START_READ_OR_WRITE_EVT, DEFAULT_READ_OR_WRITE_DELAY);
                    }
                    else
                    {
                        GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_REQ);
                    }
                }
                }
                if(write_choose &0x04)
                               {
                  PRINT("write_choose %02x\r\n",write_choose);

                  req.pValue = GATT_bm_alloc(centralConnHandle, ATT_WRITE_CMD, req.len, NULL, 0);
                               if(req.pValue != NULL)
                               {


                                   *req.pValue = centralCharVal;

                                   //if(GATT_WriteCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS)
                                     if(GATT_WriteNoRsp(centralConnHandle, &req) == SUCCESS)

                                   {
                                       //centralProcedureInProgress = TRUE;
                                      // centralDoWrite = !centralDoWrite;
                                       tmos_start_task(centralTaskId, START_READ_OR_WRITE_EVT, DEFAULT_READ_OR_WRITE_DELAY);
                                   }
                                   else
                                   {
                                       GATT_bm_free((gattMsg_t *)&req, ATT_WRITE_CMD);
                                   }
                               }
                               }
            }
//            else
//            {
//                // Do a read
//                attReadReq_t req;
//
//                req.handle = centralCharHdl;
//                if(GATT_ReadCharValue(centralConnHandle, &req, centralTaskId) == SUCCESS)
//                {
//                    centralProcedureInProgress = TRUE;
//                    centralDoWrite = !centralDoWrite;
//                }
//            }
        }
     //   tmos_start_task(centralTaskId, START_READ_OR_WRITE_EVT, DEFAULT_READ_OR_WRITE_DELAY);
        return (events ^ START_READ_OR_WRITE_EVT);
    }

 

仅是个人学习分享如有错漏请指正。

posted @ 2025-03-01 13:36  小舟从此逝_1  阅读(154)  评论(0)    收藏  举报