2 // Copyright 2017 The Android Open Source Project
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define LOG_TAG "android.hardware.bluetooth@1.1.sim"
19 #include "bluetooth_hci.h"
22 #include <cutils/properties.h>
24 #include <netinet/in.h>
27 #include "hci_internals.h"
35 using android::hardware::hidl_vec;
36 using test_vendor_lib::AsyncTaskId;
37 using test_vendor_lib::DualModeController;
38 using test_vendor_lib::TaskCallback;
42 bool BtTestConsoleEnabled() {
43 // Assume enabled by default.
44 return property_get_bool("bt.rootcanal_test_console", true);
49 class BluetoothDeathRecipient : public hidl_death_recipient {
51 BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
54 uint64_t /* cookie */,
55 const wp<::android::hidl::base::V1_0::IBase>& /* who */) override {
56 LOG_ERROR("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
60 sp<IBluetoothHci> mHci;
61 bool getHasDied() const {
64 void setHasDied(bool has_died) {
72 BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {}
74 Return<void> BluetoothHci::initialize(
75 const sp<V1_0::IBluetoothHciCallbacks>& cb) {
76 return initialize_impl(cb, nullptr);
79 Return<void> BluetoothHci::initialize_1_1(
80 const sp<V1_1::IBluetoothHciCallbacks>& cb) {
81 return initialize_impl(cb, cb);
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__);
89 LOG_ERROR("cb == nullptr! -> Unable to call initializationComplete(ERR)");
93 death_recipient_->setHasDied(false);
94 auto link_ret = cb->linkToDeath(death_recipient_, 0);
95 CHECK(link_ret.isOk()) << "Error calling linkToDeath.";
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); });
104 controller_ = std::make_shared<DualModeController>();
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)});
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);
115 CHECK(death_recipient_->getHasDied())
116 << "Error sending event callback, but no death notification.";
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);
125 CHECK(death_recipient_->getHasDied())
126 << "Error sending acl callback, but no death notification.";
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);
135 CHECK(death_recipient_->getHasDied())
136 << "Error sending sco callback, but no death notification.";
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);
146 CHECK(death_recipient_->getHasDied())
147 << "Error sending iso callback, but no death notification.";
152 controller_->RegisterTaskScheduler(
153 [this](std::chrono::milliseconds delay, const TaskCallback& task) {
154 return async_manager_.ExecAsync(delay, task);
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);
163 controller_->RegisterTaskCancel(
164 [this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); });
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();
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());
184 if (BtTestConsoleEnabled()) {
185 SetUpTestChannel(6111);
187 [this](int fd) { test_model_.IncomingHciConnection(fd); });
188 SetUpLinkLayerServer(
189 6311, [this](int fd) { test_model_.IncomingLinkLayerConnection(fd); });
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);
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({});
205 unlink_cb_ = [this, cb](sp<BluetoothDeathRecipient>& death_recipient) {
206 if (death_recipient->getHasDied())
207 LOG_INFO("Skipping unlink call, service died.");
209 auto ret = cb->unlinkToDeath(death_recipient);
211 CHECK(death_recipient_->getHasDied())
212 << "Error calling unlink, but no death notification.";
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.";
225 Return<void> BluetoothHci::close() {
226 LOG_INFO("%s", __func__);
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);
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);
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);
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);
266 void BluetoothHci::SetUpHciServer(int port, const std::function<void(int)>& connection_callback) {
267 int socket_fd = remote_hci_transport_.SetUp(port);
269 test_channel_.RegisterSendResponse([](const std::string& response) {
270 LOG_INFO("No HCI Response channel: %s", response.c_str());
273 if (socket_fd == -1) {
274 LOG_ERROR("Remote HCI channel SetUp(%d) failed.", port);
278 async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) {
279 int conn_fd = remote_hci_transport_.Accept(socket_fd);
281 LOG_ERROR("Error watching remote HCI channel fd.");
284 int flags = fcntl(conn_fd, F_GETFL, NULL);
286 ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK);
287 CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno);
289 connection_callback(conn_fd);
293 void BluetoothHci::SetUpLinkLayerServer(int port, const std::function<void(int)>& connection_callback) {
294 int socket_fd = remote_link_layer_transport_.SetUp(port);
296 test_channel_.RegisterSendResponse([](const std::string& response) {
297 LOG_INFO("No LinkLayer Response channel: %s", response.c_str());
300 if (socket_fd == -1) {
301 LOG_ERROR("Remote LinkLayer channel SetUp(%d) failed.", port);
305 async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) {
306 int conn_fd = remote_link_layer_transport_.Accept(socket_fd);
308 LOG_ERROR("Error watching remote LinkLayer channel fd.");
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);
315 connection_callback(conn_fd);
319 int BluetoothHci::ConnectToRemoteServer(const std::string& server, int port) {
320 int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
322 LOG_INFO("socket() call failed: %s", strerror(errno));
326 struct hostent* host;
327 host = gethostbyname(server.c_str());
329 LOG_INFO("gethostbyname() failed for %s: %s", server.c_str(),
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);
340 int result = connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
342 LOG_INFO("connect() failed for %s@%d: %s", server.c_str(), port,
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);
354 void BluetoothHci::SetUpTestChannel(int port) {
355 int socket_fd = test_channel_transport_.SetUp(port);
357 test_channel_.RegisterSendResponse([](const std::string& response) {
358 LOG_INFO("No test channel: %s", response.c_str());
361 if (socket_fd == -1) {
362 LOG_ERROR("Test channel SetUp(%d) failed.", port);
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);
370 LOG_ERROR("Error watching test channel fd.");
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); });
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); });
384 /* Fallback to shared library if there is no service. */
385 IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) {
386 return new BluetoothHci();
391 } // namespace bluetooth
392 } // namespace hardware
393 } // namespace android