1 //
2 // Copyright 2017 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 "[email protected]"
18 
19 #include "bluetooth_hci.h"
20 
21 #include <cutils/properties.h>
22 #include <log/log.h>
23 #include <netdb.h>
24 #include <netinet/in.h>
25 #include <string.h>
26 
27 #include "hci_internals.h"
28 #include "model/devices/hci_device.h"
29 #include "model/devices/link_layer_socket_device.h"
30 #include "model/hci/hci_socket_transport.h"
31 
32 namespace android {
33 namespace hardware {
34 namespace bluetooth {
35 namespace V1_1 {
36 namespace sim {
37 
38 using android::hardware::hidl_vec;
39 using ::bluetooth::hci::Address;
40 using rootcanal::AsyncTaskId;
41 using rootcanal::DualModeController;
42 using rootcanal::HciDevice;
43 using rootcanal::HciSocketTransport;
44 using rootcanal::LinkLayerSocketDevice;
45 using rootcanal::TaskCallback;
46 
47 namespace {
48 
BtTestConsoleEnabled()49 bool BtTestConsoleEnabled() {
50   // Assume enabled by default.
51   return property_get_bool("vendor.bt.rootcanal_test_console", true);
52 }
53 
54 }  // namespace
55 
56 class BluetoothDeathRecipient : public hidl_death_recipient {
57 public:
BluetoothDeathRecipient(const sp<IBluetoothHci> hci)58   BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
59 
serviceDied(uint64_t,const wp<::android::hidl::base::V1_0::IBase> &)60   void serviceDied(uint64_t /* cookie */,
61                    const wp<::android::hidl::base::V1_0::IBase>& /* who */) override {
62     ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
63     has_died_ = true;
64     mHci->close();
65   }
66   sp<IBluetoothHci> mHci;
getHasDied() const67   bool getHasDied() const { return has_died_; }
setHasDied(bool has_died)68   void setHasDied(bool has_died) { has_died_ = has_died; }
69 
70 private:
71   bool has_died_{false};
72 };
73 
BluetoothHci()74 BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {}
75 
initialize(const sp<V1_0::IBluetoothHciCallbacks> & cb)76 Return<void> BluetoothHci::initialize(const sp<V1_0::IBluetoothHciCallbacks>& cb) {
77   return initialize_impl(cb, nullptr);
78 }
79 
initialize_1_1(const sp<V1_1::IBluetoothHciCallbacks> & cb)80 Return<void> BluetoothHci::initialize_1_1(const sp<V1_1::IBluetoothHciCallbacks>& cb) {
81   return initialize_impl(cb, cb);
82 }
83 
initialize_impl(const sp<V1_0::IBluetoothHciCallbacks> & cb,const sp<V1_1::IBluetoothHciCallbacks> & cb_1_1)84 Return<void> BluetoothHci::initialize_impl(const sp<V1_0::IBluetoothHciCallbacks>& cb,
85                                            const sp<V1_1::IBluetoothHciCallbacks>& cb_1_1) {
86   ALOGI("%s", __func__);
87   if (cb == nullptr) {
88     ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
89     return Void();
90   }
91 
92   death_recipient_->setHasDied(false);
93   auto link_ret = cb->linkToDeath(death_recipient_, 0);
94   ALOG_ASSERT(link_ret.isOk(), "Error calling linkToDeath.");
95 
96   test_channel_transport_.RegisterCommandHandler([this](const std::string& name,
97                                                         const std::vector<std::string>& args) {
98     async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0),
99                              [this, name, args]() { test_channel_.HandleCommand(name, args); });
100   });
101 
102   controller_ = std::make_shared<DualModeController>();
103 
104   char mac_property[PROPERTY_VALUE_MAX] = "";
105   property_get("vendor.bt.rootcanal_mac_address", mac_property, "3C:5A:B4:01:02:03");
106   auto addr = Address::FromString(std::string(mac_property));
107   if (addr) {
108     controller_->SetAddress(*addr);
109   } else {
110     LOG_ALWAYS_FATAL("Invalid address: %s", mac_property);
111   }
112 
113   controller_->RegisterEventChannel([this, cb](std::shared_ptr<std::vector<uint8_t>> packet) {
114     hidl_vec<uint8_t> hci_event(packet->begin(), packet->end());
115     auto ret = cb->hciEventReceived(hci_event);
116     if (!ret.isOk()) {
117       ALOGE("Error sending event callback");
118       if (!death_recipient_->getHasDied()) {
119         ALOGE("Closing");
120         close();
121       }
122     }
123   });
124 
125   controller_->RegisterAclChannel([this, cb](std::shared_ptr<std::vector<uint8_t>> packet) {
126     hidl_vec<uint8_t> acl_packet(packet->begin(), packet->end());
127     auto ret = cb->aclDataReceived(acl_packet);
128     if (!ret.isOk()) {
129       ALOGE("Error sending acl callback");
130       if (!death_recipient_->getHasDied()) {
131         ALOGE("Closing");
132         close();
133       }
134     }
135   });
136 
137   controller_->RegisterScoChannel([this, cb](std::shared_ptr<std::vector<uint8_t>> packet) {
138     hidl_vec<uint8_t> sco_packet(packet->begin(), packet->end());
139     auto ret = cb->scoDataReceived(sco_packet);
140     if (!ret.isOk()) {
141       ALOGE("Error sending sco callback");
142       if (!death_recipient_->getHasDied()) {
143         ALOGE("Closing");
144         close();
145       }
146     }
147   });
148 
149   if (cb_1_1 != nullptr) {
150     controller_->RegisterIsoChannel([this, cb_1_1](std::shared_ptr<std::vector<uint8_t>> packet) {
151       hidl_vec<uint8_t> iso_packet(packet->begin(), packet->end());
152       auto ret = cb_1_1->isoDataReceived(iso_packet);
153       if (!ret.isOk()) {
154         ALOGE("Error sending iso callback");
155         if (!death_recipient_->getHasDied()) {
156           ALOGE("Closing");
157           close();
158         }
159       }
160     });
161   }
162 
163   // Add the controller as a device in the model.
164   size_t controller_index = test_model_.AddDevice(controller_);
165   size_t low_energy_phy_index = test_model_.AddPhy(rootcanal::Phy::Type::LOW_ENERGY);
166   size_t classic_phy_index = test_model_.AddPhy(rootcanal::Phy::Type::BR_EDR);
167   test_model_.AddDeviceToPhy(controller_index, low_energy_phy_index);
168   test_model_.AddDeviceToPhy(controller_index, classic_phy_index);
169   test_model_.SetTimerPeriod(std::chrono::milliseconds(10));
170   test_model_.StartTimer();
171 
172   // Send responses to logcat if the test channel is not configured.
173   test_channel_.RegisterSendResponse(
174           [](const std::string& response) { ALOGI("No test channel yet: %s", response.c_str()); });
175 
176   if (BtTestConsoleEnabled()) {
177     test_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6111, &async_manager_);
178     hci_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6211, &async_manager_);
179     link_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6311, &async_manager_);
180     connector_ = std::make_shared<net::PosixAsyncSocketConnector>(&async_manager_);
181     SetUpTestChannel();
182     SetUpHciServer([this](std::shared_ptr<AsyncDataChannel> socket, AsyncDataChannelServer* srv) {
183       auto transport = HciSocketTransport::Create(socket);
184       test_model_.AddHciConnection(HciDevice::Create(transport, rootcanal::ControllerProperties()));
185       srv->StartListening();
186     });
187     SetUpLinkLayerServer([this](std::shared_ptr<AsyncDataChannel> socket,
188                                 AsyncDataChannelServer* srv) {
189       auto phy_type = Phy::Type::BR_EDR;
190       test_model_.AddLinkLayerConnection(LinkLayerSocketDevice::Create(socket, phy_type), phy_type);
191       srv->StartListening();
192     });
193   } else {
194     // This should be configurable in the future.
195     ALOGI("Adding Beacons so the scan list is not empty.");
196     test_channel_.AddDevice({"beacon", "be:ac:10:00:00:01", "1000"});
197     test_model_.AddDeviceToPhy(controller_index + 1, low_energy_phy_index);
198     test_channel_.AddDevice({"beacon", "be:ac:10:00:00:02", "1000"});
199     test_model_.AddDeviceToPhy(controller_index + 2, low_energy_phy_index);
200     test_channel_.AddDevice({"scripted_beacon", "5b:ea:c1:00:00:03",
201                              "/data/vendor/bluetooth/bluetooth_sim_ble_playback_file",
202                              "/data/vendor/bluetooth/bluetooth_sim_ble_playback_events"});
203     test_model_.AddDeviceToPhy(controller_index + 3, low_energy_phy_index);
204     test_channel_.List({});
205   }
206 
207   unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
208     if (death_recipient->getHasDied()) {
209       ALOGI("Skipping unlink call, service died.");
210     } else {
211       auto ret = cb->unlinkToDeath(death_recipient);
212       if (!ret.isOk()) {
213         ALOG_ASSERT(death_recipient_->getHasDied(),
214                     "Error calling unlink, but no death notification.");
215       }
216     }
217   };
218 
219   auto init_ret = cb->initializationComplete(V1_0::Status::SUCCESS);
220   if (!init_ret.isOk()) {
221     ALOG_ASSERT(death_recipient_->getHasDied(),
222                 "Error sending init callback, but no death notification.");
223   }
224   return Void();
225 }
226 
close()227 Return<void> BluetoothHci::close() {
228   ALOGI("%s", __func__);
229   test_model_.Reset();
230   return Void();
231 }
232 
sendHciCommand(const hidl_vec<uint8_t> & packet)233 Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
234   async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0), [this, packet]() {
235     std::shared_ptr<std::vector<uint8_t>> packet_copy =
236             std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
237     controller_->HandleCommand(packet_copy);
238   });
239   return Void();
240 }
241 
sendAclData(const hidl_vec<uint8_t> & packet)242 Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) {
243   async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0), [this, packet]() {
244     std::shared_ptr<std::vector<uint8_t>> packet_copy =
245             std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
246     controller_->HandleAcl(packet_copy);
247   });
248   return Void();
249 }
250 
sendScoData(const hidl_vec<uint8_t> & packet)251 Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) {
252   async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0), [this, packet]() {
253     std::shared_ptr<std::vector<uint8_t>> packet_copy =
254             std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
255     controller_->HandleSco(packet_copy);
256   });
257   return Void();
258 }
259 
sendIsoData(const hidl_vec<uint8_t> & packet)260 Return<void> BluetoothHci::sendIsoData(const hidl_vec<uint8_t>& packet) {
261   async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0), [this, packet]() {
262     std::shared_ptr<std::vector<uint8_t>> packet_copy =
263             std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
264     controller_->HandleIso(packet_copy);
265   });
266   return Void();
267 }
268 
SetUpHciServer(ConnectCallback connection_callback)269 void BluetoothHci::SetUpHciServer(ConnectCallback connection_callback) {
270   test_channel_.RegisterSendResponse([](const std::string& response) {
271     ALOGI("No HCI Response channel: %s", response.c_str());
272   });
273 
274   if (!remote_hci_transport_.SetUp(hci_socket_server_, connection_callback)) {
275     ALOGE("Remote HCI channel SetUp failed.");
276     return;
277   }
278 }
279 
SetUpLinkLayerServer(ConnectCallback connection_callback)280 void BluetoothHci::SetUpLinkLayerServer(ConnectCallback connection_callback) {
281   remote_link_layer_transport_.SetUp(link_socket_server_, connection_callback);
282 
283   test_channel_.RegisterSendResponse([](const std::string& response) {
284     ALOGI("No LinkLayer Response channel: %s", response.c_str());
285   });
286 }
287 
ConnectToRemoteServer(const std::string & server,int port,Phy::Type phy_type)288 std::shared_ptr<Device> BluetoothHci::ConnectToRemoteServer(const std::string& server, int port,
289                                                             Phy::Type phy_type) {
290   auto socket = connector_->ConnectToRemoteServer(server, port);
291   if (!socket->Connected()) {
292     return nullptr;
293   }
294   return LinkLayerSocketDevice::Create(socket, phy_type);
295 }
296 
SetUpTestChannel()297 void BluetoothHci::SetUpTestChannel() {
298   bool transport_configured = test_channel_transport_.SetUp(
299           test_socket_server_,
300           [this](std::shared_ptr<AsyncDataChannel> conn_fd, AsyncDataChannelServer*) {
301             ALOGI("Test channel connection accepted.");
302             test_channel_.RegisterSendResponse([this, conn_fd](const std::string& response) {
303               test_channel_transport_.SendResponse(conn_fd, response);
304             });
305 
306             conn_fd->WatchForNonBlockingRead([this](AsyncDataChannel* conn_fd) {
307               test_channel_transport_.OnCommandReady(conn_fd, []() {});
308             });
309             return false;
310           });
311   test_channel_.RegisterSendResponse(
312           [](const std::string& response) { ALOGI("No test channel: %s", response.c_str()); });
313 
314   if (!transport_configured) {
315     ALOGE("Test channel SetUp failed.");
316     return;
317   }
318 
319   ALOGI("Test channel SetUp() successful");
320 }
321 
322 /* Fallback to shared library if there is no service. */
HIDL_FETCH_IBluetoothHci(const char *)323 IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) { return new BluetoothHci(); }
324 
325 }  // namespace sim
326 }  // namespace V1_1
327 }  // namespace bluetooth
328 }  // namespace hardware
329 }  // namespace android
330