当前位置: 首页 > news >正文

【android bluetooth 协议分析 07】【SDP详解 1】【SDP 介绍】

一、SDP概述

蓝牙服务发现协议(Service Discovery Protocol, SDP)是蓝牙核心规范中定义的一种协议,用于帮助设备发现附近其他蓝牙设备提供的服务及其特性。

1.1 SDP的基本作用

SDP主要解决蓝牙环境中服务发现的特殊需求:

  • 动态性:蓝牙设备不断移动,服务可用性随RF(射频)距离变化

  • 无中心化:不需要中央注册机构,设备可自主定义服务

  • 资源受限:适合在计算能力有限的设备上运行

SDP只负责发现服务信息,不提供实际访问服务的能力。发现服务后,需要通过其他协议建立连接来使用服务。

1.2 SDP架构

SDP采用客户端-服务器模型

  • SDP服务器:维护服务记录数据库,响应查询请求

  • SDP客户端:发起查询请求,获取服务信息

在这里插入图片描述

将上图可以简化为:
在这里插入图片描述

SDP 涉及 SDP 服务器和 SDP 客户端之间的通信。服务器维护一个 SDP 数据库,该数据库包含一系列服务记录,这些记录描述了与服务器关联的服务的特征。每条服务记录都包含一项服务的信息。客户端可以通过发出 SDP 请求来从 SDP 服务器维护的服务记录中检索信息。

如果客户端或与客户端关联的应用程序决定使用某项服务,它会打开一个单独的连接到服务提供商以便使用该服务。SDP 提供了一种发现服务及其属性(包括相关的服务访问协议)的机制,但它并未提供使用这些服务的机制。

如果设备上有多个应用程序提供服务,SDP 服务器可以代表这些服务提供商处理有关其所提供服务的信息请求。同样,多个客户端应用程序可以使用 SDP 客户端代表客户端应用程序查询服务器。

SDP 客户端可用的 SDP 服务器集合会根据服务器与客户端的 RF 接近度动态变化。当某个服务器可用时,必须通过 SDP 以外的方式通知潜在客户,以便客户端可以使用 SDP 向服务器查询其服务。同样,当服务器离开接近度或因任何原因不可用时,服务发现协议不会发出明确通知。但是,客户端可以使用 SDP 轮询服务器,如果服务器不再响应请求,则可以推断该服务器不可用。

二、核心概念

2.1 服务记录(Service Record)

在这里插入图片描述

每个服务对应一个服务记录,包含该服务的所有属性信息。服务记录由多个服务属性组成。

关键点

  • 每个服务记录有唯一的32位服务记录句柄(ServiceRecordHandle)

  • 句柄只在同一SDP服务器内有效

  • 必须包含的两个属性:ServiceRecordHandle和ServiceClassIDList

2.2 服务属性(Service Attribute)

每个属性描述服务的一个特征,由属性ID属性值组成。

常见通用属性

属性名属性ID说明
ServiceRecordHandle0x0000服务记录的唯一标识符
ServiceClassIDList0x0001服务所属的类UUID列表
ProtocolDescriptorList0x0004访问服务所需的协议栈
BrowseGroupList0x0005服务所属的浏览组
ServiceName0x0100服务名称(可读)

2.3 服务类(Service Class)

每个服务都是一个服务类的实例。服务类定义:

  • 该类别服务应包含哪些属性

  • 每个属性的格式和含义

服务类使用UUID(通用唯一标识符)标识,可以形成继承层次。


每项服务都是某个服务类的一个实例。服务类定义提供了代表该类实例的服务记录中包含的所有属性的定义。每个属性定义指定了属性 ID 的数值、属性值的预期用途以及属性值的格式。服务记录包含特定于某个服务类的属性,以及所有服务通用的通用属性。

每个服务类还分配有一个唯一标识符。此服务类标识符包含在 ServiceClassIDList 属性的属性值中,并以 UUID 形式表示。由于服务记录中许多属性的格式和含义取决于服务记录的服务类,因此 ServiceClassIDList 属性非常重要。在使用任何特定于类的属性之前,应检查或验证其值。由于服务记录中的所有属性都必须符合服务的所有类,因此 ServiceClassIDList 属性中包含的服务类标识符是相关的。通常,每个服务类都是另一个类的子类,而另一个类的标识符包含在列表中。服务子类定义与其超类的不同之处在于,子类包含特定于该子类的附加属性定义。

