Windows 笔无缝配对实施指南

注意

本文档详细介绍了协议实施,以便通过 Windows 11 上的笔数字化器实现兼容传感器的无缝蓝牙配对。 本实施指南与笔传感器和笔数字化器之间使用的笔协议无关,但实施可以选择使用任何具有上行链路功能的笔协议,以促进此处所述的相关参数的交换。

设备分类

无缝蓝牙配对支持是 Windows 上笔设备类的扩展。 本实施指南将添加到现有的笔设备实施指南中,重点介绍如何在主机和笔传感器之间实施必要的参数交换。

设备总线连接

请参阅以下先决条件指南:协议实施 (pen-protocol-implementation) | Microsoft Docs

需要对 HID 协议有很好的理解才能理解此处提供的信息。 有关 HID 协议的信息,请参阅以下资源:

Windows 包括 HID 类驱动程序和相应的微型端口驱动程序 HID I²C、HID SPI、HID USB 和 HID BTH 微型端口驱动程序,因此不需要任何第三方微型端口驱动程序。

笔数字化器固件只需要报告本主题中描述的使用情况。 Windows 将利用兼容的固件及其自己的收件箱驱动程序来支持无缝配对体验。

下面的示例报告描述符部分提供了示例描述符。

所需顶级 HID 集合

Required top level HID collection for seamless pairing

能够支持无缝配对的笔数字化器应提供一个顶级集合 (TLC),该集合显示为特定于供应商(页面 0xFFF4、使用情况 0x01)。 这应该是集成 Windows 笔集合的同级 TLC。

数字化器选择加入无缝配对的 INF 修饰

鉴于在本实施指南中使用 Microsoft 供应商特定的 HID 使用情况,笔数字化器必须显式选择加入,以允许 OS 与相应的 TLC 通信来将其公开。 下面应以与笔数字化器设备相对应的等效扩展 INF 提供。 以下设备属性的存在将指示选择该等加入。

[Digitizer_Device.NT.Interfaces] AddInterface = {4D1E55B2-F16F-11CF-88CB-001111000030},,Digitizer_Device.AddInterface

[Digitizer_Device.AddInterface] AddProperty = Digitizer_Device.AddProperty

[Digitizer_Device.AddProperty] ; DEVPKEY_BluetoothOobCouplingChannel_OptInForUse {FE683ED0-DE80-4766-B422-4195993F4330}, 2, 0x11, , 1

设备功能报告(使用情况 0x16)

这是一个双向功能报告,这意味着主机应在枚举时将其功能传达给数字化器,然后查询数字化器的功能。 设备功能报告中应存在以下使用情况,以传达数字化器或主机能够支持无缝对式笔传感器。

此功能报告将在枚举时发送并随后检索。

成员 说明 ID 必需/可选
支持无缝对 指示数字化器是否能够支持无缝对式笔传感器(位标志,其中 1 指示功能) 0xFFF4 0x10 必需

设备蓝牙报告(使用情况 0x13)

设备蓝牙报告中应存在以下使用情况,该报告将传达与笔传感器集成的蓝牙无线电的相关参数。

仅在支持无缝对的传感器在范围内并验证是否已完成与主机的现有配对关系后,才会发送此输入报告一次。

成员 说明 ID 必需/可选
设备蓝牙地址 与传感器中的无线电关联的 48 位蓝牙 MAC 地址 0xFFF4 0x02 必需
设备蓝牙地址类型 指示设备蓝牙地址是否不是公共地址 0xFFF4 0x08 必需
主机配对存在 指示传感器是否已与此主机存在现有配对 0xFFF4 0x11 必需

必需使用情况

设备蓝牙地址

此使用情况应为 6 个字节,其中包含与集成到笔传感器中的蓝牙无线电关联的 48 位 MAC 地址。 即 11:22:33:44:55:66

设备蓝牙地址类型

此使用情况应为一个标志,指示设备蓝牙地址使用情况是否应由主机解释为由标志清除 = 0 指示的公共,或标志集 = 1 指示的随机。

支持无缝对的传感器在范围内

此使用情况应为一个标志,指示支持无缝配对的传感器现在是否在标志集 = 1 指示为 TRUE 的笔数字化器范围内。 如果传感器在范围外或范围内的传感器不支持无缝配对,则不应生成整个输入报告。

