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