当定义一个作为现有服务类子类的新服务类时,该新服务类将保留其父类中定义的所有属性。此外,还可以定义特定于新服务类的其他属性。换句话说,向现有服务类的某些实例添加新属性的机制是创建一个作为现有服务类子类的新服务类。

如果产品的 SDP 数据库中公开了服务类 UUID,则包含该 SDP 记录的产品应符合定义与 UUID 对应的服务的规范。

2.4 例子

2.4.1 A2DP SINK

在这里插入图片描述

  • 上面的例子是,手机向 车机查询, ServiceRecordHandle 0x10004 是什么服务。

  • 车机 回复了 对应的 Service Record 最外面那个红色框

    • 酒红色框住的,就是 这个 Service Record 所包含的 Service Attribute
    • 其中紫色 框 , 的两个 Service Attribute 是必须包含的。
      • ServiceRecordHandle
      • ServiceClassIDList
2.4.2 AVRCP

在这里插入图片描述

2.4.3 HFP

在这里插入图片描述

2.4.4 PBAP
  • 车机主动查询 手机 , 此时查询是根据 service class 来查询的
    在这里插入图片描述

  • 手机 回复了对应的 Service Record
    在这里插入图片描述

2.4.5 IAP

在这里插入图片描述

2.4.6 carplay

在这里插入图片描述

2.4.7 PNP

在这里插入图片描述

三、服务发现方式

3.1 服务搜索(Searching)

基于UUID查找特定服务:

客户端 → 发送包含UUID的搜索模式 → 服务器 → 返回匹配的服务记录句柄

特点

  • 只能基于UUID属性搜索

  • 搜索模式是UUID列表,服务记录只需包含所有这些UUID即可匹配

3.1.1 查找所有l2cap 的服务
  • 示例:查找所有使用l2cap 的服务

在这里插入图片描述

在这里插入图片描述

  • 手机向车机查询, 所有使用了 l2cap 的服务, 车机 将所有使用 l2cap 的服务的 handle 发送给手机。
  • 然后,手机 根据 handle 一个个 的请求,是什么服务。 具体内容看 2.4 小节例子
3.1.2 查询所有 Pnp 的服务

在这里插入图片描述

在这里插入图片描述

  • 这里看到, 车机只 回复了一个 handle.
  • 后面 手机, 有通过 请求 0x10002 来具体访问这个 服务的信息, 具体内容看 2.4.7

3.2 服务浏览(Browsing)

浏览服务层次结构而不需要预先知道服务特性:

客户端 → 从根浏览组(PublicBrowseRoot)开始 → 服务器 → 返回可浏览的服务组

浏览组

  • 服务通过BrowseGroupList属性声明所属的浏览组

  • 浏览组本身也是服务(BrowseGroupDescriptor类)

  • 形成层次结构,适合组织大量服务

3.2.1 示例

示例浏览层次

在这里插入图片描述

图 2.5 展示了一个虚构的服务浏览层次结构,阐明了浏览组描述符的使用方式。浏览组描述符服务记录用 (G) 标识;其他服务记录用 (S) 标识。

公共根
├─ 娱乐
│  ├─ 游戏
│  └─ 电影
├─ 新闻
└─ 参考

四、数据表示

SDP使用数据元素(Data Element)结构表示所有数据。

4.1 数据元素结构

在这里插入图片描述

4.2 主要数据类型

  • 下面的表格是, 4.1 Type 的取值范围
    在这里插入图片描述
类型值类型描述有效大小
0Nil(空)0
1无符号整数0-4
2有符号整数0-4
3UUID1,2,4
4文本字符串5-7
5布尔值0
6数据元素序列5-7

4.3 Size Index

  • 下面的表格是, 4.1 Size Index 的取值范围
  • 例如
    • Type = 4 : 表示文本字符串
    • Size Index = 5, 真正的 字符串大小在, 另外的 8bit中=3 表示三个字符

在这里插入图片描述

4.4 例子

