CC26x2R1笔记(14)从机特征值的添加

1平台条件

《1》软件平台:simplelink_cc13x2_26x2_sdk_3_30_00_03
《2》硬件平台:CC26X2

2 .c文件

用到4个特征值

/*********************************************************************
 * INCLUDES
 */

#include "service_init.h"
#include "simple_uart.h"
#include "in_flash_manage.h"
#include "ble_data.h"
#include "ble_center.h"
#include "simple_peripheral_oad_onchip.h"

static ProfileCBs_t *Profile_AppCBs = NULL;


// step 1
/**********************************************************************************************/
//============ uuid 赋值==================
// Simple GATT Profile Service UUID: 0xFFF0
 uint8 FExx_PrimaServUUID[ATT_BT_UUID_SIZE] =
{
 LO_UINT16(PRIMA_SERV_UUID), HI_UINT16(PRIMA_SERV_UUID)
};

// Characteristic 1 UUID: 0xFFF1
uint8 FFx1_UUID[ATT_BT_UUID_SIZE] =
{
 LO_UINT16(FEx1_UUID), HI_UINT16(FEx1_UUID)
};

// Characteristic 2 UUID: 0xFFF2
 uint8 FFx2_UUID[ATT_BT_UUID_SIZE] =
{
 LO_UINT16(FEx2_UUID), HI_UINT16(FEx2_UUID)
};

// Characteristic 3 UUID: 0xFFF3
 uint8 FFx3_UUID[ATT_BT_UUID_SIZE] =
{
 LO_UINT16(FEx3_UUID), HI_UINT16(FEx3_UUID)
};

// Characteristic 4 UUID: 0xFFF4
uint8 FFx4_UUID[ATT_BT_UUID_SIZE] =
{
 LO_UINT16(FEx4_UUID), HI_UINT16(FEx4_UUID)
};


static CONST gattAttrType_t Profile_Service = { ATT_BT_UUID_SIZE, FExx_PrimaServUUID };


 /********************************************************************************************************/
// step 2:通道特征
//================FEx1 通道==========================================
// Properties
static uint8 FEx1_Props = GATT_PROP_NOTIFY;

static uint8          FEx1_char_valu[BLE_SEND_LEN];//  Value
static gattCharCfg_t *FEx1_Config;
static uint8 FEx1_UserDesp[17] = "rx_data";//  User Description


//================FEx2通道========================================
//  Properties
static uint8 FEx2_Props = GATT_PROP_WRITE_NO_RSP;
static uint8 FEx2_char_valu[BLE_SEND_LEN] = { 0, 0, 0, 0, 0 };
static uint8 FEX2_UserDesp[17] = "tx_data";

//==================FEx3 通道=======================================
// Properties
static uint8 FEx3_Props = GATT_PROP_NOTIFY;

static uint8          FEx3_char_valu[BLE_SEND_LEN];//  Value
static gattCharCfg_t *FEx3_Config;
static uint8 FEx3_UserDesp[17] = "rx_at_cmd";//


//==================FEx4通道===========================================
//  Properties
static uint8 FEx4_Props = GATT_PROP_WRITE_NO_RSP;
static uint8 FEx4_char_valu[BLE_SEND_LEN] = { 0, 0, 0, 0, 0 };
static uint8 FEX4_UserDesp[17] = "tx_at_cmd";



uint8_t ble_write_len=0;
/*********************************************************************
 * Profile Attributes - Tabled  属性表
 */
