本篇博文最后修改时间:2017年06月02日,10:37。
一、简介
本文以SimpleBLEPeripheral工程为例,介绍如何使用notify通知的两种方式。
二、实验平台
协议栈版本:BLE-CC254x-1.4.0
编译软件: IAR 8.20.2
硬件平台: Smart RF开发板(主芯片CC2541)
手机型号: 小米4S
安卓版本:安卓5.1
安卓app:TruthBlue2_1
三、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.NET/feilusia
联系方式:[email protected]
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
香瓜BLE之Android群:541462902
五、基础知识
1、简介notify通知的两种方式
答:
1)GATT_Notification
在从机代码中使用,由从机主动通知,且不需要主机发出请求和回应。
2)GATTServApp_ProcessCharCfg
在从机代码中使用,需要主机发送一次“通知请求”给从机,从机收到“通知请求”才发送通知。
实际上这个函数里依然会调用GATT_Notification这个函数。
2、什么是CCC?
答:
Client Characteristic Configuration,俗称CCC。
notify属性的特征值,会多读、写属性的特征值多一个CCC。
从机要想使用notify函数时能正常发送出数据,就必须保证CCC是被打开的。
3、CCC如何打开?
答:notify开关可由主机端或者从机端打开,但应尽量保证由主机来打开比较合适,毕竟它是“主机”,“主机“就该有主动权。
1)主机端打开(推荐)
先获取到CCC的特征值句柄,然后利用CCC的特征值句柄往CCC的特征值中写入0x0001。
参考本博客博文《CC2541之主机端获取notify数据》。
2)从机端打开(不推荐)
注,如果上面的0x0001改为0x0000,则为关闭notify开关。
4、如何获取CCC的句柄?
答:先获取到这个CCC所属的特征值的特征值句柄,然后将该特征值句柄+1。
例如,想要获取到char6的CCC的句柄,我就必须先获取到char6的特征值句柄(参考本博客博文《CC2541之发现服务与特征值》),比如获取到的值是0x0035,则CCC的特征值句柄就是0x0036。之所以加1,是因为char6的CCC所在属性表的位置,正好在char6的特征值后面。
5、是否可以直接在主机代码中使用0x0036当做char6的CCC句柄?
答:可以,但是不推荐。
由于句柄是osal自动分配的,代码编译好之后,特征值句柄是固定的。但是一旦你在char6之前添加了一个特征值,那么char6的CCC句柄也会往后推算,这时候你的0x0036显然就没用了。
因此强烈推荐下文中使用的方法,自动获取句柄,详情自己看代码。
六、GATT_Notification的使用范例
看上述的参考博文。
七、GATTServApp_ProcessCharCfg的使用范例
注:TI提供的SimpleBLEPeripheral项目中,在周期事件里每隔5S即读取char3值一次,并把char3的值通知出去,此时用的就是GATTServApp_ProcessCharCfg方式。
1、周期事件中不停地设置char4的值
static void performPeriodicTask( void )
{
uint8 valueToCopy;
uint8 stat;
stat = SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR3, &valueToCopy);
if( stat == SUCCESS )
{
/*
* Call to set that value of the fourth characteristic in the profile. Note
* that if notifications of the fourth characteristic have been enabled by
* a GATT client device, then a notification will be sent every time this
* function is called.
*/
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof(uint8), &valueToCopy);
}
}
case SIMPLEPROFILE_CHAR4:
if ( len == sizeof ( uint8 ) )
{
simpleProfileChar4 = *((uint8*)value);
// See if Notification has been enabled
GATTServApp_ProcessCharCfg( simpleProfileChar4Config, &simpleProfileChar4, FALSE,
simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
INVALID_TASK_ID );
}
else
{
ret = bleInvalidRange;
}
break;
3、实验结果
char4不停地通知着char3的值0x03。