在这里插入图片描述

Data Element: Sequence uint8 3 bytes0011 0... = Data Element Type: Sequence (6).... .101 = Data Element Size: uint8 (5)Data Element Var Size: 3Data ValueData Element: UUID 2 bytes0001 1... = Data Element Type: UUID (3).... .001 = Data Element Size: 2 bytes (1)Data ValueValue: UUID: Handsfree Audio Gateway (0x111f)

在这里插入图片描述

  • 上面的 type = 6: 数据元素序列,其数据字段是数据元素序列的数据元素
  • 也就是说他的数据内容, 0x19 0x11 0x1f 也是一个数据元素,所以同样也需要使用 上面的 方式来解析
4.4.1 UUID表示

UUID 是一个通用唯一标识符,预期其在所有空间和时间上都是唯一的(更准确地说,独立生成的 UUID 相同的概率可以忽略不计)。UUID 可以以分布式方式独立创建。无需集中注册已分配的 UUID。UUID 是一个 128 位值。

为了减轻存储和传输 128 位 UUID 值的负担,我们预先分配了一系列 UUID 值,用于分配给常用的注册用途。此预分配范围内的第一个 UUID 称为 Bluetooth_Base_UUID,其值为 00000000-0000-1000-800000805F9B34FB。预分配范围内的 UUID 值具有表示为 16 位或 32 位值的别名。这些别名通常被称为 16 位或 32 位 UUID,但实际上每个别名都代表一个 128 位 UUID 值。

可以通过简单的算术运算计算出 16 位或 32 位 UUID 的完整 128 位值。

128BitValue=(16BitValue)∗296+BluetoothBaseUUID128BitValue = (16BitValue) * 2^{96} + BluetoothBaseUUID128BitValue=(16BitValue)296+BluetoothBaseUUID
128BitValue=(32BitValue)∗296+BluetoothBaseUUID128BitValue = (32BitValue) * 2^{96} + BluetoothBaseUUID128BitValue=(32BitValue)296+BluetoothBaseUUID

通过将 16 位 UUID 值零扩展为 32 位,可以将 16 位 UUID 转换为 32 位 UUID 格式。另一种等效方法是将 16 位 UUID 值添加到零值的 32 位 UUID 上。

注意:两个 16 位 UUID 可以直接比较,两个 32 位 UUID 或两个 128 位 UUID 也可以。如果要比较两个不同大小的 UUID,则必须先将较短的 UUID 转换为较长的 UUID 格式,然后再进行比较。

  • 完整UUID是128位

    • 如:Bluetooth_Base_UUID : 00000000-0000-1000-8000-00805F9B34FB
  • 常用UUID使用16位或32位短格式

  • 短格式UUID通过公式转换为128位:

    • 128BitValue=(16BitValue)∗296+BluetoothBaseUUID128BitValue = (16BitValue) * 2^{96} + BluetoothBaseUUID128BitValue=(16BitValue)296+BluetoothBaseUUID

在这里插入图片描述

  • Type :=3 :数据元素,是一个 UUID
  • Size index := 1: 没有补充位, 表示后面的 数据长度为 2个字节
  • 0x111f: hfp 所对应的 UUID, 16bit的短 uuid

五、协议细节

5.1 PDU格式

在这里插入图片描述

5.1.1 例子

例子一: 车机 (runningand) 接收到了 手机 发送的请求 查询所有 的 l2cap 服务

812	0x001	2025-01-02 15:48:45.210393	Apple_7c:81:36 (Jxl)	f8:6b:14:e5:b9:2e (runningand)	SDP	22	Rcvd Service Search Request : L2CAPFrame 812: 22 bytes on wire (176 bits), 22 bytes captured (176 bits)
Bluetooth
Bluetooth HCI H4
Bluetooth HCI ACL Packet
Bluetooth L2CAP Protocol
Bluetooth SDP ProtocolPDU: Service Search Request (0x02)     # PDU IDTransaction Id: 0x0001                 # Transaction IDParameter Length: 8                    # ParameterLength# 下面就是 ParametersService Search Pattern : L2CAPMaximum Service Record Count: 48Continuation State: no (00)

例子二: 车机向 手机回复了所有 使用 l2cap 的服务

