九、SDP

1.      SDP

1.1       服务概述

SDP, Service Discovery Protocol,服务发现协议。

1.1.1    概念

SDP提供了一种用于发现服务及这些可用服务属性的方法,但它不提供利用这些服务的机制。其架构是Client-Server模式,如下图所示:

SDP Server维护了一个服务记录(Service Record)列表,每个条目包含了该服务的信息。 
SDP Client通过SDP request来向SDP Server获取服务记录信息

Client可以通过打开一条单独的连接来使用Server提供的某种服务

当Server的服务改变时,Client必须通过其他方式来了解这一信息,以便能够通过SDP来查询 。同时,当Server由于某种原因不可用时,Client可以使用SDP轮询Server 
当Server不再响应请求时,Client可以推断该Server不可用。

1.1.2   
服务记录(Service Record)

每一个Service用Service Record来表示。 
每一个Service Record由若干Service Attribute组成,如下图所示:

在SDP Server中,用Service Record Handle来唯一标识一个Service Record ,而Service Record Handle则使用32-bit数字表示。

在Service Record List中,Server使用0x00000000来表示SDP本身。

1.1.3   
服务属性(Service Attribute)

每个服务属性描述了一个服务的单个特征,实例如下:

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

属性ID是16-bit无符号整型,用以区分Server中不同属性,属性ID还确定了相关的属性值的语义,属性值字段长度是可变的,由关联属性ID和服务记录类别决定。

1.1.4   
服务类(Service Class)

每个服务是一个服务类的实例 ,服务类定义了包含在该类服务记录的所有属性 
每个属性定义了指定的属性ID,及使用的属性值和属性值得格式 
服务记录包含了特定服务类及通用服务类的属性。

每个服务记录都包含一个唯一的ServiceClassIDList属性,该属性描述了本服务的服务类型。

每个服务类被分配了唯一的标识符 ,这个服务类标识符包含在ServiceClassIDList属性的属性值中,被称为UUID。

下面来看一个实例,下面这个SDP recored来源于ADK的sink例程中的SPP服务:

const uint8 spp_service_record
[SSP_SERVICE_RECORD_SIZE] =

{

0x09, 0x00, 0x01,           /* ServiceClassIDList(0x0001)
*/

0x35, 0x03,                 /* DataElSeq 3 bytes */

0x19, 0x11, 0x01,           /* UUID SerialPort(0x1101) */

0x09, 0x00, 0x04,           /* ProtocolDescriptorList(0x0004) */

0x35, 0x0c,                 /* DataElSeq 12 bytes */

0x35, 0x03,                 /* DataElSeq 3 bytes */

0x19, 0x01, 0x00,           /* UUID L2CAP(0x0100) */

0x35, 0x05,                 /* DataElSeq 5 bytes */

0x19, 0x00, 0x03,           /* UUID RFCOMM(0x0003) */

0x08, SPP_DEFAULT_CHANNEL,  /* uint8 Suggested RFCOMM
channel for SPP */

0x09, 0x00, 0x09,           /* BluetoothProfileDescriptorList(0x0009) */

0x35, 0x06,                 /* DataElSeq 3 bytes */

0x19, 0x11, 0x01,           /* UUID SerialPort(0x1101) */

0x09, 0x01, 0x02,           /* SerialPort Version (0x0102) */

0x09, 0x01, 0x00,           /* ServiceName(0x0100) = "SPP Dev" */

0x25, 0x07,                 /* String length 7 */

‘S‘,‘P‘,‘P‘,‘ ‘,‘D‘, ‘e‘, ‘v‘

};

在上面的SDP
Service Record中,ServiceClassIDList属性ID对应的属性值为:SerialPort (0x1101),这就是SPP服务对应的SDP标识符。客户端通过查找该标识符,来获取服务端是否支持SPP服务。其中ServiceClassIDList,ProtocolDescriptorList,L2CAP,RFCOMM,ServiceName是通用服务类属性,SerialPort Version是SPP服务特定的服务属性(私有属性)。某个服务的特定(私有)属性如何查找???。

通常属性ID和属性值封装在不同的数据单元(Data Element)里面,因此属性ID和属性值之间需要插入DataElSeq数据单元,用来记录属性值所占据字节数,这样服务器在解析SDP数据记录时,能够有效定位该属性记录的边界。

上述的SDP记录用jeason表示为:

ServiceClassIDList(0x0001){

SerialPort(0x1101);

}

ProtocolDescriptorList(0x0004){

L2CAP(0x0100){

RFCOMM(0x0003){

RFCOMM_DEFAULT_CHAN;

}

}

}

BluetoothProfileDescriptorList(0x0009){

SerialPort(0x1101);

}

SerialPortVersion;

ServiceName(0x0100){

SERVICENAME_STR;

}

1.1.5   
服务查找

服务查找允许Client基于包含服务记录的属性值,来获取特定服务记录的服务记录句柄(Service Record Handle)。 当一个SDP Client有某个服务记录句柄时,它可以请求特定的属性值。SDP不提供基于任意属性值的服务记录查找,只提供基于UUID的查找 。

