CC2640R2F修改特征值Char1

本章实验

实现char1具备 notify 通知属性、可发不定长特征值数据

特征值是什么?
	特征值是一个变量或者一个数组,它被定义在 server 端,它是 client 端与 server 端之间传输数据的缓冲区
	比如添加一个 char1[10],它的值初始化为 0.
	当 char1 具有读、写属性时,client 端可以通过 GATT_ReadCharValue、GATT_WriteCharValue进行读、写 server 端的 char1。
	当 char1 具有 notify 通知属性时,server 端可以将 char1 的值通知给 client 机。
修改步骤
  1. 修改 char1 的宏定义(在 simple_gatt_profile.h中部分)
#define SIMPLEPROFILE_CHAR1_LEN           10
extern uint8 charValue1[SIMPLEPROFILE_CHAR1_LEN];
extern bStatus_t UserProfile_Notify(uint8 param, uint8 *pValue, uint8 len);
  1. 修改char1 的相关参数 (在 simple_gatt_profile.c中部分)
uint8 charValue1[SIMPLEPROFILE_CHAR1_LEN] = {0};    // 特征1值

#define SERVAPP_NUM_ATTR_SUPPORTED        18	// 0~17

//属性在属性表中的偏移值
#define ATTRTBL_CHAR1_IDX                   2   // 特征1在属性表的偏移值
#define ATTRTBL_CHAR1_CCC_IDX               3   // 特征1的notify开关在属性表的偏移值
#define ATTRTBL_CHAR4_IDX                   12   // 特征4在属性表的偏移值
#define ATTRTBL_CHAR4_CCC_IDX               13   // 特征4的notify开关在属性表的偏移值
  1. 修改char1的配置属性
// Simple Profile Characteristic 1 Properties
static uint8 simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE | GATT_PROP_NOTIFY;

// Characteristic 1 Value
static uint8 simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] = {0};

static gattCharCfg_t *simpleProfileChar1Config;

// Simple Profile Characteristic 1 User Description
static uint8 simpleProfileChar1UserDesp[17] = "Characteristic 1";
  1. 修改属性表(在simple_gatt_profile.c的simpleProfileAttrTbl数组中)
  // Characteristic Value 1
  {
    { ATT_BT_UUID_SIZE, simpleProfilechar1UUID },
    GATT_PERMIT_READ | GATT_PERMIT_WRITE,
    0,
    simpleProfileChar1
  },
  
  // Characteristic 1 configuration
  {
    { ATT_BT_UUID_SIZE, clientCharCfgUUID },
    GATT_PERMIT_READ | GATT_PERMIT_WRITE,
    0,
    (uint8 *)&simpleProfileChar1Config
  },

  // Characteristic 1 User Description
  {
    { ATT_BT_UUID_SIZE, charUserDescUUID },
    GATT_PERMIT_READ,
    0,
    simpleProfileChar1UserDesp
  },
  1. 修改char1 的通知开关初始化(在simple_gatt_profile.c的SimpleProfile_AddService函数中)
 //只有通知属性的才需要初始化通知开关属性。
 bStatus_t SimpleProfile_AddService( uint32 services )
{
  uint8 status;
  // Allocate Client Characteristic Configuration table
  simpleProfileChar1Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *linkDBNumConns );
  if ( simpleProfileChar1Config == NULL )
  {
    return ( bleMemAllocError );
  }
  simpleProfileChar4Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *linkDBNumConns );
  if ( simpleProfileChar4Config == NULL )
  {
    return ( bleMemAllocError );
  }
  // Initialize Client Characteristic Configuration attributes
  GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar1Config );
  GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar4Config );
  if ( services & SIMPLEPROFILE_SERVICE )
  {
    // Register GATT attribute list and CBs with GATT Server App
    status = GATTServApp_RegisterService( simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                          GATT_MAX_ENCRYPT_KEY_SIZE,&simpleProfileCBs );
  }
  else
  {
    status = SUCCESS;
  }
  return ( status );
}
  1. 修改char1 的数值可设置的处理(在simple_gatt_profile.c的SimpleProfile_SetParameter函数中)
    case SIMPLEPROFILE_CHAR1:
      if ( len == SIMPLEPROFILE_CHAR1_LEN )
      {
          VOID memcpy( simpleProfileChar1, value, SIMPLEPROFILE_CHAR1_LEN );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;
  1. 修改char1 的数值可获取的处理(在simple_gatt_profile.c的SimpleProfile_GetParameter函数中)
    case SIMPLEPROFILE_CHAR1:
        VOID memcpy( value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN );
      break;
  1. 修改 char1 的数值读取的处理(在simple_gatt_profile.c的simpleProfile_ReadAttrCB函数中)
  case SIMPLEPROFILE_CHAR1_UUID:
    *pLen = SIMPLEPROFILE_CHAR1_LEN;
    VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN );
    break;  
  1. 修改char1 的数值写入的处理(在simple_gatt_profile.c的simpleProfile_WriteAttrCB函数中)