813	0x001	2025-01-02 15:48:45.210794	f8:6b:14:e5:b9:2e (runningand)	Apple_7c:81:36 (Jxl)	SDP	71	Sent Service Search Response Frame 813: 71 bytes on wire (568 bits), 71 bytes captured (568 bits)
Bluetooth
Bluetooth HCI H4
Bluetooth HCI ACL Packet
Bluetooth L2CAP Protocol
Bluetooth SDP ProtocolPDU: Service Search Response (0x03)             # PDU IDTransaction Id: 0x0001                          # Transaction IDParameter Length: 57                            # ParameterLength# 下面就是 ParametersTotal Service Record Count: 13Current Service Record Count: 13Service Record Handle List [count = 13]Service Record Handle: 0x00010000Service Record Handle: 0x00010001Service Record Handle: 0x00010003Service Record Handle: 0x00010004Service Record Handle: 0x00010005Service Record Handle: 0x00010006Service Record Handle: 0x0001000aService Record Handle: 0x0001000bService Record Handle: 0x0001000cService Record Handle: 0x0001000dService Record Handle: 0x0001000eService Record Handle: 0x0001000fService Record Handle: 0x00010010Continuation State: no (00)

5.2 主要PDU类型

PDU类型PDU ID说明
SDP_ERROR_RSP0x01错误响应
SDP_SERVICE_SEARCH_REQ0x02服务搜索请求
SDP_SERVICE_SEARCH_RSP0x03服务搜索响应
SDP_SERVICE_ATTR_REQ0x04服务属性请求
SDP_SERVICE_ATTR_RSP0x05服务属性响应
SDP_SERVICE_SEARCH_ATTR_REQ0x06服务搜索属性请求
SDP_SERVICE_SEARCH_ATTR_RSP0x07服务搜索属性响应

5.3 分片响应

当响应数据过大时,服务器会返回部分响应继续状态(Continuation State),客户端可发送包含继续状态的后续请求获取剩余数据。

在实际中可以重点关注:

    Continuation State: no (00)
  • 暂时没有遇到过 需要分片的情况。
  • 如果有幸遇到 我在 补充.

六、相关属性详解

你清楚这些字段的含义吗?

SDP PDU                                                                                Transaction ID                                 0x0000                                Parameters                                                                           AttributeLists                                                                     AttributeList 1                                                                  Service Record Handle                    0x4F49112F                            Service Class ID List                                                          Service Class 1                        Phonebook Access - PSE                Service Record State                     0                                     Protocol Descriptor List                                                       Protocol 1                                                                   Protocol                             L2CAP                                 Protocol 2                                                                   Protocol                             RFCOMM                                Server Channel                       13                                    Protocol 3                                                                   Protocol                             OBEX                                  Browse Group List                                                              Group 1                                Public Browse Group                   Language Base Attribute ID List                                                Element 1                              25'966                                Element 2                              106                                   Element 3                              256                                   Element 4                              26'226                                Element 5                              106                                   Element 6                              272                                   Element 7                              25'701                                Element 8                              106                                   Element 9                              288                                   Element 10                             27'233                                Element 11                             106                                   Element 12                             304                                   Service Availability                     255                                   Bluetooth Profile Descriptor List                                              Profile 1                                                                    Profile                              Phonebook Access                      Version                              1.2                                   Service Name                             "Phonebook"                           GOEP L2CAP Psm                           0x1005                                VendorSpecific (0x0314)                  9                                     VendorSpecific (0x0317)                  15

6.1 ServiceRecordHandle

服务记录句柄是一个 32 位数字,用于唯一标识 SDP 服务器中的每条服务记录。通常,每个句柄仅在每个 SDP 服务器内是唯一的。如果 SDP 服务器 S1 和 SDP 服务器 S2 都包含相同的服务记录(代表同一项服务),则用于引用这些相同服务记录的服务记录句柄是完全独立的。通常,如果将 S1 上用于引用服务的句柄提供给 S2,则该句柄将毫无意义。服务记录句柄值 0x00000001 至 0x0000FFFF 保留以备将来使用。

        Service Record Handle                    0x4F49112F  

6.2 ServiceClassIDList