static gattAttribute_t ProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
{
      // Simple Profile Service
      {
        { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
        GATT_PERMIT_READ,                         /* permissions */
        0,                                        /* handle */
        (uint8 *)&Profile_Service            /* pValue */
      },

/************************ FEX1 *******************************/
    //  Declaration
    {
      { ATT_BT_UUID_SIZE, characterUUID },
      GATT_PERMIT_READ,
      0,
      &FEx1_Props
    },

      // Characteristic Value 
      {
        { ATT_BT_UUID_SIZE, FFx1_UUID },
         GATT_PERMIT_READ | GATT_PERMIT_WRITE, 
        0,
        FEx1_char_valu
      },

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

      // Characteristic  User Description
      {
        { ATT_BT_UUID_SIZE, charUserDescUUID },
        GATT_PERMIT_READ,
        0,
        FEx1_UserDesp
      },
     
 /***********************************FEX2 *******************/
    //  Declaration
    {
      { ATT_BT_UUID_SIZE, characterUUID },
      GATT_PERMIT_READ,
      0,
      &FEx2_Props
    },

      // Characteristic Value 
      {
        { ATT_BT_UUID_SIZE, FFx2_UUID },
        GATT_PERMIT_WRITE, 
        0,
        FEx2_char_valu
      },

      // User Description
      {
        { ATT_BT_UUID_SIZE, charUserDescUUID },
        GATT_PERMIT_READ,
        0,
        FEX2_UserDesp
      },
/************************ FEX3 *******************************/
      //  Declaration
      {
        { ATT_BT_UUID_SIZE, characterUUID },
        GATT_PERMIT_READ,
        0,
        &FEx3_Props
      },
        // Characteristic Value   9
      {
        { ATT_BT_UUID_SIZE, FFx3_UUID },
           GATT_PERMIT_READ | GATT_PERMIT_WRITE,
           0,
          FEx3_char_valu
     },
        // Characteristic  configuration
        {
          { ATT_BT_UUID_SIZE, clientCharCfgUUID },
          GATT_PERMIT_READ | GATT_PERMIT_WRITE,
          0,
          (uint8 *)&FEx3_Config
        },
        // Characteristic  User Description
        {
          { ATT_BT_UUID_SIZE, charUserDescUUID },
          GATT_PERMIT_READ,
          0,
          FEx3_UserDesp
        },

/***********************************FEX4 *******************/
       //  Declaration
       {
         { ATT_BT_UUID_SIZE, characterUUID },
         GATT_PERMIT_READ,
         0,
         &FEx4_Props
       },
         // Characteristic Value
         {

           { ATT_BT_UUID_SIZE, FFx4_UUID },
           GATT_PERMIT_WRITE,
           0,
           FEx4_char_valu
         },
         // User Description
         {
           { ATT_BT_UUID_SIZE, charUserDescUUID },
           GATT_PERMIT_READ,
           0,
           FEX4_UserDesp
         },

};

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

CONST gattServiceCBs_t ProfileCBs =
{
  Profile_ReadAttrCB,  // Read callback function pointer
  Profile_WriteAttrCB, // Write callback function pointer
  NULL                       // Authorization callback function pointer
};
/*********************************************************
 *
 *  @ 注册app 服务
 */
bStatus_t Profile_AddService( uint32 services )
{
  uint8 status;

/************************* fex1 cccd  *************************************************************/
  FEx1_Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *
                                                            MAX_NUM_BLE_CONNS );
  if ( FEx1_Config == NULL )
  {
    return ( bleMemAllocError );
  }

  // Initialize Client Characteristic Configuration attributes
  GATTServApp_InitCharCfg( LINKDB_CONNHANDLE_INVALID, FEx1_Config );

 /************************* fex3 cccd *************************************************************/
  FEx3_Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *
                                                           MAX_NUM_BLE_CONNS );
  if ( FEx3_Config == NULL )
  {
    return ( bleMemAllocError );
  }

  // Initialize Client Characteristic Configuration attributes
  GATTServApp_InitCharCfg( LINKDB_CONNHANDLE_INVALID, FEx3_Config );

  //服务初始化
  if ( services & PROFILE_SERVICE )
  {
    // Register GATT attribute list and CBs with GATT Server App
    status = GATTServApp_RegisterService( ProfileAttrTbl,
                                          GATT_NUM_ATTRS(ProfileAttrTbl ),
                                          GATT_MAX_ENCRYPT_KEY_SIZE,
                                          &ProfileCBs );
  }
  else
  {
    status = SUCCESS;
  }

  return ( status );
}

