CC2640R2F 自定义UUID

本文档记录TI CC2640F2R simple_peripheral 工程下UUID 修改

硬件平台:官方 LAUNCHXL-CC2640R2F (http://www.ti.com/tool/cn/launchxl-cc2640r2)

SDK:  simplelink_cc2640r2_sdk_1_50_00_58  (http://www.ti.com/tool/download/SIMPLELINK-CC2640R2-SDK)

编译环境: iar for arm 8.20.2 (https://www.iar.com)

 

1、软件安装略......

2、修改工程

  1)、打开simple_peripheral 工程如下,(user_gatt_profile.c, user_gatt_profile.h 在后面说明)

 

2)、新增文件描述

在目录 simplelink_cc2640r2_sdk_1_50_00_58\source\ti\blestack\profiles 增加文件夹 user_gatt、 cc26xx,增加文件user_gatt_profile.c、user_gatt_profile.h, 其结构如下:

 

 user_gatt_profile.h 如下

#ifndef USERGATTPROFILE_H
#define USERGATTPROFILE_H

#define SDIPROFILE_SERV_UUID                  (0x0213)

#define SDIPROFILE_RECV_CHAR                  (0x02)  
#define SDIPROFILE_SEND_CHAR                  (0x03)  
#define SDIPROFILE_OTA_RECV_CHAR              (0xFE)

#define SDI_PROFILE_SERV_UUID                {0x8C,0xF9,0x97,0xA6,0xEE,0x94,0xE3,0xBC,0xF8,0x21,0xB2,0x60,0x00,0x80,0x00,0x00}
#define SDI_PROFILE_SEND_UUID                {0x8C,0xF9,0x97,0xA6,0xEE,0x94,0xE3,0xBC,0xF8,0x21,0xB2,0x60,0x02,0x80,0x00,0x00}
#define SDI_PROFILE_RECV_UUID                {0x8C,0xF9,0x97,0xA6,0xEE,0x94,0xE3,0xBC,0xF8,0x21,0xB2,0x60,0x01,0x80,0x00,0x00}

#define SDI_PROFILE_OTA_SERV_UUID            (0x1902)
#define SDI_PROFILE_OTA_RECV_UUID            (0x2B12)


typedef void (*sdiProfileChange_t)( uint8 paramID);

typedef struct
{
  sdiProfileChange_t        pfnsdiProfileChange;  // Called when characteristic value changes
} sdiProfileCBs_t;


//-----------------------------------------------------------
extern bStatus_t sdiProfile_AddService( uint32 services );
extern bStatus_t sdiProfile_RegisterAppCBs( sdiProfileCBs_t *appCallbacks );
extern bStatus_t sdiProfile_SetParameter( uint8 param, uint8 len, void *value );
extern bStatus_t sdiProfile_GetParameter( uint8 param, void *value );


#endif

user_gatt_profile.c 如下

/*********************************************************************
 * INCLUDES
 */
#include <string.h>
#include <icall.h>
#include "util.h"
/* This Header file contains all BLE API and icall structure definition */
#include "icall_ble_api.h"

#include "user_gatt_profile.h"

/************************************************************************/
#define SERVAPP_NUM_ATTR_SUPPORTED    (8)
#define OTA_SERV_NUM_ATTR_SUPPORTED   (4)

/********************* user uuid define *********************************/

CONST uint8 SDI_profile_user_server_uuid[ATT_UUID_SIZE] = SDI_PROFILE_SERV_UUID;
CONST uint8 SDI_profile_user_recv_uuid[ATT_UUID_SIZE] = SDI_PROFILE_RECV_UUID;
CONST uint8 SDI_profile_user_send_uuid[ATT_UUID_SIZE] = SDI_PROFILE_SEND_UUID;

static sdiProfileCBs_t *sdiProfile_AppCBs = NULL;

// sdi Profile Service attribute
static CONST gattAttrType_t sdiProfileService = { ATT_UUID_SIZE, SDI_profile_user_server_uuid};

static uint8 SDI_profile_recv_props = GATT_PROP_WRITE_NO_RSP;  // Simple Profile Characteristic 3 Properties
static uint8 SDI_profile_recv_buf[20] = {0};                   // Characteristic 3 Value
static uint8 SDI_profile_recv_desp[10] = "SDI->SEND";          // Simple Profile Characteristic 3 User Description

static uint8 SDI_profile_send_props = GATT_PROP_NOTIFY;       // Simple Profile Characteristic 4 Properties
static uint8 SDI_profile_send_buf[20] = {0};                  // Characteristic 4 Value
static gattCharCfg_t *SDI_profile_send_config; 
static uint8 SDI_profile_send_desp[10] = "SDI->RECV";         // Simple Profile Characteristic 4 User Description


//OTA
CONST uint8 SDI_profile_ota_server_uuid[ATT_BT_UUID_SIZE] = {LO_UINT16(SDI_PROFILE_OTA_SERV_UUID), HI_UINT16(SDI_PROFILE_OTA_SERV_UUID)};
CONST uint8 SDI_profile_ota_recv_uuid[ATT_BT_UUID_SIZE] = {LO_UINT16(SDI_PROFILE_OTA_RECV_UUID), HI_UINT16(SDI_PROFILE_OTA_RECV_UUID)};

//static sdiProfileCBs_t *SDI_OTAProfile_AppCBs = NULL;

// ota Profile Service attribute
static CONST gattAttrType_t SDI_profile_ota_service = { ATT_BT_UUID_SIZE, SDI_profile_ota_server_uuid};

static uint8 SDI_profile_ota_recv_props = GATT_PROP_WRITE_NO_RSP;  // Simple Profile Characteristic 3 Properties
static uint8 SDI_profile_ota_recv_buf[20] = {0};                   // Characteristic 3 Value
static uint8 SDI_profile_ota_recv_desp[9] = "SDI->OTA";          // Simple Profile Characteristic 3 User Description

/*********************************************************************/

uint8 g_recv_buf[21];
uint8 g_ota_recv_buf[21];

static uint8 g_send_buf[20];
static uint8 g_send_len;

/*********************************************************************
 * Profile Attributes - Table
 */

static gattAttribute_t sdiProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
{
  // Sdi Profile Service
  {
    { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
    GATT_PERMIT_READ,                         /* permissions */
    0,                                        /* handle */
    (uint8 *)&sdiProfileService               /* pValue */
  },
    // Characteristic 3 Declaration
    {
      { ATT_BT_UUID_SIZE, characterUUID },
      GATT_PERMIT_READ,
      0,
      &SDI_profile_recv_props
    },

      // Characteristic Value 3
      {
        { ATT_UUID_SIZE, SDI_profile_user_recv_uuid },
        GATT_PERMIT_WRITE,
        0,
        SDI_profile_recv_buf
      },

      // Characteristic 3 User Description
      {
        { ATT_BT_UUID_SIZE, charUserDescUUID },
        GATT_PERMIT_READ,
        0,
        SDI_profile_recv_desp
      },

    // Characteristic 4 Declaration
    {
      { ATT_BT_UUID_SIZE, characterUUID },
      GATT_PERMIT_READ,
      0,
      &SDI_profile_send_props
    },

      // Characteristic Value 4
      {
        { ATT_UUID_SIZE, SDI_profile_user_send_uuid },
        0,
        0,
        SDI_profile_send_buf
      },

      // Characteristic 4 configuration
      {
        { ATT_BT_UUID_SIZE, clientCharCfgUUID },
        GATT_PERMIT_READ | GATT_PERMIT_WRITE,
        0,
        (uint8 *)&SDI_profile_send_config
      },

      // Characteristic 4 User Description
      {
        { ATT_BT_UUID_SIZE, charUserDescUUID },
        GATT_PERMIT_READ,
        0,
        SDI_profile_send_desp
      },
};


//OTA
static gattAttribute_t SDI_profile_ota_attrtbl[OTA_SERV_NUM_ATTR_SUPPORTED] =
{
  // ota Profile Service
  {
    { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
    GATT_PERMIT_READ,                         /* permissions */
    0,                                        /* handle */
    (uint8 *)&SDI_profile_ota_service         /* pValue */
  },
    // Characteristic 3 Declaration
    {
      { ATT_BT_UUID_SIZE, characterUUID },
      GATT_PERMIT_READ,
      0,
      &SDI_profile_ota_recv_props
    },

      // Characteristic Value 3
      {
        { ATT_BT_UUID_SIZE, SDI_profile_ota_recv_uuid },
        GATT_PERMIT_WRITE,
        0,
        SDI_profile_ota_recv_buf
      },

      // Characteristic 3 User Description
      {
        { ATT_BT_UUID_SIZE, charUserDescUUID },
        GATT_PERMIT_READ,
        0,
        SDI_profile_ota_recv_desp
      },
};

/*********************************************************************
 * LOCAL FUNCTIONS
 */
static bStatus_t sdiProfile_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 sdiProfile_WriteAttrCB(uint16_t connHandle,
                                           gattAttribute_t *pAttr,
                                           uint8_t *pValue, uint16_t len,
                                           uint16_t offset, uint8_t method);
static bStatus_t otaProfile_WriteAttrCB(uint16_t connHandle,
                                           gattAttribute_t *pAttr,
                                           uint8_t *pValue, uint16_t len,
                                           uint16_t offset, uint8_t method);

/*********************************************************************
 * PROFILE CALLBACKS
 */

// sdi Profile Service Callbacks
// Note: When an operation on a characteristic requires authorization and
// pfnAuthorizeAttrCB is not defined for that characteristic's service, the
// Stack will report a status of ATT_ERR_UNLIKELY to the client.  When an
// operation on a characteristic requires authorization the Stack will call
// pfnAuthorizeAttrCB to check a client's authorization prior to calling
// pfnReadAttrCB or pfnWriteAttrCB, so no checks for authorization need to be
// made within these functions.
CONST gattServiceCBs_t sdiProfileCBs =
{
  sdiProfile_ReadAttrCB,  // Read callback function pointer
  sdiProfile_WriteAttrCB, // Write callback function pointer
  NULL                       // Authorization callback function pointer
};

CONST gattServiceCBs_t otaProfileCBs =
{
  NULL,  // Read callback function pointer
  otaProfile_WriteAttrCB,  // Write callback function pointer
  NULL   // Authorization callback function pointer
};


/*********************************************************************
 * PUBLIC FUNCTIONS
 */

/*********************************************************************
 * @fn       sdiProfile_AddService
 *
 * @brief   Initializes the Simple Profile service by registering
 *          GATT attributes with the GATT server.
 *
 * @param   services - services to add. This is a bit map and can
 *                     contain more than one service.
 *
 * @return  Success or Failure
 */
bStatus_t sdiProfile_AddService( uint32 services )
{
    uint8 status;

    // Allocate Client Characteristic Configuration table
    SDI_profile_send_config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *
                                                            linkDBNumConns );
    if ( SDI_profile_send_config == NULL )
    {
        return ( bleMemAllocError );
    }

    // Initialize Client Characteristic Configuration attributes
    GATTServApp_InitCharCfg( INVALID_CONNHANDLE, SDI_profile_send_config );

    status = GATTServApp_RegisterService( sdiProfileAttrTbl,
                                          GATT_NUM_ATTRS( sdiProfileAttrTbl ),
                                          GATT_MAX_ENCRYPT_KEY_SIZE,
                                          &sdiProfileCBs );
    if(status != SUCCESS) return status;

    status = GATTServApp_RegisterService( SDI_profile_ota_attrtbl,
                                          GATT_NUM_ATTRS( SDI_profile_ota_attrtbl ),
                                          GATT_MAX_ENCRYPT_KEY_SIZE,
                                          &otaProfileCBs );

    return ( status );
}

/*********************************************************************
 * @fn       sdiProfile_RegisterAppCBs
 *
 * @brief   Registers the application callback function. Only call
 *          this function once.
 *
 * @param   callbacks - pointer to application callbacks.
 *
 * @return  SUCCESS or bleAlreadyInRequestedMode
 */
bStatus_t sdiProfile_RegisterAppCBs( sdiProfileCBs_t *appCallbacks )
{
  if ( appCallbacks )
  {
    sdiProfile_AppCBs = appCallbacks;

    return ( SUCCESS );
  }
  else
  {
    return ( bleAlreadyInRequestedMode );
  }
}

/*********************************************************************
 * @fn       sdiProfile_SetParameter
 *
 * @brief   Set a Simple Profile parameter.
 *
 * @param   param - Profile parameter ID
 * @param   len - length of data to write
 * @param   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).
 *
 * @return  bStatus_t
 */
bStatus_t sdiProfile_SetParameter( uint8 param, uint8 len, void *value )
{
    bStatus_t ret = SUCCESS;

    if(len){
        // See if Notification has been enabled
        uint8 i;
        uint8 *ptr = value;

        for(i=0; i<len; i++)
            g_send_buf[i] = *ptr++;
        g_send_len = len;
        
        GATTServApp_ProcessCharCfg( SDI_profile_send_config, &SDI_profile_send_buf[0], FALSE,
                                    sdiProfileAttrTbl, GATT_NUM_ATTRS( sdiProfileAttrTbl ),
                                    INVALID_TASK_ID, sdiProfile_ReadAttrCB );
    }else{
        ret = bleInvalidRange;
    }

  return ( ret );
}

/*********************************************************************
 * @fn           sdiProfile_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 sdiProfile_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;

  // Make sure it's not a blob operation (no attributes in the profile are long)
  if ( offset > 0 )
  {
    return ( ATT_ERR_ATTR_NOT_LONG );
  }

    *pLen = g_send_len;
    VOID memcpy(pValue, (void *)&g_send_buf[0], *pLen);

    return ( status );
}

/*********************************************************************
 * @fn      sdiProfile_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 sdiProfile_WriteAttrCB(uint16_t connHandle,
                                           gattAttribute_t *pAttr,
                                           uint8_t *pValue, uint16_t len,
                                           uint16_t offset, uint8_t method)
{
  bStatus_t status = SUCCESS;
  uint8 notifyApp = 0xFF;

  if ( pAttr->type.len == ATT_BT_UUID_SIZE )
  {
    // 16-bit UUID
    uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);

    if(uuid == GATT_CLIENT_CHAR_CFG_UUID){
        status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                 offset, GATT_CLIENT_CFG_NOTIFY );
        
     }else{
        // Should never get here! (characteristics 2 and 4 do not have write permissions)
        status = ATT_ERR_ATTR_NOT_FOUND;
    }
  }else{
    // 128-bit UUID
    uint8 uuid = pAttr->type.uuid[12];

    if(uuid == 0x01){
        if(offset == 0){
            if(len == 0) status = ATT_ERR_INVALID_HANDLE;
        }else{
            status = ATT_ERR_ATTR_NOT_LONG;
        }

        if(status == SUCCESS){
            notifyApp = SDIPROFILE_RECV_CHAR;
            //...... process recv data
            uint8 i;
            
            g_recv_buf[0] = len;
            for(i=1; i<=len; i++)
                g_recv_buf[i] = *pValue++;    
        }
    }else{    
        status = ATT_ERR_INVALID_HANDLE;
    }
  }

  // If a characteristic value changed then callback function to notify application of change
  if ( (notifyApp != 0xFF ) && sdiProfile_AppCBs && sdiProfile_AppCBs->pfnsdiProfileChange )
  {
    sdiProfile_AppCBs->pfnsdiProfileChange( notifyApp);
  }

  return ( status );
}

/*********************************************************************
*********************************************************************/
static bStatus_t otaProfile_WriteAttrCB(uint16_t connHandle,
                                           gattAttribute_t *pAttr,
                                           uint8_t *pValue, uint16_t len,
                                           uint16_t offset, uint8_t method)
{
    bStatus_t status = SUCCESS;
    uint8 notifyApp = 0xFF;
    
    if ( pAttr->type.len == ATT_BT_UUID_SIZE )
    {
        // 16-bit UUID
        uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    
        if(uuid == GATT_CLIENT_CHAR_CFG_UUID){
            status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                     offset, GATT_CLIENT_CFG_NOTIFY );
            
         }else if(uuid == SDI_PROFILE_OTA_RECV_UUID){

             if(offset == 0){
                if(len == 0) status = ATT_ERR_INVALID_HANDLE;
            }else{
                status = ATT_ERR_ATTR_NOT_LONG;
            }
    
            if(status == SUCCESS){
                notifyApp = SDIPROFILE_OTA_RECV_CHAR;
                //...... process recv data
                uint8 i;
                
                g_ota_recv_buf[0] = len;
                for(i=1; i<=len; i++)
                    g_ota_recv_buf[i] = *pValue++;    
            }            
        }
    }else{
        status = ATT_ERR_ATTR_NOT_FOUND;
    }
    
      // If a characteristic value changed then callback function to notify application of change
    if ( (notifyApp != 0xFF ) && sdiProfile_AppCBs && sdiProfile_AppCBs->pfnsdiProfileChange )
    {
        sdiProfile_AppCBs->pfnsdiProfileChange( notifyApp);
    }
    
    return ( status );
}

3)、simple_peripheral.c 修改

3.1 头文件增加user_gatt_profile.h, 删除simple_gatt_profile.h

3.2、广播数据 服务UUID修改( 此UUID 可用来扫描时过滤设备)

 

3.3、修改收到APP数据后回调接口及数据处理

                     

3.4、修改初始化 (函数static void SimpleBLEPeripheral_init(void) 内部)

 

3、重新编译 Rebuild all, 烧录

         

 

 修改补丁:https://files.cnblogs.com/files/T0213-ZH/simplelink_cc2640r2_sdk_1_50_00_58_patch_%E4%BF%AE%E6%94%B9uuid.rar

 

posted @ 2019-03-14 16:37  不在+年华  阅读(1389)  评论(0编辑  收藏  举报