ServiceClassIDList 属性由一个数据元素序列组成,其中每个数据元素都是一个 UUID,表示给定服务记录所遵循的服务类别。除非定义服务类别的配置文件规范另有规定,否则 UUID 应按从最具体类别到最通用类别的顺序列出。增强配置文件时,任何新的 UUID 都应添加到 ServiceClassIDList 的末尾(在任何现有 UUID 之后),以最大限度地减少与旧实现的互操作性问题。ServiceClassIDList 应至少包含一个服务类别 UUID。

        Service Class ID List                                                          Service Class 1                        Phonebook Access - PSE  

6.3 ServiceRecordState

ServiceRecordState 是一个 32 位整数,用于缓存服务属性。如果服务记录中包含此属性,则当服务记录中任何其他属性值被添加、删除或更改时,其值也应随之更改。这允许客户端检查此单个属性的值。如果自上次检查以来,该属性值未发生变化,则客户端知道服务记录中的其他属性值均未发生变化。

        Service Record State                     0       

6.4 ServiceID

ServiceID 是一个 UUID,用于唯一地标识服务记录所描述的服务实例。当同一服务在多个 SDP 服务器中被服务记录描述时,此服务属性尤其有用。

6.5 ProtocolDescriptorList

ProtocolDescriptorList 属性描述了一个或多个可用于访问服务记录所描述的服务的协议栈。

如果 ProtocolDescriptorList 描述的是单个协议栈,则它采用数据元素序列的形式,其中序列中的每个元素都是一个协议描述符。每个协议描述符又是一个数据元素序列,其第一个元素是标识协议的 UUID,其后续元素是协议特定参数。潜在的协议特定参数包括协议版本号和连接端口号。协议

描述符按照从最低层协议到最高层协议的顺序列出,用于访问服务。

如果可以使用多种协议栈来访问服务,则 ProtocolDescriptorList 采用数据元素替代的形式,其中每个成员都是上一段所述的数据元素序列。

协议描述符标识通信协议并提供协议特定的参数。协议描述符表示为一个数据元素序列。序列中的第一个数据元素应为标识协议的 UUID。其他数据元素可选地提供协议特定的信息,例如如下所示的 L2CAP 协议/服务多路复用器 (PSM) 和 RFCOMM 服务器通道号 (CN)。

示例

        Protocol Descriptor List                                                       Protocol 1                                                                   Protocol                             L2CAP                                 Protocol 2                                                                   Protocol                             RFCOMM                                Server Channel                       13                                    Protocol 3                                                                   Protocol                             OBEX   

表示:

  1. 从层次结构上来看:

    1. L2cap -> Rfcomm -> OBEX
  2. 使用的是 rfcomm 的 13 通道

6.6 AdditionalProtocolDescriptorList

附加协议描述符列表 (AdditionalProtocolDescriptorLists) 属性包含一系列协议描述符列表元素。每个元素的格式与 6.5 节中描述的协议描述符列表相同。元素的顺序非常重要,应在使用此属性的配置文件中指定并固定。


Attribute Attribute Value type Attribute Value
ProtocolDescriptorListProtocolDescriptor #0DataElementSequenceProtocolID UUID L2CAPParam: PSM PSM FooDataProtocolProtocolDescriptor #1DataElementSequenceProtocolID UUID FooDataProtocolAttribute Name Attribute ID Attribute Value TypeAdditionalProtocolDescriptorList 0x000D Data Element SequenceAdditionalProtocolDescriptorListsProtocolDescriptorList #0 DataElementSequenceProtocolDescriptor #0 DataElementSequenceProtocolID UUID L2CAPParam: PSM PSM FooControlProtocolProtocolDescriptor #1DataElementSequenceProtocolID UUID FooControlProtocol

6.7 BrowseGroupList

BrowseGroupList 属性由一个数据元素序列组成,其中每个元素都是一个 UUID,代表服务记录所属的浏览组。顶级浏览组 ID 称为 PublicBrowseRoot,代表浏览层次结构的根,其值为“已分配编号”中的 00001002-00001000-8000-00805F9B34FB (UUID16: 0x1002)。

        Browse Group List                                                              Group 1                                Public Browse Group      