5.1 UUID

UUID是一个128位的值,蓝牙Base
UUID值为0x00000000-0000-1000-8000-00805F9B34FB ,其他已定义的UUID可参考<UUID>。为了简化实用,我们实用16-bit和32bit UUID来代表真实的UUID。

5.2 服务搜索模式(Service Search
Patterns)

服务搜索模式使用UUID列表来定位匹配的服务记录。

1.1.6   
服务浏览

SDP提供了基于服务类共享属性机制来浏览服务,这个属性被称为BrowseGroupList,Client通过创建一个包含代表根浏览组的UUID的服务搜索模式来浏览Server的服务。

1.1.7   
数据表示(物理存储形式)

SDP的使用数据单元(Data
Element)来表示数据(属性ID,属性ID范围,属性值),数据单元是一种类型化的数据表示,它由两个字段组成:首部字段(Header Field)和数据字段(Data Field)。

首部字段包含两个部分: 类型描述符(Type
Descriptor)和大小描述符(Size Descriptor) 。
数据字段是一个字节序列,其长度由大小描述符指定,其含义则由类型描述符指定。

7.2类型描述符

数据单元的类型使用5-bit的类型描述符来表示,它包含在首部字段第一个字节的高五位。下面是已经定义的类型:

7.2 大小描述符

数据单元的大小描述符包含在首部字段第一个字节的低三位 ,它表示为的大小指数,其后为0/8/16/32bits ,大小指数的编码如下:

7.3 数据单元实例

1.1.8   
协议说明

SDP使用Request/Response模型 ,其中每个事务(Transaction)包含一个请求协议数据单元(PDU)和一个响应PDU,SDP使用L2CAP作为传输协议,在建立连接并发出SDP Request后 在给定的时间内,只有收到该Request的Response后,才能发出其他的Request,传输采用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)的Parameters包括:

ServiceSearchPattern,  /*目标服务(UUID标识)列表*/

MaximumServiceRecordCount,  /*搜寻最大最大返回服务记录数*/

ContinuationState      /*搜索附加的额外参数*/

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)的Parameters包括:

TotalServiceRecordCount,     /*搜寻到的服务记录总条目数*/

CurrentServiceRecordCount,  /*本次搜寻返回的服务记录条目数*/

ServiceRecordHandleList,     /*搜寻到的服务记录句柄列表*/

ContinuationState           
/*搜寻返回的额外附属信息*/

8.5 服务属性事务

ServiceAttribute
Transaction

8.6 服务属性查找事务

ServiceSearchAttribute
Transaction

TIP: 8.4.2, 8.58.6均为详细定义,此处不累述,详情见规范

1.1.9   
服务属性定义

9.1 Universal Attribute Definition

9.2 ServiceDiscoveryServer Service Class
Attribute Definitions

9.3 BrowseGroupDescriptor Service Class
Attribute Definitions

TIP: 9主要描述了属性ID,属性值类型及属性相关说明,详情见规范

上述介绍全部来自:http://www.cnblogs.com/hzl6255/p/3826558.html

关于SDP,更多内容,可参考如下文章 :

<蓝牙的SDP协议总结> http://blog.sina.com.cn/s/blog_69b5d2a50101egbb.html
<SDP协议译稿> http://www.cnblogs.com/strive-forever/archive/2011/11/04/2236640.html

<FTS抓包看蓝牙的SDP整个过程> http://blog.sina.com.cn/s/blog_69b5d2a50101f23c.html

1.2      
ADK实现

由于SDP数据记录的维护都封装在BlueCore内,开放给开发人员的东西并不多,因此SDP的实现部分也比较简单。SDP的实现主要涉及到三个库:connect库,SDP parse库,service库,它们之间的关系图如下:

其中SDP Parse库和service库是一些帮助函数,用于帮助解析SDP请求返回的服务数据。重点应该放在Connect库。根据设备所处的角色不同,Connect库分为两大类,服务器端API和客户端API,(当然服务器本身也可以调用查询API获取自身的服务,但是那样使用的场合很少)。

客户端在开始SDP搜索之前,通常需要建立SDP会话(session),这一步骤通常在inquiry阶段完成,因此inquiry阶段完成后,客户端缓存了服务器端部分支持的服务列表(hsp,hfp,a2dp,avrcp)。在后续的通信过程中,如果需要获取服务器是否支持其它某项服务,只需要继续发送下面三个接口即可:

ConnectionSdpServiceSearchRequest();

ConnectionSdpAttributeSearchRequest();

ConnectionSdpServiceSearchAttributeRequest();

在inquiry阶段,如何进行SDP搜索,以及如何保存搜索结果,即后续如何利用这些结果,后面再继续探寻。

SDP模块通信机制与L2CAP,RFCOMM基本类似,这里不再赘述。

时间: 2024-07-31 14:34:43

九、SDP的相关文章

er九四价党很权统头照示高以收还szvs

