在蓝牙设备互联互通的世界里,当一款蓝牙键盘想要连接电脑,或是蓝牙鼠标尝试配对平板时,它们首先要解决一个关键问题:如何让对方知道自己是谁、支持什么功能?这就像两个陌生人初次见面,需要交换名片来建立初步认知。而在蓝牙HID(人机接口设备)体系中,承担数字名片功能的核心协议正是SDP(Service Discovery Protocol,服务发现协议)。
目录
[2.1 蓝牙HID设备的SDP义务](#2.1 蓝牙HID设备的SDP义务)
[2.2 蓝牙HID主机的SDP能力](#2.2 蓝牙HID主机的SDP能力)
[3.1 核心强制属性:设备的必备身份信息](#3.1 核心强制属性:设备的必备身份信息)
[3.2 重要可选属性:设备的扩展能力说明](#3.2 重要可选属性:设备的扩展能力说明)
[3.3 已废弃属性:协议演进的痕迹](#3.3 已废弃属性:协议演进的痕迹)
[4.1 设备发现阶段](#4.1 设备发现阶段)
[4.2 服务查询阶段](#4.2 服务查询阶段)
[4.3 连接建立阶段](#4.3 连接建立阶段)
SDP协议为蓝牙HID设备和主机搭建了沟通的桥梁,它定义了设备如何声明自身能力、主机如何查询这些信息,是实现设备兼容性和互操作性的基础。本文从SDP的核心作用出发,深入剖析其在蓝牙HID中的实现细节、关键属性及实际应用场景,真正理解这个看不见的沟通使者。
一、SDP的核心定位:为什么它是蓝牙HID通信的前置条件
在深入技术细节之前,我们先搞清楚一个核心问题: SDP 协议到底解决了什么痛点?
蓝牙HID设备的种类繁多,从常见的键盘、鼠标,到游戏手柄、遥控器,再到工业场景中的温度传感器、电压表,不同设备的功能、通信方式、数据格式千差万别。如果没有统一的服务发现机制,主机(如电脑、手机)就无法识别连接的设备类型,更无法知道如何与其通信------就像一个不懂外语的人收到了一封加密信件,既不知道是谁寄的,也不知道如何解读。
SDP协议的出现正是为了解决这个问题。它的核心作用可以概括为三点:
设备身份声明:蓝牙HID设备通过SDP记录,向外界宣告自己的设备类型(如键盘/鼠标)、支持的协议(如Report Protocol/Boot Protocol)、通信参数等关键信息;
主机查询匹配:蓝牙HID主机通过SDP协议,主动查询周边设备的服务记录,筛选出符合自身需求的HID设备;
通信参数协商:SDP记录中包含了L2CAP通道配置、PSM(协议/服务多路复用器)值等关键参数,为后续的数据传输奠定基础。
形象地说,SDP就像是蓝牙HID设备的产品说明书,而SDP协议则是说明书的读取规则。没有这个规则,主机和设备就无法完成初始对话,后续的连接和数据传输也就无从谈起。
值得注意的是,SDP协议并非蓝牙HID专属,而是蓝牙体系中的通用协议,但在HID场景中,它被赋予了特定的属性和格式,以适配人机交互设备的特殊需求。这也是为什么蓝牙HID规范会专门用一个小节详细定义SDP的实现要求。
二、SDP的实现基础:设备与主机的核心要求
要实现SDP功能,蓝牙HID设备和主机需要满足一系列规范要求,这些要求是保证互操作性的关键。
2.1 蓝牙HID设备的SDP义务
作为服务的提供者,蓝牙HID设备必须实现SDP服务器功能,其核心要求包括:
必须维护一个SDP数据库,包含至少所有强制要求的HID服务属性(后续详细介绍);
必须同时实现设备识别规范(Device Identification Profile),与SDP服务形成互补;
当设备处于可发现模式(Discoverable Mode)时,除非超时,否则不能在SDP连接建立和关闭后退出可发现模式------这保证了主机有足够时间查询设备信息;
SDP数据库中的服务记录必须准确反映设备的实际能力,不能虚假声明。
这些要求看似简单,实则直接影响用户体验。比如,如果设备在主机查询过程中突然退出可发现模式,就会导致配对失败,让用户误以为设备存在故障。
2.2 蓝牙HID主机的SDP能力
作为服务的查询者,蓝牙HID主机的SDP要求根据主机类型有所区别:
通用蓝牙HID主机(如电脑):必须实现SDP客户端功能,能够解析设备返回的SDP记录,提取关键属性(如设备类型、协议支持情况);
有限蓝牙HID主机(如专用游戏设备):可以不实现完整的SDP客户端,通过直接尝试打开HID控制通道(PSM=0x0011)来判断对方是否为HID设备;
仅支持Boot协议的主机:可以通过发送SET_PROTOCOL命令来判断设备是否支持Boot协议,无需解析复杂的SDP属性。
无论哪种主机,都必须能正确处理设备返回的SDP记录------对于无法识别的属性或字段,应直接忽略而不是中断查询流程,这体现了协议的兼容性设计思想。
三、SDP服务记录:蓝牙HID设备的身份说明书详解
SDP的核心是服务记录(Service Record),它是设备所有能力的结构化描述。蓝牙HID规范定义了完整的服务记录属性集,分为强制属性(Mandatory)和可选属性(Optional),下面我们逐一解析关键属性的作用和含义。



3.1 核心强制属性:设备的必备身份信息
这些属性是每款蓝牙HID设备必须声明的,缺少任何一个都会导致主机无法正确识别设备。
3.1.1 服务类别ID列表(Service Class ID List)
该属性用于明确设备所属的服务类别,蓝牙HID设备的服务类别UUID为0x1124(HID设备服务)。这是主机识别HID设备的首要依据------当主机搜索周边蓝牙设备时,会优先筛选出服务类别包含0x1124的设备。
3.1.2 协议描述符列表(Protocol Descriptor List)
这是SDP记录中最关键的属性之一,定义了设备与主机通信时使用的协议栈。对于蓝牙HID设备,该列表必须包含两层描述:
L2CAP协议描述:指定L2CAP协议的UUID(0x0100)和PSM值(HID控制通道PSM=0x0011);
HID协议描述:指定HID协议的UUID(0x0011)。
这个属性的作用相当于告诉主机:"想要和我通信,请按照L2CAP协议配置通道,使用PSM=0x0011建立控制连接,然后通过HID协议传输数据"。
3.1.3 附加协议描述符列表(Additional Protocol Descriptor Lists)
该属性补充定义了HID中断通道的协议配置,同样包含L2CAP和HID协议描述,其中中断通道的PSM值由蓝牙分配编号文档指定。控制通道用于传输控制命令(如SET_REPORT、GET_REPORT),中断通道用于传输低延迟的输入输出数据(如鼠标移动、键盘按键),两者相辅相成,共同完成HID设备的通信需求。
3.1.4 蓝牙配置文件描述符列表(Bluetooth Profile Descriptor List)
该属性声明设备支持的蓝牙配置文件及版本,蓝牙HID设备的配置文件UUID为0x1124,版本号为0x0101(对应v1.1版本)。主机通过该属性可以判断设备支持的配置文件版本,从而启用对应的功能------比如是否支持Sniff Subrating低功耗模式、是否支持Secure Simple Pairing安全配对等。
3.1.5 语言基础属性ID列表(LanguageBaseAttributeIDList)
该属性定义了设备支持的自然语言及编码方式,用于解析后续的文本属性(如服务名称、制造商名称)。例如,英语(en)的语言ID为0x656E,UTF-8编码的ID为0x006A,基础属性ID为0x0100。
这个属性的设计体现了蓝牙协议的国际化考量------一款蓝牙键盘可能需要在不同国家销售,通过支持多语言描述,能让不同地区的用户在主机上看到熟悉的设备名称。
3.1.6 HID解析器版本(HIDParserVersion)
该属性指定设备遵循的USB HID规范版本,格式为0xJJMN(JJ为主版本号,M为次版本号,N为子次版本号)。例如,版本1.11对应的属性值为0x0111。

为什么蓝牙HID设备要声明USB HID版本?因为蓝牙HID规范大量借鉴了USB HID的设计,包括报告描述符格式、数据传输机制等。主机通过该版本号,可以确定如何解析设备的报告数据,保证数据解读的准确性。
3.1.7 HID设备子类(HIDDeviceSubclass)

该属性是设备类型的细分描述,通过8位整数的不同位组合来表示设备类别:
位7-6:表示是否为键盘/指点设备(00=都不是,01=键盘,10=指点设备,11=键盘+指点设备);
位5-2:表示具体设备类型(0000=未分类,0001=操纵杆,0010=游戏手柄,0011=遥控器,0100=传感设备等)。

例如,一款蓝牙鼠标的HIDDeviceSubclass值为0x80(位7=1,位6=0,其余位=0),表示它是指点设备;而蓝牙键盘的值为0x40(位7=0,位6=1)。主机通过该属性可以快速判断设备类型,比如电脑发现是键盘后,会自动加载键盘驱动。
3.1.8 HID国家代码(HIDCountryCode)

该属性指定设备的硬件本地化国家/地区。大多数设备不需要本地化,因此值为0;而针对特定地区设计的键盘(如美式键盘、日式键盘)会设置对应的国家代码,主机可以据此调整按键映射。
3.1.9 HID虚拟电缆(HIDVirtualCable)

这是蓝牙HID特有的属性,用于表示设备是否支持虚拟电缆功能。虚拟电缆是蓝牙HID对有线USB设备"物理电缆"的模拟,支持该功能的设备(属性值为TRUE)具有以下特性:
同一时间只能与一个主机建立连接;
仅允许与已建立虚拟电缆的主机连接(除非处于可发现模式);
连接信息会存储在持久化内存中,下次可自动重连。
这个属性很好地解决了蓝牙设备的多主机切换问题------比如一款蓝牙键盘可以与电脑、平板建立虚拟电缆,用户通过物理按键切换连接的主机,既保证了连接稳定性,又提升了使用灵活性。
3.1.10 HID重连初始化(HIDReconnectInitiate)

该属性表示设备是否会主动发起重连。属性值为TRUE时,当连接意外断开(如主机超出信号范围),设备会在检测到用户操作(如按键、移动)时主动搜索并连接之前的主机。
对于蓝牙鼠标、键盘这类设备,该属性尤为重要------用户不需要每次断开后都手动重新配对,极大提升了使用便利性。规范特别要求,支持Boot协议的设备必须将该属性设为TRUE。
3.1.11 HID描述符列表(HIDDescriptorList)

该属性包含了设备的报告描述符(Report Descriptor)和物理描述符(Physical Descriptor),其中报告描述符是核心。报告描述符定义了设备支持的报告类型(输入/输出/特征报告)、数据格式、字段含义等,是主机解析设备数据的关键依据。

例如,蓝牙鼠标的报告描述符会定义X轴、Y轴的坐标范围(通常为-127到127)、按键数量(如3个按键)等信息。主机通过解析报告描述符,就能知道如何解读从鼠标收到的输入数据------比如收到一个3字节的数据包,前两个字节是X/Y坐标变化,后一个字节是按键状态。
3.1.12 HID语言ID基础列表(HIDLANGIDBaseList)

该属性用于映射蓝牙字符串与HID语言ID,支持多语言的设备通过该属性声明不同语言的基础属性ID。例如,设备支持英语和德语,就会分别声明英语的语言ID(0x0409)和基础属性ID(0x0100),德语的语言ID(0x0407)和基础属性ID(0x0500)。
3.1.13 HID引导设备(HIDBootDevice)

该属性表示设备是否支持Boot协议模式,值为TRUE时表示支持。Boot协议是USB HID规范定义的简化协议,用于满足BIOS等资源受限环境的需求,蓝牙HID设备继承了这一特性。支持Boot协议的设备(如键盘、鼠标)可以在主机启动初期就建立连接,保证基本输入功能的可用性。
3.2 重要可选属性:设备的扩展能力说明
这些属性并非强制要求,但能让设备的能力描述更完整,主机也能据此提供更优的用户体验。
3.2.1 服务名称(Service Name)
设备的友好名称,如"XYZ Wireless Mouse",主机在显示设备列表时会展示该名称,方便用户识别。
3.2.2 HID电池供电(HIDBatteryPower)

表示设备是否为电池供电,值为TRUE时,主机可以针对性地进行电源管理------比如在设备长时间无操作时,主动进入低功耗模式以延长电池寿命。
3.2.3 HID远程唤醒(HIDRemoteWake)

表示设备是否支持远程唤醒功能,值为TRUE时,设备可以在主机休眠时通过用户操作(如按键盘按键、移动鼠标)唤醒主机。这是一个非常实用的功能,尤其适用于笔记本电脑等移动设备。
3.2.4 HID监督超时(HIDSupervisionTimeout)

指定设备推荐的基带链路监督超时时间(以时隙为单位),主机可以参考该值设置超时参数。如果设备未声明该属性,主机默认使用2秒的超时时间。该属性的作用是平衡连接稳定性和功耗------超时时间过短容易导致误断开,过长则会增加功耗。
3.2.5 HID通常可连接(HIDNormallyConnectable)

表示设备在无活动连接时是否处于page scan模式(可连接状态)。值为TRUE时,设备会持续监听主机的连接请求,方便主机随时重连;值为FALSE时,设备可能关闭蓝牙 radio 以节省功耗,需要用户通过物理操作(如按连接键)唤醒设备。
3.2.6 HID Sniff子速率相关属性(HIDSSRHostMaxLatency/HIDSSRHostMinTimeout)


这两个属性用于配置Sniff Subrating模式的参数,Sniff Subrating是蓝牙2.1+EDR引入的低功耗模式,能在保证 latency 的前提下降低设备功耗。HIDSSRHostMaxLatency指定最大延迟时间,HIDSSRHostMinTimeout指定最小超时时间,主机通过这两个属性可以准确配置低功耗参数,实现性能和功耗的平衡。
3.3 已废弃属性:协议演进的痕迹

在SDP属性集中,有几个属性已被废弃(DEPRECATED),比如HIDDeviceReleaseNumber、HIDSDPDisable、HIDProfileVersion等。这些属性被废弃的原因主要是功能冗余------例如HIDDeviceReleaseNumber的功能可以通过设备识别规范的版本属性实现,而HIDSDPDisable则是因为现代蓝牙设备的资源已足够支持SDP、控制通道和中断通道同时打开。
了解这些废弃属性有助于我们理解蓝牙协议的演进思路:去除冗余功能,优化协议效率,同时保证向后兼容性。
四、SDP的工作流程:从设备发现到服务匹配
了解了SDP的核心属性后,我们来看一看它的实际工作流程。以蓝牙鼠标连接电脑为例,整个过程可以分为三个阶段:
4.1 设备发现阶段
-
用户将蓝牙鼠标设置为可发现模式(通常通过按连接键);
-
电脑发起蓝牙查询(Inquiry),搜索周边的可发现设备;
-
鼠标收到查询请求后,返回自身的蓝牙地址、设备类别等基础信息;
-
电脑根据设备类别筛选出可能的HID设备(Major Class为Peripheral)。
4.2 服务查询阶段
-
电脑作为SDP客户端,向鼠标的SDP服务器发起服务查询请求,指定查询HID服务(UUID=0x1124);
-
鼠标的SDP服务器返回完整的HID服务记录,包含前面介绍的所有强制属性和可选属性;
-
电脑解析服务记录:
通过Service Class ID List确认是HID设备;
通过Protocol Descriptor List获取控制通道和中断通道的配置参数;
通过HIDDeviceSubclass确认是指点设备(鼠标);
通过HIDDescriptorList获取报告描述符,了解数据格式;
通过HIDReconnectInitiate和HIDNormallyConnectable了解重连能力。
4.3 连接建立阶段
-
电脑根据SDP记录中的协议描述,通过L2CAP协议打开控制通道(PSM=0x0011)和中断通道;
-
双方进行配对和加密(根据SDP记录中的安全相关属性);
-
电脑根据报告描述符解析鼠标发送的数据,鼠标根据主机的命令调整自身状态,通信正式建立。
整个流程中,SDP协议贯穿始终,为后续的连接和通信提供了关键的元数据。如果没有SDP,电脑就无法知道鼠标的通信参数和数据格式,也就无法实现精准控制。
五、SDP的实战参考
蓝牙HID规范的附录中包含了多个与SDP相关的实例和补充说明,这些内容对于理解SDP的实际应用非常有帮助。
5.1 附录I:SDP事务示例
附录I提供了完整的SDP事务示例,包括服务搜索请求、服务属性请求、服务搜索属性请求等场景,展示了SDP消息的格式、字段含义和交互过程。例如,在服务搜索请求示例中,SDP客户端(主机)发送的消息包含事务ID、服务搜索模式(HID服务UUID=0x1124)、最大服务记录数等字段;SDP服务器(设备)返回的响应包含服务记录句柄,供主机后续查询详细属性。
这些示例的价值在于,它们将抽象的协议规范转化为具体的消息格式,帮助开发者理解如何实现SDP客户端和服务器。例如,开发者可以参考示例中的消息结构,编写代码实现SDP查询功能,确保与规范的一致性。
5.2 附录I.4:多语言字符串示例
该示例展示了支持多语言的设备如何通过SDP属性声明不同语言的字符串(如服务名称、制造商名称)。例如,一款ATM机的HID接口支持英语、德语和意大利语,通过LanguageBaseAttributeIDList和HIDLANGIDBaseList属性声明不同语言的基础属性ID,再通过对应的属性ID存储不同语言的字符串。


5.3 附录C:蓝牙连接管理示例
附录C中的配对示例和虚拟电缆管理示例,间接展示了SDP属性在实际连接中的作用。例如,在配对示例中,主机通过SDP记录中的HIDBootDevice属性判断设备是否支持Boot协议,从而选择合适的配对流程;在虚拟电缆管理示例中,HIDVirtualCable属性决定了设备是否支持多主机切换。
这些示例说明,SDP属性并非孤立存在,而是与蓝牙的配对、连接管理等功能紧密关联,共同构成了蓝牙HID设备的完整通信体系。
六、测验
题目:蓝牙HID设备的SDP服务记录中,哪些属性是强制必须声明的?请列举至少5个,并说明其中HIDDescriptorList的作用。
答案:
强制属性包括:Service Class ID List、Protocol Descriptor List、Additional Protocol Descriptor Lists、Bluetooth Profile Descriptor List、LanguageBaseAttributeIDList、HIDParserVersion、HIDDeviceSubclass、HIDCountryCode、HIDVirtualCable、HIDReconnectInitiate、HIDDescriptorList、HIDLANGIDBaseList、HIDBootDevice。
HIDDescriptorList的作用是:包含设备的报告描述符和物理描述符,其中报告描述符定义了设备支持的报告类型(输入/输出/特征报告)、数据格式、字段含义、取值范围等关键信息,是主机解析设备数据的核心依据。主机通过解析该描述符,能够正确理解设备发送的输入数据(如鼠标坐标、键盘按键)和执行设备接收的输出数据(如LED控制、力反馈命令)。
题目:蓝牙HID主机如何通过SDP协议判断一款设备是否为蓝牙键盘?判断依据有哪些属性?
答案:
主机通过以下步骤和属性判断设备是否为蓝牙键盘:
-
首先查询设备的SDP服务记录,检查Service Class ID List是否包含HID服务UUID(0x1124),确认是HID设备;
-
解析HIDDeviceSubclass属性,判断位6是否为1(位6=1表示键盘,位7=1表示指点设备);
-
检查HIDBootDevice属性是否为TRUE(键盘必须支持Boot协议模式);
-
解析HIDDescriptorList中的报告描述符,确认包含键盘相关的使用页(如键盘使用页0x07)和按键定义。
核心判断依据是HIDDeviceSubclass属性(位6是否为1),结合HIDBootDevice属性和报告描述符进一步验证,确保设备确实是键盘而非其他HID设备。
题目:蓝牙HID规范中,部分SDP属性被标记为DEPRECATED(废弃),请说明这些属性被废弃的主要原因,并举例说明如何保证向后兼容性?
答案:
属性被废弃的主要原因是功能冗余或技术演进:
-
功能冗余:部分属性的功能可以通过其他规范或属性实现,例如HIDDeviceReleaseNumber的功能可通过设备识别规范的版本属性替代;
-
技术演进:随着蓝牙技术的发展,部分属性对应的功能已不再需要,例如HIDSDPDisable属性,现代蓝牙设备的资源已足够支持SDP、控制通道和中断通道同时打开。
向后兼容性的保证方式:
-
对于废弃属性,规范要求主机和设备在收到时应忽略而非中断流程,例如主机在解析SDP记录时,遇到HIDDeviceReleaseNumber属性应直接忽略,不影响其他属性的解析;
-
废弃属性的功能通过其他标准化方式实现,确保旧设备的功能需求仍能满足,例如HIDDeviceReleaseNumber的版本信息通过设备识别规范的属性提供,主机可通过该规范获取版本信息,兼容旧设备的功能需求。