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