蓝牙和 WSALookupServiceBegin for Service Discovery

为了发现蓝牙服务器上存在特定服务,客户端使用 WSALookupServiceBeginWSALookupServiceNext,以及 WSALookupServiceEnd 函数。 可以针对本地和远程地址执行查询,但只能使用远程地址建立连接。 在此作期间发现的服务句柄不能用于通过 WSASetService删除服务。 RFCOMM 不支持环回。

可以执行两种基本类型的服务发现查询:

  • 在本地设备上查询一个或多个服务
  • 在指定的对等设备上查询一个或多个服务

WSALookupServiceBegin 函数在其 lpqsRestrictions 参数中接收 WSAQUERYSET 结构。 WSALookupServiceBegin 基于 WSAQUERYSET 包含的一组搜索限制执行客户端查询。 使用 WSALookupServiceBegin 函数查询服务时,蓝牙客户端必须指定下表中列出的限制,在 WSAQUERYSET 结构中。

WSAQUERYSET 成员 限制
dwSize 设置为 sizeofWSAQUERYSET)。
lpServiceClassId 设置为最具体的蓝牙 UUID,可用于确定查询的范围。 例如,将 lpServiceClassId 设置为 L2CAP 协议的 UUID 会导致返回所有 L2CAP 服务,实质上枚举目标上的所有 SD 记录。 但是,将 UUID 设置为特定服务仅返回该服务的实例。
dwNameSpace 设置为 NS_BTH
dwNumberOfCsAddrs 设置为 0。
lpszContext 设置为用于建立 SDP 连接的蓝牙设备地址,以执行服务的查询。 此成员必须是使用 WSAAddressToString 函数转换的字符串。 如果提供了本地无线电地址,则会搜索本地 SDP 记录。
其他成员 将忽略 WSAQUERYSET 结构中的所有其他成员。

WSALookupServiceBegin 函数完成服务查询后,与远程设备的 SDP 连接不会保持活动状态;连接在 WSALookupServiceBegin 返回之前终止。 在服务查询完成后,要求 SDP 连接保持活动状态的应用程序应在发出 Windows 套接字 连接 函数调用时,使用 SOCKADDR_BTH 结构的 serviceClassId 成员指定要连接到的服务类 UUID。

下表中列出的标志在 dwControlFlags 参数中使用 WSALookupServiceBeginWSALookupServiceNext 函数来控制查询结果。 WSALookupServiceBegin 函数使用 LUP_CONTAINERSLUP_FLUSHCACHE 标志;其余标志用于调用 WSALookupServiceNext 函数。

结果
LUP_CONTAINERS 不能设置。
LUP_FLUSHCACHE 应用程序通常应指定 LUP_FLUSHCACHE。 此标志指示系统忽略任何缓存的信息,并建立与指定设备的无线 SDP 连接以执行 SDP 搜索。 此非缓存作可能需要几秒钟(而缓存的搜索会快速返回)。 蓝牙当前不会主动缓存来自附近设备的 SDP 记录,也不主动缓存以前的查询。 因此,如果未指定 LUP_FLUSHCACHE,应用程序应预测查询可能不会返回任何结果(错误代码为 WSASERVICE_NOT_FOUND)。 将来可能会增强使用 Windows 套接字接口提供的缓存数据。
LUP_RES_SERVICE 返回有关本地蓝牙地址的信息。 仅当同时指定 LUP_RETURN_ADDR 时,此标志才有效。
LUP_RETURN_NAME 返回 lpszServiceInstanceNameWSAQUERYSET 结构中服务的显示名称,以便每次调用 WSALookupServiceNext 函数。
LUP_RETURN_TYPE 返回 lpServiceClassIdWSAQUERYSET 结构的成员中的服务类 ID。 注意: 使用此标志仅适用于 WSALookupServiceBegin 函数。 对于 WSALookupServiceNext,此值始终为零。
LUP_RETURN_ADDR 返回 lpcsaBuffer 成员中要与 连接 函数调用一起使用的地址。 返回的地址包含端口号。
LUP_RETURN_BLOB 根据蓝牙 SDP 记录规范,返回 lpBlob 成员中的匹配 SD 记录。
LUP_RETURN_ALL 返回上述所有标志的信息。
LUP_RETURN_COMMENT 返回 lpszComment 成员 WSAQUERYSET 结构中的服务说明,以便每次调用 WSALookupServiceNext 函数。
LUP_FLUSHPREVIOUS 跳过下一条可用记录,并返回后面的记录。

高级服务查询

上一节中所述的查询作可用于从单个 GUID 返回所有结果,这应该足以满足大多数应用程序的需求。 高级查询使应用程序能够创建更具体的查询;它提供匹配返回信息中的 UUID 和属性的功能。

若要对服务执行高级查询,蓝牙客户端必须在传递到 lpqsRestrictions 参数的 WSAQUERYSET 结构中指定以下限制。

WSAQUERYSET 成员 限制
dwSize 设置为 sizeofWSAQUERYSET)。
lpszContext 设置为用于建立 SDP 连接的蓝牙设备地址,以执行服务的查询。 此成员必须是使用 WSAAddressToString 函数转换的字符串。 如果提供了本地无线电地址,则会搜索本地 SDP 记录。
lpBlob.pBlobData 指向包含限制查询结果的所有参数的 BTH_QUERY_SERVICE 结构的指针。
dwNameSpace 设置为 NS_BTH
其他成员 将忽略 WSAQUERYSET 结构中的所有其他成员。