6.8 LanguageBaseAttributeIDList

为了在单个服务记录中支持多种自然语言的人类可读属性,服务记录中使用的每种自然语言都会分配一个基本属性 ID。然后,人类可读的通用属性将使用相对于每个基本值的偏移量来定义,而不是使用绝对属性 ID。

LanguageBaseAttributeIDList 属性是一个列表,其中每个成员包含服务记录中使用的每种自然语言的语言标识符、字符编码标识符和基本属性 ID。LanguageBaseAttributeIDList 属性由一个数据元素序列组成,其中每个元素都是一个 16 位无符号整数。这些元素被分组为三元组(三个)。

每个三元组的第一个元素包含一个表示自然语言的标识符。语言的编码遵循 ISO 639:1988 (E/F):“语言名称表示代码”。

通过LanguageBaseAttributeIDList属性支持多语言:

每个三元组的第二个元素包含一个标识符,用于指定该语言使用的字符编码。字符编码的值可以在 IANA 数据库中找到,这些值被称为 MIBEnum 值。推荐的字符编码是 UTF-8。

每个三元组的第三个元素包含一个属性 ID,该属性 ID 用作服务记录中自然语言的基属性 ID。同一服务器内的不同服务记录可能对同一种语言使用不同的基属性 ID 值。

应选择基本属性 ID 值,以便所有指定与其偏移的属性(例如,ServiceName、ServiceDescription 和 ProviderName)的最终属性 ID 应位于 0x0100 至 0x01FF 范围内,或位于其他规范中指定的用于此目的的范围内。0x0100 至 0x01FF 范围仅用于此目的。

为了方便检索主要语言中人可读的通用属性,服务记录支持的主要语言的基属性 ID 值应为 0x0100。此外,如果服务记录中包含 LanguageBaseAttributeIDList 属性,则其第一个元素中包含的基属性 ID 值应为 0x0100。如果服务记录中包含一个或多个人可读属性,则 LanguageBaseAttributeIDList 属性应包含在该服务记录中。

        Language Base Attribute ID List                                                Element 1                              25'966                                Element 2                              106                                   Element 3                              256                                   Element 4                              26'226                                Element 5                              106                                   Element 6                              272                                   Element 7                              25'701                                Element 8                              106                                   Element 9                              288                                   Element 10                             27'233                                Element 11                             106                                   Element 12                             304    

6.9 ServiceInfoTimeToLive

ServiceTimeToLive 属性是一个 32 位整数,表示服务记录中的信息预计保持有效且不变的秒数。此时间间隔从 SDP 服务器检索属性值的时间开始计算。此值并不保证服务记录将保持可用或不变。它只是一个提示,客户端可以使用它来确定合适的轮询间隔,以重新验证服务记录的内容。

6.10 ServiceAvailability

        Service Availability                     255         

ServiceAvailability 属性是一个 8 位无符号整数,表示服务接收新客户端的相对能力。值为 0xFF 表示服务当前未使用,因此完全可用;值为 0x00 表示服务未接收新客户端。对于支持同时连接多个客户端的服务,中间值以线性比例表示服务的相对可用性。

例如,一个最多可接受 3 个客户端的服务,当有 0、1、2 和 3 个客户端正在使用该服务时,应分别提供 0xFF、0xAA、0x55 和 0x00 的 ServiceAvailability 值。0xAA 值约为 (2/3) * 0xFF,表示 2/3 的可用性;而 0x55 值约为 (1/ 3) * 0xFF,表示 1/3 的可用性。可用性值可近似为(1-(当前客户端数量/最大客户端数量))* 0xFF

当最大客户端数量很大时,必须修改此公式以确保 ServiceAvailability 值 0x00 和 0xFF 分别保留其定义的含义(不可用和完全可用)。

注意:服务可以支持的最大客户端数量可能根据服务当前客户端所使用的资源而有所不同。

ServiceAvailability 的非零值并不保证服务可用。它应被视为可用性状态的提示或近似值。

6.11 BluetoothProfileDescriptorList

        Bluetooth Profile Descriptor List                                              Profile 1                                                                    Profile                              Phonebook Access                      Version                              1.2    

