/* * Copyright 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "bt_headless_sdp" #include "test/headless/sdp/sdp.h" #include #include "bta/dm/bta_dm_int.h" #include "bta/include/bta_api.h" #include "stack/include/sdp_api.h" #include "test/headless/get_options.h" #include "test/headless/headless.h" #include "test/headless/sdp/sdp_db.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" using namespace bluetooth::legacy::stack::sdp; using namespace bluetooth::test::headless; static void bta_jv_start_discovery_callback(std::promise* promise, const RawAddress& /* bd_addr */, tSDP_STATUS result) { promise->set_value(result); } namespace { constexpr size_t kMaxDiscoveryRecords = 1024; int sdp_query_uuid([[maybe_unused]] unsigned int num_loops, [[maybe_unused]] const RawAddress& raw_address, [[maybe_unused]] const bluetooth::Uuid& uuid) { SdpDb sdp_discovery_db(kMaxDiscoveryRecords); if (!get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb( sdp_discovery_db.RawPointer(), sdp_discovery_db.Length(), 1, // num_uuid, &uuid, 0, nullptr)) { LOG_CONSOLE("Unable to initialize sdp discovery"); return -1; } LOG_CONSOLE("Initialized sdp discovery database"); std::promise promise; auto future = promise.get_future(); sdp_discovery_db.Print(stdout); if (!get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest2( raw_address, sdp_discovery_db.RawPointer(), base::BindRepeating(bta_jv_start_discovery_callback, &promise))) { fprintf(stdout, "%s Failed to start search attribute request\n", __func__); return -2; } LOG_CONSOLE("Started service search for uuid:%s", uuid.ToString().c_str()); const tSDP_STATUS result = future.get(); if (result != SDP_SUCCESS) { fprintf(stdout, "Failed search discovery result:%s\n", sdp_status_text(result).c_str()); return result; } LOG_CONSOLE("Found records peer:%s uuid:%s", raw_address.ToString().c_str(), uuid.ToString().c_str()); for (unsigned i = 0; i < BTA_MAX_SERVICE_ID; i++) { uint16_t uuid_as16Bit = bta_service_id_to_uuid_lkup_tbl[i]; tSDP_DISC_REC* rec = SDP_FindServiceInDb(sdp_discovery_db.RawPointer(), uuid_as16Bit, nullptr); if (rec != nullptr) { LOG_CONSOLE(" uuid:0x%x", uuid_as16Bit); } } return 0; } } // namespace int bluetooth::test::headless::Sdp::Run() { if (options_.loop_ < 1) { printf("This test requires at least a single loop\n"); options_.Usage(); return -1; } if (options_.device_.size() != 1) { printf("This test requires a single device specified\n"); options_.Usage(); return -1; } if (options_.uuid_.size() != 1) { printf("This test requires a single uuid specified\n"); options_.Usage(); return -1; } return RunOnHeadlessStack([this]() { return sdp_query_uuid(options_.loop_, options_.device_.front(), options_.uuid_.front()); }); }