Bluetooth SDP介绍
SDP, Service Discovery Protocol,服务发现协议
1. 概念
SDP开发了一种方法来发现现有服务及其属性,并不具备让这些服务发挥作用的机制
其架构是Client-Server模式,如下图所示

SDP Server负责管理一个包含Service Record的服务记录集合,并为每个条目存储相关信息。
SDP Client采用API请求的方式与服务器交互,并调用相关API获取所需的服务记录信息。
Client可以通过打开一条单独的连接来使用Server提供的某种服务
当Server的服务发生变动时,Client必须采取其他途径以获取相关信息从而实现通过SDP进行查询。同时,在Server因故无法正常运行时,Client应采用SDP进行查询请求。当Server不再响应客户端的请求时,Client应判断其不可用。
2. 服务记录(Service Record)
每个服务都可以通过 Service 记录来进行表示

在SDP Server中,在每个 Service Request记录中分配一个唯一的 Service Request Identifier(SRI),即 Service Request ID记录号。同时,在此过程中还生成了一个唯一的 Service Request Handle(SRH)。这些 Service Request Handles都被分配了特定的数值范围,并且它们都是基于32位的二进制数据来进行编码存储的。
ServiceRecordState and ServiceDatabaseState attributes
在Service Record List中,Server使用0x00000000来表示SDP本身
3. 服务属性(Service Attribute)
每个服务属性描述了一个服务的单个特征,实例如下

一个服务属性包含了两个部分: 属性ID和属性值

属性ID采用16位无符号整数类型,在服务器中用于标识各个不同的属性;同时该标识还决定了各属性值所蕴含的意义
属性值字段长度是可变的,由关联属性ID和服务记录类别决定
4. 服务类(Service Class)
每一个服务都是一个具体的服务类实例;
每一个具体的服务类都定义了一个完整的属性集合;
每一个属性都指定了对应的属性ID,并遵循着其标准的值和格式规范;
所有这些信息都被整合到一个完整的业务记录中。
每个服务类都被赋予了独一无二的标识符 每个服务类标识符都包含了ServiceClassIDList属性的值 其名称定义为UUID
5. 服务查找
通过分析包含服务记录的属性信息, 系统能帮助Client定位到所需的服务实例. 进而实现对目标服务实例的服务句柄访问.
当一个SDP Client有某个服务记录句柄时,它可以请求特定的属性值
SDP不具备依据任意属性值进行服务记录查找的能力,仅以唯一标识符的形式实现这种查找.在该系统中,关键属性会被用来表示为唯一的标识符
5.1 UUID
该数值由128位二进制位构成,在蓝牙标准下的Base UUID标识符为十六进制字符串 128-bit value 十六进制表示为 128-bit value 。
其他已定义的UUID标识符可参考 [UUID](https://www.bluetooth.org/en-us/specification/assigned-numbers/service-discovery) 。
为了简化实用,我们实用16-bit和32bit UUID来代表真实的UUID,
5.2 服务搜索模式(Service Search Patterns)
服务搜索模式使用UUID列表来定位匹配的服务记录
6. 服务浏览
SDP通过遵循服务类的共享属性机制来实现服务浏览,并将该功能相关的属性命名为BrowseGroupList。
Client通过生成一个包含代表根浏览组的UUID的服务访问模式来访问Server服务
7. 数据表示
SDP的使用数据单元(Data Element)来表示数据(属性ID,属性ID范围,属性值)
数据单元是一种分类化的数据形式描述,在其结构中包含两部分信息:头部信息块(Header Information Block)和数据内容区(Data Content Area)。
首部字段由两部分组成:类型标识(Type Identifier)与容量标识(Capacity Identifier)。数据字段是一系列连续的字节,并通过容量标识确定其总位数的意义,则通过数据类型的标识来确定其实质意义。
7.1 类型描述符
下面是已经定义的具体类型的示例:
- 类型1:1-bit
- 类型2:2-bit
- 类型3:3-bit
- 类型4:4-bit
- 类型5:5-bit

7.2 大小描述符
该数据单元采用一位低位字节作为大小描述符,
该指标由若干位二进制数字组成,
具体编码方案将在后续部分介绍

7.3 数据单元实例

8. 协议说明
SDP遵循Request/Response模型,在此框架下,每一个事务包括一个请求协议数据单元和一个响应数据单元
SDP以L2CAP协议作为传输介质,在完成连接建立并发送SDP请求之后
传输采用Big-Endian,高位先低位后的方式
8.1 PDU格式
SDP PDU包含一个Header和Parameters
Header包含三个字段: PDU ID, Transaction ID, ParameterLength

其中,Header三个字段的含义分别如下

8.2 Partial Responses And Continuation State

8.3 错误处理
当一个Server检测到Client的Request格式不符合预期格式或其他原因从而导致没有合适的Response时 应返回一个SDP_ErrorResponse PDU(PDU ID=0x01)
同时,其Parameters为ErrorCode,ErrorCode详细信息如下

8.4 服务查找事务
ServiceSearch Transaction
8.4.1 SDP_ServiceSearchRequest PDU
SDP_ServiceSearchRequest PDU(PDU ID=0x02)包含以下参数:服务搜索模式、最大服务记录数量和连续状态。
ServiceSearchPattern(Size: Varies):
| Value | Parametr Description |
|---|---|
| Data Element Sequence | ServiceSearchPattern是一个数据单元序列,每个单元是一个UUID,单元数为1~12 |
MaximumServiceRecordCount(Size: 2 Bytes):
| Value | Parametr Description |
|---|---|
| N | MaximumServiceRecordCount是一个16-bit数,指定可返回的了最大的服务记录句柄,取值范围: 0x0001~0xFFFF |
ContinuationState(Size: 1~17 Bytes):
| Value | Parametr Description |
|---|---|
| Continuation State | ContinuationState是一个8-bit数N,随后的N Bytes是Continuation State信息,N的范围为0~16,0表示没有Continuation State |
8.4.2 SDP_ServiceSearchResponse PDU
SDP_ServiceSearchResponse PDU(PDU ID=0x03)的Parameter字段包含记录总数字段、当前服务记录计数字段、服务记录处理列表字段以及继续状态字段。
8.5 服务属性事务
ServiceAttribute Transaction
8.6 服务属性查找事务
ServiceSearchAttribute Transaction
TIP: 8.4.2, 8.5及8.6均为详细定义,此处不累述,详情见规范
9. 服务属性定义
9.1 Universal Attribute Definition
9.2 ServiceDiscoveryServer Service Class Attribute Definitions
9.3 BrowseGroupDescriptor Service Class Attribute Definitions
TIP:9主要描述了属性ID,属性值类型及属性相关说明,详情见规范
关于SDP,更多内容,可参考如下文章
<蓝牙的SDP协议总结>
<SDP协议译稿(Part 1)>
<FTS抓包看蓝牙的SDP整个过程>
