上文中创建了GATT客户端YQS_C,本文深入代码,理解它的实现脉络。
阅读本文前,请先阅读“解读自定义GATT服务”一文。
(1)通用和定制
nrf connect是一个通用的主机程序,它能够扫描、连接任何从机设备,并能发现、解析任意的GATT服务。
实现这样的通用主机程序,逻辑比较复杂,需要依次发现所有的服务,再发现每个服务下的特征,再发现每个特征下的描述符。
实际中更常见的是针对某个GATT服务所做的GATT客户的,比如nus对应的nus_c,hrs对应的hrs_c。
实现这样的定制主机程序,逻辑比较简单,而且可以充分利用SDK中的ble_db_discovery库函数。
我们这里讨论的是定制的主机程序,针对yqs设计相应的yqs_c程序。
(2)UUID
先确定基础UUID,与YQS的基础UUID一致。
利用函数sd_ble_uuid_vs_add
写入协议栈,并利用函数ble_db_discovery_evt_register
注册到ble_db_discovery中。
(3)Discovery事件处理
Discovery事件会订阅到main.c –> db_disc_handler中。
处理函数为ble_yqs_c_on_db_disc_evt
。实际运行时,仅关注一个事件:BLE_DB_DISCOVERY_COMPLETE
,即发现GATT完毕事件。
在该事件中,可以读取YQS从设备的GATT服务和特征的全部信息,包括:
- 服务的UUID
- 该服务的句柄范围(该范围的第一个值为服务句柄)
- 特征的数目
- 各个特征的句柄、UUID、属性、值
- 描述符的句柄
(4)基础事件处理
所谓基础事件包括连接、断开等。
(5)发送数据
发送数据即对指定的Char Handle执行write:sd_ble_gattc_write
,其中的write_op参数将决定是执行write 还是write no response。
(6)使能CCCD
实际上,使能CCCD就是向CCCD Handle执行write操作。write的数据内容为{0x00, 0x01}。
(7)接收数据
只有使能的从机的CCCD以后,才可以接收数据。
接收数据后主机端产生BLE_GATTC_EVT_HVX
事件,进一步触发on_hvx回调函数。
在该函数中可以获得收到的数据内容。
(8)声明YQS_C
与GATT服务端类似,也需要先进行声明:BLE_YQS_C_DEF(m_ble_yqs_c);
。
(9)初始化YQS_C
在系统初始化阶段,初始化YQS_C:yqs_c_init
。
初始化过程中会关联事件回调函数,以告诉系统一些关键事件节点。
(10)初始化Discovery
对于主机而言,Discovery是一个特殊操作, 在函数db_discovery_init
中进行专门的初始化。
(完)