• 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_mode"
18 
19 #include <inttypes.h>
20 #include <chrono>
21 #include <cstdint>
22 #include <cstdio>
23 #include <future>
24 #include <map>
25 #include <string>
26 
27 #include "base/logging.h"  // LOG() stdout and android log
28 #include "btif/include/stack_manager.h"
29 #include "osi/include/log.h"  // android log only
30 #include "stack/include/btm_api.h"
31 #include "stack/include/btm_api_types.h"
32 #include "stack/include/hci_error_code.h"
33 #include "stack/include/l2cap_acl_interface.h"
34 #include "test/headless/connect/connect.h"
35 #include "test/headless/get_options.h"
36 #include "test/headless/headless.h"
37 #include "test/headless/interface.h"
38 #include "types/raw_address.h"
39 
40 const stack_manager_t* stack_manager_get_interface();
41 
power_mode_callback(const RawAddress & p_bda,tBTM_PM_STATUS status,uint16_t value,tHCI_STATUS hci_status)42 void power_mode_callback([[maybe_unused]] const RawAddress& p_bda,
43                          [[maybe_unused]] tBTM_PM_STATUS status,
44                          [[maybe_unused]] uint16_t value,
45                          [[maybe_unused]] tHCI_STATUS hci_status) {
46   fprintf(stdout, "Got callback\n");
47 };
48 
49 namespace connect {
50 std::promise<acl_state_changed_params_t> acl_state_changed_promise;
51 
52 }  // namespace connect
53 
callback_interface(callback_data_t * data)54 void callback_interface(callback_data_t* data) {
55   if (data->Name() == "acl_state_changed") {
56     LOG(INFO) << "Received acl state changed discovery";
57     auto params = static_cast<acl_state_changed_params_t*>(data);
58     acl_state_changed_params_t p(*params);
59     connect::acl_state_changed_promise.set_value(p);
60   }
61   LOG(ERROR) << "Received unexpected interface callback";
62 }
63 
64 namespace {
65 
do_connect(unsigned int num_loops,const RawAddress & bd_addr,std::list<std::string> options)66 int do_connect([[maybe_unused]] unsigned int num_loops,
67                [[maybe_unused]] const RawAddress& bd_addr,
68                [[maybe_unused]] std::list<std::string> options) {
69   int disconnect_wait_time{0};
70 
71   if (options.size() != 0) {
72     std::string opt = options.front();
73     options.pop_front();
74     auto v = bluetooth::test::headless::GetOpt::Split(opt);
75     if (v.size() == 2) {
76       if (v[0] == "wait") disconnect_wait_time = std::stoi(v[1]);
77     }
78   }
79   ASSERT_LOG(disconnect_wait_time >= 0, "Time cannot go backwards");
80 
81   headless_add_callback("acl_state_changed", callback_interface);
82 
83   connect::acl_state_changed_promise =
84       std::promise<acl_state_changed_params_t>();
85   auto future = connect::acl_state_changed_promise.get_future();
86 
87   fprintf(stdout, "Creating connection to:%s\n", bd_addr.ToString().c_str());
88   LOG(INFO) << "Creating classic connection to " << bd_addr.ToString();
89   acl_create_classic_connection(bd_addr, false, false);
90 
91   auto result = future.get();
92   LOG_CONSOLE("Connected created %s", result.ToString().c_str());
93 
94   connect::acl_state_changed_promise =
95       std::promise<acl_state_changed_params_t>();
96   future = connect::acl_state_changed_promise.get_future();
97 
98   uint64_t connect = std::chrono::duration_cast<std::chrono::milliseconds>(
99                          std::chrono::system_clock::now().time_since_epoch())
100                          .count();
101 
102   fprintf(stdout, "Just crushing stack\n");
103   LOG(INFO) << "Just crushing stack";
104   bluetoothInterface.disable();
105 
106   if (disconnect_wait_time == 0) {
107     fprintf(stdout, "Waiting to disconnect from supervision timeout\n");
108     auto result = future.get();
109     uint64_t disconnect =
110         std::chrono::duration_cast<std::chrono::milliseconds>(
111             std::chrono::system_clock::now().time_since_epoch())
112             .count();
113 
114     LOG_CONSOLE("Disconnected after:%" PRId64 "ms from:%s result:%s[%u]\n",
115                 disconnect - connect, bd_addr.ToString().c_str(),
116                 bt_status_text(result.status).c_str(), result.status);
117     headless_remove_callback("acl_state_changed", callback_interface);
118   } else {
119     fprintf(stdout, "Waiting %d seconds to just shutdown\n",
120             disconnect_wait_time);
121     bluetoothInterface.dump(1, nullptr);
122     bluetoothInterface.cleanup();
123   }
124   return 0;
125 }
126 
127 }  // namespace
128 
Run()129 int bluetooth::test::headless::Connect::Run() {
130   return RunOnHeadlessStack<int>([this]() {
131     return do_connect(options_.loop_, options_.device_.front(),
132                       options_.non_options_);
133   });
134 }
135