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 "include/hardware/bluetooth.h"
25 #include "macros.h"
26 #include "test/headless/log.h"
27 #include "test/headless/property.h"
28 #include "test/headless/text.h"
29 #include "types/raw_address.h"
30 
31 using namespace bluetooth;
32 
33 enum class Callback {
34   AclStateChanged,
35   AdapterProperties,
36   DeviceFound,
37   DiscoveryStateChanged,
38   RemoteDeviceProperties,
39 };
40 
callback_text(const Callback & callback)41 inline std::string callback_text(const Callback& callback) {
42   switch (callback) {
43     CASE_RETURN_TEXT(Callback::AclStateChanged);
44     CASE_RETURN_TEXT(Callback::AdapterProperties);
45     CASE_RETURN_TEXT(Callback::DeviceFound);
46     CASE_RETURN_TEXT(Callback::DiscoveryStateChanged);
47     CASE_RETURN_TEXT(Callback::RemoteDeviceProperties);
48   }
49   RETURN_UNKNOWN_TYPE_STRING(Callback, callback);
50 }
51 
52 struct callback_data_t {
Namecallback_data_t53   std::string Name() const { return std::string(name_); }
CallbackTypecallback_data_t54   Callback CallbackType() const { return callback_type_; }
55 
TimestampInMscallback_data_t56   uint64_t TimestampInMs() const { return static_cast<uint64_t>(timestamp_ms_); }
57   virtual ~callback_data_t() = default;
58 
59   virtual std::string ToString() const = 0;
60 
61 protected:
callback_data_tcallback_data_t62   callback_data_t(const char* name, Callback callback_type_)
63       : name_(name), callback_type_(callback_type_), timestamp_ms_(GetTimestampMs()) {}
64 
65 private:
66   const char* name_;
67   const Callback callback_type_;
68   const uint64_t timestamp_ms_;
69 };
70 
71 struct callback_params_t : public callback_data_t {
ToStringcallback_params_t72   virtual std::string ToString() const override { return std::string("VIRTUAL"); }
73 
74 protected:
callback_params_tcallback_params_t75   callback_params_t(const char* name, Callback callback_type)
76       : callback_data_t(name, callback_type) {}
77   virtual ~callback_params_t() = default;
78 };
79 
80 // Specializes the callback parameter
81 template <typename T>
82 // std::shared_ptr<T> Cast(std::shared_ptr<callback_params_t> params) { return
83 // std::shared_ptr<T>(static_cast<T*>(params.get()));}
Cast(std::shared_ptr<callback_params_t> params)84 std::shared_ptr<T> Cast(std::shared_ptr<callback_params_t> params) {
85   return std::make_shared<T>(*(static_cast<T*>(params.get())));
86 }
87 
88 struct callback_params_with_properties_t : public callback_params_t {
89 public:
propertiescallback_params_with_properties_t90   std::deque<bluetooth::test::headless::bt_property_t*> properties() const {
91     return property_queue_;
92   }
num_propertiescallback_params_with_properties_t93   size_t num_properties() const { return property_queue_.size(); }
94 
95 protected:
callback_params_with_properties_tcallback_params_with_properties_t96   callback_params_with_properties_t(const char* name, Callback callback_type, int num_properties,
97                                     ::bt_property_t* properties)
98       : callback_params_t(name, callback_type) {
99     for (int i = 0; i < num_properties; i++) {
100       log::debug("Processing property {}/{} {} type:{} val:{}", i, num_properties,
101                  std::format_ptr(&properties[i]), properties[i].type,
102                  std::format_ptr(properties[i].val));
103       property_queue_.push_back(bluetooth::test::headless::property_factory(properties[i]));
104     }
105   }
106   virtual ~callback_params_with_properties_t() = default;
107 
108 private:
109   std::deque<bluetooth::test::headless::bt_property_t*> property_queue_;
110 };
111 
112 struct acl_state_changed_params_t : public callback_params_t {
acl_state_changed_params_tacl_state_changed_params_t113   acl_state_changed_params_t(bt_status_t status, RawAddress remote_bd_addr, bt_acl_state_t state,
114                              int transport_link_type, bt_hci_error_code_t hci_reason,
115                              bt_conn_direction_t direction, uint16_t acl_handle)
116       : callback_params_t("acl_state_changed", Callback::AclStateChanged),
117         status(status),
118         remote_bd_addr(remote_bd_addr),
119         state(state),
120         transport_link_type(transport_link_type),
121         hci_reason(hci_reason),
122         direction(direction),
123         acl_handle(acl_handle) {}
124   acl_state_changed_params_t(const acl_state_changed_params_t& params) = default;
~acl_state_changed_params_tacl_state_changed_params_t125   virtual ~acl_state_changed_params_t() {}
126 
127   bt_status_t status;
128   RawAddress remote_bd_addr;
129   bt_acl_state_t state;
130   int transport_link_type;
131   bt_hci_error_code_t hci_reason;
132   bt_conn_direction_t direction;
133   uint16_t acl_handle;
134 
ToStringacl_state_changed_params_t135   std::string ToString() const override {
136     return std::format(
137             "status:{} remote_bd_addr:{} state:{} transport:{} reason:{}"
138             " direction:{} handle:{}",
139             bt_status_text(status), remote_bd_addr.ToString(),
140             (state == BT_ACL_STATE_CONNECTED) ? "CONNECTED" : "DISCONNECTED",
141             bt_transport_text(static_cast<const tBT_TRANSPORT>(transport_link_type)),
142             bt_status_text(static_cast<const bt_status_t>(hci_reason)),
143             bt_conn_direction_text(direction), acl_handle);
144   }
145 };
146 
147 struct discovery_state_changed_params_t : public callback_params_t {
discovery_state_changed_params_tdiscovery_state_changed_params_t148   discovery_state_changed_params_t(bt_discovery_state_t state)
149       : callback_params_t("discovery_state_changed", Callback::DiscoveryStateChanged),
150         state(state) {}
151   discovery_state_changed_params_t(const discovery_state_changed_params_t& params) = default;
152 
~discovery_state_changed_params_tdiscovery_state_changed_params_t153   virtual ~discovery_state_changed_params_t() {}
154 
155   bt_discovery_state_t state;
ToStringdiscovery_state_changed_params_t156   std::string ToString() const override {
157     return std::format("state:{}", bt_discovery_state_text(state));
158   }
159 };
160 
161 struct adapter_properties_params_t : public callback_params_with_properties_t {
adapter_properties_params_tadapter_properties_params_t162   adapter_properties_params_t(bt_status_t status, int num_properties, ::bt_property_t* properties)
163       : callback_params_with_properties_t("adapter_properties", Callback::AdapterProperties,
164                                           num_properties, properties),
165         status(status) {}
166   adapter_properties_params_t(const adapter_properties_params_t& params) = default;
167 
~adapter_properties_params_tadapter_properties_params_t168   virtual ~adapter_properties_params_t() {}
169   bt_status_t status;
170 
ToStringadapter_properties_params_t171   std::string ToString() const override {
172     return std::format("status:{} num_properties:{}", bt_status_text(status), num_properties());
173   }
174 };
175 
176 struct remote_device_properties_params_t : public callback_params_with_properties_t {
remote_device_properties_params_tremote_device_properties_params_t177   remote_device_properties_params_t(bt_status_t status, RawAddress bd_addr, int num_properties,
178                                     ::bt_property_t* properties)
179       : callback_params_with_properties_t("remote_device_properties",
180                                           Callback::RemoteDeviceProperties, num_properties,
181                                           properties),
182         status(status),
183         bd_addr(bd_addr) {}
184   remote_device_properties_params_t(const remote_device_properties_params_t& params) = default;
185 
~remote_device_properties_params_tremote_device_properties_params_t186   virtual ~remote_device_properties_params_t() {}
187   bt_status_t status;
188   RawAddress bd_addr;
189 
ToStringremote_device_properties_params_t190   std::string ToString() const override {
191     return std::format("status:{} bd_addr:{} num_properties:{}", bt_status_text(status),
192                        bd_addr.ToString(), num_properties());
193   }
194 };
195 
196 struct device_found_params_t : public callback_params_with_properties_t {
device_found_params_tdevice_found_params_t197   device_found_params_t(int num_properties, ::bt_property_t* properties)
198       : callback_params_with_properties_t("device_found", Callback::DeviceFound, num_properties,
199                                           properties) {}
200 
201   device_found_params_t(const device_found_params_t& params) = default;
~device_found_params_tdevice_found_params_t202   virtual ~device_found_params_t() {}
203 
ToStringdevice_found_params_t204   std::string ToString() const override {
205     return std::format("num_properties:{}", num_properties());
206   }
207 };
208 
209 using callback_function_t = void (*)(callback_data_t*);
210 
211 void headless_add_callback(const std::string interface_name, callback_function_t function);
212 void headless_remove_callback(const std::string interface_name);
213