主机配对存在

此使用情况应为一个标志,指示支持无缝的传感器是否在范围内并且已与此主机建立配对关系。 这由标志集 = 1 表示为 TRUE。 如果与此主机不存在配对关系,则此标志应为清除 = 0。

主机蓝牙报告(使用情况 0x06)

主机蓝牙报告中应存在以下使用情况,该报告传达有关主机蓝牙无线电的相关参数。

成员 说明 ID 必需/可选
主机蓝牙地址 与主机无线电关联的 48 位蓝牙 MAC 地址 0xFFF4 0x03 必需
主机蓝牙地址类型 指示主机蓝牙地址是否为公共地址 0xFFF4 0x09 必需

必需使用情况

主机蓝牙地址

此使用情况应为 6 个字节,其中包含与主机蓝牙无线电关联的 48 位 MAC 地址。 即 11:22:33:44:55:66

主机蓝牙地址类型

此使用情况应为一个标志,指示主机蓝牙地址使用情况是否应由数字化器和传感器解释为由标志清除 = 0 指示的公共,或标志集 = 1 指示的随机。 注意:在 Windows 上,这始终应为公共类型,标志为清除 = 0。

配对密钥报告(使用情况 0x15)

成员 说明 ID 必需/可选
主机配对密钥 主机提供的 128 位配对密钥 0xFFF4 0x14 必需
设备蓝牙地址 与传感器中的无线电关联的 48 位蓝牙 MAC 地址 0xFFF4 0x02 必需
设备蓝牙地址类型 指示设备蓝牙地址是否不是公共地址 0xFFF4 0x08 必需

必需使用情况

主机配对密钥

此使用情况应为 16 个字节,其中包含主机签发的 128 位临时配对密钥,以方便以前报告的支持传感器的无缝配对。 如果主机已锁定/受保护或不支持无缝配对,则主机永远不会签发配对密钥报告。

设备蓝牙地址

这与上述设备蓝牙报告的使用情况相同,但主机使用此报告来指示在一个数字化器同时支持多个支持蓝牙的笔的场景中,此报告中主的机配对密钥与之关联的蓝牙设备。

设备蓝牙地址类型

这与上述设备蓝牙报告具有相同的使用情况,与设备蓝牙地址一起使用,作为主机配对密钥索引编制的一部分。

预期序列

1. 枚举

在 Windows 10 或 Windows 11 OS 上,Microsoft [供应商特定] 蓝牙带外集合将在枚举后由内置 OS 服务打开。 然后,主机将使用主机蓝牙地址和主机蓝牙地址类型签发主机蓝牙报告 SET FEATURE。 然后,主机还会针对设备功能报告签发 GET FEATURE。 如果数字化器未返回此报告或返回 0,则不会执行与无缝配对相关的其他操作。

2. 支持无缝的笔在范围内

一旦支持无缝的笔进入数字化器的范围,并且已确定与主机蓝牙地址的任何现有配对关系,则设备蓝牙输入报告应一次性签发所有必需使用情况。

注意

如果在数字化器范围内的笔不支持无缝,则不得签发任何输入报告。 如果支持无缝对的笔不在范围内,则无法通过此报告指示不在范围内。 支持无缝的给定设备的状态机应在每次收到输入报告时使用其蓝牙地址重置。

数字化器固件如何从传感器获取涉及设备蓝牙地址的参数的机制特定于笔协议,并在内部由相应的规范(即 MPP 2.6、AES 2.1)定义

3. 主机配对密钥生成

如果设备蓝牙报告指示笔在范围内没有与此主机的现有配对关系,并且主机未锁定/安全时,则应根据设备蓝牙地址生成临时配对密钥。 然后,主机应签发包含主机配对密钥的配对密钥输出报告。

注意

在 Windows 10 上,OS 服务不支持无缝配对,因此永远不会提供主机配对密钥,因此永远不会签发此输出报告。

数字化器固件如何为传感器的蓝牙无线电提供临时配对密钥的机制特定于笔协议,并且在内部由相应的规范(即 MPP 2.6、AES 2.1)定义

4. 配对