以下标志在 WSALookupServiceBegindwControlFlags 参数中传递,以控制高级查询的结果。

结果
LUP_CONTAINERS 不能设置。
LUP_FLUSHCACHE 应用程序通常应指定 LUP_FLUSHCACHE。 此标志指示系统忽略任何缓存的信息,并建立与指定设备的无线 SDP 连接以执行 SDP 搜索。 此非缓存作可能需要几秒钟(而缓存的搜索会快速返回)。 蓝牙不会主动缓存来自附近设备的 SDP 记录,也不会主动缓存以前的查询。 因此,如果未指定 LUP_FLUSHCACHE,应用程序应期望查询经常不返回任何结果(WSASERVICE_NOT_FOUND)。 将来可能会增强使用 Windows 套接字接口提供的缓存数据。
LUP_RES_SERVICE 返回本地蓝牙地址的信息。 仅当还指定了 LUP_RETURN_ADDRR 时,设置此标志才有效。
LUP_RETURN_NAME 返回服务的显示名称。 对于 SDP_SERVICE_SEARCH_REQUEST,忽略此标志。
LUP_RETURN_TYPE 返回服务类 ID。 对于 SDP_SERVICE_SEARCH_REQUEST,忽略此标志。
LUP_RETURN_ADDR 返回 lpcsaBuffer 成员中要与 连接 函数调用一起使用的地址。 返回的地址包含端口号。 对于 SDP_SERVICE_SEARCH_REQUEST,忽略此标志。
LUP_RETURN_BLOB 以符合蓝牙 SDP 记录规范的格式返回匹配的 SD 记录。 对于 SDP_SERVICE_SEARCH_REQUEST,后续调用 WSALookupServiceNext 的结果是蓝牙 SDP 句柄数组,lpBlob。 对于 SDP_SERVICE_ATTRIBUTE_REQUESTSDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST,对 WSALookupServiceNext 的每个后续调用的结果都是二进制蓝牙 SDP 记录,其属性限制为查询 pRange 成员指定的记录。 SDP_SERVICE_SEARCH_REQUEST需要此标志。
LUP_RETURN_COMMENT 返回 lpszComment 成员 WSAQUERYSET 结构中的服务说明,以便每次调用 WSALookupServiceNext 函数。
LUP_FLUSHPREVIOUS 跳过下一条可用记录,并返回后面的记录。

输入时,lpBlob->pBlobData 指向包含下表中列出的值的 BTH_QUERY_SERVICE 结构。

注意

初始搜索请求必须能够容纳到一个 L2CAP 数据包中。 但是,响应可能会分解成许多 L2CAP 数据包。

成员 价值
类型 要执行的搜索类型。 此值可以是 SDP_SERVICE_SEARCH_REQUESTSDP_SERVICE_ATTRIBUTE_REQUESTSDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST之一。 每个搜索类型都与蓝牙 SDP 规范定义的底层搜索机制相关联。 每个返回结果都以 WSAQUERYSET 结构描述的形式返回,该结构在本(高级服务查询)部分前面定义。
serviceHandle 用于属性搜索。 此值指定查询 pRange 成员中的属性的服务句柄。
uuids 用于服务和 serviceAttribute 搜索。 此值指定记录必须包含的 UUID 以匹配搜索。 如果要查询小于 MAX_UUIDS_IN_QUERY UUID,则此值将紧跟最后一个有效 UUID 的 SdpQueryUuid 元素设置为所有零。
numRange 用于属性和 serviceAttribute 搜索。 此值指定 pRange中的元素数。
pRange 用于属性和 serviceAttribute 搜索。 此值指定要检索任何匹配记录的属性值。

每次成功调用 WSALookupServiceNext 函数后,lpBlob->pBlobData 指向包含下表中列出的值的一个数据块。

价值 描述
SDP_SERVICE_SEARCH_REQUEST SDP 记录句柄数组,该句柄与蓝牙 1.1 SDP 4.5.2 定义的 ServiceRecordHandleList 相同。 返回的 SDP 句柄数由 (lpBlob->cbSize) /sizeof(ULONG) 计算。 所有结果在对 WSALookupServiceNext 函数的单个调用中返回。
SDP_SERVICE_ATTRIBUTE_REQUESTSDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST 二进制蓝牙 SDP 记录。 对于 SDP_SERVICE_ATTRIBUTE_REQUEST,所有结果在对 WSALookupServiceNext 函数的单个调用中返回。

注意

如果在服务查询的输入过程中未指定 lpBlob 成员,则会针对从 0 到 0xFFFF 的属性在 lpServiceClassId 成员中指定的服务执行服务和属性搜索。

蓝牙和 WSAQUERYSET 进行服务查询

发现蓝牙设备和服务

蓝牙和 WSALookupServiceNext

蓝牙和 WSALookupServiceBegin 进行设备查询

BTH_QUERY_SERVICE

连接

SOCKADDR_BTH

WSAAddressToString

WSALookupServiceBegin

WSALookupServiceEnd

WSALookupServiceNext

WSAQUERYSET

Windows 套接字