//*********************************************************************
// 注册 app
bStatus_t Profile_RegisterAppCBs(ProfileCBs_t *appCallbacks )
{
  if ( appCallbacks )
  {
    Profile_AppCBs = appCallbacks;

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

// *********************************************************************
// 设置 uuid 

uint8 check_err =0;
bStatus_t Profile_SetParameter( uint8 param, uint8 len, void *value )
{
  bStatus_t ret = SUCCESS;
  switch ( param )
  {
    case CHAR_FEx1_ID:
      if ( len <=BLE_SEND_LEN )
      {
        memcpy(FEx1_char_valu,(uint8 *)value,len);
        // See if Notification has been enabled
        check_err = GATTServApp_ProcessCharCfg( FEx1_Config, FEx1_char_valu, FALSE,
                                    ProfileAttrTbl, GATT_NUM_ATTRS( ProfileAttrTbl ),
                                    INVALID_TASK_ID, Profile_ReadAttrCB );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case CHAR_FEx2_ID:
      if ( len <= BLE_SEND_LEN )
      {
        VOID memcpy(FEx2_char_valu, value, BLE_SEND_LEN );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    case CHAR_FEx3_ID:
      if ( len <=BLE_SEND_LEN )
      {
        memcpy(FEx3_char_valu,(uint8 *)value,len);
        // See if Notification has been enabled
        GATTServApp_ProcessCharCfg( FEx3_Config, FEx3_char_valu, FALSE,
                                    ProfileAttrTbl, GATT_NUM_ATTRS( ProfileAttrTbl ),
                                    INVALID_TASK_ID, Profile_ReadAttrCB );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;
    case CHAR_FEx4_ID:
      if ( len <= BLE_SEND_LEN )
      {
        VOID memcpy(FEx4_char_valu, value, BLE_SEND_LEN );
      }
      else
      {
        ret = bleInvalidRange;
      }
      break;

    default:
      ret = INVALIDPARAMETER;
      break;
  }

  return ( ret );
}

//*********************************************************************
// 得到特征值数据---
bStatus_t Profile_GetParameter( uint8 param, void *value )
{
  bStatus_t ret = SUCCESS;
  switch ( param )
  {
    case CHAR_FEx1_ID:
      *((uint8*)value) = FEx1_char_valu[0];
      break;
    case CHAR_FEx2_ID:
     VOID memcpy( value,FEx2_char_valu, ble_write_len );
      break;
    case CHAR_FEx3_ID:
      *((uint8*)value) = FEx3_char_valu[0];
      break;
    case CHAR_FEx4_ID:
      VOID memcpy( value,FEx4_char_valu, ble_write_len );
      break;
    default:
      ret = INVALIDPARAMETER;
      break;
  }
  return ( ret );
}


 /**********************************************************************/                                   
//特征值读取操作                                 
static bStatus_t Profile_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 );
  }

  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==FEx1_UUID)
    {
        *pLen = BLE_SEND_LEN;
        pValue[0] = *pAttr->pValue;
    }
    else if(uuid==FEx2_UUID)
    {
        *pLen = BLE_SEND_LEN;
        VOID memcpy( pValue, pAttr->pValue, BLE_SEND_LEN );
    }
    else if(uuid==FEx3_UUID)
    {
        *pLen = BLE_SEND_LEN;
        VOID memcpy( pValue, pAttr->pValue, BLE_SEND_LEN );
    }
    else if(uuid==FEx4_UUID)
    {
        *pLen = BLE_SEND_LEN;
        VOID memcpy( pValue, pAttr->pValue, BLE_SEND_LEN );
    }
    else
    {
        *pLen = 0;
        status = ATT_ERR_ATTR_NOT_FOUND;
    }
  }
  else
  {
    // 128-bit UUID
    *pLen = 0;
    status = ATT_ERR_INVALID_HANDLE;
  }

  return ( status );
}

//*********************************************************************
//特征值写操作和notify
uint8  uuid_data[20] ;
uint16 write_uuid= 0;
static bStatus_t Profile_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;


  write_uuid= 0;
  if ( pAttr->type.len == ATT_BT_UUID_SIZE )
  {
    // 16-bit UUID
    write_uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
    
    if(write_uuid==GATT_CLIENT_CHAR_CFG_UUID) // cccf 打开notify开关
    {
        status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
                 offset, GATT_CLIENT_CFG_NOTIFY );

       ble_uart_send_data("cccfg\r\n",6);
    }
