1 /*
2  * Copyright 2023 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 #pragma once
18 
19 #include <bluetooth/log.h>
20 
21 #include <deque>
22 #include <string>
23 
24 #include "gd/os/log.h"
25 #include "include/hardware/bluetooth.h"
26 #include "macros.h"
27 #include "test/headless/log.h"
28 #include "test/headless/property.h"
29 #include "test/headless/text.h"
30 #include "types/raw_address.h"
31 
32 using namespace bluetooth;
33 
34 enum class Callback {
35   AclStateChanged,
36   AdapterProperties,
37   DeviceFound,
38   DiscoveryStateChanged,
39   RemoteDeviceProperties,
40 };
41 
callback_text(const Callback & callback)42 inline std::string callback_text(const Callback& callback) {
43   switch (callback) {
44     CASE_RETURN_TEXT(Callback::AclStateChanged);
45     CASE_RETURN_TEXT(Callback::AdapterProperties);
46     CASE_RETURN_TEXT(Callback::DeviceFound);
47     CASE_RETURN_TEXT(Callback::DiscoveryStateChanged);
48     CASE_RETURN_TEXT(Callback::RemoteDeviceProperties);
49   }
50   RETURN_UNKNOWN_TYPE_STRING(Callback, callback);
51 }
52 
53 struct callback_data_t {
Namecallback_data_t54   std::string Name() const { return std::string(name_); }
CallbackTypecallback_data_t55   Callback CallbackType() const { return callback_type_; }
56 
TimestampInMscallback_data_t57   uint64_t TimestampInMs() const {
58     return static_cast<uint64_t>(timestamp_ms_);
59   }
60   virtual ~callback_data_t() = default;
61 
62   virtual std::string ToString() const = 0;
63 
64  protected:
callback_data_tcallback_data_t65   callback_data_t(const char* name, Callback callback_type_)
66       : name_(name),
67         callback_type_(callback_type_),
68         timestamp_ms_(GetTimestampMs()) {}
69 
70  private:
71   const char* name_;
72   const Callback callback_type_;
73   const long long timestamp_ms_;
74 };
75 
76 struct callback_params_t : public callback_data_t {
ToStringcallback_params_t77   virtual std::string ToString() const override {
78     return std::string("VIRTUAL");
79   }
80 
81  protected:
callback_params_tcallback_params_t82   callback_params_t(const char* name, Callback callback_type)
83       : callback_data_t(name, callback_type) {}
84   virtual ~callback_params_t() = default;
85 };
86 
87 // Specializes the callback parameter
88 template <typename T>
89 // std::shared_ptr<T> Cast(std::shared_ptr<callback_params_t> params) { return
90 // std::shared_ptr<T>(static_cast<T*>(params.get()));}
Cast(std::shared_ptr<callback_params_t> params)91 std::shared_ptr<T> Cast(std::shared_ptr<callback_params_t> params) {
92   return std::make_shared<T>(*(static_cast<T*>(params.get())));
93 }
94 
95 struct callback_params_with_properties_t : public callback_params_t {
96  public:
propertiescallback_params_with_properties_t97   std::deque<bluetooth::test::headless::bt_property_t*> properties() const {
98     return property_queue_;
99   }
num_propertiescallback_params_with_properties_t100   size_t num_properties() const { return property_queue_.size(); }
101 
102  protected:
callback_params_with_properties_tcallback_params_with_properties_t103   callback_params_with_properties_t(const char* name, Callback callback_type,
104                                     int num_properties,
105                                     ::bt_property_t* properties)
106       : callback_params_t(name, callback_type) {
107     for (int i = 0; i < num_properties; i++) {
108       log::debug("Processing property {}/{} {} type:{} val:{}", i,
109                  num_properties, fmt::ptr(&properties[i]), properties[i].type,
110                  fmt::ptr(properties[i].val));
111       property_queue_.push_back(
112           bluetooth::test::headless::property_factory(properties[i]));
113     }
114   }
115   virtual ~callback_params_with_properties_t() = default;
116 
117  private:
118   std::deque<bluetooth::test::headless::bt_property_t*> property_queue_;
119 };
120 
121 struct acl_state_changed_params_t : public callback_params_t {
acl_state_changed_params_tacl_state_changed_params_t122   acl_state_changed_params_t(bt_status_t status, RawAddress remote_bd_addr,
123                              bt_acl_state_t state, int transport_link_type,
124                              bt_hci_error_code_t hci_reason,
125                              bt_conn_direction_t direction, uint16_t acl_handle)
126       : callback_params_t("acl_state_changed", Callback::AclStateChanged),
127         status(status),
128         remote_bd_addr(remote_bd_addr),
129         state(state),
130         transport_link_type(transport_link_type),
131         hci_reason(hci_reason),
132         direction(direction),
133         acl_handle(acl_handle) {}
134   acl_state_changed_params_t(const acl_state_changed_params_t& params) =
135       default;
~acl_state_changed_params_tacl_state_changed_params_t136   virtual ~acl_state_changed_params_t() {}
137 
138   bt_status_t status;
139   RawAddress remote_bd_addr;
140   bt_acl_state_t state;
141   int transport_link_type;
142   bt_hci_error_code_t hci_reason;
143   bt_conn_direction_t direction;
144   uint16_t acl_handle;
145 
ToStringacl_state_changed_params_t146   std::string ToString() const override {
147     return fmt::format(
148         "status:{} remote_bd_addr:{} state:{} transport:{} reason:{}"
149         " direction:{} handle:{}",
150         bt_status_text(status), remote_bd_addr.ToString(),
151         (state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED",
152         bt_transport_text(
153             static_cast<const tBT_TRANSPORT>(transport_link_type)),
154         bt_status_text(static_cast<const bt_status_t>(hci_reason)),
155         bt_conn_direction_text(direction), acl_handle);
156   }
157 };
158 
159 struct discovery_state_changed_params_t : public callback_params_t {
discovery_state_changed_params_tdiscovery_state_changed_params_t160   discovery_state_changed_params_t(bt_discovery_state_t state)
161       : callback_params_t("discovery_state_changed",
162                           Callback::DiscoveryStateChanged),
163         state(state) {}
164   discovery_state_changed_params_t(
165       const discovery_state_changed_params_t& params) = default;
166 
~discovery_state_changed_params_tdiscovery_state_changed_params_t167   virtual ~discovery_state_changed_params_t() {}
168 
169   bt_discovery_state_t state;
ToStringdiscovery_state_changed_params_t170   std::string ToString() const override {
171     return fmt::format("state:{}", bt_discovery_state_text(state));
172   }
173 };
174 
175 struct adapter_properties_params_t : public callback_params_with_properties_t {
adapter_properties_params_tadapter_properties_params_t176   adapter_properties_params_t(bt_status_t status, int num_properties,
177                               ::bt_property_t* properties)
178       : callback_params_with_properties_t("adapter_properties",
179                                           Callback::AdapterProperties,
180                                           num_properties, properties),
181         status(status) {}
182   adapter_properties_params_t(const adapter_properties_params_t& params) =
183       default;
184 
~adapter_properties_params_tadapter_properties_params_t185   virtual ~adapter_properties_params_t() {}
186   bt_status_t status;
187 
ToStringadapter_properties_params_t188   std::string ToString() const override {
189     return fmt::format("status:{} num_properties:{}", bt_status_text(status),
190                        num_properties());
191   }
192 };
193 
194 struct remote_device_properties_params_t
195     : public callback_params_with_properties_t {
remote_device_properties_params_tremote_device_properties_params_t196   remote_device_properties_params_t(bt_status_t status, RawAddress bd_addr,
197                                     int num_properties,
198                                     ::bt_property_t* properties)
199       : callback_params_with_properties_t("remote_device_properties",
200                                           Callback::RemoteDeviceProperties,
201                                           num_properties, properties),
202         status(status),
203         bd_addr(bd_addr) {}
204   remote_device_properties_params_t(
205       const remote_device_properties_params_t& params) = default;
206 
~remote_device_properties_params_tremote_device_properties_params_t207   virtual ~remote_device_properties_params_t() {}
208   bt_status_t status;
209   RawAddress bd_addr;
210 
ToStringremote_device_properties_params_t211   std::string ToString() const override {
212     return fmt::format("status:{} bd_addr:{} num_properties:{}",
213                        bt_status_text(status), bd_addr.ToString(),
214                        num_properties());
215   }
216 };
217 
218 struct device_found_params_t : public callback_params_with_properties_t {
device_found_params_tdevice_found_params_t219   device_found_params_t(int num_properties, ::bt_property_t* properties)
220       : callback_params_with_properties_t("device_found", Callback::DeviceFound,
221                                           num_properties, properties) {}
222 
223   device_found_params_t(const device_found_params_t& params) = default;
~device_found_params_tdevice_found_params_t224   virtual ~device_found_params_t() {}
225 
ToStringdevice_found_params_t226   std::string ToString() const override {
227     return fmt::format("num_properties:{}", num_properties());
228   }
229 };
230 
231 using callback_function_t = void (*)(callback_data_t*);
232 
233 void headless_add_callback(const std::string interface_name,
234                            callback_function_t function);
235 void headless_remove_callback(const std::string interface_name);
236