• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "connection_shim.h"
16 
17 #include <algorithm>
18 #include <cstdint>
19 #include <iterator>
20 #include <optional>
21 
22 #include "hci/acl_manager.h"
23 #include "hci/address_with_type.h"
24 #include "hci/hci_packets.h"
25 #include "main/shim/entry.h"
26 #ifndef TARGET_FLOSS
27 #include "src/connection/ffi.rs.h"
28 #endif
29 #include "src/core/ffi/types.h"
30 #include "stack/btm/btm_dev.h"
31 
32 extern const tBLE_BD_ADDR convert_to_address_with_type(
33     const RawAddress& bd_addr, const tBTM_SEC_DEV_REC* p_dev_rec);
34 
35 namespace bluetooth {
36 namespace connection {
37 
38 #ifdef TARGET_FLOSS
39 struct LeAclManagerCallbackShim {
OnLeConnectSuccessbluetooth::connection::LeAclManagerCallbackShim40   void OnLeConnectSuccess(core::AddressWithType addr) const {
41     LOG_ALWAYS_FATAL("system/rust not available in Floss");
42   }
OnLeConnectFailbluetooth::connection::LeAclManagerCallbackShim43   void OnLeConnectFail(core::AddressWithType addr, uint8_t status) const {
44     LOG_ALWAYS_FATAL("system/rust not available in Floss");
45   };
OnLeDisconnectionbluetooth::connection::LeAclManagerCallbackShim46   void OnLeDisconnection(core::AddressWithType addr) const {
47     LOG_ALWAYS_FATAL("system/rust not available in Floss");
48   };
49 };
50 
51 using BoxedLeAclManagerCallbackShim = std::unique_ptr<LeAclManagerCallbackShim>;
52 
53 #else
54 
55 using BoxedLeAclManagerCallbackShim = ::rust::Box<LeAclManagerCallbackShim>;
56 
57 #endif
58 
59 namespace {
ToCppAddress(core::AddressWithType address)60 hci::AddressWithType ToCppAddress(core::AddressWithType address) {
61   auto hci_address = hci::Address();
62   hci_address.FromOctets(address.address.data());
63   return hci::AddressWithType(hci_address,
64                               (hci::AddressType)address.address_type);
65 }
66 
ToRustAddress(hci::AddressWithType address)67 core::AddressWithType ToRustAddress(hci::AddressWithType address) {
68   return core::AddressWithType{address.GetAddress().address,
69                                (core::AddressType)address.GetAddressType()};
70 }
71 }  // namespace
72 
73 struct LeAclManagerShim::impl : hci::acl_manager::LeAcceptlistCallbacks {
74  public:
implbluetooth::connection::LeAclManagerShim::impl75   impl() { acl_manager_ = shim::GetAclManager(); }
76 
~implbluetooth::connection::LeAclManagerShim::impl77   ~impl() {
78     if (callbacks_.has_value()) {
79       callbacks_.reset();
80       auto promise = std::promise<void>();
81       auto future = promise.get_future();
82       acl_manager_->UnregisterLeAcceptlistCallbacks(this, std::move(promise));
83       future.wait();
84     }
85   }
86 
CreateLeConnectionbluetooth::connection::LeAclManagerShim::impl87   void CreateLeConnection(core::AddressWithType address, bool is_direct) {
88     acl_manager_->CreateLeConnection(ToCppAddress(address), is_direct);
89   }
90 
CancelLeConnectbluetooth::connection::LeAclManagerShim::impl91   void CancelLeConnect(core::AddressWithType address) {
92     acl_manager_->CancelLeConnect(ToCppAddress(address));
93   }
94 
95 #ifndef TARGET_FLOSS
RegisterRustCallbacksbluetooth::connection::LeAclManagerShim::impl96   void RegisterRustCallbacks(BoxedLeAclManagerCallbackShim callbacks) {
97     callbacks_ = std::move(callbacks);
98     acl_manager_->RegisterLeAcceptlistCallbacks(this);
99   }
100 #endif
101 
102   // hci::acl_manager::LeAcceptlistCallbacks
OnLeConnectSuccessbluetooth::connection::LeAclManagerShim::impl103   virtual void OnLeConnectSuccess(hci::AddressWithType address) {
104     callbacks_.value()->OnLeConnectSuccess(ToRustAddress(address));
105   }
106 
107   // hci::acl_manager::LeAcceptlistCallbacks
OnLeConnectFailbluetooth::connection::LeAclManagerShim::impl108   virtual void OnLeConnectFail(hci::AddressWithType address,
109                                hci::ErrorCode reason) {
110     callbacks_.value()->OnLeConnectFail(ToRustAddress(address),
111                                         static_cast<uint8_t>(reason));
112   }
113 
114   // hci::acl_manager::LeAcceptlistCallbacks
OnLeDisconnectionbluetooth::connection::LeAclManagerShim::impl115   virtual void OnLeDisconnection(hci::AddressWithType address) {
116     callbacks_.value()->OnLeDisconnection(ToRustAddress(address));
117   }
118 
119   // hci::acl_manager::LeAcceptlistCallbacks
OnResolvingListChangebluetooth::connection::LeAclManagerShim::impl120   virtual void OnResolvingListChange() {}
121 
122  private:
123   std::optional<BoxedLeAclManagerCallbackShim> callbacks_;
124   hci::AclManager* acl_manager_{};
125 };
126 
LeAclManagerShim()127 LeAclManagerShim::LeAclManagerShim() {
128   pimpl_ = std::make_unique<LeAclManagerShim::impl>();
129 }
130 
131 LeAclManagerShim::~LeAclManagerShim() = default;
132 
CreateLeConnection(core::AddressWithType address,bool is_direct) const133 void LeAclManagerShim::CreateLeConnection(core::AddressWithType address,
134                                           bool is_direct) const {
135   pimpl_->CreateLeConnection(address, is_direct);
136 }
137 
CancelLeConnect(core::AddressWithType address) const138 void LeAclManagerShim::CancelLeConnect(core::AddressWithType address) const {
139   pimpl_->CancelLeConnect(address);
140 }
141 
142 #ifndef TARGET_FLOSS
RegisterRustCallbacks(BoxedLeAclManagerCallbackShim callbacks)143 void LeAclManagerShim::RegisterRustCallbacks(
144     BoxedLeAclManagerCallbackShim callbacks) {
145   pimpl_->RegisterRustCallbacks(std::move(callbacks));
146 }
147 #endif
148 
149 namespace {
150 
151 std::optional<RustConnectionManager> connection_manager;
152 
153 }  // namespace
154 
GetConnectionManager()155 RustConnectionManager& GetConnectionManager() {
156   return connection_manager.value();
157 }
158 
RegisterRustApis(::rust::Fn<void (uint8_t client_id,core::AddressWithType address)> start_direct_connection,::rust::Fn<void (uint8_t client_id,core::AddressWithType address)> stop_direct_connection,::rust::Fn<void (uint8_t client_id,core::AddressWithType address)> add_background_connection,::rust::Fn<void (uint8_t client_id,core::AddressWithType address)> remove_background_connection,::rust::Fn<void (uint8_t client_id)> remove_client,::rust::Fn<void (core::AddressWithType address)> stop_all_connections_to_device)159 void RegisterRustApis(
160     ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
161         start_direct_connection,
162     ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
163         stop_direct_connection,
164     ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
165         add_background_connection,
166     ::rust::Fn<void(uint8_t client_id, core::AddressWithType address)>
167         remove_background_connection,
168     ::rust::Fn<void(uint8_t client_id)> remove_client,
169     ::rust::Fn<void(core::AddressWithType address)>
170         stop_all_connections_to_device) {
171   connection_manager = {start_direct_connection,
172                         stop_direct_connection,
173                         add_background_connection,
174                         remove_background_connection,
175                         remove_client,
176                         stop_all_connections_to_device};
177 }
178 
ResolveRawAddress(RawAddress bd_addr)179 core::AddressWithType ResolveRawAddress(RawAddress bd_addr) {
180   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
181   tBLE_BD_ADDR address = convert_to_address_with_type(bd_addr, p_dev_rec);
182   return core::ToRustAddress(address);
183 }
184 
185 }  // namespace connection
186 }  // namespace bluetooth
187