OSDN Git Service

Return after removing sample LTK device am: 7c86810c44 am: e8ba00c87c am: a326247710
[android-x86/system-bt.git] / test / rootcanal / bluetooth_hci.cc
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
42 bool BtTestConsoleEnabled() {
43   // Assume enabled by default.
44   return property_get_bool("bt.rootcanal_test_console", true);
45 }
46
47 }  // namespace
48
49 class BluetoothDeathRecipient : public hidl_death_recipient {
50  public:
51   BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
52
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;
61   bool getHasDied() const {
62     return has_died_;
63   }
64   void setHasDied(bool has_died) {
65     has_died_ = has_died;
66   }
67
68  private:
69   bool has_died_;
70 };
71
72 BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {}
73
74 Return<void> BluetoothHci::initialize(
75     const sp<V1_0::IBluetoothHciCallbacks>& cb) {
76   return initialize_impl(cb, nullptr);
77 }
78
79 Return<void> BluetoothHci::initialize_1_1(
80     const sp<V1_1::IBluetoothHciCallbacks>& cb) {
81   return initialize_impl(cb, cb);
82 }
83
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             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("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           CHECK(death_recipient_->getHasDied())
116               << "Error sending event callback, but no death notification.";
117         }
118       });
119
120   controller_->RegisterAclChannel(
121       [this, cb](std::shared_ptr<std::vector<uint8_t>> packet) {
122         hidl_vec<uint8_t> acl_packet(packet->begin(), packet->end());
123         auto ret = cb->aclDataReceived(acl_packet);
124         if (!ret.isOk()) {
125           CHECK(death_recipient_->getHasDied())
126               << "Error sending acl callback, but no death notification.";
127         }
128       });
129
130   controller_->RegisterScoChannel(
131       [this, cb](std::shared_ptr<std::vector<uint8_t>> packet) {
132         hidl_vec<uint8_t> sco_packet(packet->begin(), packet->end());
133         auto ret = cb->aclDataReceived(sco_packet);
134         if (!ret.isOk()) {
135           CHECK(death_recipient_->getHasDied())
136               << "Error sending sco callback, but no death notification.";
137         }
138       });
139
140   if (cb_1_1 != nullptr) {
141     controller_->RegisterIsoChannel(
142         [this, cb_1_1](std::shared_ptr<std::vector<uint8_t>> packet) {
143           hidl_vec<uint8_t> iso_packet(packet->begin(), packet->end());
144           auto ret = cb_1_1->isoDataReceived(iso_packet);
145           if (!ret.isOk()) {
146             CHECK(death_recipient_->getHasDied())
147                 << "Error sending iso callback, but no death notification.";
148           }
149         });
150   }
151
152   controller_->RegisterTaskScheduler(
153       [this](std::chrono::milliseconds delay, const TaskCallback& task) {
154         return async_manager_.ExecAsync(delay, task);
155       });
156
157   controller_->RegisterPeriodicTaskScheduler(
158       [this](std::chrono::milliseconds delay, std::chrono::milliseconds period,
159              const TaskCallback& task) {
160         return async_manager_.ExecAsyncPeriodically(delay, period, task);
161       });
162
163   controller_->RegisterTaskCancel(
164       [this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); });
165
166   test_model_.Reset();
167
168   // Add the controller as a device in the model.
169   size_t controller_index = test_model_.Add(controller_);
170   size_t low_energy_phy_index =
171       test_model_.AddPhy(test_vendor_lib::Phy::Type::LOW_ENERGY);
172   size_t classic_phy_index =
173       test_model_.AddPhy(test_vendor_lib::Phy::Type::BR_EDR);
174   test_model_.AddDeviceToPhy(controller_index, low_energy_phy_index);
175   test_model_.AddDeviceToPhy(controller_index, classic_phy_index);
176   test_model_.SetTimerPeriod(std::chrono::milliseconds(10));
177   test_model_.StartTimer();
178
179   // Send responses to logcat if the test channel is not configured.
180   test_channel_.RegisterSendResponse([](const std::string& response) {
181     LOG_INFO("No test channel yet: %s", response.c_str());
182   });
183
184   if (BtTestConsoleEnabled()) {
185     SetUpTestChannel(6111);
186     SetUpHciServer(6211,
187                    [this](int fd) { test_model_.IncomingHciConnection(fd); });
188     SetUpLinkLayerServer(
189         6311, [this](int fd) { test_model_.IncomingLinkLayerConnection(fd); });
190   } else {
191     // This should be configurable in the future.
192     LOG_INFO("Adding Beacons so the scan list is not empty.");
193     test_channel_.Add({"beacon", "be:ac:10:00:00:01", "1000"});
194     test_model_.AddDeviceToPhy(controller_index + 1, low_energy_phy_index);
195     test_channel_.Add({"beacon", "be:ac:10:00:00:02", "1000"});
196     test_model_.AddDeviceToPhy(controller_index + 2, low_energy_phy_index);
197     test_channel_.Add(
198         {"scripted_beacon", "5b:ea:c1:00:00:03",
199          "/data/vendor/bluetooth/bluetooth_sim_ble_playback_file",
200          "/data/vendor/bluetooth/bluetooth_sim_ble_playback_events"});
201     test_model_.AddDeviceToPhy(controller_index + 3, low_energy_phy_index);
202     test_channel_.List({});
203   }
204
205   unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) {
206     if (death_recipient->getHasDied())
207       LOG_INFO("Skipping unlink call, service died.");
208     else {
209       auto ret = cb->unlinkToDeath(death_recipient);
210       if (!ret.isOk()) {
211         CHECK(death_recipient_->getHasDied())
212             << "Error calling unlink, but no death notification.";
213       }
214     }
215   };
216
217   auto init_ret = cb->initializationComplete(V1_0::Status::SUCCESS);
218   if (!init_ret.isOk()) {
219     CHECK(death_recipient_->getHasDied())
220         << "Error sending init callback, but no death notification.";
221   }
222   return Void();
223 }
224
225 Return<void> BluetoothHci::close() {
226   LOG_INFO("%s", __func__);
227   return Void();
228 }
229
230 Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
231   async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
232     std::shared_ptr<std::vector<uint8_t>> packet_copy =
233         std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
234     controller_->HandleCommand(packet_copy);
235   });
236   return Void();
237 }
238
239 Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) {
240   async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
241     std::shared_ptr<std::vector<uint8_t>> packet_copy =
242         std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
243     controller_->HandleAcl(packet_copy);
244   });
245   return Void();
246 }
247
248 Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) {
249   async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
250     std::shared_ptr<std::vector<uint8_t>> packet_copy =
251         std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
252     controller_->HandleSco(packet_copy);
253   });
254   return Void();
255 }
256
257 Return<void> BluetoothHci::sendIsoData(const hidl_vec<uint8_t>& packet) {
258   async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
259     std::shared_ptr<std::vector<uint8_t>> packet_copy =
260         std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
261     controller_->HandleIso(packet_copy);
262   });
263   return Void();
264 }
265
266 void BluetoothHci::SetUpHciServer(int port, const std::function<void(int)>& connection_callback) {
267   int socket_fd = remote_hci_transport_.SetUp(port);
268
269   test_channel_.RegisterSendResponse([](const std::string& response) {
270     LOG_INFO("No HCI Response channel: %s", response.c_str());
271   });
272
273   if (socket_fd == -1) {
274     LOG_ERROR("Remote HCI channel SetUp(%d) failed.", port);
275     return;
276   }
277
278   async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) {
279     int conn_fd = remote_hci_transport_.Accept(socket_fd);
280     if (conn_fd < 0) {
281       LOG_ERROR("Error watching remote HCI channel fd.");
282       return;
283     }
284     int flags = fcntl(conn_fd, F_GETFL, NULL);
285     int ret;
286     ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK);
287     CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno);
288
289     connection_callback(conn_fd);
290   });
291 }
292
293 void BluetoothHci::SetUpLinkLayerServer(int port, const std::function<void(int)>& connection_callback) {
294   int socket_fd = remote_link_layer_transport_.SetUp(port);
295
296   test_channel_.RegisterSendResponse([](const std::string& response) {
297     LOG_INFO("No LinkLayer Response channel: %s", response.c_str());
298   });
299
300   if (socket_fd == -1) {
301     LOG_ERROR("Remote LinkLayer channel SetUp(%d) failed.", port);
302     return;
303   }
304
305   async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) {
306     int conn_fd = remote_link_layer_transport_.Accept(socket_fd);
307     if (conn_fd < 0) {
308       LOG_ERROR("Error watching remote LinkLayer channel fd.");
309       return;
310     }
311     int flags = fcntl(conn_fd, F_GETFL, NULL);
312     int ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK);
313     CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno);
314
315     connection_callback(conn_fd);
316   });
317 }
318
319 int BluetoothHci::ConnectToRemoteServer(const std::string& server, int port) {
320   int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
321   if (socket_fd < 1) {
322     LOG_INFO("socket() call failed: %s", strerror(errno));
323     return -1;
324   }
325
326   struct hostent* host;
327   host = gethostbyname(server.c_str());
328   if (host == NULL) {
329     LOG_INFO("gethostbyname() failed for %s: %s", server.c_str(),
330              strerror(errno));
331     return -1;
332   }
333
334   struct sockaddr_in serv_addr;
335   memset((void*)&serv_addr, 0, sizeof(serv_addr));
336   serv_addr.sin_family = AF_INET;
337   serv_addr.sin_addr.s_addr = INADDR_ANY;
338   serv_addr.sin_port = htons(port);
339
340   int result = connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
341   if (result < 0) {
342     LOG_INFO("connect() failed for %s@%d: %s", server.c_str(), port,
343              strerror(errno));
344     return -1;
345   }
346
347   int flags = fcntl(socket_fd, F_GETFL, NULL);
348   int ret = fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK);
349   CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno);
350
351   return socket_fd;
352 }
353
354 void BluetoothHci::SetUpTestChannel(int port) {
355   int socket_fd = test_channel_transport_.SetUp(port);
356
357   test_channel_.RegisterSendResponse([](const std::string& response) {
358     LOG_INFO("No test channel: %s", response.c_str());
359   });
360
361   if (socket_fd == -1) {
362     LOG_ERROR("Test channel SetUp(%d) failed.", port);
363     return;
364   }
365
366   LOG_INFO("Test channel SetUp() successful");
367   async_manager_.WatchFdForNonBlockingReads(socket_fd, [this](int socket_fd) {
368     int conn_fd = test_channel_transport_.Accept(socket_fd);
369     if (conn_fd < 0) {
370       LOG_ERROR("Error watching test channel fd.");
371       return;
372     }
373     LOG_INFO("Test channel connection accepted.");
374     test_channel_.RegisterSendResponse(
375         [this, conn_fd](const std::string& response) { test_channel_transport_.SendResponse(conn_fd, response); });
376
377     async_manager_.WatchFdForNonBlockingReads(conn_fd, [this](int conn_fd) {
378       test_channel_transport_.OnCommandReady(conn_fd,
379                                              [this, conn_fd]() { async_manager_.StopWatchingFileDescriptor(conn_fd); });
380     });
381   });
382 }
383
384 /* Fallback to shared library if there is no service. */
385 IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) {
386   return new BluetoothHci();
387 }
388
389 }  // namespace sim
390 }  // namespace V1_1
391 }  // namespace bluetooth
392 }  // namespace hardware
393 }  // namespace android