static bStatus_t simpleProfile_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]);
    switch ( uuid )
    {
      case SIMPLEPROFILE_CHAR1_UUID:
          if ( offset == 0 )
          {
              if ( len > SIMPLEPROFILE_CHAR1_LEN )
              {
                  status = ATT_ERR_INVALID_VALUE_SIZE;
              }
          }
          else
          {
              status = ATT_ERR_ATTR_NOT_LONG;
          }
          //Write the value
          if ( status == SUCCESS )
          {
              VOID memcpy(pAttr->pValue,  pValue, len );
              notifyApp = SIMPLEPROFILE_CHAR1;
          }
          break;
      case SIMPLEPROFILE_CHAR3_UUID:

        //Validate the value
        // Make sure it's not a blob oper
        if ( offset == 0 )
        {
          if ( len != 1 )
          {
            status = ATT_ERR_INVALID_VALUE_SIZE;
          }
        }
        else
        {
          status = ATT_ERR_ATTR_NOT_LONG;
        }
        //Write the value
        if ( status == SUCCESS )
        {
          uint8 *pCurValue = (uint8 *)pAttr->pValue;
          *pCurValue = pValue[0];
//          if( pAttr->pValue == &simpleProfileChar1 )
//          {
//            notifyApp = SIMPLEPROFILE_CHAR1;
//          }
//          else
//          {
              notifyApp = SIMPLEPROFILE_CHAR3;
//          }
        }
        break;
      case GATT_CLIENT_CHAR_CFG_UUID:
         //CHAR1 的通知开关
          if(pAttr->handle == simpleProfileAttrTbl[ATTRTBL_CHAR1_CCC_IDX].handle)
          {
              status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                      offset, GATT_CLIENT_CFG_NOTIFY );
          }
          //CHAR4 的通知开关
          else if(pAttr->handle == simpleProfileAttrTbl[ATTRTBL_CHAR4_CCC_IDX].handle)
          {
              status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                                                                   offset, GATT_CLIENT_CFG_NOTIFY );
          }
          else
          {
              status = ATT_ERR_INVALID_HANDLE;
          }
        break;
      default:
        // Should never get here! (characteristics 2 and 4 do not have write permissions)
        status = ATT_ERR_ATTR_NOT_FOUND;
        break;
    }
  }
  else	//其他情况不打开通知开关
  {
    // 128-bit UUID
    status = ATT_ERR_INVALID_HANDLE;
  }
  // If a characteristic value changed then callback function to notify application of change
  if ( (notifyApp != 0xFF ) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange )
  {
    simpleProfile_AppCBs->pfnSimpleProfileChange( notifyApp );
  }
  return ( status );
}
  1. 修改char1 的发送通知数据的函数(在simple_gatt_profile.c的UserProfile_Notify函数中)
bStatus_t UserProfile_Notify(uint8 param, uint8 *pValue, uint8 len)
{
    attHandleValueNoti_t  attHandleValueNoti;
    gattCharCfg_t *pItem = simpleProfileChar1Config;
    uint16 value;
    bStatus_t ret = SUCCESS;
    switch(param)
    {
        // 特征1
        case SIMPLEPROFILE_CHAR1:
        {
            // 读出CCC
            value = GATTServApp_ReadCharCfg(pItem->connHandle, simpleProfileChar1Config);
            // 判断CCC是否被打开
            if(value & GATT_CLIENT_CFG_NOTIFY)
            {
                // 分配发送数据缓冲区
                attHandleValueNoti.pValue = GATT_bm_alloc(pItem->connHandle,
                                                          ATT_HANDLE_VALUE_NOTI,
                                                          SIMPLEPROFILE_CHAR1_LEN, NULL);
                // 分配成功,则发送数据
                if(attHandleValueNoti.pValue != NULL)
                {
                    // 填充数据
                    attHandleValueNoti.handle = simpleProfileAttrTbl[ATTRTBL_CHAR1_IDX].handle;
                    attHandleValueNoti.len = len;
                    memcpy(attHandleValueNoti.pValue, pValue, len);

                    // 发送数据
                    if(GATT_Notification(pItem->connHandle, &attHandleValueNoti, FALSE) != SUCCESS)
                    {
                        GATT_bm_free((gattMsg_t *)&attHandleValueNoti, ATT_HANDLE_VALUE_NOTI);
                    }
                }
                else
                    ret = FAILURE;
            }
            else
                ret = FAILURE;
            break;
        }
    default: ret = FAILURE; break;
    }
    return (ret);
}
修改应用层
  1. 修改特征值初始化的数值(在simple_gatt_profile.c的SimpleBLEPeripheral_init函数中)
#ifndef FEATURE_OAD_ONCHIP
  // Setup the SimpleProfile Characteristic Values
  // For more information, see the sections in the User's Guide:
  // http://software-dl.ti.com/lprf/ble5stack-docs-latest/html/ble-stack/gatt.html#
  // http://software-dl.ti.com/lprf/ble5stack-docs-latest/html/ble-stack/gatt.html#gattservapp-module
  {
    uint8_t charValue2 = 2;
    uint8_t charValue3 = 3;
    uint8_t charValue4 = 4;
    uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),&charValue1);
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),&charValue2);
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),&charValue3);
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),&charValue4);
    SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,charValue5);
  }
  1. 发蓝牙数据
 UserProfile_Notify(SIMPLEPROFILE_CHAR1,pValue,2);//蓝牙发送数据
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值