主机签发带配对密钥的输出报告后,它将等待长达 30 秒的播发。 然后,笔的蓝牙连接应将可连接的定向播发发送到主机蓝牙无线电,形成连接,然后允许主机启动指定 OOB(带外)方法的配对仪式。 此时,笔的蓝牙无线电将验证主机地址是否与其收到的主机地址相同(通过 SET FEATURE 报告),然后提供适当的配对响应,包括临时密钥。 主机蓝牙无线电将验证临时密钥,成功后,笔和主机将交换会话加密密钥并完成配对仪式。

如果配对成功,下次笔重新进入范围内时,设备蓝牙输入报告应指示主机配对存在 = 1 (TRUE)。

示例报告描述符

//Microsoft Bluetooth Out-of-Band TLC
0x06, 0xF4, 0xFF, // Usage Page (Vendor Defined 0xFFF4)
0x09, 0x01, // Usage (0x01)
0xA1, 0x01, // Collection (Application)
		
0x09, 0x16, // USAGE (Device Capability Report)
0xA1, 0x02, // COLLECTION (Logical)
0x85, 0x70, // REPORT_ID (0x70)
0x09, 0x10, // USAGE (Seamless Pair Capable) 
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x01, // REPORT_COUNT (1)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0xB1, 0x02, // FEATURE (Data,Var,Abs)
0x75, 0x07, // REPORT_SIZE (7)
0x95, 0x01, // REPORT_COUNT (1)
0xB1, 0x01, // FEATURE (Const,Var,Abs)
0xC0, // END_COLLECTION
		
0x09, 0x06, // USAGE (Host Bluetooth Report)
0xA1, 0x02, // COLLECTION (Logical)
0x85, 0x56, // REPORT_ID (0x56)
0x09, 0x03, // USAGE (Host Bluetooth Address)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0xFF, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x06, // REPORT_COUNT (6)
0xB2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf) 
0x09, 0x09, // USAGE (Host Bluetooth Address Type) 
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x01, // REPORT_COUNT (1)
0xB1, 0x02, // FEATURE (Data,Var,Abs)
0x75, 0x07, // REPORT_SIZE (7)
0x95, 0x01, // REPORT_COUNT (1)
0xB1, 0x01, // FEATURE (Cnst,Ary,Abs)	 
0xC0, // END_COLLECTION
		
0x09, 0x13, // USAGE (Device Bluetooth Report)
0xA1, 0x02, // COLLECTION (Logical)
0x85, 0x6E, // REPORT_ID (0X6E)
0x09, 0x02, // USAGE (Device Bluetooth Address)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0xFF, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x06, // REPORT_COUNT (6)
0x82, 0x02, 0x01, // INPUT (Data,Var,Abs,Buf)
0x09, 0x08, // USAGE (Device Bluetooth Address Type) 
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x01, // REPORT_COUNT (1) 
0x81, 0x02, // INPUT (Data,Var,Abs) 
0x09, 0x11, // USAGE (Host Pairing Exists)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x01, // REPORT_COUNT (1) 
0x81, 0x02, // INPUT (Data,Var,Abs)
0x75, 0x06, // REPORT_SIZE (6) [PADDING]
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x01 // INPUT (Cnst,Ary,Abs)
0xC0, // END_COLLECTION
		

0x09, 0x15, // USAGE (Pairing Key Report) 
0xA1, 0x02, // COLLECTION (Logical)
0x85, 0x6f, // REPORT_ID (0X6F)
0x09, 0x02, // USAGE (Device Bluetooth Address)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x06, // REPORT_COUNT (6)
0x92, 0x02, 0x01, // OUTPUT (Data,Var,Abs,Buf)
0x09, 0x08, // USAGE (Device Bluetooth Address Type)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x01, // REPORT_COUNT (1)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x75, 0x07, // REPORT_SIZE (7)
0x95, 0x01, // REPORT_COUNT (1)
0x91, 0x01, // OUTPUT (Cnst,Ary,Abs)
0x09, 0x14, // USAGE (Temporary Key)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0xFF, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x10, // REPORT_COUNT (16)
0x92, 0x02, 0x01, // OUTPUT (Data,Var,Abs,Buf)
0xC0, // END_COLLECTION