• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "bt_headless_sdp"
18 
19 #include "test/headless/sdp/sdp.h"
20 
21 #include <future>
22 
23 #include "bta/dm/bta_dm_int.h"
24 #include "bta/include/bta_api.h"
25 #include "stack/include/sdp_api.h"
26 #include "test/headless/get_options.h"
27 #include "test/headless/headless.h"
28 #include "test/headless/sdp/sdp_db.h"
29 #include "types/bluetooth/uuid.h"
30 #include "types/raw_address.h"
31 
32 using namespace bluetooth::legacy::stack::sdp;
33 using namespace bluetooth::test::headless;
34 
bta_jv_start_discovery_callback(std::promise<tSDP_STATUS> * promise,const RawAddress &,tSDP_STATUS result)35 static void bta_jv_start_discovery_callback(std::promise<tSDP_STATUS>* promise,
36                                             const RawAddress& /* bd_addr */,
37                                             tSDP_STATUS result) {
38   promise->set_value(result);
39 }
40 
41 namespace {
42 
43 constexpr size_t kMaxDiscoveryRecords = 1024;
44 
sdp_query_uuid(unsigned int num_loops,const RawAddress & raw_address,const bluetooth::Uuid & uuid)45 int sdp_query_uuid([[maybe_unused]] unsigned int num_loops,
46                    [[maybe_unused]] const RawAddress& raw_address,
47                    [[maybe_unused]] const bluetooth::Uuid& uuid) {
48   SdpDb sdp_discovery_db(kMaxDiscoveryRecords);
49 
50   if (!get_legacy_stack_sdp_api()->service.SDP_InitDiscoveryDb(
51           sdp_discovery_db.RawPointer(), sdp_discovery_db.Length(),
52           1,  // num_uuid,
53           &uuid, 0, nullptr)) {
54     LOG_CONSOLE("Unable to initialize sdp discovery");
55     return -1;
56   }
57   LOG_CONSOLE("Initialized sdp discovery database");
58 
59   std::promise<tSDP_STATUS> promise;
60   auto future = promise.get_future();
61 
62   sdp_discovery_db.Print(stdout);
63 
64   if (!get_legacy_stack_sdp_api()->service.SDP_ServiceSearchAttributeRequest2(
65           raw_address, sdp_discovery_db.RawPointer(),
66           base::BindRepeating(bta_jv_start_discovery_callback, &promise))) {
67     fprintf(stdout, "%s Failed to start search attribute request\n", __func__);
68     return -2;
69   }
70   LOG_CONSOLE("Started service search for uuid:%s", uuid.ToString().c_str());
71 
72   const tSDP_STATUS result = future.get();
73   if (result != SDP_SUCCESS) {
74     fprintf(stdout, "Failed search discovery result:%s\n",
75             sdp_status_text(result).c_str());
76     return result;
77   }
78 
79   LOG_CONSOLE("Found records peer:%s uuid:%s", raw_address.ToString().c_str(),
80               uuid.ToString().c_str());
81   for (unsigned i = 0; i < BTA_MAX_SERVICE_ID; i++) {
82     uint16_t uuid_as16Bit = bta_service_id_to_uuid_lkup_tbl[i];
83     tSDP_DISC_REC* rec = SDP_FindServiceInDb(sdp_discovery_db.RawPointer(),
84                                              uuid_as16Bit, nullptr);
85     if (rec != nullptr) {
86       LOG_CONSOLE("   uuid:0x%x", uuid_as16Bit);
87     }
88   }
89 
90   return 0;
91 }
92 
93 }  // namespace
94 
Run()95 int bluetooth::test::headless::Sdp::Run() {
96   if (options_.loop_ < 1) {
97     printf("This test requires at least a single loop\n");
98     options_.Usage();
99     return -1;
100   }
101   if (options_.device_.size() != 1) {
102     printf("This test requires a single device specified\n");
103     options_.Usage();
104     return -1;
105   }
106   if (options_.uuid_.size() != 1) {
107     printf("This test requires a single uuid specified\n");
108     options_.Usage();
109     return -1;
110   }
111 
112   return RunOnHeadlessStack<int>([this]() {
113     return sdp_query_uuid(options_.loop_, options_.device_.front(),
114                           options_.uuid_.front());
115   });
116 }
117