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.

[参考译文] CC2642R:处理16位以上的 UUID

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1161075/cc2642r-more-than-16-bit-uuid-handling

器件型号:CC2642R

很抱歉这个问题  

我已经通过使用16位 UUID 手动创建了定制服务  

现在、我正在尝试使用服务生成 器 https://dev.ti.com/tirex/explore/content/simplelink_academy_cc13x2_26x2sdk_5_10_00_00/modules/ble5stack/ble_01_custom_profile/ble_01_custom_profile.html#example-service-generator 创建符合北欧半导体 UART 服务(NUS) https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v14.0.0%2Fble_sdk_app_nus_eval.html 的服务

看起来不是很难、但 UUID 超过16位 (也超过128位)  

NUS UUID: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E (16位偏移:0x0001)。

Nordic 的 UART 服务包括以下特性:

名称
TX
RX

必填项
是的
是的

UUID
0x0002
0x0003

类型
U8[20]
U8[20]

R

X

W
X

N

X



RX Characteristic UUID:6E400002-B5A3-F393-E0A9-E50E24DCCA9E (16位偏移:0x0002)。

TX 特征 UUID:6E400003-B5A3-F393-E0A9-E50E24DCCA9E (16位偏移:0x0003)。

如果我仅保留16位偏移 uuid、则我的 NUS_SERV_UUID (0x0001)与   ProjectZero_processApplicationMessage 中的 PZ_SERVICE_CFG_EVT 发生冲突

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

    NUS_service.h

    /**********************************************************************************************
     * Filename:       NUS.h
     *
     * Description:    This file contains the NUS service definitions and
     *                 prototypes.
     *
     * Copyright (c) 2015-2019, 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.
     *
     *************************************************************************************************/
    
    
    #ifndef _NUS_H_
    #define _NUS_H_
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    /*********************************************************************
     * INCLUDES
     */
    
    /*********************************************************************
    * CONSTANTS
    */
    
    // Service UUID
    #define NUS_SERV_UUID 0x0001
    
    //  Characteristic defines
    #define NUS_RX_ID   0
    #define NUS_RX_UUID 0x0002
    #define NUS_RX_LEN  20
    
    //  Characteristic defines
    #define NUS_TX_ID   1
    #define NUS_TX_UUID 0x0003
    #define NUS_TX_LEN  20
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * Profile Callbacks
     */
    
    // Callback when a characteristic value has changed
    typedef void (*NUSChange_t)(uint16_t connHandle, uint8_t paramID, uint16_t len, uint8_t *pValue);
    
    typedef struct
    {
      NUSChange_t        pfnChangeCb;  // Called when characteristic value changes
      NUSChange_t        pfnCfgChangeCb;
    } NUSCBs_t;
    
    
    
    /*********************************************************************
     * API FUNCTIONS
     */
    
    
    /*
     * NUS_AddService- Initializes the NUS service by registering
     *          GATT attributes with the GATT server.
     *
     */
    extern bStatus_t NUS_AddService( uint8_t rspTaskId);
    
    /*
     * NUS_RegisterAppCBs - Registers the application callback function.
     *                    Only call this function once.
     *
     *    appCallbacks - pointer to application callbacks.
     */
    extern bStatus_t NUS_RegisterAppCBs( NUSCBs_t *appCallbacks );
    
    /*
     * NUS_SetParameter - Set a NUS parameter.
     *
     *    param - Profile parameter ID
     *    len - length of data to right
     *    value - pointer to data to write.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     */
    extern bStatus_t NUS_SetParameter(uint8_t param, uint16_t len, void *value);
    
    /*
     * NUS_GetParameter - Get a NUS parameter.
     *
     *    param - Profile parameter ID
     *    value - pointer to data to write.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     */
    extern bStatus_t NUS_GetParameter(uint8_t param, uint16_t *len, void *value);
    
    /*********************************************************************
    *********************************************************************/
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* _NUS_H_ */

    NUS_SERVICE.c

    /**********************************************************************************************
     * Filename:       NUS.c
     *
     * Description:    This file contains the implementation of the service.
     *
     * Copyright (c) 2015-2019, 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 <icall.h>
    
    /* This Header file contains all BLE API and icall structure definition */
    #include "icall_ble_api.h"
    
    #include "NUS.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
    * GLOBAL VARIABLES
    */
    
    // NUS Service UUID
    CONST uint8_t NUSUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(NUS_SERV_UUID), HI_UINT16(NUS_SERV_UUID)
    };
    
    // RX UUID
    CONST uint8_t NUS_RXUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(NUS_RX_UUID), HI_UINT16(NUS_RX_UUID)
    };
    // TX UUID
    CONST uint8_t NUS_TXUUID[ATT_BT_UUID_SIZE] =
    {
      LO_UINT16(NUS_TX_UUID), HI_UINT16(NUS_TX_UUID)
    };
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    static NUSCBs_t *pAppCBs = NULL;
    
    /*********************************************************************
    * Profile Attributes - variables
    */
    
    // Service declaration
    static CONST gattAttrType_t NUSDecl = { ATT_BT_UUID_SIZE, NUSUUID };
    
    // Characteristic "RX" Properties (for declaration)
    static uint8_t NUS_RXProps = GATT_PROP_READ | GATT_PROP_NOTIFY;
    
    // Characteristic "RX" Value variable
    static uint8_t NUS_RXVal[NUS_RX_LEN] = {0};
    
    // Characteristic "RX" CCCD
    static gattCharCfg_t *NUS_RXConfig;
    // Characteristic "TX" Properties (for declaration)
    static uint8_t NUS_TXProps = GATT_PROP_WRITE;
    
    // Characteristic "TX" Value variable
    static uint8_t NUS_TXVal[NUS_TX_LEN] = {0};
    
    /*********************************************************************
    * Profile Attributes - Table
    */
    
    static gattAttribute_t NUSAttrTbl[] =
    {
      // NUS Service Declaration
      {
        { ATT_BT_UUID_SIZE, primaryServiceUUID },
        GATT_PERMIT_READ,
        0,
        (uint8_t *)&NUSDecl
      },
        // RX Characteristic Declaration
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &NUS_RXProps
        },
          // RX Characteristic Value
          {
            { ATT_BT_UUID_SIZE, NUS_RXUUID },
            GATT_PERMIT_READ,
            0,
            NUS_RXVal
          },
          // RX CCCD
          {
            { ATT_BT_UUID_SIZE, clientCharCfgUUID },
            GATT_PERMIT_READ | GATT_PERMIT_WRITE,
            0,
            (uint8 *)&NUS_RXConfig
          },
        // TX Characteristic Declaration
        {
          { ATT_BT_UUID_SIZE, characterUUID },
          GATT_PERMIT_READ,
          0,
          &NUS_TXProps
        },
          // TX Characteristic Value
          {
            { ATT_BT_UUID_SIZE, NUS_TXUUID },
            GATT_PERMIT_WRITE,
            0,
            NUS_TXVal
          },
    };
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static bStatus_t NUS_ReadAttrCB( uint16_t connHandle, gattAttribute_t *pAttr,
                                               uint8_t *pValue, uint16_t *pLen, uint16_t offset,
                                               uint16_t maxLen, uint8_t method );
    static bStatus_t NUS_WriteAttrCB( uint16_t connHandle, gattAttribute_t *pAttr,
                                                uint8_t *pValue, uint16_t len, uint16_t offset,
                                                uint8_t method );
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    // Simple Profile Service Callbacks
    CONST gattServiceCBs_t NUSCBs =
    {
      NUS_ReadAttrCB,  // Read callback function pointer
      NUS_WriteAttrCB, // Write callback function pointer
      NULL                       // Authorization callback function pointer
    };
    
    /*********************************************************************
    * PUBLIC FUNCTIONS
    */
    
    /*
     * NUS_AddService- Initializes the NUS service by registering
     *          GATT attributes with the GATT server.
     *
     */
    extern bStatus_t NUS_AddService( uint8_t rspTaskId )
    {
      uint8_t status;
    
      // Allocate Client Characteristic Configuration table
      NUS_RXConfig = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) * linkDBNumConns );
      if ( NUS_RXConfig == NULL )
      {
        return ( bleMemAllocError );
      }
    
      // Initialize Client Characteristic Configuration attributes
      GATTServApp_InitCharCfg( LINKDB_CONNHANDLE_INVALID, NUS_RXConfig );
      // Register GATT attribute list and CBs with GATT Server App
      status = GATTServApp_RegisterService( NUSAttrTbl,
                                            GATT_NUM_ATTRS( NUSAttrTbl ),
                                            GATT_MAX_ENCRYPT_KEY_SIZE,
                                            &NUSCBs );
    
      return ( status );
    }
    
    /*
     * NUS_RegisterAppCBs - Registers the application callback function.
     *                    Only call this function once.
     *
     *    appCallbacks - pointer to application callbacks.
     */
    bStatus_t NUS_RegisterAppCBs( NUSCBs_t *appCallbacks )
    {
      if ( appCallbacks )
      {
        pAppCBs = appCallbacks;
    
        return ( SUCCESS );
      }
      else
      {
        return ( bleAlreadyInRequestedMode );
      }
    }
    
    /*
     * NUS_SetParameter - Set a NUS parameter.
     *
     *    param - Profile parameter ID
     *    len - length of data to right
     *    value - pointer to data to write.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     */
    bStatus_t NUS_SetParameter( uint8_t param, uint16_t len, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
        case NUS_RX_ID:
          if ( len == NUS_RX_LEN )
          {
            memcpy(NUS_RXVal, value, len);
    
            // Try to send notification.
            GATTServApp_ProcessCharCfg( NUS_RXConfig, (uint8_t *)&NUS_RXVal, FALSE,
                                        NUSAttrTbl, GATT_NUM_ATTRS( NUSAttrTbl ),
                                        INVALID_TASK_ID,  NUS_ReadAttrCB);
          }
          else
          {
            ret = bleInvalidRange;
          }
          break;
    
        default:
          ret = INVALIDPARAMETER;
          break;
      }
      return ret;
    }
    
    
    /*
     * NUS_GetParameter - Get a NUS parameter.
     *
     *    param - Profile parameter ID
     *    value - pointer to data to write.  This is dependent on
     *          the parameter ID and WILL be cast to the appropriate
     *          data type (example: data type of uint16 will be cast to
     *          uint16 pointer).
     */
    bStatus_t NUS_GetParameter( uint8_t param, uint16_t *len, void *value )
    {
      bStatus_t ret = SUCCESS;
      switch ( param )
      {
        case NUS_TX_ID:
          memcpy(value, NUS_TXVal, NUS_TX_LEN);
          break;
    
        default:
          ret = INVALIDPARAMETER;
          break;
      }
      return ret;
    }
    
    
    /*********************************************************************
     * @fn          NUS_ReadAttrCB
     *
     * @brief       Read an attribute.
     *
     * @param       connHandle - connection message was received on
     * @param       pAttr - pointer to attribute
     * @param       pValue - pointer to data to be read
     * @param       pLen - length of data to be read
     * @param       offset - offset of the first octet to be read
     * @param       maxLen - maximum length of data to be read
     * @param       method - type of read message
     *
     * @return      SUCCESS, blePending or Failure
     */
    static bStatus_t NUS_ReadAttrCB( uint16_t connHandle, gattAttribute_t *pAttr,
                                           uint8_t *pValue, uint16_t *pLen, uint16_t offset,
                                           uint16_t maxLen, uint8_t method )
    {
      bStatus_t status = SUCCESS;
    
      // See if request is regarding the RX Characteristic Value
    if ( ! memcmp(pAttr->type.uuid, NUS_RXUUID, pAttr->type.len) )
      {
        if ( offset > NUS_RX_LEN )  // Prevent malicious ATT ReadBlob offsets.
        {
          status = ATT_ERR_INVALID_OFFSET;
        }
        else
        {
          *pLen = MIN(maxLen, NUS_RX_LEN - offset);  // Transmit as much as possible
          memcpy(pValue, pAttr->pValue + offset, *pLen);
        }
      }
      else
      {
        // If we get here, that means you've forgotten to add an if clause for a
        // characteristic value attribute in the attribute table that has READ permissions.
        *pLen = 0;
        status = ATT_ERR_ATTR_NOT_FOUND;
      }
    
      return status;
    }
    
    
    /*********************************************************************
     * @fn      NUS_WriteAttrCB
     *
     * @brief   Validate attribute data prior to a write operation
     *
     * @param   connHandle - connection message was received on
     * @param   pAttr - pointer to attribute
     * @param   pValue - pointer to data to be written
     * @param   len - length of data
     * @param   offset - offset of the first octet to be written
     * @param   method - type of write message
     *
     * @return  SUCCESS, blePending or Failure
     */
    static bStatus_t NUS_WriteAttrCB( uint16_t connHandle, gattAttribute_t *pAttr,
                                            uint8_t *pValue, uint16_t len, uint16_t offset,
                                            uint8_t method )
    {
      bStatus_t status  = SUCCESS;
      uint8_t   paramID = 0xFF;
    
      // See if request is regarding a Client Characterisic Configuration
      if ( ! memcmp(pAttr->type.uuid, clientCharCfgUUID, pAttr->type.len) )
      {
        // Allow only notifications.
        status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                 offset, GATT_CLIENT_CFG_NOTIFY);
      }
      // See if request is regarding the TX Characteristic Value
      else if ( ! memcmp(pAttr->type.uuid, NUS_TXUUID, pAttr->type.len) )
      {
        if ( offset + len > NUS_TX_LEN )
        {
          status = ATT_ERR_INVALID_OFFSET;
        }
        else
        {
          // Copy pValue into the variable we point to from the attribute table.
          memcpy(pAttr->pValue + offset, pValue, len);
    
          // Only notify application if entire expected value is written
          if ( offset + len == NUS_TX_LEN)
            paramID = NUS_TX_ID;
        }
      }
      else
      {
        // If we get here, that means you've forgotten to add an if clause for a
        // characteristic value attribute in the attribute table that has WRITE permissions.
        status = ATT_ERR_ATTR_NOT_FOUND;
      }
    
      // Let the application know something changed (if it did) by using the
      // callback it registered earlier (if it did).
      if (paramID != 0xFF)
        if ( pAppCBs && pAppCBs->pfnChangeCb )
          pAppCBs->pfnChangeCb(connHandle, paramID, len, pValue); // Call app function from stack task context.
    
      return status;
    }

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

    您好!

    链接的 SimpleLink Academy 模块中的示例服务生成器支持生成128位 UUID。 我认为不需要进行额外的修改来支持这一点、以便您可以使用服务生成器提供的模板。

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

    还行,但是如果我在发生器中设置128位 uuid (0x6E400001B5A3F393E0A9E50E24DCCA9E)  

     对于 uuid、pzCharacteristicData_t 结构仍使用16位值

    typedef struct
    {
        uint16_t svcUUID; // UUID of the service
        uint16_t dataLen; //
        uint8_t paramID; // Index of the characteristic
        uint8_t data[]; // Flexible array member, extended to malloc - sizeof(.)
    } spCharacteristicData_t;
    

    在向主要任务发送消息时、这是不合适的  

    static void user_NUS_ValueChangeCB(uint16_t connHandle,
                                  uint8_t paramID, uint16_t len,
                                  uint8_t *pValue)
    {
        pzCharacteristicData_t *pValChange =
            ICall_malloc(sizeof(pzCharacteristicData_t) + len);
    
        if(pValChange != NULL)
        {
            pValChange->svcUUID = NUS_SERV_UUID;
            pValChange->paramID = paramID;
            memcpy(pValChange->data, pValue, len);
            pValChange->dataLen = len;
    
            ProjectZero_enqueueMsg(PZ_SERVICE_WRITE_EVT, pValChange);
        }
    }
    

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

    即使 是 TI_BASE_UUUUUID_128宏也会遇到 int 过大的错误

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

    对任何混淆表示歉意。 默认情况下、Project Zero 设置为对服务和特征使用128位 UUID。

    我将查看 DATA_SERVICE.c (例如、我相信 Project Zero 中的其他配置文件也可以被引用)。 当配置文件被写入时、将调用 Data_Service_WriteAttrCB。 在此阶段、使用 Data_Service_findCharParamId 搜索特征。 在该层上完全检查 UUID。 标识特征后、索引会传递到应用层。 这将使我们转到 ProjectZero_DataService_ValueChangeCB、上面 显示的 pzCharacteristic Data_t 在这里发挥作用。 在此阶段、外设已经知道要写入的 svcUUID 是什么(来自配置文件的回调已触发)、因此仅使用16位标识符与应用程序进行通信。

    希望这对您有所帮助。