/************************************** fex2通道写入函数 ****************************************************************/
    if(write_uuid== FEx2_UUID )
      {
          if ( offset == 0 )
          {
              if ( len <= BLE_SEND_LEN )
              {
                  ble_write_len= len;
              }
          }
          else
          {
            status = ATT_ERR_ATTR_NOT_LONG;
          }
          //Write the value
          if ( status == SUCCESS )
          {

            VOID osal_memcpy( pAttr->pValue, pValue, ble_write_len );
            if( pAttr->pValue == FEx2_char_valu)
                notifyApp = CHAR_FEx2_ID;
          }
          else
          {
            // Should never get here! (characteristics 2 and 4 do not have write permissions)
            status = ATT_ERR_ATTR_NOT_FOUND;
          }
      }
/************************************** fex4通道写入函数 ****************************************************************/
    if(write_uuid== FEx4_UUID  )
    {
        if ( offset == 0 )
        {
            if ( len <= BLE_SEND_LEN )
            {
             // status = ATT_ERR_INVALID_VALUE_SIZE;
                ble_write_len= len;
            }
        }
        else
        {
          status = ATT_ERR_ATTR_NOT_LONG;
        }
        //Write the value
        if ( status == SUCCESS )
        {

         VOID osal_memcpy( pAttr->pValue, pValue, ble_write_len );

         if( pAttr->pValue == FEx4_char_valu)
              notifyApp = CHAR_FEx4_ID;
        }
        else
        {
          // Should never get here! (characteristics 2 and 4 do not have write permissions)
          status = ATT_ERR_ATTR_NOT_FOUND;
        }
    }
  }
  else
  {
      // 128-bit UUID
//      const uint8 uuid[ATT_UUID_SIZE] =
//      {
//       BLE_BASE_UUID_128(BUILD_UINT16( pAttr->type.uuid[12], pAttr->type.uuid[13]))
 //     };
  }

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

  return ( status );
}



/***************************************************************
 *
 * 从机 app写入数据函数
 */
uint8  ble_data[300];
extern status_t SimplePeripheral_enqueueMsg(uint8_t event, void *pData);
static void Peripheral_charValueChangeCB(uint8_t paramId)
{
    switch(paramId)
    {
      case CHAR_FEx2_ID:
        Profile_GetParameter(CHAR_FEx2_ID, ble_data);
        ble_queue_data_in(ble_data,ble_write_len,MASTER_SPP);
        break;

      case CHAR_FEx4_ID:
        Profile_GetParameter(CHAR_FEx4_ID, ble_data);
        ble_queue_data_in(ble_data,ble_write_len,MASTER_AT);
        break;

      default:
        // should not reach here!
        break;
    }

   return ;
}

// Simple GATT Profile Callbacks
static ProfileCBs_t Peripheral_simpleProfileCBs =
{
     Peripheral_charValueChangeCB // Characteristic value change callback
};

/******************************************
 *
 * @  用户私有服务初始化
 */
void  user_serv_init(void)
{ 
    Profile_AddService(GATT_ALL_SERVICES);
    
    uint8_t char_Value[20] = { 1, 2, 3, 4, 5 ,6,4,8,6,1,8};

    Profile_SetParameter(CHAR_FEx1_ID,sizeof(char_Value),char_Value);
    Profile_SetParameter(CHAR_FEx2_ID, sizeof(char_Value),char_Value);
    Profile_SetParameter(CHAR_FEx3_ID, sizeof(char_Value),char_Value);
    Profile_SetParameter(CHAR_FEx4_ID, sizeof(char_Value),char_Value);
    
    Profile_RegisterAppCBs(&Peripheral_simpleProfileCBs);
}


将user_serv_init放在
在这里插入图片描述

3.h文件

#ifndef service_init_h_
#define service_init_h_


#include "_hal_types.h"
#include "bcomdef.h"
#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 "simple_gatt_profile.h"

#ifdef SYSCFG
#include "ti_ble_config.h"
#endif



// 0x0000fee0-0000-1000-8000-00805f9b34fb  -----逆序过来
#define BLE_BASE_UUID_128( uuid )  0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, \
                                   0x00, 0x10, 0x00, 0x00, LO_UINT16( uuid ), HI_UINT16( uuid ), 0x00, 0x00



