blob: 4d414dddcff63e74a0ef12a97d9c46b366528996 [file] [log] [blame]
Arman Uguray4fdadb62015-08-13 16:09:35 -07001//
Jakub Pawlowski5b790fe2017-09-18 09:00:20 -07002// Copyright 2015 Google, Inc.
Arman Uguray4fdadb62015-08-13 16:09:35 -07003//
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#include "service/adapter.h"
18
Arman Uguray0a0d3932015-11-19 15:57:57 -080019#include <atomic>
20#include <mutex>
21#include <string>
22#include <unordered_set>
Arman Uguray4fdadb62015-08-13 16:09:35 -070023
Arman Uguray0a0d3932015-11-19 15:57:57 -080024#include <base/logging.h>
25#include <base/observer_list.h>
26
Bailey Forrest62aa15f2017-01-30 17:38:58 -080027#include "service/a2dp_sink.h"
Bailey Forrest780e29c2018-08-21 17:20:29 -070028#include "service/a2dp_source.h"
Bailey Forrest62aa15f2017-01-30 17:38:58 -080029#include "service/avrcp_control.h"
Bailey Forrest780e29c2018-08-21 17:20:29 -070030#include "service/avrcp_target.h"
Arman Uguray0a0d3932015-11-19 15:57:57 -080031#include "service/common/bluetooth/util/atomic_string.h"
32#include "service/gatt_client.h"
33#include "service/gatt_server.h"
34#include "service/hal/bluetooth_interface.h"
Arman Uguray4fdadb62015-08-13 16:09:35 -070035#include "service/logging_helpers.h"
Jakub Pawlowski67d5a252016-07-13 11:55:16 -070036#include "service/low_energy_advertiser.h"
Arman Uguray0a0d3932015-11-19 15:57:57 -080037#include "service/low_energy_client.h"
Myles Watson911d1ae2016-11-28 16:44:40 -080038#include "service/low_energy_scanner.h"
Arman Uguray4fdadb62015-08-13 16:09:35 -070039
Arman Uguray6791e9a2015-11-17 13:29:55 -080040using std::lock_guard;
41using std::mutex;
42
Arman Uguray4fdadb62015-08-13 16:09:35 -070043namespace bluetooth {
44
Bailey Forrest62aa15f2017-01-30 17:38:58 -080045namespace {
46
47RemoteDeviceProps ParseRemoteDeviceProps(int num_properties,
48 bt_property_t* properties) {
Jakub Pawlowski7b00a3b2018-10-23 21:54:53 +020049 std::string name;
50 std::string address;
Bailey Forrest62aa15f2017-01-30 17:38:58 -080051 std::vector<Uuid> service_uuids;
52 int32_t device_class = 0;
53 int32_t device_type = 0;
54 int32_t rssi = 0;
55
56 for (int i = 0; i < num_properties; ++i) {
57 bt_property_t* property = properties + i;
58 switch (property->type) {
59 case BT_PROPERTY_BDNAME: {
60 if (property->len < 0) {
61 NOTREACHED() << "Invalid length for BT_PROPERTY_BDNAME";
62 break;
63 }
64 bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val);
Jakub Pawlowski7b00a3b2018-10-23 21:54:53 +020065 name = reinterpret_cast<char*>(hal_name->name);
Bailey Forrest62aa15f2017-01-30 17:38:58 -080066 break;
67 }
68 case BT_PROPERTY_BDADDR: {
69 if (property->len != sizeof(RawAddress)) {
70 NOTREACHED() << "Invalid length for BT_PROPERTY_BDADDR";
71 break;
72 }
Jakub Pawlowski7b00a3b2018-10-23 21:54:53 +020073 address = BtAddrString(reinterpret_cast<RawAddress*>(property->val));
Bailey Forrest62aa15f2017-01-30 17:38:58 -080074 break;
75 }
76 case BT_PROPERTY_UUIDS: {
77 if (property->len < 0) {
78 NOTREACHED() << "Negative length on BT_PROPERTY_UUIDS:";
79 break;
80 }
Bailey Forrest26a73ae2018-08-24 17:04:00 -070081 if (property->len % sizeof(Uuid) != 0) {
Bailey Forrest62aa15f2017-01-30 17:38:58 -080082 NOTREACHED() << "Trailing bytes on BT_PROPERTY_UUIDS:";
83 }
Bailey Forrest26a73ae2018-08-24 17:04:00 -070084 auto uuids = static_cast<const Uuid*>(property->val);
Bailey Forrest62aa15f2017-01-30 17:38:58 -080085
Bailey Forrest26a73ae2018-08-24 17:04:00 -070086 for (size_t i = 0; i < property->len / sizeof(Uuid); ++i) {
87 service_uuids.push_back(uuids[i]);
Bailey Forrest62aa15f2017-01-30 17:38:58 -080088 }
89 break;
90 }
91 case BT_PROPERTY_CLASS_OF_DEVICE: {
92 if (property->len != sizeof(int32_t)) {
93 NOTREACHED() << "Invalid length for BT_PROPERTY_CLASS_OF_DEVICE";
94 break;
95 }
96 device_class = *reinterpret_cast<const int32_t*>(property->val);
97 break;
98 }
99 case BT_PROPERTY_TYPE_OF_DEVICE: {
100 if (property->len != sizeof(int32_t)) {
101 NOTREACHED() << "Invalid length for BT_PROPERTY_TYPE_OF_DEVICE";
102 break;
103 }
104 device_type = *reinterpret_cast<const int32_t*>(property->val);
105 break;
106 }
107 case BT_PROPERTY_REMOTE_RSSI: {
108 if (property->len != sizeof(int8_t)) {
109 NOTREACHED() << "Invalid length for BT_PROPERTY_REMOTE_RSSI";
110 break;
111 }
112 rssi = *reinterpret_cast<const int8_t*>(property->val);
113 break;
114 }
115 default:
116 VLOG(1) << "Unhandled adapter property: "
117 << BtPropertyText(property->type);
118 break;
119 }
120 }
121
122 return RemoteDeviceProps(name, address, service_uuids, device_class,
123 device_type, rssi);
124}
125
126} // namespace
127
Arman Uguray03b1f0f2015-08-17 17:23:42 -0700128// static
129const char Adapter::kDefaultAddress[] = "00:00:00:00:00:00";
130// static
131const char Adapter::kDefaultName[] = "not-initialized";
132
Arman Uguray6791e9a2015-11-17 13:29:55 -0800133// TODO(armansito): The following constants come straight from
134// packages/apps/Bluetooth/src/c/a/b/btservice/AdapterService.java. It would be
135// nice to know if there were a way to obtain these values from the stack
136// instead of hardcoding them here.
137
Arman Uguray10b54c42015-08-21 14:59:57 -0700138// The minimum number of advertising instances required for multi-advertisement
139// support.
Arman Uguray6791e9a2015-11-17 13:29:55 -0800140const int kMinAdvInstancesForMultiAdv = 5;
141
142// Used when determining if offloaded scan filtering is supported.
143const int kMinOffloadedFilters = 10;
144
145// Used when determining if offloaded scan batching is supported.
146const int kMinOffloadedScanStorageBytes = 1024;
Arman Uguray10b54c42015-08-21 14:59:57 -0700147
Arman Uguray4cebc7e2015-08-20 11:38:49 -0700148void Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
149 AdapterState prev_state,
150 AdapterState new_state) {
151 // Default implementation does nothing
152}
153
Arman Uguray0f29c002015-11-13 15:05:48 -0800154void Adapter::Observer::OnDeviceConnectionStateChanged(
155 Adapter* adapter, const std::string& device_address, bool connected) {
156 // Default implementation does nothing
157}
158
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800159void Adapter::Observer::OnScanEnableChanged(Adapter* adapter,
160 bool scan_enabled) {
161 // Default implementation does nothing
162}
163
164void Adapter::Observer::OnSspRequest(Adapter* adapter,
165 const std::string& device_address,
166 const std::string& device_name, int cod,
167 int pairing_variant, int pass_key) {
168 // Default implementation does nothing
169}
170
171void Adapter::Observer::OnBondStateChanged(Adapter* adapter, int status,
172 const std::string& device_address,
173 int state) {
174 // Default implementation does nothing
175}
176
177void Adapter::Observer::OnGetBondedDevices(
178 Adapter* adapter, int status,
179 const std::vector<std::string>& bonded_devices) {
180 // Default implementation does nothing
181}
182
183void Adapter::Observer::OnGetRemoteDeviceProperties(
184 Adapter* adapter, int status, const std::string& device_address,
185 const RemoteDeviceProps& properties) {
186 // Default implementation does nothing
187}
188
189void Adapter::Observer::OnDeviceFound(Adapter* adapter,
190 const RemoteDeviceProps& properties) {
191 // Default implementation does nothing
192}
193
Arman Uguray0a0d3932015-11-19 15:57:57 -0800194// The real Adapter implementation used in production.
Myles Watson911d1ae2016-11-28 16:44:40 -0800195class AdapterImpl : public Adapter, public hal::BluetoothInterface::Observer {
Arman Uguray0a0d3932015-11-19 15:57:57 -0800196 public:
197 AdapterImpl()
Myles Watson911d1ae2016-11-28 16:44:40 -0800198 : state_(ADAPTER_STATE_OFF),
199 address_(kDefaultAddress),
200 name_(kDefaultName) {
Arman Uguray0a0d3932015-11-19 15:57:57 -0800201 memset(&local_le_features_, 0, sizeof(local_le_features_));
202 hal::BluetoothInterface::Get()->AddObserver(this);
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800203 a2dp_sink_factory_.reset(new A2dpSinkFactory);
Bailey Forrest780e29c2018-08-21 17:20:29 -0700204 a2dp_source_factory_.reset(new A2dpSourceFactory);
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800205 avrcp_control_factory_.reset(new AvrcpControlFactory);
Bailey Forrest780e29c2018-08-21 17:20:29 -0700206 avrcp_target_factory_.reset(new AvrcpTargetFactory);
Jakub Pawlowski60b0e8f2016-01-12 13:51:35 -0800207 ble_client_factory_.reset(new LowEnergyClientFactory(*this));
Jakub Pawlowski67d5a252016-07-13 11:55:16 -0700208 ble_advertiser_factory_.reset(new LowEnergyAdvertiserFactory());
Jakub Pawlowskic3f6a512016-10-27 11:49:40 -0700209 ble_scanner_factory_.reset(new LowEnergyScannerFactory(*this));
Arman Uguray0a0d3932015-11-19 15:57:57 -0800210 gatt_client_factory_.reset(new GattClientFactory());
211 gatt_server_factory_.reset(new GattServerFactory());
212 hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties();
Arman Uguray4fdadb62015-08-13 16:09:35 -0700213 }
214
Arman Uguray0a0d3932015-11-19 15:57:57 -0800215 ~AdapterImpl() override {
216 hal::BluetoothInterface::Get()->RemoveObserver(this);
Arman Uguray4fdadb62015-08-13 16:09:35 -0700217 }
218
Arman Uguray0a0d3932015-11-19 15:57:57 -0800219 void AddObserver(Adapter::Observer* observer) override {
220 lock_guard<mutex> lock(observers_lock_);
221 observers_.AddObserver(observer);
Arman Uguray4fdadb62015-08-13 16:09:35 -0700222 }
223
Arman Uguray0a0d3932015-11-19 15:57:57 -0800224 void RemoveObserver(Adapter::Observer* observer) override {
225 lock_guard<mutex> lock(observers_lock_);
226 observers_.RemoveObserver(observer);
Arman Uguray4fdadb62015-08-13 16:09:35 -0700227 }
228
Myles Watson911d1ae2016-11-28 16:44:40 -0800229 AdapterState GetState() const override { return state_.load(); }
Arman Uguray4fdadb62015-08-13 16:09:35 -0700230
Myles Watson911d1ae2016-11-28 16:44:40 -0800231 bool IsEnabled() const override { return state_.load() == ADAPTER_STATE_ON; }
Arman Uguray4fdadb62015-08-13 16:09:35 -0700232
Martin Brabham1a88ace2019-05-10 12:42:15 -0700233 bool Enable() override {
Arman Uguray0a0d3932015-11-19 15:57:57 -0800234 AdapterState current_state = GetState();
235 if (current_state != ADAPTER_STATE_OFF) {
236 LOG(INFO) << "Adapter not disabled - state: "
237 << AdapterStateToString(current_state);
238 return false;
Arman Uguray03b1f0f2015-08-17 17:23:42 -0700239 }
240
Arman Uguray0a0d3932015-11-19 15:57:57 -0800241 // Set the state before calling enable() as there might be a race between
242 // here and the AdapterStateChangedCallback.
243 state_ = ADAPTER_STATE_TURNING_ON;
244 NotifyAdapterStateChanged(current_state, state_);
Arman Uguray4fdadb62015-08-13 16:09:35 -0700245
Martin Brabham1a88ace2019-05-10 12:42:15 -0700246 int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable();
Arman Uguray0a0d3932015-11-19 15:57:57 -0800247 if (status != BT_STATUS_SUCCESS) {
248 LOG(ERROR) << "Failed to enable Bluetooth - status: "
249 << BtStatusText((const bt_status_t)status);
250 state_ = ADAPTER_STATE_OFF;
251 NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_ON, state_);
252 return false;
253 }
Arman Uguray0f29c002015-11-13 15:05:48 -0800254
Arman Uguray0a0d3932015-11-19 15:57:57 -0800255 return true;
Arman Uguray0f29c002015-11-13 15:05:48 -0800256 }
257
Arman Uguray0a0d3932015-11-19 15:57:57 -0800258 bool Disable() override {
259 if (!IsEnabled()) {
260 LOG(INFO) << "Adapter is not enabled";
261 return false;
262 }
263
264 AdapterState current_state = GetState();
265
266 // Set the state before calling enable() as there might be a race between
267 // here and the AdapterStateChangedCallback.
268 state_ = ADAPTER_STATE_TURNING_OFF;
269 NotifyAdapterStateChanged(current_state, state_);
270
271 int status = hal::BluetoothInterface::Get()->GetHALInterface()->disable();
272 if (status != BT_STATUS_SUCCESS) {
273 LOG(ERROR) << "Failed to disable Bluetooth - status: "
274 << BtStatusText((const bt_status_t)status);
275 state_ = current_state;
276 NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_OFF, state_);
277 return false;
278 }
279
280 return true;
281 }
282
Myles Watson911d1ae2016-11-28 16:44:40 -0800283 std::string GetName() const override { return name_.Get(); }
Arman Uguray0a0d3932015-11-19 15:57:57 -0800284
285 bool SetName(const std::string& name) override {
286 bt_bdname_t hal_name;
287 size_t max_name_len = sizeof(hal_name.name);
288
289 // Include the \0 byte in size measurement.
290 if (name.length() >= max_name_len) {
291 LOG(ERROR) << "Given name \"" << name << "\" is larger than maximum"
292 << " allowed size: " << max_name_len;
293 return false;
294 }
295
296 strncpy(reinterpret_cast<char*>(hal_name.name), name.c_str(),
297 name.length() + 1);
298
299 VLOG(1) << "Setting adapter name: " << name;
300
301 if (!SetAdapterProperty(BT_PROPERTY_BDNAME, &hal_name, sizeof(hal_name))) {
302 LOG(ERROR) << "Failed to set adapter name: " << name;
303 return false;
304 }
305
306 return true;
307 }
308
Myles Watson911d1ae2016-11-28 16:44:40 -0800309 std::string GetAddress() const override { return address_.Get(); }
Arman Uguray0a0d3932015-11-19 15:57:57 -0800310
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800311 bool SetScanMode(int scan_mode) override {
312 switch (scan_mode) {
313 case BT_SCAN_MODE_NONE:
314 case BT_SCAN_MODE_CONNECTABLE:
315 case BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
316 break;
317 default:
318 LOG(ERROR) << "Unknown scan mode: " << scan_mode;
319 return false;
320 }
321
322 auto bd_scanmode = static_cast<bt_scan_mode_t>(scan_mode);
323
324 if (!SetAdapterProperty(BT_PROPERTY_ADAPTER_SCAN_MODE, &bd_scanmode,
325 sizeof(bd_scanmode))) {
326 LOG(ERROR) << "Failed to set scan mode to : " << scan_mode;
327 return false;
328 }
329
330 return true;
331 }
332
333 bool SetScanEnable(bool scan_enable) override {
334 if (scan_enable) {
335 int status =
336 hal::BluetoothInterface::Get()->GetHALInterface()->start_discovery();
337 if (status != BT_STATUS_SUCCESS) {
338 LOG(ERROR) << "Failed to enable scanning";
339 return false;
340 }
341 } else {
342 int status =
343 hal::BluetoothInterface::Get()->GetHALInterface()->cancel_discovery();
344 if (status != BT_STATUS_SUCCESS) {
345 LOG(ERROR) << "Failed to disable scanning";
346 return false;
347 }
348 }
349 return true;
350 }
351
352 bool SspReply(const std::string& device_address, int variant, bool accept,
353 int32_t pass_key) override {
354 RawAddress addr;
355 if (!RawAddress::FromString(device_address, addr)) {
356 LOG(ERROR) << "Invalid device address given: " << device_address;
357 return false;
358 }
359
360 int status = hal::BluetoothInterface::Get()->GetHALInterface()->ssp_reply(
361 &addr, static_cast<bt_ssp_variant_t>(variant), accept, pass_key);
362 if (status != BT_STATUS_SUCCESS) {
363 LOG(ERROR) << "Failed to send SSP response - status: "
364 << BtStatusText((const bt_status_t)status);
365 return false;
366 }
367
368 return true;
369 }
370
371 bool CreateBond(const std::string& device_address, int transport) override {
372 RawAddress addr;
373 if (!RawAddress::FromString(device_address, addr)) {
374 LOG(ERROR) << "Invalid device address given: " << device_address;
375 return false;
376 }
377
378 int status = hal::BluetoothInterface::Get()->GetHALInterface()->create_bond(
379 &addr, transport);
380 if (status != BT_STATUS_SUCCESS) {
381 LOG(ERROR) << "Failed to create bond - status: "
382 << BtStatusText((const bt_status_t)status);
383 return false;
384 }
385
386 return true;
387 }
388
Arman Uguray0a0d3932015-11-19 15:57:57 -0800389 bool IsMultiAdvertisementSupported() override {
390 lock_guard<mutex> lock(local_le_features_lock_);
391 return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv;
392 }
393
394 bool IsDeviceConnected(const std::string& device_address) override {
Arman Uguray6791e9a2015-11-17 13:29:55 -0800395 lock_guard<mutex> lock(connected_devices_lock_);
Arman Uguray0a0d3932015-11-19 15:57:57 -0800396 return connected_devices_.find(device_address) != connected_devices_.end();
Arman Uguray0f29c002015-11-13 15:05:48 -0800397 }
398
Arman Uguray0a0d3932015-11-19 15:57:57 -0800399 int GetTotalNumberOfTrackableAdvertisements() override {
400 lock_guard<mutex> lock(local_le_features_lock_);
401 return local_le_features_.total_trackable_advertisers;
Arman Uguray4fdadb62015-08-13 16:09:35 -0700402 }
403
Arman Uguray0a0d3932015-11-19 15:57:57 -0800404 bool IsOffloadedFilteringSupported() override {
405 lock_guard<mutex> lock(local_le_features_lock_);
406 return local_le_features_.max_adv_filter_supported >= kMinOffloadedFilters;
407 }
Arman Uguray4fdadb62015-08-13 16:09:35 -0700408
Arman Uguray0a0d3932015-11-19 15:57:57 -0800409 bool IsOffloadedScanBatchingSupported() override {
410 lock_guard<mutex> lock(local_le_features_lock_);
411 return local_le_features_.scan_result_storage_size >=
Myles Watson911d1ae2016-11-28 16:44:40 -0800412 kMinOffloadedScanStorageBytes;
Arman Uguray0a0d3932015-11-19 15:57:57 -0800413 }
Arman Uguray4cebc7e2015-08-20 11:38:49 -0700414
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800415 bool GetBondedDevices() override {
416 int status =
417 hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_property(
418 BT_PROPERTY_ADAPTER_BONDED_DEVICES);
419 if (status != BT_STATUS_SUCCESS) {
420 LOG(ERROR) << "Failed to get bonded devices. Status: "
421 << BtStatusText(static_cast<bt_status_t>(status));
422 return false;
423 }
424
425 return true;
426 }
427
428 bool RemoveBond(const std::string& device_address) override {
429 RawAddress addr;
430 if (!RawAddress::FromString(device_address, addr)) {
431 LOG(ERROR) << "Invalid device address given: " << device_address;
432 return false;
433 }
434
435 int status =
436 hal::BluetoothInterface::Get()->GetHALInterface()->remove_bond(&addr);
437 if (status != BT_STATUS_SUCCESS) {
438 LOG(ERROR) << "Failed to send remove bond - status: "
439 << BtStatusText(static_cast<bt_status_t>(status));
440 return false;
441 }
442
443 return true;
444 }
445
446 bool GetRemoteDeviceProperties(const std::string& device_address) override {
447 RawAddress addr;
448 if (!RawAddress::FromString(device_address, addr)) {
449 LOG(ERROR) << "Invalid device address given: " << device_address;
450 return false;
451 }
452
453 int status = hal::BluetoothInterface::Get()
454 ->GetHALInterface()
455 ->get_remote_device_properties(&addr);
456 if (status != BT_STATUS_SUCCESS) {
457 LOG(ERROR) << "Failed to send GetRemoteDeviceProperties - status: "
458 << BtStatusText((const bt_status_t)status);
459 return false;
460 }
461
462 return true;
463 }
464
465 A2dpSinkFactory* GetA2dpSinkFactory() const override {
466 return a2dp_sink_factory_.get();
467 }
468
Bailey Forrest780e29c2018-08-21 17:20:29 -0700469 A2dpSourceFactory* GetA2dpSourceFactory() const override {
470 return a2dp_source_factory_.get();
471 }
472
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800473 AvrcpControlFactory* GetAvrcpControlFactory() const override {
474 return avrcp_control_factory_.get();
475 }
476
Bailey Forrest780e29c2018-08-21 17:20:29 -0700477 AvrcpTargetFactory* GetAvrcpTargetFactory() const override {
478 return avrcp_target_factory_.get();
479 }
480
Arman Uguray0a0d3932015-11-19 15:57:57 -0800481 LowEnergyClientFactory* GetLowEnergyClientFactory() const override {
482 return ble_client_factory_.get();
483 }
484
Jakub Pawlowski67d5a252016-07-13 11:55:16 -0700485 LowEnergyAdvertiserFactory* GetLeAdvertiserFactory() const override {
486 return ble_advertiser_factory_.get();
487 }
488
Jakub Pawlowskic3f6a512016-10-27 11:49:40 -0700489 LowEnergyScannerFactory* GetLeScannerFactory() const override {
490 return ble_scanner_factory_.get();
491 }
492
Arman Uguray0a0d3932015-11-19 15:57:57 -0800493 GattClientFactory* GetGattClientFactory() const override {
494 return gatt_client_factory_.get();
495 }
496
497 GattServerFactory* GetGattServerFactory() const override {
498 return gatt_server_factory_.get();
499 }
500
501 // hal::BluetoothInterface::Observer overrides.
502 void AdapterStateChangedCallback(bt_state_t state) override {
503 LOG(INFO) << "Adapter state changed: " << BtStateText(state);
504
505 AdapterState prev_state = GetState();
506
507 switch (state) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800508 case BT_STATE_OFF:
509 state_ = ADAPTER_STATE_OFF;
510 break;
Arman Uguray0a0d3932015-11-19 15:57:57 -0800511
Myles Watson911d1ae2016-11-28 16:44:40 -0800512 case BT_STATE_ON:
513 state_ = ADAPTER_STATE_ON;
514 break;
Arman Uguray0a0d3932015-11-19 15:57:57 -0800515
Myles Watson911d1ae2016-11-28 16:44:40 -0800516 default:
517 NOTREACHED();
Arman Uguray0a0d3932015-11-19 15:57:57 -0800518 }
519
520 NotifyAdapterStateChanged(prev_state, GetState());
521 }
522
Myles Watson911d1ae2016-11-28 16:44:40 -0800523 void AdapterPropertiesCallback(bt_status_t status, int num_properties,
Arman Uguray0a0d3932015-11-19 15:57:57 -0800524 bt_property_t* properties) override {
525 LOG(INFO) << "Adapter properties changed";
526
527 if (status != BT_STATUS_SUCCESS) {
528 LOG(ERROR) << "status: " << BtStatusText(status);
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800529
530 for (int i = 0; i < num_properties; ++i) {
531 bt_property_t* property = properties + i;
532 if (property->type == BT_PROPERTY_ADAPTER_BONDED_DEVICES) {
533 lock_guard<mutex> lock(observers_lock_);
534 for (auto& observer : observers_) {
535 observer.OnGetBondedDevices(this, status, {});
536 }
537 }
538 }
Arman Uguray0a0d3932015-11-19 15:57:57 -0800539 return;
540 }
541
542 for (int i = 0; i < num_properties; i++) {
543 bt_property_t* property = properties + i;
544 switch (property->type) {
545 case BT_PROPERTY_BDADDR: {
Myles Watson911d1ae2016-11-28 16:44:40 -0800546 std::string address =
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700547 BtAddrString(reinterpret_cast<RawAddress*>(property->val));
Arman Uguray0a0d3932015-11-19 15:57:57 -0800548 LOG(INFO) << "Adapter address changed: " << address;
549 address_.Set(address);
550 break;
551 }
552 case BT_PROPERTY_BDNAME: {
553 bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val);
554 std::string name = reinterpret_cast<char*>(hal_name->name);
555 LOG(INFO) << "Adapter name changed: " << name;
556 name_.Set(name);
557 break;
558 }
559 case BT_PROPERTY_LOCAL_LE_FEATURES: {
560 lock_guard<mutex> lock(local_le_features_lock_);
561 if (property->len != sizeof(bt_local_le_features_t)) {
562 LOG(WARNING) << "Malformed value received for property: "
563 << "BT_PROPERTY_LOCAL_LE_FEATURES";
564 break;
565 }
566 bt_local_le_features_t* features =
567 reinterpret_cast<bt_local_le_features_t*>(property->val);
568 memcpy(&local_le_features_, features, sizeof(*features));
569 LOG(INFO) << "Supported LE features updated";
570 break;
571 }
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800572 case BT_PROPERTY_ADAPTER_BONDED_DEVICES: {
573 if (property->len < 0) {
574 NOTREACHED() << "Negative property length";
575 break;
576 }
577 auto addrs = reinterpret_cast<const RawAddress*>(property->val);
578 if (property->len % sizeof(addrs[0]) != 0) {
579 LOG(ERROR) << "Invalid property length: " << property->len;
580 // TODO(bcf): Seems to be a bug where we hit this somewhat
581 // frequently.
582 break;
583 }
584 std::vector<std::string> str_addrs;
585
586 for (size_t i = 0; i < property->len / sizeof(addrs[0]); ++i)
587 str_addrs.push_back(BtAddrString(addrs + i));
588
589 lock_guard<mutex> lock(observers_lock_);
590 for (auto& observer : observers_) {
591 observer.OnGetBondedDevices(this, status, str_addrs);
592 }
593 break;
594 }
Arman Uguray0a0d3932015-11-19 15:57:57 -0800595 default:
596 VLOG(1) << "Unhandled adapter property: "
597 << BtPropertyText(property->type);
598 break;
599 }
600
601 // TODO(armansito): notify others of the updated properties
602 }
603 }
604
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800605 void RemoteDevicePropertiesCallback(bt_status_t status,
606 RawAddress* remote_bdaddr,
607 int num_properties,
608 bt_property_t* properties) override {
609 std::string device_address = BtAddrString(remote_bdaddr);
610 if (status != BT_STATUS_SUCCESS) {
611 lock_guard<mutex> lock(observers_lock_);
612 for (auto& observer : observers_) {
613 observer.OnGetRemoteDeviceProperties(this, status, device_address,
614 RemoteDeviceProps());
615 }
616 return;
617 }
618
619 RemoteDeviceProps props =
620 ParseRemoteDeviceProps(num_properties, properties);
621
Jakub Pawlowski7b00a3b2018-10-23 21:54:53 +0200622 std::string address = BtAddrString(remote_bdaddr);
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800623 props.set_address(address);
624
625 lock_guard<mutex> lock(observers_lock_);
626 for (auto& observer : observers_) {
627 observer.OnGetRemoteDeviceProperties(this, status, device_address, props);
628 }
629 }
630
631 void DeviceFoundCallback(int num_properties,
632 bt_property_t* properties) override {
633 RemoteDeviceProps props =
634 ParseRemoteDeviceProps(num_properties, properties);
635
636 lock_guard<mutex> lock(observers_lock_);
637 for (auto& observer : observers_) {
638 observer.OnDeviceFound(this, props);
639 }
640 }
641
642 void DiscoveryStateChangedCallback(bt_discovery_state_t state) override {
643 bool enabled = false;
644 switch (state) {
645 case BT_DISCOVERY_STOPPED:
646 enabled = false;
647 break;
648 case BT_DISCOVERY_STARTED:
649 enabled = true;
650 break;
651 default:
652 NOTREACHED();
653 }
654
655 for (auto& observer : observers_) {
656 observer.OnScanEnableChanged(this, enabled);
657 }
658 }
659
660 void SSPRequestCallback(RawAddress* remote_bdaddr, bt_bdname_t* bd_name,
661 uint32_t cod, bt_ssp_variant_t pairing_variant,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700662 uint32_t pass_key) override {
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800663 std::string device_address = BtAddrString(remote_bdaddr);
664 std::string name = reinterpret_cast<char*>(bd_name->name);
665
666 lock_guard<mutex> lock(observers_lock_);
667 for (auto& observer : observers_) {
668 observer.OnSspRequest(this, device_address, name, cod, pairing_variant,
669 pass_key);
670 }
671 }
672
673 void BondStateChangedCallback(bt_status_t status, RawAddress* remote_bdaddr,
674 bt_bond_state_t state) override {
675 std::string device_address = BtAddrString(remote_bdaddr);
676
677 lock_guard<mutex> lock(observers_lock_);
678 for (auto& observer : observers_) {
679 observer.OnBondStateChanged(this, status, device_address, state);
680 }
Jakub Pawlowski197a1b92017-02-23 14:43:08 -0800681 }
682
Arman Uguray0a0d3932015-11-19 15:57:57 -0800683 void AclStateChangedCallback(bt_status_t status,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700684 const RawAddress& remote_bdaddr,
Arman Uguray0a0d3932015-11-19 15:57:57 -0800685 bt_acl_state_t state) override {
686 std::string device_address = BtAddrString(&remote_bdaddr);
687 bool connected = (state == BT_ACL_STATE_CONNECTED);
Myles Watson911d1ae2016-11-28 16:44:40 -0800688 LOG(INFO) << "ACL state changed: " << device_address
689 << " - connected: " << (connected ? "true" : "false");
Arman Uguray0a0d3932015-11-19 15:57:57 -0800690
691 // If this is reported with an error status, I suppose the best thing we can
692 // do is to log it and ignore the event.
693 if (status != BT_STATUS_SUCCESS) {
694 LOG(ERROR) << "status: " << BtStatusText(status);
695 return;
696 }
697
698 // Introduce a scope to manage |connected_devices_lock_| with RAII.
699 {
700 lock_guard<mutex> lock(connected_devices_lock_);
701 if (connected)
702 connected_devices_.insert(device_address);
703 else
704 connected_devices_.erase(device_address);
705 }
706
707 lock_guard<mutex> lock(observers_lock_);
Hidehiko Abeaeca7aa2017-12-13 18:57:10 +0900708 for (auto& observer : observers_) {
709 observer.OnDeviceConnectionStateChanged(this, device_address, connected);
710 }
Arman Uguray0a0d3932015-11-19 15:57:57 -0800711 }
712
713 // Sends a request to set the given HAL adapter property type and value.
714 bool SetAdapterProperty(bt_property_type_t type, void* value, int length) {
715 CHECK(length > 0);
716 CHECK(value);
717
718 bt_property_t property;
719 property.len = length;
720 property.val = value;
721 property.type = type;
722
Myles Watson911d1ae2016-11-28 16:44:40 -0800723 int status =
724 hal::BluetoothInterface::Get()->GetHALInterface()->set_adapter_property(
725 &property);
Arman Uguray0a0d3932015-11-19 15:57:57 -0800726 if (status != BT_STATUS_SUCCESS) {
727 VLOG(1) << "Failed to set property";
728 return false;
729 }
730
731 return true;
732 }
733
734 // Helper for invoking the AdapterStateChanged observer method.
735 void NotifyAdapterStateChanged(AdapterState prev_state,
736 AdapterState new_state) {
Myles Watson911d1ae2016-11-28 16:44:40 -0800737 if (prev_state == new_state) return;
Arman Uguray0a0d3932015-11-19 15:57:57 -0800738
739 lock_guard<mutex> lock(observers_lock_);
Hidehiko Abeaeca7aa2017-12-13 18:57:10 +0900740 for (auto& observer : observers_) {
741 observer.OnAdapterStateChanged(this, prev_state, new_state);
742 }
Arman Uguray0a0d3932015-11-19 15:57:57 -0800743 }
744
745 private:
746 // The current adapter state.
747 std::atomic<AdapterState> state_;
748
749 // The Bluetooth device address of the local adapter in string from
750 // (i.e.. XX:XX:XX:XX:XX:XX)
751 util::AtomicString address_;
752
753 // The current local adapter name.
754 util::AtomicString name_;
755
756 // The current set of supported LE features as obtained from the stack. The
757 // values here are all initially set to 0 and updated when the corresponding
758 // adapter property has been received from the stack.
759 std::mutex local_le_features_lock_;
760 bt_local_le_features_t local_le_features_;
761
762 // List of observers that are interested in notifications from us.
763 std::mutex observers_lock_;
764 base::ObserverList<Adapter::Observer> observers_;
765
766 // List of devices addresses that are currently connected.
767 std::mutex connected_devices_lock_;
768 std::unordered_set<std::string> connected_devices_;
769
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800770 // Factory used to create per-app A2dpSink instances.
771 std::unique_ptr<A2dpSinkFactory> a2dp_sink_factory_;
772
Bailey Forrest780e29c2018-08-21 17:20:29 -0700773 // Factory used to create per-app A2dpSource instances.
774 std::unique_ptr<A2dpSourceFactory> a2dp_source_factory_;
775
Bailey Forrest62aa15f2017-01-30 17:38:58 -0800776 // Factory used to create per-app AvrcpControl instances.
777 std::unique_ptr<AvrcpControlFactory> avrcp_control_factory_;
778
Bailey Forrest780e29c2018-08-21 17:20:29 -0700779 // Factory used to create per-app AvrcpTarget instances.
780 std::unique_ptr<AvrcpTargetFactory> avrcp_target_factory_;
781
Arman Uguray0a0d3932015-11-19 15:57:57 -0800782 // Factory used to create per-app LowEnergyClient instances.
783 std::unique_ptr<LowEnergyClientFactory> ble_client_factory_;
784
Jakub Pawlowski67d5a252016-07-13 11:55:16 -0700785 // Factory used to create per-app LeAdvertiser instances.
786 std::unique_ptr<LowEnergyAdvertiserFactory> ble_advertiser_factory_;
787
Jakub Pawlowskic3f6a512016-10-27 11:49:40 -0700788 // Factory used to create per-app LeScanner instances.
789 std::unique_ptr<LowEnergyScannerFactory> ble_scanner_factory_;
790
Arman Uguray0a0d3932015-11-19 15:57:57 -0800791 // Factory used to create per-app GattClient instances.
792 std::unique_ptr<GattClientFactory> gatt_client_factory_;
793
794 // Factory used to create per-app GattServer instances.
795 std::unique_ptr<GattServerFactory> gatt_server_factory_;
796
797 DISALLOW_COPY_AND_ASSIGN(AdapterImpl);
798};
799
800// static
801std::unique_ptr<Adapter> Adapter::Create() {
802 return std::unique_ptr<Adapter>(new AdapterImpl());
Arman Uguray4cebc7e2015-08-20 11:38:49 -0700803}
804
Arman Uguray4fdadb62015-08-13 16:09:35 -0700805} // namespace bluetooth