|
增加特征值步骤如下:
一、simpleGATTprofile.c
1.增加特征值UUID
// Characteristic 8 UUID: 0xFFF8
CONST uint8 simpleProfilechar8UUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16(SIMPLEPROFILE_CHAR8_UUID), HI_UINT16(SIMPLEPROFILE_CHAR8_UUID)
};
#define SIMPLEPROFILE_CHAR8_UUID 0xFFF8
2.增加特征值属性
Staticuint8simpleProfileChar8Props=GATT_PROP_WRITE| GATT_PROP_READ | GATT_PROP_NOTIFY; //可读可写可通知
static uint8 simpleProfileChar8[SIMPLEPROFILE_CHAR8_LEN] = { 0, 0, 0, 0, 0 ,0, 0, 0, 0, 0,0, 0, 0, 0, 0,0, 0, 0, 0, 0}; //设置初值
Static uint8 simpleProfileChar8Len=0; //设置任意读写的数据长度
StaticgattCharCfg_tsimpleProfileChar8Config[GATT_MAX_NUM_CONN]; //notify开关定义如不需要notify功能,不需要这句
static uint8 simpleProfileChar8UserDesp[17] = "Characteristic 8"; //特征值描述
#define SIMPLEPROFILE_CHAR8_LEN 20
3.增加特征值属性到属性表
//属性表数组,增加属性后需要修改数组长度SERVAPP_NUM_ATTR_SUPPORTED
// Characteristic 8 Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ, //特征值的申明,只读
0,
&simpleProfileChar8Props
},
// Characteristic Value 8 //22
{
{ ATT_BT_UUID_SIZE, simpleProfilechar8UUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE, //特征值的值可读可写
0,
simpleProfileChar8 //由于值是数组,如果是单字节就&simpleProfileChar8
},
// Characteristic 8 configuration //如没有notify功能,不需要这结构体
{
{ ATT_BT_UUID_SIZE, clientCharCfgUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE, //从机notify使能被主机控制,可读可写
0, //notify关使能
(uint8 *)simpleProfileChar8Config
},
// Characteristic 8 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar8UserDesp
}
4.初始化notify使能变量(如没有notify功能不需要增加此函数
bStatus_t SimpleProfile_AddService( uint32 services ) //注册系统全部服务
{
uint8 status = SUCCESS;
// Initialize Client Characteristic Configuration attributes
GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar4Config ); //初始化char configuration
GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar8Config ); //(主机控制的从机通知开关
// Register with Link DB to receive link status change callback
...... .
........ .
........ .
}
static void simpleProfile_HandleConnStatusCB( uint16 connHandle, uint8 changeType ) //在连接状态改变时
//自动重置所有的configuration values.
{
// Make sure this is not loopback connection
if ( connHandle != LOOPBACK_CONNHANDLE )
{
if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED ) ||
( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) &&
( !linkDB_Up( connHandle ) ) ) )
{
GATTServApp_InitCharCfg( connHandle/*INVALID_CONNHANDLE*/, simpleProfileChar4Config );
GATTServApp_InitCharCfg( connHandle/*INVALID_CONNHANDLE*/, simpleProfileChar8Config );
}
}
}
5.在设置参数值的函数中增加特征值的处理
bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
{
bStatus_t ret = SUCCESS;
switch ( param )
{
...... .
........ .
........ .
case SIMPLEPROFILE_CHAR8:
if ( len <= SIMPLEPROFILE_CHAR8_LEN )
{
VOID osal_memcpy( simpleProfileChar8, value, len );
simpleProfileChar8Len = len;
}
else
{
ret = bleInvalidRange;
}
break;
...... .
........ .
........ .
}
6.在获取参数值的函数中增加特征值的处理
bStatus_t SimpleProfile_GetParameter( uint8 param, void *value, uint8 *returnBytes)
{
bStatus_t ret = SUCCESS;
switch ( param )
{
...... .
........ .
........ .
case SIMPLEPROFILE_CHAR8:
VOID osal_memcpy( value, simpleProfileChar8, simpleProfileChar8Len );
*returnBytes = simpleProfileChar8Len;
break;
...... .
........ .
........ .
}
7.在从机接收到主机写操作函数中增加特征值的处理
static uint8 simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 *pLen, uint16 offset, uint8 maxLen )
{
...... .
........ .
........ .
if ( pAttr->type.len == ATT_BT_UUID_SIZE ) //判断是否为有效UUID
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch ( uuid )
{
...... .
........ .
........ .
case SIMPLEPROFILE_CHAR8_UUID:
*pLen = simpleProfileChar8Len;
VOID osal_memcpy( pValue, pAttr->pValue, simpleProfileChar8Len );
break;
default:
// Should never get here! (characteristics 3 and 4 do not have read permissions)
*pLen = 0;
status = ATT_ERR_ATTR_NOT_FOUND;
break;
...... .
........ .
........ .
}
8.在从机接收到主机读操作函数中增加特征值的处理
static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t *pAttr,
uint8 *pValue, uint8 len, uint16 offset )
{
...... .
........ .
........ .
if ( pAttr->type.len == ATT_BT_UUID_SIZE ) //判断UUID是否有效
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]); //读取UUID
switch ( uuid ) //判断UUID
{
...... .
........ .
........ .
case SIMPLEPROFILE_CHAR8_UUID:
/****************************检测数据是否合法**********************************/
//Validate the value,Make sure it\'s not a blob oper
if ( offset == 0 )
{
//if ( len != SIMPLEPROFILE_CHAR8_LEN )
if ( len > SIMPLEPROFILE_CHAR8_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, len );
simpleProfileChar8Len = len;
notifyApp = SIMPLEPROFILE_CHAR8;
}
break;
...... .
........ .
........ .
}
注意事项
一、在使用手机软件作为主机调试时,最好每次大改动时,都清一下手机蓝牙的缓冲和调试软件的缓冲,不然从机修改的部分不会更新过来,或者导致一些错误;
|
|