// prima----uuid
#define PRIMA_SERV_UUID               0xFEE0

// char uuid
#define FEx1_UUID            0xFEE0
#define FEx2_UUID            0xFEE1
#define FEx3_UUID            0xFEE2
#define FEx4_UUID            0xFEE3



#define SERVAPP_NUM_ATTR_SUPPORTED        15// 属性表大小

//属性在属性表中的偏移值  cc偏移值
#define ATTRTBL_FEx1_IDX                   2
#define ATTRTBL_FEx1_CCC_IDX               3

//属性在属性表中的偏移值  ccfg
#define ATTRTBL_FEx3_IDX                   9
#define ATTRTBL_FEx3_CCC_IDX               11





// step 3
// Profile Parameters
#define CHAR_FEx1_ID                0  //
#define CHAR_FEx2_ID                1 //
#define CHAR_FEx3_ID                2 //
#define CHAR_FEx4_ID                3 //

// Simple Keys Profile Services bit fields
#define PROFILE_SERVICE               0x00000001

// Length of Characteristic 5 in bytes
#define BLE_SEND_LEN      247





// 服务事件--------------  
#define SP_CHAR_CHANGE_EVT     0x41
   





extern uint8 FExx_PrimaServUUID[ATT_BT_UUID_SIZE];


// Callback when a characteristic value has changed
typedef void (*ProfileChange_t)( uint8 paramID );

typedef struct
{
  ProfileChange_t        pfn_ProfileChange;  // Called when characteristic value changes
} ProfileCBs_t;



/*********************************************************************
 * API FUNCTIONS
 */

extern bStatus_t Profile_AddService( uint32 services );
extern bStatus_t Profile_RegisterAppCBs( ProfileCBs_t *appCallbacks );
extern bStatus_t Profile_SetParameter( uint8 param, uint8 len, void *value );
extern bStatus_t Profile_GetParameter( uint8 param, void *value );
void  user_serv_init(void);

uint16_t get_ble_conncet_handle(void);
void start_uart_time_ms(bool type);
uint16_t ble_send_data(uint8_t *dataout,uint16_t len,uint16_t max_len,uint8 role);
uint16_t FEx3_send_data(uint8_t *dataout,uint16_t len,uint16_t max_len,bool is_spp);
uint8 is_ble_conn_state(void);
#endif



4 send data函数

/*****************************************************************
 *
 * Send_Notify 函数  高类聚-低耦合
 * @param: CHAR_FEx1_ID(通道一) ----CHAR_FEx3_ID(通道三)
 */
void ble_Send_Notify( uint8 param, uint8 *pValue, uint8 len)
{
  attHandleValueNoti_t  noti;
  uint16 value;
  uint16 Conn_Handle=0;

   Conn_Handle = connList[get_currt_conn_num()-1].connHandle;

   // 通道1
   if(CHAR_FEx1_ID==param)
   {
       value  = GATTServApp_ReadCharCfg( Conn_Handle, FEx1_Config);//读出CCC
   }
   else
   {
       value  = GATTServApp_ReadCharCfg( Conn_Handle, FEx3_Config);//读出CCC
   }
      //判断CCC是否被打开
      if ( value & GATT_CLIENT_CFG_NOTIFY )
      {
        //分配发送数据缓冲区
        noti.pValue = GATT_bm_alloc(Conn_Handle, ATT_HANDLE_VALUE_NOTI, BLE_SEND_LEN, NULL);

        //分配成功,则发送数据
        if(noti.pValue != NULL)
        {
          if(CHAR_FEx1_ID==param) // 通道1
               noti.handle = ProfileAttrTbl[ATTRTBL_FEx1_IDX].handle;
          else
              noti.handle = ProfileAttrTbl[ATTRTBL_FEx3_IDX].handle;

          noti.len = len;
          memcpy( noti.pValue, pValue, len);  //填充数据

          //发送数据
          if (GATT_Notification(Conn_Handle, &noti, FALSE) != SUCCESS)
          {
//              ble_uart_send_data("notif6",6);
             GATT_bm_free((gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI);
             return;
          }

        }
      }
}

可以加入QQ群:687360507
与大伙沟通交流,技术在于分享而进步

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值