BluetoothProfileDescriptorList 属性由一个数据元素序列组成,其中每个元素都是一个Profile描述符,其中包含此服务记录所代表的服务所遵循的蓝牙Profile的信息。每个Profile描述符都是一个数据元素序列,其第一个元素是分配给该配置文件的 UUID,第二个元素是 16 位配置文件版本号。

每个Profile版本都会分配一个 16 位无符号整数的Profile版本号,该版本号由两个 8 位字段组成。高 8 位包含主版本号字段,低 8 位包含次版本号字段。每个Profile的初始版本的主版本号为 1,次版本号为 0。当Profile进行向上兼容的更改时,次版本号将递增。如果Profile进行不兼容的更改,则主版本号将递增。

6.12 DocumentationURL

此属性是一个 URL,指向服务记录所描述的服务文档。

6.13 ClientExecutableURL

此属性包含一个 URL,指向可用于使用服务记录所述服务的应用程序的位置。由于不同的操作环境需要不同的可执行文件格式,因此我们定义了一种机制,允许使用此单一属性来定位适合客户端设备操作环境的可执行文件。在属性值 URL 中,客户端应用程序需要将值为 0x2A(ASCII 字符“*”)的第一个字节替换为表示所需操作环境的字符串,之后才能使用该 URL。

表示操作环境的标准化字符串列表包含在“分配编号”中。

6.14 IconURL

此属性包含一个 URL,指向可用于表示服务记录所描述的服务的图标的位置。由于不同的硬件设备需要不同的图标格式,因此已制定了一种机制定义此单一属性,允许使用此属性来定位适合客户端设备的图标。在属性值 URL 中,客户端应用程序应将值为 0x2A(ASCII 字符“*”)的第一个字节替换为表示所需图标格式的字符串,然后才能使用该 URL。
表示图标格式的标准化字符串列表包含在“分配编号”中。

6.15 ServiceName

ServiceName 属性是一个字符串,包含服务记录所代表的服务的名称。该属性应简短,并适合用图标来表示服务。将偏移量 0x0000 添加到属性 ID 基数(包含在 LanguageBaseAttributeIDList 属性中)是为了计算此属性的属性 ID。

        Service Name                             "Phonebook"    

6.16 ServiceDescription

此属性是一个包含服务简要描述的字符串。其长度应小于 200 个字符。将偏移量 0x0001 添加到属性 ID 基数(包含在 LanguageBaseAttributeIDList 属性中),以便计算此属性的属性 ID。

6.17 ProviderName

此属性是一个字符串,包含提供服务的个人或组织的名称。将偏移量 0x0002 添加到属性 ID 基数(包含在 LanguageBaseAttributeIDList 属性中),以便计算此属性的属性 ID。

6.18 Reserved universal attribute IDs

0x000E 至 0x00FF 范围内的属性 ID 保留供将来使用。

七、实际应用示例

7.1 查找所有包含的 l2cap 服务

  1. 客户端发送SDP_SERVICE_SEARCH_REQ,包含l2cap UUID

  2. 服务器返回SDP_SERVICE_SEARCH_RSP,包含匹配的服务记录句柄

  3. 客户端发送SDP_SERVICE_ATTR_REQ查询特定服务的ProtocolDescriptorList

  4. 服务器返回协议栈信息,客户端可据此建立连接

参照 3.1.1 小节

7.2 浏览服务

  1. 客户端从根浏览组(PublicBrowseRoot)开始浏览

  2. 服务器返回顶层浏览组(如"娱乐"、“新闻”)

  3. 客户端选择"娱乐"后,服务器返回子组(“游戏”、“电影”)

  4. 最终客户端可获取具体服务信息

八、总结

SDP是蓝牙设备发现和了解彼此服务能力的关键协议,其特点包括:

  • 专为动态蓝牙环境设计

  • 基于属性-值的灵活服务描述

  • 支持精确搜索和层次化浏览

  • 采用高效的二进制数据表示

  • 提供分片机制处理大数据响应

通过SDP,蓝牙设备能够有效地在短距离无线环境中发现和识别可用服务,为后续的服务使用奠定基础。

aosp 中相关 sdp 的初始化入口函数如下:

