UUID,就是用来唯一识别一个特征值的ID.
handle,就是对应的attribute的一个句柄。
所有对特征值的操作,都是通过对UUID的搜索得到对应的handle之后,通过handle来操作特征值的。
添加新的特征值CHAR6
下面对主要几个文件进行修改
simpleGATTprofile.h文件添加以下定义
#define SIMPLEPROFILE_CHAR6 5
#define SIMPLEPROFILE_CHAR6_UUID 0xFFF6
#define SIMPLEPROFILE_CHAR6_LEN 5(单字节没这句)
SIMPLEPROFILE_CHAR6 全大写case参数用到如case SIMPLEPROFILE_CHAR6:
在simpleGATTprofile.c
1、 添加特征值UUID
// Characteristic 6 UUID: 0xFFF6
CONST uint8 simpleProfilechar6UUID[ATT_BT_UUID_SIZE] =
{
LO_UINT16(SIMPLEPROFILE_CHAR6_UUID), //低八位
HI_UINT16(SIMPLEPROFILE_CHAR6_UUID) }; //高八位
/**************#define HI_UINT16(a) (((a) >> 8) & 0xFF)*******
/**************#define LO_UINT16(a) ((a) & 0xFF)*******
2、 设置属性
// Simple Profile Characteristic 6 Properties 可读可写(声明而已,只是能让lightblue在列表中显示为可读可写或通知,真正要改在属性表那里改。Props= Properties,Desp=Description,)
static uint8 simpleProfileChar6Props = GATT_PROP_READ | GATT_PROP_WRITE;
// Characteristic 6 Value // simpleProfileChar6是个5位数组,接收数据后存在这
static uint8simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN] = { 0, 0, 0, 0, 0 };
// Simple Profile Characteristic 6 User Description
static uint8 simpleProfileChar6UserDesp[17] = "Characteristic 6\0";
3、 属性表 (Profile Attributes - Table)最重要,添加了这个才会在lightblue中列表出来
static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED]
这里要把数组改为
#define SERVAPP_NUM_ATTR_SUPPORTED 20 原来是17
(//添加了3组结构体数组CHAR6)
simpleProfileAttrTbl表中,可读可写属性都是3个数组,只有char4的通知是4组,多了个// Characteristic 4 configuration
并把CHAR6添加进去
// Characteristic 6 Declaration (声明,没加这个lightblue属性表找不到)
{
{ 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 //由于值是5位数组,不用&,一个字节就用
},
// Characteristic 6 User Description //描述
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar6UserDesp
},
能列出来了但是 点进去会报错,还没设置读写参数simpleProfile_WriteAttrCB, 和
simpleProfile_ReadAttrCB
4、设置参数函数 (SimpleProfile_SetParameter函数)
bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )中:
//即修改SimpleProfile_SetParameter();函数
添加以下代码:
case SIMPLEPROFILE_CHAR6:
if ( len == SIMPLEPROFILE_CHAR6_LEN ) //特征值赋值到数组
{
VOID osal_memcpy(simpleProfileChar6, value, SIMPLEPROFILE_CHAR6_LEN );
//把要改写的数据写到simpleProfileChar6数组来
}
else
{
ret = bleInvalidRange;
}
break;
4、 获取参数函数 {SimpleProfile_GetParameter(UUID,获取到的值)函数}
实际上就是把被新进的值simpleProfileChar6放进value数组
在bStatus_tSimpleProfile_GetParameter( uint8 param, void *value )中添加:
case SIMPLEPROFILE_CHAR6:
VOID osal_memcpy( value, simpleProfileChar6, SIMPLEPROFILE_CHAR6_LEN );
break;
//读取simpleProfileChar6的值放到*value中,char1是单个字节读取,为
*((uint8*)value) = simpleProfileChar1;
· 6、读写特征值函数(2个回调函数
· 这个两个是注册到GATT层的回调函数,在GATT初始化的时候注册的.这部分代码封装在库里面.
每当GATT层有数据发过来的时候,会调用simpleProfile_WriteAttrCB,
每当GATT层收到对方读取数据请求的时候,会调用simpleProfile_ReadAttrCB
这两个函数包含在gattServiceCBs_t类型的结构体里CONST gattServiceCBs_t simpleProfileCBs,
读simpleProfile_ReadAttrCB
这个设置后就能在lightblue里读出值,值为
simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN]={数组的数值(16进制显示)}
写simpleProfile_WriteAttrCB
读取被写进去的值
)
在static uint8 simpleProfile_ReadAttrCB( uint16 connHandle,
gattAttribute_t *pAttr,
uint8 *pValue,
uint8 *pLen,
uint16 offset,
uint8 maxLen )中:
添加 case SIMPLEPROFILE_CHAR6_UUID:
*pLen = SIMPLEPROFILE_CHAR6_LEN;
VOID osal_memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR6_LEN );
break; //读:pAttr->pValue的内容复制到pValue
添加单字节char7要在接char1或3后面,不能加break
在simpleProfile_WriteAttrCB()中添加(添加后发送过去就不会提示出错了)
case SIMPLEPROFILE_CHAR6_UUID:
//Validate the value检测输入数据是否合法
// Make sure it's not a blob oper
if ( offset == 0 )//是第一字节
{
if ( len != SIMPLEPROFILE_CHAR6_LEN )
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}//若输入长度不对,status为
}
else
{
status = ATT_ERR_ATTR_NOT_LONG;//不是第一字节
}
//Write the value一开始定义了status == SUCCESS,若上述条件不符,不会运行到这里。osal_memcpy(目的A,源地址B,长度)复制B内容到A
if ( status == SUCCESS )
{
VOID osal_memcpy( pAttr->pValue, pValue, SIMPLEPROFILE_CHAR6_LEN );
notifyApp = SIMPLEPROFILE_CHAR6;
} //写:pValue的内容复制到pAttr->pValue(别弄反了)
break;
(下面没用到)osal_memset为字符串集体赋同一数值 return目的存储区地址
void *osal_memset(void *dest, uint8 value , intlen)
{
Return memset(dest,value,len);
}
if ( status == SUCCESS )
{
uint8 *pCurValue = (uint8 *)pAttr->pValue;
osal_memset(pCurValue, 0, SIMPLEPROFILE_CHAR6_LEN );
//为新数组pCurValue赋值N个0
VOID osal_memcpy(pCurValue, pValue, SIMPLEPROFILE_CHAR6_LEN );
//复制pValue内容到新数组pCurValue notifyApp = SIMPLEPROFILE_CHAR6;
}
break;
7 .在simpleBLEperipheral.c添加初始化值
在void SimpleBLEPeripheral_Init( uint8 task_id )函数中初始化参数
现在可以在手机设备中读取CHAR6的值为0x0102030405;
向char6写进0x3344556677 再读取值已经改写为0x3344556677