浅谈 BLE 控制点属性

一、概述

蓝牙产品在开发过程中,常常会涉及到低功耗的处理,在没有数据需要上报或者设备断开蓝牙的情况下,可能需要对设备进行功耗上的优化,那么,有没有一种情况是可以实现主机端对设备通知进入 Suspend 的呢? 当然有,那就是 HID Control Point。以下我们就来讲控制点属性这一概念,大多数人可能会觉得比较陌生,简单来说,它可以应用在 HID 蓝牙设备上,例如蓝牙键盘或鼠标,仅当主机端支持挂起模式时,主机可以通过该特性通知设备去进入挂起模式。

二、应用场景

在 HID 键鼠产品开发中,我们所涉及到的控制点属性主要有 Service Change 和 HID Control Point,前者主要是需要向连接设备指示服务已经更改(即添加、删除或修改)。本文主要讲的是 HID Control Point,该控制点属性是不能读取,但只能写入、通知或指示,这些属性可以被更改层使用来启用设备特定的过程,例如命令的写入或设备上给定过程完成时的指示。比如在蓝牙键盘与 MAC 电脑连接时,MAC 电脑进入睡眠后,会通过该特性给键盘端发一个 Suspend 的通知,如果在特定时间内用 MAC 电脑键盘唤醒电脑,MAC 电脑也会给键盘端发送一个 Exit Suspend 的通知,告知设备现在主机已退出睡眠,在整个流程中,键盘是始终与 MAC 电脑保持蓝牙连接的,也是与一般 Windows 电脑不同的一点。

三、规范要求说明

控制点特性是通过客户端即主机端去向该服务写入值的,服务会将这个立即使用写入的值,在其被消耗之后不必存储该值。简单理解就是一个即时通知的属性,设备并不用理会是哪个主机对控制点发号施令的,只需按照写入控制点的指令进行操作即可。

HID Control Point 特性用来指示 HID Host 的状态,由下图可知,在被写入 0x00 时通知 HID Device,此时 HID Host 进入了挂起状态。在写入 0x01 时通知 HID DEVICE,此时 HID Host 退出了挂起状态。协议中规定了设备时不需要接收该状态指示命令后对主机进行回复的,所以其特性权限需要设定为 gGattCharPropWriteWithoutRsp_c。


图一

对于 WriteWithoutResponse 权限要求,当使用该权限 (ATT Write Command) 写入属性时触发 gEvtAttributeWrittenWithoutResponse c。因为这个过程不需要响应,所以应用程序可以处理它,如果必要的话,还可以将它写入数据库。不管该值是否有效,应用程序都不需要响应。挂起操作允许蓝牙 HID Host 明确地通知蓝牙 HID Device不再需要正常的性能,并且它可以下电不需要唤醒系统的逻辑,这时 HID Device 可以进入休眠状态或者选择性地断开与 HID Host 的连接,这取决于应用程序的设定。

查看《HID over GATT Profile Specification》文档的 HID Host 要求和行为章节可知,如果 HID Host 支持挂起模式,那么其 HID Device 也必须支持 HID Control Point特性。


图二


四、代码示例

在 NXP QN9080 BLE HID Device 例程中,它实现了蓝牙鼠标的基本功能,可以通过查看 gatt_db.h 文件能够发现设备端支持 HID Control Point 特性,如下所示:

    CHARACTERISTIC(char_hid_control_point, gBleSig_HidCtrlPoint_d, (gGattCharPropWriteWithoutRsp_c) )
VALUE(value_hid_control_point, gBleSig_HidCtrlPoint_d, (gPermissionFlagWritable_c), 1, 0x00)

在 BleApp_GattServerCallback 函数中我们可以找到该特性对应的回调函数事件,即 gEvtAttributeWrittenWithoutResponse_c,事件中会将从主机下发的特性值

传到相应的处理函数中。

static void BleApp_GattServerCallback (deviceId_t deviceId, gattServerEvent_t* pServerEvent)

{
uint16_t handle;
uint8_t status;

switch (pServerEvent->eventType)
{
case gEvtAttributeWritten_c:
case gEvtAttributeWrittenWithoutResponse_c:
{
handle = pServerEvent->eventData.attributeWrittenEvent.handle;
status = (uint8_t)gAttErrCodeNoError_c;

if (handle == (uint16_t)value_hid_control_point)
{
status = Hid_ControlPointHandler((uint16_t)service_hid, pServerEvent->eventData.attributeWrittenEvent.aValue[0]);
}
(void)GattServer_SendAttributeWrittenStatus(deviceId, handle, status);
}
break;
default:
; /* For MISRA Compliance */
break;
}
}

通过该特性值可以指示设备进入 gHid_Suspend_c 或 gHid_ExitSuspend_c 事件,即主机处于挂起状态或者主机退出挂起状态的情况。

uint8_t Hid_ControlPointHandler(uint16_t serviceHandle, hidControlPointValues_t value)
{
uint8_t retStatus = (uint8_t)gAttErrCodeNoError_c;

switch (value)
{
case gHid_Suspend_c:
break;

case gHid_ExitSuspend_c:
break;

default:
retStatus = (uint8_t)gAttErrCodeRequestNotSupported_c;
break;
}

return retStatus;
}

我们可以在相应函数下添加打印事件去观察结果,目前发现只有 MAC 电脑支持该挂起模式,所以用 MAC 电脑来测试该特性。以下为开发板和 MAC 电脑在测试中的打印结果:

[14:34:08.333]收一>ADV
[14:34:22.710]收<-Bas_RecordBatteryieasurement
[14:34:25.730]收<-gEytAttributeWrittenWithoutResponse_c: gHid Suspend_c
[14:36:05.543]收<-gvtAttributeWrittenWithoutResponse_c: gHid Suspend_c
[14:36:37.930]收<-gEytAttributeWrittenWithoutResponse_c: gHid Suspend c
[14:38:07.013]收<-PB2
[14:38:08.681]收<-Bas RecordBatterylleasurement
[14:38:16.828]收<-gEytAttributeWrittenWithoutResponse_c: gHid Suspend_c
[14:38:22.262]收<-gEvtAttributeWrittenWithoutResponse_c: gHid ExitSuspend_c
[14:38:26.806]收<-EvtAttributeWrittenWithoutResponse_c: gHid Suspend_c
[14:38:37.090]收<-gEvtAttributeWrittenWithoutResponse_c: gHid ExitSuspend c
[14:38:40.409]收<-Bas RecordBatteryleasurement
[14:38:42.782]收<-gEvtAttributeWrittenWithoutResponse_c: gHid Suspend_c
[14:38:55.258]收<-gEytAttributeWrittenWithoutResponse_c: gHid ExitSuspend c
[14:39:00.028]收<-gEytAttributeWrittenWithoutResponse_c: gHid Suspendc

由于该特性不能读取,只能写入,设备端是只能够被动接收该值的,我们也可以看到每一次主机端进入挂起状态或退出挂起状态时都会触发相应的事件。

五、总结

通过以上讲解,相信大家对控制点属性已经有了初步的理解,以后可能会有越来越多的设备支持这一挂起模式,所以我们的蓝牙设备端也是需要去兼容这部分功能的。

六、参考资料

【1】HID_BLE_GATT.PDF

【2】HIDS_SPEC_V10.PDF

【3】低功耗蓝牙开发权威指南(中文版).PDF

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论