TI BLE CC2541 关于Notification的设置及应用
2016-04-28 19:47
405 查看
注:本文的主要目的是为了记录自己的学习过程,也方便与大家做交流。转载请注明来自:
http://blog.csdn.net/ab198604
一、修改从机端代码(Server端):
A 对Profile的修改
如果要使用Notification或Indification方法,必须在Profile中添加configuration,如下:
其中, clientCharCfgUUID值如下,它是uint16类型的值,具体表示为GATT_CLIENT_CHAR_CFG_UUID宏的值
#define GATT_CLIENT_CHAR_CFG_UUID 0x2902
说白了,上面在profile中添加的configuration的UUID为GATT_CLIENT_CHAR_CFG_UUID (0x2902),主机若一搜到就知道它指的是什么了(当然是notification)
需要主机的client端对它进行打开通知操作后,从机才能notification通知到主机client.
B 初始化这个client配置特征表
当然是调用这个了。不过在例程中并不是直接调用,而是在回调函数中被执行调用。
上面这个函数是个回调函数,它是在下面函数中注册的。
linkDB_Register()函数中,simpleProfile_HandleConnStatusCB作为参数进行注册。
下面看看linkDB_Register接口的含义:
也就是说当底层的链路连接状态发生变化时回调函数就会被执行,也就是说,如果未来主从建立连接,断开连接等状态,此回调函数就会被触发,而在回调中继续执行client配置表的初始化操作。
虽然过程比较曲折,不过最终目标是执行了初始化。
C Client端需要打开Server端的Notification通知功能。
这里当然不是讲在client如何打开这个通知。而是Server端在接收到这个打开通知请求后的处理流程。需要弄明白以下几个问题:
(1)client什么时候打开这个通知? ---anytime.... 一般连接建立后,根据具体的业务,找到它的Handle后直接打开
(2)client通过什么方式打开? ----当然是要发数据包了,当然是发write命令
(3)client对什么write? ----- 还记得上面提到的GATT_CLIENT_CHAR_CFG_UUID(0x2902)吗?通过这个UUID找到它的HANDLE,然后对这个Handle进行写操作。
上面几个问题弄几白了,后面思路就清楚了,既然是对Server进行write,那么Server的Write回调将会被执行。
TI CC2541软件开发指南中有如下英文描述,上面执行的代码就是打开通知。GATT_CLIENT_CFG_NOTIY宏为0x0001
一旦操作成功后,如果Server要想主动的给Client发数据,只需要调用SimpleProfile_SetParameter方法即可。
D Server端主动通知Client
下面来看看这个方法的实现:
如果是操作CHAR4,则会调用GATTServApp_ProcessCharCfg()方法,这是一个间接的notification方式。
注:上面代码中最好加入是否添加NOTIFICATION开关通知的判断,如果client没有打开,则不允许主动通知
value = GATTServApp_ReadCharCfg( connHandle, simpleProfileChar6Config );//读出CCC的值
if ( value & GATT_CLIENT_CFG_NOTIFY ) //判断是否打开通知开关,打开了则发送数据
{
noti.handle = simpleProfileAttrTbl[ATTRTBL_CHAR6_IDX].handle;
noti.len = len;
osal_memcpy( noti.value, pValue, len); //数据
GATT_Notification( connHandle, ¬i, FALSE );
}
E Server端实例演示,代码如下:
二、修改主机端代码(Client)
A 通过Server端Client Config的UUID获取其Handle
使用接口GATT_DiscCharsByUUID()来获取相应的Handle
B 开启Notification功能
使用接口GATT_WriteCharValue
前期先通过A操作获取到对应的Handle,这个handle一般是characteristic value的handle+1,句柄的顺序是characteristic declaration, characteristic value, 然后是 CCC.
CCC是指Client Characteristic Configuration 的这个descriptor.
下面是个例子:
attWriteReq_t writeReq;
writeReq.handle = 0x002f;
writeReq.len = 2;
writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); // 0x01 【1:开启Notification 0:关闭Notify】
writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY); // 0x00 【1:开启Indification 0:关闭Indi】
writeReq.sig = 0;
writeReq.cmd = 0;
GATT_WriteCharValue( simpleBLEConnHandle, &writeReq, simpleBLETaskId );
C 接收来自Server的Notification消息
当Client端接收到来自对方的消息,系统会产生一个事件GATT_MSG_EVENT告之,
方法如下:
static void simpleBLECentralProcessGATTMsg( gattMsgEvent_t *pMsg )所有通过蓝牙发送的数据都会让GATT这个函数来处理.因此,发送的数据就到这里了。gattMsgEvent_t是个很大的联合体代码中都有注释,只要找到相应的结构体就行了。
typedef union
{
// Request messages
attExchangeMTUReq_t exchangeMTUReq; //!<
ATT Exchange MTU Request
attFindInfoReq_t findInfoReq; //!<
ATT Find Information Request
attFindByTypeValueReq_t findByTypeValueReq; //!<
ATT Find By Type Vaue Request
attReadByTypeReq_t readByTypeReq; //!<
ATT Read By Type Request
attReadReq_t readReq; //!<
ATT Read Request
attReadBlobReq_t readBlobReq; //!<
ATT Read Blob Request
attReadMultiReq_t readMultiReq; //!<
ATT Read Multiple Request
attReadByGrpTypeReq_t readByGrpTypeReq; //!<
ATT Read By Group Type Request
attWriteReq_t writeReq; //!<
ATT Write Request
attPrepareWriteReq_t prepareWriteReq; //!<
ATT Prepare Write Request
attExecuteWriteReq_t executeWriteReq; //!<
ATT Execute Write Request
gattReadByTypeReq_t gattReadByTypeReq; //!<
GATT Read By Type Request
gattWriteLongReq_t gattWriteLongReq; //!<
GATT Long Write Request
gattReliableWritesReq_t gattReliableWritesReq; //!< GATT Reliable Writes Request
// Response messages
attErrorRsp_t errorRsp; //!<
ATT Error Response
attExchangeMTURsp_t exchangeMTURsp; //!<
ATT Exchange MTU Response
http://blog.csdn.net/ab198604
一、修改从机端代码(Server端):
A 对Profile的修改
如果要使用Notification或Indification方法,必须在Profile中添加configuration,如下:
其中, clientCharCfgUUID值如下,它是uint16类型的值,具体表示为GATT_CLIENT_CHAR_CFG_UUID宏的值
#define GATT_CLIENT_CHAR_CFG_UUID 0x2902
说白了,上面在profile中添加的configuration的UUID为GATT_CLIENT_CHAR_CFG_UUID (0x2902),主机若一搜到就知道它指的是什么了(当然是notification)
需要主机的client端对它进行打开通知操作后,从机才能notification通知到主机client.
B 初始化这个client配置特征表
当然是调用这个了。不过在例程中并不是直接调用,而是在回调函数中被执行调用。
上面这个函数是个回调函数,它是在下面函数中注册的。
linkDB_Register()函数中,simpleProfile_HandleConnStatusCB作为参数进行注册。
下面看看linkDB_Register接口的含义:
也就是说当底层的链路连接状态发生变化时回调函数就会被执行,也就是说,如果未来主从建立连接,断开连接等状态,此回调函数就会被触发,而在回调中继续执行client配置表的初始化操作。
虽然过程比较曲折,不过最终目标是执行了初始化。
C Client端需要打开Server端的Notification通知功能。
这里当然不是讲在client如何打开这个通知。而是Server端在接收到这个打开通知请求后的处理流程。需要弄明白以下几个问题:
(1)client什么时候打开这个通知? ---anytime.... 一般连接建立后,根据具体的业务,找到它的Handle后直接打开
(2)client通过什么方式打开? ----当然是要发数据包了,当然是发write命令
(3)client对什么write? ----- 还记得上面提到的GATT_CLIENT_CHAR_CFG_UUID(0x2902)吗?通过这个UUID找到它的HANDLE,然后对这个Handle进行写操作。
上面几个问题弄几白了,后面思路就清楚了,既然是对Server进行write,那么Server的Write回调将会被执行。
TI CC2541软件开发指南中有如下英文描述,上面执行的代码就是打开通知。GATT_CLIENT_CFG_NOTIY宏为0x0001
一旦操作成功后,如果Server要想主动的给Client发数据,只需要调用SimpleProfile_SetParameter方法即可。
D Server端主动通知Client
下面来看看这个方法的实现:
如果是操作CHAR4,则会调用GATTServApp_ProcessCharCfg()方法,这是一个间接的notification方式。
注:上面代码中最好加入是否添加NOTIFICATION开关通知的判断,如果client没有打开,则不允许主动通知
value = GATTServApp_ReadCharCfg( connHandle, simpleProfileChar6Config );//读出CCC的值
if ( value & GATT_CLIENT_CFG_NOTIFY ) //判断是否打开通知开关,打开了则发送数据
{
noti.handle = simpleProfileAttrTbl[ATTRTBL_CHAR6_IDX].handle;
noti.len = len;
osal_memcpy( noti.value, pValue, len); //数据
GATT_Notification( connHandle, ¬i, FALSE );
}
E Server端实例演示,代码如下:
二、修改主机端代码(Client)
A 通过Server端Client Config的UUID获取其Handle
使用接口GATT_DiscCharsByUUID()来获取相应的Handle
B 开启Notification功能
使用接口GATT_WriteCharValue
前期先通过A操作获取到对应的Handle,这个handle一般是characteristic value的handle+1,句柄的顺序是characteristic declaration, characteristic value, 然后是 CCC.
CCC是指Client Characteristic Configuration 的这个descriptor.
下面是个例子:
attWriteReq_t writeReq;
writeReq.handle = 0x002f;
writeReq.len = 2;
writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); // 0x01 【1:开启Notification 0:关闭Notify】
writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY); // 0x00 【1:开启Indification 0:关闭Indi】
writeReq.sig = 0;
writeReq.cmd = 0;
GATT_WriteCharValue( simpleBLEConnHandle, &writeReq, simpleBLETaskId );
C 接收来自Server的Notification消息
当Client端接收到来自对方的消息,系统会产生一个事件GATT_MSG_EVENT告之,
方法如下:
static void simpleBLECentralProcessGATTMsg( gattMsgEvent_t *pMsg )所有通过蓝牙发送的数据都会让GATT这个函数来处理.因此,发送的数据就到这里了。gattMsgEvent_t是个很大的联合体代码中都有注释,只要找到相应的结构体就行了。
typedef union
{
// Request messages
attExchangeMTUReq_t exchangeMTUReq; //!<
ATT Exchange MTU Request
attFindInfoReq_t findInfoReq; //!<
ATT Find Information Request
attFindByTypeValueReq_t findByTypeValueReq; //!<
ATT Find By Type Vaue Request
attReadByTypeReq_t readByTypeReq; //!<
ATT Read By Type Request
attReadReq_t readReq; //!<
ATT Read Request
attReadBlobReq_t readBlobReq; //!<
ATT Read Blob Request
attReadMultiReq_t readMultiReq; //!<
ATT Read Multiple Request
attReadByGrpTypeReq_t readByGrpTypeReq; //!<
ATT Read By Group Type Request
attWriteReq_t writeReq; //!<
ATT Write Request
attPrepareWriteReq_t prepareWriteReq; //!<
ATT Prepare Write Request
attExecuteWriteReq_t executeWriteReq; //!<
ATT Execute Write Request
gattReadByTypeReq_t gattReadByTypeReq; //!<
GATT Read By Type Request
gattWriteLongReq_t gattWriteLongReq; //!<
GATT Long Write Request
gattReliableWritesReq_t gattReliableWritesReq; //!< GATT Reliable Writes Request
// Response messages
attErrorRsp_t errorRsp; //!<
ATT Error Response
attExchangeMTURsp_t exchangeMTURsp; //!<
ATT Exchange MTU Response
相关文章推荐
- 关于“C++语言程序设计”书的一个类
- html5支持自定义标签保存值
- Unity世界坐标与屏幕坐标之间如何转换
- C++的动态库和静态库(dll)
- mysql 主主互备
- 番茄工作法不适合程序开发
- PAT-B 1016. 部分A+B
- HTML5触摸界面的程序设计
- JQuery中Ajax的操作
- 多位数乘多位数
- maven 学习---使用Maven创建Java项目
- fedora 的截图快捷键
- 团队作业五
- LA 4725 Airport
- Unity ScreentoWorldPoint中的z坐标说明
- 数据存储单位
- 笔试题42. LeetCode OJ (29)
- 这是作业!
- 架构漫谈读书笔记
- Javascript创建XMLHttpRequest对象的3种方式