蓝牙4.0 BLE SimpleBLEPeripheral_添加新CHAR值及UUID

SimpleGATTProfile 中5个特征值,每一个特征值都不同 

 

simplegattprofile

 

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:

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)*******

 

SIMPLEPROFILE CHAR6 uuid

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";

                                                                                                                           

4

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

 

5

并把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 

     },

 

6

能列出来了但是 点进去会报错,还没设置读写参数simpleProfile_WriteAttrCB, 

simpleProfile_ReadAttrCB

 

 

4、设置参数函数 (SimpleProfile_SetParameter函数)

 

 

bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )中:

//即修改SimpleProfile_SetParameter();函数

7

 

 

添加以下代码:

case SIMPLEPROFILE_CHAR6:

     if ( len == SIMPLEPROFILE_CHAR6_LEN ) //特征值赋值到数组

     {

       VOID osal_memcpy(simpleProfileChar6, value, SIMPLEPROFILE_CHAR6_LEN );

 //把要改写的数据写到simpleProfileChar6数组来

     }

     else

     {

       ret = bleInvalidRange;

     }

     break;

 

 

8

 

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;

9

 

·        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

      

10

添加单字节char7要在接char1或3后面,不能加break

11

 

在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;

 

12

 

7 .在simpleBLEperipheral.c添加初始化值

 

在void SimpleBLEPeripheral_Init( uint8 task_id )函数中初始化参数

13

 

现在可以在手机设备中读取CHAR6的值为0x0102030405;

向char6写进0x3344556677 再读取值已经改写为0x3344556677

 

查看 39429
本栏更多文章: how to unlock the Kinetis chip? »