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 "android.hardware.bluetooth@1.1.sim"
18 
19 #include "bluetooth_hci.h"
20 
21 #include "log/log.h"
22 #include <cutils/properties.h>
23 #include <netdb.h>
24 #include <netinet/in.h>
25 #include <string.h>
26 
27 #include "hci_internals.h"
28 
29 namespace android {
30 namespace hardware {
31 namespace bluetooth {
32 namespace V1_1 {
33 namespace sim {
34 
35 using android::hardware::hidl_vec;
36 using test_vendor_lib::AsyncTaskId;
37 using test_vendor_lib::DualModeController;
38 using test_vendor_lib::TaskCallback;
39 
40 namespace {
41 
BtTestConsoleEnabled()42 bool BtTestConsoleEnabled() {
43   // Assume enabled by default.
44   return property_get_bool("vendor.bt.rootcanal_test_console", true);
45 }
46 
47 }  // namespace
48 
49 class BluetoothDeathRecipient : public hidl_death_recipient {
50  public:
BluetoothDeathRecipient(const sp<IBluetoothHci> hci)51   BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
52 
serviceDied(uint64_t,const wp<::android::hidl::base::V1_0::IBase> &)53   void serviceDied(
54       uint64_t /* cookie */,
55       const wp<::android::hidl::base::V1_0::IBase>& /* who */) override {
56     LOG_ERROR("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
57     has_died_ = true;
58     mHci->close();
59   }
60   sp<IBluetoothHci> mHci;
getHasDied() const61   bool getHasDied() const {
62     return has_died_;
63   }
setHasDied(bool has_died)64   void setHasDied(bool has_died) {
65     has_died_ = has_died;
66   }
67 
68  private:
69   bool has_died_;
70 };
71 
BluetoothHci()72 BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {}
73 
initialize(const sp<V1_0::IBluetoothHciCallbacks> & cb)74 Return<void> BluetoothHci::initialize(
75     const sp<V1_0::IBluetoothHciCallbacks>& cb) {
76   return initialize_impl(cb, nullptr);
77 }
78 
initialize_1_1(const sp<V1_1::IBluetoothHciCallbacks> & cb)79 Return<void> BluetoothHci::initialize_1_1(
80     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(
85     const sp<V1_0::IBluetoothHciCallbacks>& cb,
86     const sp<V1_1::IBluetoothHciCallbacks>& cb_1_1) {
87   LOG_INFO("%s", __func__);
88   if (cb == nullptr) {
89     LOG_ERROR("cb == nullptr! -> Unable to call initializationComplete(ERR)");
90     return Void();
91   }
92 
93   death_recipient_->setHasDied(false);
94   auto link_ret = cb->linkToDeath(death_recipient_, 0);
95   CHECK(link_ret.isOk()) << "Error calling linkToDeath.";
96 
97   test_channel_transport_.RegisterCommandHandler(
98       [this](const std::string& name, const std::vector<std::string>& args) {
99         async_manager_.ExecAsync(
100             user_id_, std::chrono::milliseconds(0),
101             [this, name, args]() { test_channel_.HandleCommand(name, args); });
102       });
103 
104   controller_ = std::make_shared<DualModeController>();
105 
106   char mac_property[PROPERTY_VALUE_MAX] = "";
107   property_get("vendor.bt.rootcanal_mac_address", mac_property, "3C:5A:B4:01:02:03");
108   controller_->Initialize({"dmc", std::string(mac_property)});
109 
110   controller_->RegisterEventChannel(
111       [this, cb](std::shared_ptr<std::vector<uint8_t>> packet) {
112         hidl_vec<uint8_t> hci_event(packet->begin(), packet->end());
113         auto ret = cb->hciEventReceived(hci_event);
114         if (!ret.isOk()) {
115           LOG_ERROR("Error sending event callback");
116           if (!death_recipient_->getHasDied()) {
117             LOG_ERROR("Closing");
118             close();
119           }
120         }
121       });
122 
123   controller_->RegisterAclChannel(
124       [this, cb](std::shared_ptr<std::vector<uint8_t>> packet) {
125         hidl_vec<uint8_t> acl_packet(packet->begin(), packet->end());
126         auto ret = cb->aclDataReceived(acl_packet);
127         if (!ret.isOk()) {
128           LOG_ERROR("Error sending acl callback");
129           if (!death_recipient_->getHasDied()) {
130             LOG_ERROR("Closing");
131             close();
132           }
133         }
134       });
135 
136   controller_->RegisterScoChannel(
137       [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           LOG_ERROR("Error sending sco callback");
142           if (!death_recipient_->getHasDied()) {
143             LOG_ERROR("Closing");
144             close();
145           }
146         }
147       });
148 
149   if (cb_1_1 != nullptr) {
150     controller_->RegisterIsoChannel(
151         [this, cb_1_1](std::shared_ptr<std::vector<uint8_t>> packet) {
152           hidl_vec<uint8_t> iso_packet(packet->begin(), packet->end());
153           auto ret = cb_1_1->isoDataReceived(iso_packet);
154           if (!ret.isOk()) {
155             LOG_ERROR("Error sending iso callback");
156             if (!death_recipient_->getHasDied()) {
157               LOG_ERROR("Closing");
158               close();
159             }
160           }
161         });
162   }
163 
164   controller_->RegisterTaskScheduler(
165       [this](std::chrono::milliseconds delay, const TaskCallback& task) {
166         return async_manager_.ExecAsync(user_id_, delay, task);
167       });
168 
169   controller_->RegisterPeriodicTaskScheduler(
170       [this](std::chrono::milliseconds delay, std::chrono::milliseconds period,
171              const TaskCallback& task) {
172         return async_manager_.ExecAsyncPeriodically(user_id_, delay, period,
173                                                     task);
174       });
175 
176   controller_->RegisterTaskCancel(
177       [this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); });
178 
179   // Add the controller as a device in the model.
180   size_t controller_index = test_model_.Add(controller_);
181   size_t low_energy_phy_index =
182       test_model_.AddPhy(test_vendor_lib::Phy::Type::LOW_ENERGY);
183   size_t classic_phy_index =
184       test_model_.AddPhy(test_vendor_lib::Phy::Type::BR_EDR);
185   test_model_.AddDeviceToPhy(controller_index, low_energy_phy_index);
186   test_model_.AddDeviceToPhy(controller_index, classic_phy_index);
187   test_model_.SetTimerPeriod(std::chrono::milliseconds(10));
188   test_model_.StartTimer();
189 
190   // Send responses to logcat if the test channel is not configured.
191   test_channel_.RegisterSendResponse([](const std::string& response) {
192     LOG_INFO("No test channel yet: %s", response.c_str());
193   });
194 
195   if (BtTestConsoleEnabled()) {
196     SetUpTestChannel(6111);
197     SetUpHciServer(6211,
198                    [this](int fd) { test_model_.IncomingHciConnection(fd); });
199     SetUpLinkLayerServer(
200         6311, [this](int fd) { test_model_.IncomingLinkLayerConnection(fd); });
201   } else {
202     // This should be configurable in the future.
203     LOG_INFO("Adding Beacons so the scan list is not empty.");
204     test_channel_.Add({"beacon", "be:ac:10:00:00:01", "1000"});
205     test_model_.AddDeviceToPhy(controller_index + 1, low_energy_phy_index);
206     test_channel_.Add({"beacon", "be:ac:10:00:00:02", "1000"});
207     test_model_.AddDeviceToPhy(controller_index + 2, low_energy_phy_index);
208     test_channel_.Add(
209         {"scripted_beacon", "5b:ea:c1:00:00:03",
210          "/data/vendor/bluetooth/bluetooth_sim_ble_playback_file",
211          "/data/vendor/bluetooth/bluetooth_sim_ble_playback_events"});
212     test_model_.AddDeviceToPhy(controller_index + 3, low_energy_phy_index);
213     test_channel_.List({});
214   }
215 
216   unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) {
217     if (death_recipient->getHasDied())
218       LOG_INFO("Skipping unlink call, service died.");
219     else {
220       auto ret = cb->unlinkToDeath(death_recipient);
221       if (!ret.isOk()) {
222         CHECK(death_recipient_->getHasDied())
223             << "Error calling unlink, but no death notification.";
224       }
225     }
226   };
227 
228   auto init_ret = cb->initializationComplete(V1_0::Status::SUCCESS);
229   if (!init_ret.isOk()) {
230     CHECK(death_recipient_->getHasDied())
231         << "Error sending init callback, but no death notification.";
232   }
233   return Void();
234 }
235 
close()236 Return<void> BluetoothHci::close() {
237   LOG_INFO("%s", __func__);
238   test_model_.Reset();
239   return Void();
240 }
241 
sendHciCommand(const hidl_vec<uint8_t> & packet)242 Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
243   async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0),
244                            [this, packet]() {
245                              std::shared_ptr<std::vector<uint8_t>> packet_copy =
246                                  std::shared_ptr<std::vector<uint8_t>>(
247                                      new std::vector<uint8_t>(packet));
248                              controller_->HandleCommand(packet_copy);
249                            });
250   return Void();
251 }
252 
sendAclData(const hidl_vec<uint8_t> & packet)253 Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) {
254   async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0),
255                            [this, packet]() {
256                              std::shared_ptr<std::vector<uint8_t>> packet_copy =
257                                  std::shared_ptr<std::vector<uint8_t>>(
258                                      new std::vector<uint8_t>(packet));
259                              controller_->HandleAcl(packet_copy);
260                            });
261   return Void();
262 }
263 
sendScoData(const hidl_vec<uint8_t> & packet)264 Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) {
265   async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0),
266                            [this, packet]() {
267                              std::shared_ptr<std::vector<uint8_t>> packet_copy =
268                                  std::shared_ptr<std::vector<uint8_t>>(
269                                      new std::vector<uint8_t>(packet));
270                              controller_->HandleSco(packet_copy);
271                            });
272   return Void();
273 }
274 
sendIsoData(const hidl_vec<uint8_t> & packet)275 Return<void> BluetoothHci::sendIsoData(const hidl_vec<uint8_t>& packet) {
276   async_manager_.ExecAsync(user_id_, std::chrono::milliseconds(0),
277                            [this, packet]() {
278                              std::shared_ptr<std::vector<uint8_t>> packet_copy =
279                                  std::shared_ptr<std::vector<uint8_t>>(
280                                      new std::vector<uint8_t>(packet));
281                              controller_->HandleIso(packet_copy);
282                            });
283   return Void();
284 }
285 
SetUpHciServer(int port,const std::function<void (int)> & connection_callback)286 void BluetoothHci::SetUpHciServer(int port, const std::function<void(int)>& connection_callback) {
287   int socket_fd = remote_hci_transport_.SetUp(port);
288 
289   test_channel_.RegisterSendResponse([](const std::string& response) {
290     LOG_INFO("No HCI Response channel: %s", response.c_str());
291   });
292 
293   if (socket_fd == -1) {
294     LOG_ERROR("Remote HCI channel SetUp(%d) failed.", port);
295     return;
296   }
297 
298   async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) {
299     int conn_fd = remote_hci_transport_.Accept(socket_fd);
300     if (conn_fd < 0) {
301       LOG_ERROR("Error watching remote HCI channel fd.");
302       return;
303     }
304     int flags = fcntl(conn_fd, F_GETFL, NULL);
305     int ret;
306     ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK);
307     CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno);
308 
309     connection_callback(conn_fd);
310   });
311 }
312 
SetUpLinkLayerServer(int port,const std::function<void (int)> & connection_callback)313 void BluetoothHci::SetUpLinkLayerServer(int port, const std::function<void(int)>& connection_callback) {
314   int socket_fd = remote_link_layer_transport_.SetUp(port);
315 
316   test_channel_.RegisterSendResponse([](const std::string& response) {
317     LOG_INFO("No LinkLayer Response channel: %s", response.c_str());
318   });
319 
320   if (socket_fd == -1) {
321     LOG_ERROR("Remote LinkLayer channel SetUp(%d) failed.", port);
322     return;
323   }
324 
325   async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) {
326     int conn_fd = remote_link_layer_transport_.Accept(socket_fd);
327     if (conn_fd < 0) {
328       LOG_ERROR("Error watching remote LinkLayer channel fd.");
329       return;
330     }
331     int flags = fcntl(conn_fd, F_GETFL, NULL);
332     int ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK);
333     CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno);
334 
335     connection_callback(conn_fd);
336   });
337 }
338 
ConnectToRemoteServer(const std::string & server,int port)339 int BluetoothHci::ConnectToRemoteServer(const std::string& server, int port) {
340   int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
341   if (socket_fd < 1) {
342     LOG_INFO("socket() call failed: %s", strerror(errno));
343     return -1;
344   }
345 
346   struct hostent* host;
347   host = gethostbyname(server.c_str());
348   if (host == NULL) {
349     LOG_INFO("gethostbyname() failed for %s: %s", server.c_str(),
350              strerror(errno));
351     return -1;
352   }
353 
354   struct sockaddr_in serv_addr;
355   memset((void*)&serv_addr, 0, sizeof(serv_addr));
356   serv_addr.sin_family = AF_INET;
357   serv_addr.sin_addr.s_addr = INADDR_ANY;
358   serv_addr.sin_port = htons(port);
359 
360   int result = connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
361   if (result < 0) {
362     LOG_INFO("connect() failed for %s@%d: %s", server.c_str(), port,
363              strerror(errno));
364     return -1;
365   }
366 
367   int flags = fcntl(socket_fd, F_GETFL, NULL);
368   int ret = fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK);
369   CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno);
370 
371   return socket_fd;
372 }
373 
SetUpTestChannel(int port)374 void BluetoothHci::SetUpTestChannel(int port) {
375   int socket_fd = test_channel_transport_.SetUp(port);
376 
377   test_channel_.RegisterSendResponse([](const std::string& response) {
378     LOG_INFO("No test channel: %s", response.c_str());
379   });
380 
381   if (socket_fd == -1) {
382     LOG_ERROR("Test channel SetUp(%d) failed.", port);
383     return;
384   }
385 
386   LOG_INFO("Test channel SetUp() successful");
387   async_manager_.WatchFdForNonBlockingReads(socket_fd, [this](int socket_fd) {
388     int conn_fd = test_channel_transport_.Accept(socket_fd);
389     if (conn_fd < 0) {
390       LOG_ERROR("Error watching test channel fd.");
391       return;
392     }
393     LOG_INFO("Test channel connection accepted.");
394     test_channel_.RegisterSendResponse(
395         [this, conn_fd](const std::string& response) { test_channel_transport_.SendResponse(conn_fd, response); });
396 
397     async_manager_.WatchFdForNonBlockingReads(conn_fd, [this](int conn_fd) {
398       test_channel_transport_.OnCommandReady(conn_fd,
399                                              [this, conn_fd]() { async_manager_.StopWatchingFileDescriptor(conn_fd); });
400     });
401   });
402 }
403 
404 /* Fallback to shared library if there is no service. */
HIDL_FETCH_IBluetoothHci(const char *)405 IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) {
406   return new BluetoothHci();
407 }
408 
409 }  // namespace sim
410 }  // namespace V1_1
411 }  // namespace bluetooth
412 }  // namespace hardware
413 }  // namespace android
414