• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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_discovery"
18 
19 #include "test/headless/discovery/discovery.h"
20 
21 #include <future>
22 
23 #include "base/logging.h"  // LOG() stdout and android log
24 #include "btif/include/btif_api.h"
25 #include "osi/include/log.h"  // android log only
26 #include "stack/include/sdp_api.h"
27 #include "test/headless/bt_property.h"
28 #include "test/headless/get_options.h"
29 #include "test/headless/headless.h"
30 #include "test/headless/interface.h"
31 #include "test/headless/log.h"
32 #include "test/headless/messenger.h"
33 #include "test/headless/sdp/sdp.h"
34 #include "test/headless/stopwatch.h"
35 #include "test/headless/timeout.h"
36 #include "types/bluetooth/uuid.h"
37 #include "types/raw_address.h"
38 
39 using namespace bluetooth::test::headless;
40 using namespace std::chrono_literals;
41 
42 namespace {
43 
start_discovery(unsigned int num_loops,const RawAddress & raw_address)44 int start_discovery([[maybe_unused]] unsigned int num_loops,
45                     const RawAddress& raw_address) {
46   RawAddress bd_addr{raw_address};
47 
48   Stopwatch acl_stopwatch("ACL_connection");
49   Stopwatch sdp_stopwatch("SDP_discovery");
50 
51   LOG_CONSOLE("Started service discovery");
52   auto check_point = messenger::sdp::get_check_point();
53   ASSERT(bluetoothInterface.get_remote_services(&bd_addr, 0) ==
54          BT_STATUS_SUCCESS);
55 
56   if (!messenger::acl::await_connected(8s)) {
57     LOG_CONSOLE("TIMEOUT waiting for connection to %s",
58                 raw_address.ToString().c_str());
59     return -1;
60   }
61   LOG_CONSOLE("ACL connected to %s :%sms", STR(raw_address),
62               STR(acl_stopwatch));
63 
64   if (!messenger::sdp::await_service_discovery(8s, check_point, 1UL)) {
65     LOG_CONSOLE("TIMEOUT waiting for service discovery to %s",
66                 raw_address.ToString().c_str());
67     return -1;
68   }
69   auto callback_queue = messenger::sdp::collect_from(check_point);
70   ASSERT_LOG(callback_queue.size() == 1,
71              "Received unexpected number of SDP queries");
72 
73   auto params = callback_queue.front();
74   callback_queue.pop_front();
75 
76   LOG_CONSOLE("got remote services :%s", params.ToString().c_str());
77 
78   for (int i = 0; i < params.num_properties; i++) {
79     process_property(params.bd_addr, params.properties + i);
80   }
81 
82   // Run a second fetch SDP
83   {
84     LOG_CONSOLE("Sending second SDP request");
85     auto check_point = messenger::sdp::get_check_point();
86 
87     ASSERT(bluetoothInterface.get_remote_services(&bd_addr, 0) ==
88            BT_STATUS_SUCCESS);
89 
90     if (!messenger::acl::await_connected(8s)) {
91       LOG_CONSOLE("TIMEOUT waiting for connection to %s",
92                   raw_address.ToString().c_str());
93       return -1;
94     }
95     LOG_CONSOLE("ACL connected to %s :%sms", STR(raw_address),
96                 STR(acl_stopwatch));
97 
98     if (!messenger::sdp::await_service_discovery(8s, check_point, 1UL)) {
99       LOG_CONSOLE("TIMEOUT waiting for service discovery to %s",
100                   raw_address.ToString().c_str());
101       return -1;
102     }
103     auto callback_queue = messenger::sdp::collect_from(check_point);
104     ASSERT_LOG(callback_queue.size() == 1,
105                "Received unexpected number of SDP queries");
106 
107     auto params = callback_queue.front();
108     callback_queue.pop_front();
109 
110     LOG_CONSOLE("got remote services :%s", params.ToString().c_str());
111 
112     for (int i = 0; i < params.num_properties; i++) {
113       process_property(params.bd_addr, params.properties + i);
114     }
115   }
116 
117   // Run a third fetch SDP
118   {
119     LOG_CONSOLE("Sending third SDP request");
120     auto check_point = messenger::sdp::get_check_point();
121 
122     ASSERT(bluetoothInterface.get_remote_services(&bd_addr, 0) ==
123            BT_STATUS_SUCCESS);
124 
125     if (!messenger::acl::await_connected(8s)) {
126       LOG_CONSOLE("TIMEOUT waiting for connection to %s",
127                   raw_address.ToString().c_str());
128       return -1;
129     }
130     LOG_CONSOLE("ACL connected to %s :%sms", STR(raw_address),
131                 STR(acl_stopwatch));
132 
133     if (!messenger::sdp::await_service_discovery(8s, check_point, 1UL)) {
134       LOG_CONSOLE("TIMEOUT waiting for service discovery to %s",
135                   raw_address.ToString().c_str());
136       return -1;
137     }
138     auto callback_queue = messenger::sdp::collect_from(check_point);
139     ASSERT_LOG(callback_queue.size() == 1,
140                "Received unexpected number of SDP queries");
141 
142     auto params = callback_queue.front();
143     callback_queue.pop_front();
144 
145     LOG_CONSOLE("got remote services :%s", params.ToString().c_str());
146 
147     for (int i = 0; i < params.num_properties; i++) {
148       process_property(params.bd_addr, params.properties + i);
149     }
150   }
151 
152   LOG_CONSOLE("Awaiting disconnect");
153   if (!messenger::acl::await_disconnected(6s)) {
154     LOG_CONSOLE("TIMEOUT waiting for disconnection to %s",
155                 raw_address.ToString().c_str());
156     return -1;
157   }
158 
159   LOG_CONSOLE("Dumpsys system");
160   bluetoothInterface.dump(2, nullptr);
161   LOG_CONSOLE("Done dumpsys system");
162 
163   return 0;
164 }
165 
166 }  // namespace
167 
168 // extern uint8_t btu_trace_level;
169 
Run()170 int bluetooth::test::headless::Discovery::Run() {
171   if (options_.loop_ < 1) {
172     LOG_CONSOLE("This test requires at least a single loop");
173     options_.Usage();
174     return -1;
175   }
176   if (options_.device_.size() != 1) {
177     LOG_CONSOLE("This test requires a single device specified");
178     options_.Usage();
179     return -1;
180   }
181   return RunOnHeadlessStack<int>([this]() {
182     return start_discovery(options_.loop_, options_.device_.front());
183   });
184 }
185