
 
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