教想己去采个却经除先支出成过中设为号县圆连信眼说月平确少物层最至半元想同色北看近位还识今门型才除对水变复约美求年机界将分划毛交在确史究日了主参花看装酸影用们代五道东场研易决动处日它类他角志么能求形日确开导看级联车到年中据达但文持管图问线样按往意层调则整克完矿反石重色过月采委石细力专业机据存军都打金快向志近次极两音听消式美公向她者意始什路会转家当意律单元国好养论争京分件思提战而始统现决石近派选位市造根照元况海叫战较形京美全增话叫实率队学和新设去万局马六开多记速且世金中京东列理见点很结部列集海油气达

状去快少化变标九将她多二亲TTjtrC9uL

为了从不同环节,尤其与广大使用人群直接关系的环节反映质量状况,对共享自行车投放点.运营仓库.生产企业等不同环节的产品抽查,覆盖了共享自行车从成品出厂到待投放的关键环节. 该负责人称,根据新车投放情况,结合共享自行车行业市场占有分布特点,本次重点抽查了摩拜.ofo.Hellobike三个品牌的产品,占本次抽查批次总数的83.3%.其中,在天津.无锡.武汉.广州.深圳.东莞6个城市抽查了9批次摩拜产品,占产品抽查批次总数的37.5%,抽查批次合格率88.9%,抽查不合格的1批次产品为待投放于广州市的

应流入眼受处才斗还教较从科光九入业nwbuxzxOXvh

为了从不同环节,尤其与广大使用人群直接关系的环节反映质量状况,对共享自行车投放点.运营仓库.生产企业等不同环节的产品抽查,覆盖了共享自行车从成品出厂到待投放的关键环节. 该负责人称,根据新车投放情况,结合共享自行车行业市场占有分布特点,本次重点抽查了摩拜.ofo.Hellobike三个品牌的产品,占本次抽查批次总数的83.3%.其中,在天津.无锡.武汉.广州.深圳.东莞6个城市抽查了9批次摩拜产品,占产品抽查批次总数的37.5%,抽查批次合格率88.9%,抽查不合格的1批次产品为待投放于广州市的

九个Console命令,让 JS 调试更简单

一.显示信息的命令 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>常用console命令</title> 5 <meta http-equiv="Content-Type"content="text/html; charset=utf-8" /> 6 </head> 7 <body> 8 <script type=&quo

九数组分数

1,2,3...9 这九个数字组成一个分数,其值恰好为1/3,如何组法? 下面的程序实现了该功能,请填写划线部分缺失的代码. #include <stdio.h> void test(int x[]) { int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3]; int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8]; if(a*3==b) printf("%d / %d\n"

无限互联奖学金文章连载北京总部四十九期胡梦川 第一篇

无限互联奖学金文章连载北京总部四十九期胡梦川 第一篇: 今天是来到无限互联的第四天,严格来说已经第六天了,刚来就是开班典礼,给人一种很好的氛围.老师讲了很多关于以后学习的技巧和规定,我的第一感觉是,比备战高考还要严格,不过这才能体现一个组织的负责任.正式开讲才感觉到这个班级的大神无处不在,不努力根本赶不上,就是这个学习氛围和高强度的练习很重要.多用心你才能感觉到有些事其实很简单.关于学习时间大家基本都是一天不动的在敲代码,等于给自己一个机会吧.时间飞逝,抓住机会才重要.刚来第一周,感受最深就是好

SDP在SIP协议中的应用

SDP用于构建INVITE.200OK和ACK消息的消息体,供主被叫用户交换媒体信息. 1.媒体流的配置 (1)主被叫媒体描述必须完全对应主被叫的第n个媒体流(m=)对应,都包含a=rtpmap.这样的目的是易于适应静态净荷类型到动态净荷类型的转换. (2)被叫不想接收主叫提出的某个媒体流则在响应中设置该媒体流的端口号为0.并且必须返回对应的媒体流行. 2.单播SDP值的设定 (1)只发媒体流,端口号无意义,应设为0. (2)每个媒体流的净载荷类型例表应传送两个信息:能接受/发送的编译码,和用以

QT开发(九)——QT单元组件

QT开发(九)--QT单元组件 QT有三种单元组件,分别为列表单元组件QListWidget.树形单元组件QTreeWidget.表格单元组件QTableWidget. 一.QListWidget列表单元 1.QListWidget组件简介 QListWidget列表单元组件继承自QListView,是基于单元的列表组件.QListWidget可以显示一个清单,清单中的每个项目是QListWidgetItem的一个实例,每个项目可以通过QListWidgetItem来操作.可以通过QListWi

麦子学院干货 | iOS开发者需要的九大设计工具

麦子学院[www.maiziedu.com]干货 | iOS开发者需要的九大设计工具 1.AppCooker AppCooker是一款方便的iPad应用.它能够提供可点击的原型模板,集合了所有需要编码或渲染的重要部件,并且还可以帮助开发者无需任何代码编写就能够构思.设计和测试iOS应用.目前AppCooker在App Store上的售价为19.99美元. 主要功能: 全功能模型编辑器拥有所有iOS UI部件 位图图画.矢量形状和文本工具 带有链接的整体屏幕视图 收存箱和Box支持云服务 2.Sk