This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC2340R5:获取特性值 0x00

Guru**** 2419530 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1544714/cc2340r5-getting-char-value-0x00

器件型号:CC2340R5


工具/软件:

您好论坛、

我实现了 GAP 客户端角色、其中尝试使用 API “GATT_DiscCharsByUUUUID"和“和查找句柄来发现字符句柄。 使用这些句柄、我尝试使用 API“ GATT_ReadCharValue ()“读取 char 值。 响应中得到 0x00、但实际字符值为 0x02。

我尝试使用其他客户端 (NRF Connect)、尝试连接到外设器件并读取相同的字符值、得到了正确的响应、即 0x02。  

我确定了“char handle“值、因为我已经使用监听器进行了验证。

uint8_t UUID[2] = {0xF0,0xFF};
void disc_services()
{
    switch(Disc_state)
    {
        case MTU_EXCHANGE:
        {
            sprint("\nMTU Exchange");
            uint8_t status;
            attExchangeMTUReq_t req;
            req.clientRxMTU = MAX_PDU_SIZE- L2CAP_HDR_SIZE;
            status = GATT_ExchangeMTU(App_connHndl, &req, BLEAppUtil_getSelfEntity());
            if(status == SUCCESS)
                {
                    Disc_state = DISCOVER_PRIMARY_SERVICE;
                }
            else{
                    Disc_state = DISC_FAIL;
                }
    
            break;
        }
        case DISCOVER_PRIMARY_SERVICE:
         {
                sprint("\nDiscovery Primary Service");
                uint8_t status;
                status = GATT_DiscPrimaryServiceByUUID(App_connHndl,UUID, ATT_BT_UUID_SIZE, BLEAppUtil_getSelfEntity());
                if( status == SUCCESS)
                    {
                        sprint("\nStatus:");print(&status,1);
                        Disc_state = STORE_PRIM_SERVICE_HNDLS;
                    }
                else
                    {
                        Disc_state = DISC_FAIL;
                    }
                           
            break;
         }

        case STORE_PRIM_SERVICE_HNDLS:
                {
                sprint("\nStore Prim Service Hndls");
                if(gattMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP)
                    {
                        startHndl = ATT_ATTR_HANDLE(gattMsg->msg.findByTypeValueRsp.pHandlesInfo,0);
                        endHndl   = ATT_GRP_END_HANDLE(gattMsg->msg.findByTypeValueRsp.pHandlesInfo,0);
                        sprint("\nstart:");print(&startHndl,2);sprint(" | end:");print(&endHndl,2);
                        Disc_state = DISCOVER_SERVICE_CHAR;
                        BLEAppUtil_invokeFunctionNoData(disc_services);
                    }
                    break;
                }

        case DISCOVER_SERVICE_CHAR:
            {
            sprint("\nDiscover_Service_Char");
            uint8_t status;
            uint8_t serUUID[2] = {0xF2,0xFF};
            attReadByTypeReq_t pReq;
            pReq.startHandle   = startHndl;
            pReq.endHandle     = endHndl;
            pReq.type.len          = ATT_BT_UUID_SIZE;
            memcpy(pReq.type.uuid,serUUID,ATT_BT_UUID_SIZE);
    
            status = GATT_DiscCharsByUUID(App_connHndl,&pReq,BLEAppUtil_getSelfEntity());
            sprint("\nStatus:");print(&status,1);
            if(status == SUCCESS)
                {
                    Disc_state =  STORE_SERVICE_HNDL;
                }
            break;
            }

        case STORE_SERVICE_HNDL:
             {
                sprint("\nSTORE_SERVICE_HNDL");
                if(gattMsg->method == ATT_READ_BY_TYPE_RSP )
                    {
                        sprint("\nDataLen:");print(&gattMsg->msg.readByTypeRsp.dataLen,2);
                        sprint("\nnumPair:");print(&gattMsg->msg.readByTypeRsp.numPairs,1);
                        if( gattMsg->msg.readByTypeRsp.numPairs > 0)
                            {
                                uint16_t rspUUID;
                                for(uint8_t i=0; i < gattMsg->msg.readByTypeRsp.numPairs; i++)
                                    {
                                        uint8_t* p = gattMsg->msg.readByTypeRsp.pDataList + i*gattMsg->msg.readByTypeRsp.len;                                        
                                        rspUUID = BUILD_UINT16(p[5], p[6]);
                                        if(rspUUID == 0xFFF2)
                                            {
                                                char_startHndl  = BUILD_UINT16(p[3],p[4]);
                                                char_endHndl    = BUILD_UINT16(p[7],p[8]);
                                                Disc_state = READ_CHAR_VAL;
                                                sprint("\nDone...");sprint("start: ");print(&char_startHndl,2);sprint("EndHndl:");print(&char_endHndl,2);
                                                BLEAppUtil_invokeFunctionNoData(disc_services);
                                            }
                                    }
                            }
                            else
                                sprint("\nNum Pairs are less");
                    }
        break;
        }

        case READ_CHAR_VAL:
        {
            sprint("\nREAD_CHAR_VAL");
            uint8_t status;
            attReadReq_t pReq;
            pReq.handle = char_startHndl;
            sprint(" | Hndl:");print(&pReq.handle,2);
            status =  GATT_ReadCharValue(App_connHndl,&pReq,BLEAppUtil_getSelfEntity());
            if(status == SUCCESS)
                {
                    Disc_state = DISPLAY_CHAR_VAL;
                }
            else
                {
                    sprint(" | status:");print(&status,1);
                    Disc_state = READ_CHAR_VAL;
                    BLEAppUtil_invokeFunctionNoData(disc_services);
                }
            
        break;
        }
        case DISPLAY_CHAR_VAL:
        {
          sprint("\nDISPLAY_CHAR_VAL");
          sprint("\nMsg:");print(&gattMsg->msg.readRsp,2);
          Disc_state = DISC_COMPLETE;
        break;
        }

请告诉我、为什么我会得到错误的回答。

此致

Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您读取特征值的方式有点非常规。 您认为调用 GATT_ReadCharValue 是正确的方法、但此函数是异步的、不会阻止程序。 发生的情况是、该函数将返回 0、因为它成功地向外设发送了 ATT 值读取数据包、但外设需要一段时间才能回复该值。

    您应该做的是定义一个 BLEApp EventHandler_t 对象以提供给 Util_Event 函数。 在 BLEApp.Handler_t 中、您可以定义事件处理程序、每次 Util_Event 栈接收到您的事件掩码中的 ATT 事件时都会调用该事件处理程序。 这进而会使用 BLEAppUtil_msgHdr_t 参数调用您的函数。 然后可以将此参数转换为 gattMsgEvent_t、事件类型的筛选器、并调用要调用的适当函数。

    例如、您的代码可能如下所示:

    //*****************************************************************************
    //! Includes
    //*****************************************************************************
    
    #include <ti/ble/app_util/menu/menu_module.h>
    #include <ti/ble/app_util/framework/bleapputil_api.h>
    
    //*****************************************************************************
    //! Globals
    //*****************************************************************************
    
    // Events handlers struct, contains the handlers and event masks
    // of the application data module
    BLEAppUtil_EventHandler_t dataGATTHandler =
    {
        .handlerType    = BLEAPPUTIL_GATT_TYPE,
        .pEventHandler  = ATTUtil_EventHandler,
        .eventMask      = BLEAPPUTIL_ATT_READ_RSP |
                          BLEAPPUTIL_ATT_ERROR_RSP
    };
    
    //*****************************************************************************
    //! Functions
    //*****************************************************************************
    
    /*********************************************************************
     * @fn      Data_start
     *
     * @brief   This function is called after stack initialization,
     *          the purpose of this function is to initialize and
     *          register the specific events handlers of the data
     *          application module
     *
     * @return  SUCCESS, errorInfo
     */
    bStatus_t Data_start( void )
    {
      bStatus_t status = SUCCESS;
    
      // Register the handlers
      status = BLEAppUtil_registerEventHandler( &dataGATTHandler );
    
      // Return status value
      return( status );
    }
    
    /*********************************************************************
     * @fn      ATTUtil_EventHandler
     *
     * @brief   This function is called when the BLE stack recieved an ATT
     *          packet. the pMsgData parameter contains all the unformatted
     *          information of the packet.
     * 
     * @param   event - unused
     * @param   pMsgData - data of the event
     *          
     * @return  none
     */
    void ATTUtil_EventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData)
    {
        gattMsgEvent_t *gattMsg = ( gattMsgEvent_t * )pMsgData;
        
        switch ( gattMsg->method )
        {
            case ATT_READ_RSP:
            {
                attReadRsp_t readResponse = gattMsg->msg.readRsp;
                uint8_t rspStatus = gattMsg->hdr.status;
    
                # Do something with the response, like displaying it like you did
                GATT_bm_free(&gattMsg->msg, ATT_READ_RSP );
            }
            break;
    
            case ATT_ERROR_RSP:
            {
                attErrorRsp_t errResponse = gattMsg->msg.errorRsp;
                uint8_t rspStatus = gattMsg->hdr.status;
    
                # Handle the error
                GATT_bm_free(&gattMsg->msg, ATT_ERROR_RSP );
            }
            break;
    
    
            default:
                break;
        }
    }

    请尝试修改您的代码、以便使用我在示例中向您展示的 ATT 事件处理程序、并告诉我是否仍然存在相同的问题。


    此致、
    Maxence

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Maxence、

    我已经遵循了您的建议方法。 请看一下

    /******************************************************************************
    
    @file  app_data.c
    
    @brief This file contains the application data functionality
    
    Group: WCS, BTS
    Target Device: cc23xx
    
    ******************************************************************************
    
     Copyright (c) 2022-2025, Texas Instruments Incorporated
     All rights reserved.
    
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
     are met:
    
     *  Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    
     *  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    
     *  Neither the name of Texas Instruments Incorporated nor the names of
        its contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
    ******************************************************************************
    
    
    *****************************************************************************/
    
    //*****************************************************************************
    //! Includes
    //*****************************************************************************
    #include <string.h>
    #include "ti/ble/app_util/framework/bleapputil_api.h"
    #include "ti/ble/app_util/menu/menu_module.h"
    #include <app_main.h>
    #include "Client/client.h"
    #include <ti/drivers/UART2.h>
    
    //*****************************************************************************
    //! Defines
    BLEAppUtil_entityId_t getSelfEntity; 
    gattMsgEvent_t *gattMsg;
    //*****************************************************************************
    
    //*****************************************************************************
    //! Globals
    extern UART2_Handle uart;
    extern uint16_t App_connHndl;
    extern void disc_services();
    extern uint8_t Disc_state;
    //*****************************************************************************
    
    static void GATT_EventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData);
    
    // Events handlers struct, contains the handlers and event masks
    // of the application data module
    BLEAppUtil_EventHandler_t dataGATTHandler =
    {
        .handlerType    = BLEAPPUTIL_GATT_TYPE,
        .pEventHandler  = GATT_EventHandler,
        .eventMask      = BLEAPPUTIL_ATT_FLOW_CTRL_VIOLATED_EVENT |
                          BLEAPPUTIL_ATT_EXCHANGE_MTU_RSP |
                          BLEAPPUTIL_ATT_FIND_INFO_RSP |
                          BLEAPPUTIL_ATT_READ_RSP |
                          BLEAPPUTIL_ATT_READ_BY_TYPE_RSP|
                          BLEAPPUTIL_ATT_FIND_BY_TYPE_VALUE_RSP |
                          BLEAPPUTIL_ATT_READ_BY_GRP_TYPE_RSP
    
    };
    
    //*****************************************************************************
    //! Functions
    //*****************************************************************************
    
    /*********************************************************************
     * @fn      GATT_EventHandler
     *
     * @brief   The purpose of this function is to handle GATT events
     *          that rise from the GATT and were registered in
     *          @ref BLEAppUtil_RegisterGAPEvent
     *
     * @param   event - message event.
     * @param   pMsgData - pointer to message data.
     *
     * @return  none
     */
    static void GATT_EventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData)
    {
      getSelfEntity = BLEAppUtil_getSelfEntity();
      gattMsg = ( gattMsgEvent_t * )pMsgData;
    
      // sprint("\nGATT_MSG:");
      // print(&gattMsg->msg,10);
      switch ( gattMsg->method )
      {
        case ATT_FLOW_CTRL_VIOLATED_EVENT:
          {
              
          }
          break;
    
        case ATT_EXCHANGE_MTU_RSP:
          {
              sprint("\nMTU Updated");
               disc_services();
          }
          break;
    
      
        case ATT_READ_RSP :
        case ATT_FIND_INFO_RSP:
        case ATT_READ_BY_TYPE_RSP:   
        case ATT_FIND_BY_TYPE_VALUE_RSP:
          {
          if(Disc_state != DISC_COMPLETE)
              {
                disc_services();
              }
          }
        break;
    
        default:
          break;
      }
      GATT_bm_free(&(gattMsg->msg), gattMsg->method);
    }
    
    /*********************************************************************
     * @fn      Data_start
     *
     * @brief   This function is called after stack initialization,
     *          the purpose of this function is to initialize and
     *          register the specific events handlers of the data
     *          application module
     *
     * @return  SUCCESS, errorInfo
     */
    bStatus_t Data_start( void )
    {
      bStatus_t status = SUCCESS;
    
      // Register the handlers
      status = BLEAppUtil_registerEventHandler( &dataGATTHandler );
    
      // Return status value
      return( status );
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您可以尝试在 READ_CHAR_VAL 情况下检查接收到的 GATT msg 方法是否为正确的类型、类似于在 STORE_SERVICE_HNDL 情况下所做的操作。

    您也可以尝试对 UUID 进行硬编码并打印用于接收的 UUID、以查看您是否实际查询了正确的 GATT 属性。

    此致、
    Maxemce