藍牙 和 WSALookupServiceBegin for Service Discovery
若要探索 藍牙 伺服器上的特定服務是否存在,用戶端會使用 WSALookupServiceBegin、WSALookupServiceNext 和 WSALookupServiceEnd 函式。 您可以針對本機和遠端位址執行查詢,但只能使用遠端位址建立連線。 在此作業期間探索到的服務句柄無法用來透過 WSASetService 刪除服務。 RFCOMM 不支援回送。
您可以執行基本類型的服務探索查詢:
- 本機裝置上一或多個服務的查詢
- 查詢指定對等裝置上的一或多個服務
WSALookupServiceBegin 函式會在其 lpqsRestrictions 參數中接收 WSAQUERYSET 結構。 WSALookupServiceBegin 會根據 WSAQUERYSET 所包含的一組搜尋限制來執行客戶端查詢。 藍牙 客戶端必須指定下表中所列的限制使用 WSALookupServiceBegin 函式查詢服務時,WSAQUERYSET 結構。
WSAQUERYSET 成員 | 限制 |
---|---|
dwSize | 設定為 sizeof(WSAQUERYSET)。 |
lpServiceClassId | 設定為最特定的 藍牙 UUID,可用來判斷查詢的範圍。 例如,將 lpServiceClassId 設定為 L2CAP 通訊協定的 UUID 會導致傳回的所有 L2CAP 服務,基本上列舉目標上的所有 SD 記錄。 不過,將 UUID 設定為特定服務只會傳回該服務的實例。 |
dwNameSpace | 設定為 NS_BTH。 |
dwNumberOfCsAddrs | 請將 設為 0。 |
lpszContext | 設定為要用來建立 SDP 連線以執行服務查詢的 藍牙 裝置位址。 這個成員必須是使用 WSAAddressToString 函式轉換的字串。 如果提供本機無線電位址,則會搜尋本機 SDP 記錄。 |
其他成員 | 會忽略 WSAQUERYSET 結構的其他所有成員。 |
WSALookupServiceBegin 函式完成服務查詢之後,遠端裝置的 SDP 連線不會保持作用中;聯機會在 WSALookupServiceBegin 傳回之前終止。 要求 SDP 連線在服務查詢完成之後保持作用中的應用程式,應該在發出 Windows Sockets connect 函式呼叫時,使用 SOCKADDR_BTH 結構的 serviceClassId 成員來指定要連線的服務類別 UUID。
下表所列的旗標會用於 WSALookupServiceBegin 和 WSALookupServiceNext 函式的 dwControlFlags 參數中,以控制查詢結果。 WSALookupServiceBegin 函式會使用LUP_CONTAINERS和LUP_FLUSHCACHE旗標;其餘的旗標則用於呼叫 WSALookupServiceNext 函式。
旗標 | 結果 |
---|---|
LUP_CONTAINERS | 不得設定。 |
LUP_FLUSHCACHE | 應用程式通常應該指定 LUP_FLUSHCACHE。 此旗標會指示系統忽略任何快取的資訊,並建立與指定裝置的無線 SDP 連線,以執行 SDP 搜尋。 此非快取作業可能需要幾秒鐘的時間(而快取的搜尋會快速傳回)。 藍牙 目前不會主動快取來自附近裝置的 SDP 記錄,目前也不會主動快取先前的查詢。 因此,如果未指定LUP_FLUSHCACHE,應用程式應該預期查詢可能不會傳回任何結果(錯誤碼為 WSASERVICE_NOT_FOUND)。 未來可能會增強使用 Windows Sockets 介面提供的快取數據。 |
LUP_RES_SERVICE | 傳回本機 藍牙 位址的相關信息。 只有在同時指定LUP_RETURN_ADDR時,此旗標才會生效。 |
LUP_RETURN_NAME | 針對 WSALookupServiceNext 函式的每個呼叫,傳回 WSAQUERYSET 結構的 lpszServiceInstanceName 成員中服務的顯示名稱。 |
LUP_RETURN_TYPE | 傳回 WSAQUERYSET 結構的 lpServiceClassId 成員中的服務類別標識碼。 注意: 使用此旗標僅適用於 WSALookupServiceBegin 函式。 WSALookupServiceNext 的這個值一律為零。 |
LUP_RETURN_ADDR | 傳回 lpcsaBuffer 成員中要與 connect 函式呼叫搭配使用的位址。 傳回的位址包含埠號碼。 |
LUP_RETURN_BLOB | 根據 藍牙 SDP 記錄規格,傳回 lpBlob 成員中的相符 SD 記錄。 |
LUP_RETURN_ALL | 傳回上述所有旗標的資訊。 |
LUP_RETURN_COMMENT | 針對 WSALookupServiceNext 函式的每個呼叫,傳回 WSAQUERYSET 結構的 lpszComment 成員中的服務描述。 |
LUP_FLUSHPREVIOUS | 略過下一個可用的記錄,並傳回其後面的記錄。 |
進階服務查詢
上一節中所述的查詢作業可用來從單一 GUID 傳回所有結果,這應該足以讓大多數應用程式使用。 進階查詢可讓應用程式建立更具體的查詢;它提供在傳回資訊中比對 UUID 和屬性的功能。
若要執行服務的進階查詢,藍牙 客戶端必須在傳遞至 lpqsRestrictions 參數的 WSAQUERYSET 結構中指定下列限制。
WSAQUERYSET 成員 | 限制 |
---|---|
dwSize | 設定為 sizeof(WSAQUERYSET)。 |
lpszContext | 設定為用來建立 SDP 連線以執行服務查詢的 藍牙 裝置位址。 這個成員必須是使用 WSAAddressToString 函式轉換的字串。 如果提供本機無線電位址,則會搜尋本機 SDP 記錄。 |
lpBlob.pBlobData | BTH_QUERY_SERVICE結構的指標,其中包含限制查詢結果的所有參數。 |
dwNameSpace | 設定為 NS_BTH。 |
其他成員 | 會忽略 WSAQUERYSET 結構的其他所有成員。 |
下列旗標會在 WSALookupServiceBegin 的 dwControlFlags 參數中傳遞,以控制進階查詢的結果。
旗標 | 結果 |
---|---|
LUP_CONTAINERS | 不得設定。 |
LUP_FLUSHCACHE | 應用程式通常應該指定 LUP_FLUSHCACHE。 此旗標會指示系統忽略任何快取的資訊,並建立與指定裝置的無線 SDP 連線,以執行 SDP 搜尋。 此非快取作業可能需要幾秒鐘的時間(而快取的搜尋會快速傳回)。 藍牙 不會主動快取來自附近裝置的 SDP 記錄,也不會主動快取先前的查詢。 因此,如果未指定LUP_FLUSHCACHE,應用程式應該預期查詢經常不會傳回任何結果(WSASERVICE_NOT_FOUND)。 未來可能會增強使用 Windows Sockets 介面提供的快取數據。 |
LUP_RES_SERVICE | 傳回本機 藍牙 地址的資訊。 只有在同時指定LUP_RETURN_ADDRR時,設定此旗標才會生效。 |
LUP_RETURN_NAME | 傳回服務的顯示名稱。 SDP_SERVICE_SEARCH_REQUEST會忽略此旗標。 |
LUP_RETURN_TYPE | 傳回服務類別標識碼。 SDP_SERVICE_SEARCH_REQUEST會忽略此旗標。 |
LUP_RETURN_ADDR | 傳回 lpcsaBuffer 成員中要與 connect 函式呼叫搭配使用的位址。 傳回的位址包含埠號碼。 SDP_SERVICE_SEARCH_REQUEST會忽略此旗標。 |
LUP_RETURN_BLOB | 以符合 藍牙 SDP 記錄規格的格式傳回相符的 SD 記錄。 針對 SDP_SERVICE_SEARCH_REQUEST,後續呼叫 WSALookupServiceNext 的結果為 lpBlob 是 藍牙 SDP 句柄的陣列。 對於SDP_SERVICE_ATTRIBUTE_REQUEST和SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST,每個後續呼叫 WSALookupServiceNext 的結果都是二進位 藍牙 SDP 記錄,其屬性僅限於查詢 pRange 成員所指定的記錄。 SDP_SERVICE_SEARCH_REQUEST需要 此旗標。 |
LUP_RETURN_COMMENT | 針對 WSALookupServiceNext 函式的每個呼叫,傳回 WSAQUERYSET 結構的 lpszComment 成員中的服務描述。 |
LUP_FLUSHPREVIOUS | 略過下一個可用的記錄,並傳回其後面的記錄。 |
在輸入時,lpBlob-pBlobData> 指向包含下表所列值的BTH_QUERY_SERVICE結構。
注意
初始搜尋要求必須能夠放入一個 L2CAP 封包中。 不過,回應可能會分成許多 L2CAP 封包。
member | 值 |
---|---|
type | 要執行的搜尋類型。 此值可以是SDP_SERVICE_SEARCH_REQUEST、SDP_SERVICE_ATTRIBUTE_REQUEST或SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST之一。 每個搜尋類型都會與 藍牙 SDP 規格所定義的基礎搜尋機制相關聯。 每個傳回結果都會以 WSAQUERYSET 結構所描述 的形式呈現,而 WSAQUERYSET 結構稍早在此(進階服務查詢)一節中定義。 |
serviceHandle | 用於屬性搜尋。 這個值會指定要用來查詢 pRange 成員中屬性的服務句柄。 |
uuids | 用於服務和 serviceAttribute 搜尋。 這個值會指定記錄必須包含以符合搜尋的 UUID。 如果要查詢小於 MAX_UUIDS_IN_QUERY UUID,這個值會將 SdpQueryUuid 元素設定在最後一個有效 UUID 之後立即設為所有零。 |
numRange | 用於屬性和服務 Attribute 搜尋。 這個值會指定 pRange 中的項目數目。 |
pRange | 用於屬性和服務 Attribute 搜尋。 這個值會指定要針對任何相符記錄擷取的屬性值。 |
每次成功呼叫 WSALookupServiceNext 函式之後,lpBlob-pBlobData> 會指向包含下表所列值的區塊數據。
值 | Description |
---|---|
SDP_SERVICE_SEARCH_REQUEST | SDP 記錄句柄的陣列,與 藍牙 1.1 SDP 4.5.2 所定義的 ServiceRecordHandleList 相同。 傳回的 SDP 句柄數目是由 (lpBlob-cbSize>)/sizeof(ULONG) 計算。 所有結果都會在對 WSALookupServiceNext 函式的單一呼叫中傳回。 |
SDP_SERVICE_ATTRIBUTE_REQUEST或SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST | 二進位 藍牙 SDP 記錄。 針對SDP_SERVICE_ATTRIBUTE_REQUEST,所有結果都會以對 WSALookupServiceNext 函式的單一呼叫傳回。 |
注意
如果在服務查詢的輸入期間未指定 lpBlob 成員,則會針對從 0 到 0xFFFF 之屬性上的 lpServiceClassId 成員中指定的服務執行服務和屬性搜尋。