软件平台:IAR
硬件平台:CC2640
操作系统:TI-RTOS--SYS/BIOS
工程基础:基于SimpleBLEPeripheral官方例程
目的:在系统中增加"characteristic service"特性服务
步骤如下:
1. 在simpleGATTprofile.c中添加全局变量,如下代码:
// Characteristic 6 UUID: 0xFFF6
CONST uint8 simpleProfilechar6UUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16(SIMPLEPROFILE_CHAR6_UUID), HI_UINT16(SIMPLEPROFILE_CHAR6_UUID)
};
// Simple Profile Characteristic 6 Properties 可读,可写, 可通知
static uint8 simpleProfileChar6Props = GATT_PROP_READ | GATT_PROP_WRITE_NO_RSP | GATT_PROP_NOTIFY;
// Characteristic 6 Value
static uint8 simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN] = {0};// 特征值初始化
static uint8 simpleProfileChar6Len = 0;
// Simple Profile Characteristic 6 Configuration Each client has its own
// instantiation of the Client Characteristic Configuration. Reads of the
// Client Characteristic Configuration only shows the configuration for
// that client and writes only affect the configuration of that client.
static gattCharCfg_t *simpleProfileChar6Config;
// Simple Profile Characteristic 6 User Description
static uint8 simpleProfileChar6UserDesp[17] = "Characteristic 6"; // 特征值描述
在"static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED]"中添加代码:
// Characteristic 6 Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar6Props
},
// Characteristic Value 6
{
{ ATT_BT_UUID_SIZE, simpleProfilechar6UUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
simpleProfileChar6
},
// Characteristic 6 configuration
{
{ ATT_BT_UUID_SIZE, clientCharCfgUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8 *)&simpleProfileChar6Config
},
// Characteristic 6 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar6UserDesp
},
2. 在simpleGATTprofile.c文件的各函数中添加相应代码:
a. 在函数"bStatus_t SimpleProfile_AddService( uint32 services )"中添加代码如下:
#if 1
// Allocate Client Characteristic Configuration table
simpleProfileChar6Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *
linkDBNumConns );
if ( simpleProfileChar6Config == NULL )
{
return ( bleMemAllocError );
}
// Initialize Client Characteristic Configuration attributes
GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar6Config );
#endif
b. 在函数"bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )"中添加代码如下:
case SIMPLEPROFILE_CHAR6:
//LCD_WRITE_STRING_VALUE( "SetParameter 6 len=", len, 10, HAL_LCD_LINE_1 );
//if ( len == SIMPLEPROFILE_CHAR6_LEN )
if ( len <= SIMPLEPROFILE_CHAR6_LEN )
{
memcpy( simpleProfileChar6, value, len );
simpleProfileChar6Len = len;
// See if Notification has been enabled
GATTServApp_ProcessCharCfg( simpleProfileChar6Config, simpleProfileChar6, FALSE,
simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
INVALID_TASK_ID, simpleProfile_ReadAttrCB );
}
else
{
ret = bleInvalidRange;
}
break;
c. 在函数"bStatus_t SimpleProfile_GetParameter( uint8 param, void *value, uint8 *returnBytes)"中添加代码如下:
bStatus_t SimpleProfile_GetParameter( uint8 param, void *value, uint8 *returnBytes)
{
bStatus_t ret = SUCCESS;
switch ( param )
{
case SIMPLEPROFILE_CHAR1:
*((uint8*)value) = simpleProfileChar1;
*returnBytes = 1;
break;
case SIMPLEPROFILE_CHAR2:
*((uint8*)value) = simpleProfileChar2;
*returnBytes = 1;
break;
case SIMPLEPROFILE_CHAR3:
*((uint8*)value) = simpleProfileChar3;
*returnBytes = 1;
break;
case SIMPLEPROFILE_CHAR4:
*((uint8*)value) = simpleProfileChar4;
*returnBytes = 1;
break;
case SIMPLEPROFILE_CHAR5:
memcpy( value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN );
*returnBytes = 1;
break;
case SIMPLEPROFILE_CHAR6:
memcpy( value, simpleProfileChar6, simpleProfileChar6Len );
*returnBytes = simpleProfileChar6Len;
//*returnBytes = 1;
break;
default:
ret = INVALIDPARAMETER;
*returnBytes = 0;
break;
}
return ( ret );
}
d. 在函数"static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,gattAttribute_t *pAttr,uint8_t *pValue,
uint16_t *pLen,uint16_t offset, uint16_t maxLen,uint8_t method)"中添加代码如下:
case SIMPLEPROFILE_CHAR6_UUID:
*pLen = simpleProfileChar6Len;
memcpy( pValue, pAttr->pValue, simpleProfileChar6Len );
{
// 这个变量用于表明上一次写数据到从机已经成功, 可用于判断写数据时的判断, 以确保数据的完整性
// extern bool simpleBLEChar6DoWrite2;
// simpleBLEChar6DoWrite2 = TRUE;
}
break;
e. 在函数"static bStatus simpleProfile_WriteAttrCB(uint16_t connHandle,gattAttribute_t *pAttr,uint8_t *pValue, uint16_t len
uint16_t offset, uint8_t method)"中添加代码如下:
case SIMPLEPROFILE_CHAR6_UUID:
//Validate the value
// Make sure it's not a blob oper
if ( offset == 0 )
{
//if ( len != SIMPLEPROFILE_CHAR6_LEN )
if ( len > SIMPLEPROFILE_CHAR6_LEN )
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}
}
else
{
status = ATT_ERR_ATTR_NOT_LONG;
}
//Write the value
if ( status == SUCCESS )
{
//VOID osal_memcpy( pAttr->pValue, pValue, SIMPLEPROFILE_CHAR6_LEN );
memcpy( pAttr->pValue, pValue, len );
simpleProfileChar6Len = len;
notifyApp = SIMPLEPROFILE_CHAR6;
}
break;
3. 在simpleGATTprofile.h文件中添加如下代码:
#define SIMPLEPROFILE_CHAR6 5 // RW uint8 - Profile Characteristic 5 value
#define SIMPLEPROFILE_CHAR6_UUID 0xFFF6
#define SIMPLEPROFILE_CHAR6_LEN 20 //主机读写
extern bStatus_t SimpleProfile_GetParameter( uint8 param, void *value, uint8 *returnBytes);
4. 在simpleBLEPeripheral.c文件中添加如下代码:
a.在函数SimpleBLEPeripheral_processCharValueChangeEvt(uint8 paramID)中添加如下代码:
case SIMPLEPROFILE_CHAR6: // read the data from char6 and send it to UART
SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR6, newValue, &returnBytes);
if(returnBytes > 0)
{
MY_UART_Send_Num(newValue, returnBytes);
}
break;