/********************************************************************************* Function         sdp_init** Description      This function initializes the SDP unit.** Returns          void*******************************************************************************/
void sdp_init(void) {/* Clears all structures and local SDP database (if Server is enabled) */memset(&sdp_cb, 0, sizeof(tSDP_CB));for (int i = 0; i < SDP_MAX_CONNECTIONS; i++) {sdp_cb.ccb[i].sdp_conn_timer = alarm_new("sdp.sdp_conn_timer");}/* Initialize the L2CAP configuration. We only care about MTU */sdp_cb.l2cap_my_cfg.mtu_present = true;sdp_cb.l2cap_my_cfg.mtu = SDP_MTU_SIZE;sdp_cb.max_attr_list_size = SDP_MTU_SIZE - 16;sdp_cb.max_recs_per_search = SDP_MAX_DISC_SERVER_RECS;sdp_cb.trace_level = BT_TRACE_LEVEL_WARNING;sdp_cb.reg_info.pL2CA_ConnectInd_Cb = sdp_connect_ind;sdp_cb.reg_info.pL2CA_ConnectCfm_Cb = sdp_connect_cfm;sdp_cb.reg_info.pL2CA_ConfigInd_Cb = sdp_config_ind;sdp_cb.reg_info.pL2CA_ConfigCfm_Cb = sdp_config_cfm;sdp_cb.reg_info.pL2CA_DisconnectInd_Cb = sdp_disconnect_ind;sdp_cb.reg_info.pL2CA_DisconnectCfm_Cb = sdp_disconnect_cfm;sdp_cb.reg_info.pL2CA_DataInd_Cb = sdp_data_ind;sdp_cb.reg_info.pL2CA_Error_Cb = sdp_on_l2cap_error;/* Now, register with L2CAP */if (!L2CA_Register2(BT_PSM_SDP, sdp_cb.reg_info, true /* enable_snoop */,nullptr, SDP_MTU_SIZE, 0, BTM_SEC_NONE)) {SDP_TRACE_ERROR("SDP Registration failed");}
}

在接下来相关的 sdp 的介绍中, 我将 详细介绍 这个函数。敬请期待。

http://www.dtcms.com/a/275992.html

相关文章:

  • 19th Day| 530.二叉搜索树的最小绝对差,501.二叉搜索树中的众数, 236.二叉树的最近公共祖先
  • springboot3X 整合高版本mybatisplus
  • pyqt5绘制矩形和线条
  • 【从零开始编写数据库:基于Python语言实现数据库ToyDB的ACID特性】
  • C语言<数据结构-单链表>(收尾)
  • Windows 开启和关闭 Administrator 用户的方法
  • 软考高级系系统分师和架构师常考知识点总结三
  • Typecho博客系统与WebSocket实时通信整合指南
  • 网络安全初级--搭建
  • GPU编程入门:CUDA与OpenCL全面解析
  • 聊下easyexcel导出
  • 岛屿数量问题
  • [爬虫实战] 多进程/多线程/协程-异步爬取豆瓣Top250
  • 小架构step系列12:单元测试
  • 【LeetCode】算法详解#8 ---螺旋矩阵
  • Linux->基础IO
  • 佩戴头盔数据集,5498张图片,平均识别率95.3% 其中戴头盔的图有2348张,支持yolo,coco json, pasical voc xml格式的标注
  • Ansible 入门指南:自动化配置管理核心技术与实战 SELinux 配置
  • day051-ansible循环、判断与jinja2模板
  • Frida绕过SSL Pinning (证书绑定)抓包;Frida注入;app无法抓包问题解决。
  • Spring之【写一个简单的IOC容器EasySpring】
  • 2025年亚太杯(中文赛项)数学建模B题【疾病的预测与大数据分析】原创论文分享
  • UE5多人MOBA+GAS 19、创建升龙技能,以及带力的被动,为升龙技能添加冷却和消耗
  • 3. java 堆和 JVM 内存结构
  • YOLOv8
  • pytables模块安装
  • 【TOOL】ubuntu升级cmake版本
  • 单细胞分析教程 | (二)标准化、特征选择、降为、聚类及可视化
  • STM32用PWM驱动步进电机
  • 快捷跑通ultralytics下的yolo系列