Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: components/arc/bluetooth/arc_bluetooth_bridge.cc

Issue 1927803002: arc: bluetooth: Add gatt client functionality (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix compile warning Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/arc/bluetooth/arc_bluetooth_bridge.h" 5 #include "components/arc/bluetooth/arc_bluetooth_bridge.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <iomanip> 10 #include <iomanip>
11 #include <string> 11 #include <string>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/posix/eintr_wrapper.h" 15 #include "base/posix/eintr_wrapper.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
18 #include "base/threading/thread_task_runner_handle.h" 18 #include "base/threading/thread_task_runner_handle.h"
19 #include "base/time/time.h" 19 #include "base/time/time.h"
20 #include "components/arc/arc_bridge_service.h" 20 #include "components/arc/arc_bridge_service.h"
21 #include "components/arc/bluetooth/bluetooth_type_converters.h" 21 #include "components/arc/bluetooth/bluetooth_type_converters.h"
22 #include "device/bluetooth/bluetooth_adapter_factory.h" 22 #include "device/bluetooth/bluetooth_adapter_factory.h"
23 #include "device/bluetooth/bluetooth_device.h" 23 #include "device/bluetooth/bluetooth_device.h"
24 #include "device/bluetooth/bluetooth_gatt_connection.h"
25 #include "device/bluetooth/bluetooth_gatt_notify_session.h"
24 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" 26 #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h"
25 #include "device/bluetooth/bluetooth_remote_gatt_descriptor.h" 27 #include "device/bluetooth/bluetooth_remote_gatt_descriptor.h"
26 #include "device/bluetooth/bluetooth_remote_gatt_service.h" 28 #include "device/bluetooth/bluetooth_remote_gatt_service.h"
27 29
28 using device::BluetoothAdapter; 30 using device::BluetoothAdapter;
29 using device::BluetoothAdapterFactory; 31 using device::BluetoothAdapterFactory;
32 using device::BluetoothAdvertisement;
30 using device::BluetoothDevice; 33 using device::BluetoothDevice;
34 using device::BluetoothDiscoveryFilter;
31 using device::BluetoothDiscoverySession; 35 using device::BluetoothDiscoverySession;
36 using device::BluetoothGattConnection;
37 using device::BluetoothGattNotifySession;
38 using device::BluetoothGattCharacteristic;
39 using device::BluetoothGattDescriptor;
40 using device::BluetoothGattService;
32 using device::BluetoothRemoteGattCharacteristic; 41 using device::BluetoothRemoteGattCharacteristic;
33 using device::BluetoothRemoteGattDescriptor; 42 using device::BluetoothRemoteGattDescriptor;
34 using device::BluetoothRemoteGattService; 43 using device::BluetoothRemoteGattService;
44 using device::BluetoothUUID;
45
46 namespace {
47 const int kMinBtleVersion = 1;
48 } // namespace
35 49
36 namespace arc { 50 namespace arc {
37 51
38 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) 52 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service)
39 : ArcService(bridge_service), binding_(this), weak_factory_(this) { 53 : ArcService(bridge_service), binding_(this), weak_factory_(this) {
40 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { 54 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
41 VLOG(1) << "registering bluetooth adapter"; 55 VLOG(1) << "registering bluetooth adapter";
42 BluetoothAdapterFactory::GetAdapter(base::Bind( 56 BluetoothAdapterFactory::GetAdapter(base::Bind(
43 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); 57 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr()));
44 } else { 58 } else {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 return; 112 return;
99 113
100 if (device->IsConnected()) 114 if (device->IsConnected())
101 return; 115 return;
102 116
103 mojo::Array<mojom::BluetoothPropertyPtr> properties = 117 mojo::Array<mojom::BluetoothPropertyPtr> properties =
104 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); 118 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
105 119
106 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 120 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
107 std::move(properties)); 121 std::move(properties));
122
123 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
124 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
125 return;
126 }
127
128 mojom::BluetoothAddressPtr addr =
129 mojom::BluetoothAddress::From(device->GetAddress());
130 int rssi = device->GetInquiryRSSI();
131 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
132 GetAdvertisingData(device);
133 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
134 std::move(addr), rssi, std::move(adv_data));
108 } 135 }
109 136
110 void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter, 137 void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter,
111 BluetoothDevice* device) { 138 BluetoothDevice* device) {
112 // TODO(smbarber): device properties changed; inform the container. 139 // TODO(smbarber): device properties changed; inform the container.
113 } 140 }
114 141
115 void ArcBluetoothBridge::DeviceAddressChanged(BluetoothAdapter* adapter, 142 void ArcBluetoothBridge::DeviceAddressChanged(BluetoothAdapter* adapter,
116 BluetoothDevice* device, 143 BluetoothDevice* device,
117 const std::string& old_address) { 144 const std::string& old_address) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 184
158 void ArcBluetoothBridge::GattServiceRemoved( 185 void ArcBluetoothBridge::GattServiceRemoved(
159 BluetoothAdapter* adapter, 186 BluetoothAdapter* adapter,
160 BluetoothDevice* device, 187 BluetoothDevice* device,
161 BluetoothRemoteGattService* service) { 188 BluetoothRemoteGattService* service) {
162 // Placeholder for GATT client functionality 189 // Placeholder for GATT client functionality
163 } 190 }
164 191
165 void ArcBluetoothBridge::GattServicesDiscovered(BluetoothAdapter* adapter, 192 void ArcBluetoothBridge::GattServicesDiscovered(BluetoothAdapter* adapter,
166 BluetoothDevice* device) { 193 BluetoothDevice* device) {
167 // Placeholder for GATT client functionality 194 if (!HasBluetoothInstance())
195 return;
196
197 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
198 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
199 return;
200 }
201
202 mojom::BluetoothAddressPtr addr =
203 mojom::BluetoothAddress::From(device->GetAddress());
204
205 arc_bridge_service()->bluetooth_instance()->OnSearchComplete(
206 std::move(addr), mojom::BluetoothGattStatus::GATT_SUCCESS);
168 } 207 }
169 208
170 void ArcBluetoothBridge::GattDiscoveryCompleteForService( 209 void ArcBluetoothBridge::GattDiscoveryCompleteForService(
171 BluetoothAdapter* adapter, 210 BluetoothAdapter* adapter,
172 BluetoothRemoteGattService* service) { 211 BluetoothRemoteGattService* service) {
173 // Placeholder for GATT client functionality 212 // Placeholder for GATT client functionality
174 } 213 }
175 214
176 void ArcBluetoothBridge::GattServiceChanged( 215 void ArcBluetoothBridge::GattServiceChanged(
177 BluetoothAdapter* adapter, 216 BluetoothAdapter* adapter,
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 BluetoothDevice* device = 493 BluetoothDevice* device =
455 bluetooth_adapter_->GetDevice(addr->To<std::string>()); 494 bluetooth_adapter_->GetDevice(addr->To<std::string>());
456 if (!device) { 495 if (!device) {
457 callback.Run(false); 496 callback.Run(false);
458 return; 497 return;
459 } 498 }
460 499
461 callback.Run(device->IsConnected()); 500 callback.Run(device->IsConnected());
462 } 501 }
463 502
503 void ArcBluetoothBridge::StartLEScan() {
504 DCHECK(bluetooth_adapter_);
505 if (discovery_session_) {
506 LOG(WARNING) << "Discovery session already running; leaving alone";
507 SendCachedDevicesFound();
508 return;
509 }
510 bluetooth_adapter_->StartDiscoverySessionWithFilter(
511 base::WrapUnique(new BluetoothDiscoveryFilter(
512 BluetoothDiscoveryFilter::Transport::TRANSPORT_LE)),
513 base::Bind(&ArcBluetoothBridge::OnDiscoveryStarted,
514 weak_factory_.GetWeakPtr()),
515 base::Bind(&ArcBluetoothBridge::OnDiscoveryError,
516 weak_factory_.GetWeakPtr()));
517 }
518
519 void ArcBluetoothBridge::StopLEScan() {
520 CancelDiscovery();
521 }
522
523 void ArcBluetoothBridge::OnGattConnectStateChanged(
524 mojom::BluetoothAddressPtr addr,
525 bool connected) const {
526 if (!HasBluetoothInstance())
527 return;
528
529 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
530 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
531 return;
532 }
533
534 DCHECK(addr);
535
536 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
537 std::move(addr), connected);
538 }
539
540 void ArcBluetoothBridge::OnGattConnected(
541 mojom::BluetoothAddressPtr addr,
542 std::unique_ptr<BluetoothGattConnection> connection) const {
543 OnGattConnectStateChanged(std::move(addr), true);
544 }
545
546 void ArcBluetoothBridge::OnGattConnectError(
547 mojom::BluetoothAddressPtr addr,
548 BluetoothDevice::ConnectErrorCode error_code) const {
549 OnGattConnectStateChanged(std::move(addr), false);
550 }
551
552 void ArcBluetoothBridge::OnGattDisconnected(
553 mojom::BluetoothAddressPtr addr) const {
554 OnGattConnectStateChanged(std::move(addr), false);
555 }
556
557 void ArcBluetoothBridge::ConnectLEDevice(
558 mojom::BluetoothAddressPtr remote_addr) {
559 if (!HasBluetoothInstance())
560 return;
561
562 BluetoothDevice* device =
563 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
564 DCHECK(device);
565
566 if (device->IsConnected()) {
567 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
568 std::move(remote_addr), true);
569 return;
570 }
571
572 // Also pass disconnect callback in error case
573 // since it would be disconnected anyway.
574 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
575 device->CreateGattConnection(
576 base::Bind(&ArcBluetoothBridge::OnGattConnected,
577 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
578 base::Bind(&ArcBluetoothBridge::OnGattConnectError,
579 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone)));
580 }
581
582 void ArcBluetoothBridge::DisconnectLEDevice(
583 mojom::BluetoothAddressPtr remote_addr) {
584 if (!HasBluetoothInstance())
585 return;
586
587 BluetoothDevice* device =
588 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
589 DCHECK(device);
590
591 if (!device->IsConnected()) {
592 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
593 std::move(remote_addr), false);
594 return;
595 }
596
597 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
598 device->Disconnect(
599 base::Bind(&ArcBluetoothBridge::OnGattDisconnected,
600 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
601 base::Bind(&ArcBluetoothBridge::OnGattDisconnected,
602 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone)));
603 }
604
605 void ArcBluetoothBridge::SearchService(mojom::BluetoothAddressPtr remote_addr) {
606 if (!HasBluetoothInstance())
607 return;
608
609 BluetoothDevice* device =
610 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
611 DCHECK(device);
612
613 // Call the callback if discovery is completed
614 if (device->IsGattServicesDiscoveryComplete()) {
615 arc_bridge_service()->bluetooth_instance()->OnSearchComplete(
616 std::move(remote_addr), mojom::BluetoothGattStatus::GATT_SUCCESS);
617 return;
618 }
619
620 // Discard result. Will call the callback when discovery is completed.
621 device->GetGattServices();
622 }
623
624 void ArcBluetoothBridge::OnStartLEListenDone(
625 const StartLEListenCallback& callback,
626 scoped_refptr<BluetoothAdvertisement> advertisement) {
627 advertisment_ = advertisement;
628 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
629 }
630
631 void ArcBluetoothBridge::OnStartLEListenError(
632 const StartLEListenCallback& callback,
633 BluetoothAdvertisement::ErrorCode error_code) {
634 advertisment_ = nullptr;
635 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
636 }
637
638 void ArcBluetoothBridge::StartLEListen(const StartLEListenCallback& callback) {
639 std::unique_ptr<BluetoothAdvertisement::Data> adv_data =
640 base::WrapUnique(new BluetoothAdvertisement::Data(
641 BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST));
642 bluetooth_adapter_->RegisterAdvertisement(
643 std::move(adv_data), base::Bind(&ArcBluetoothBridge::OnStartLEListenDone,
644 weak_factory_.GetWeakPtr(), callback),
645 base::Bind(&ArcBluetoothBridge::OnStartLEListenError,
646 weak_factory_.GetWeakPtr(), callback));
647 }
648
649 void ArcBluetoothBridge::OnStopLEListenDone(
650 const StopLEListenCallback& callback) {
651 advertisment_ = nullptr;
652 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
653 }
654
655 void ArcBluetoothBridge::OnStopLEListenError(
656 const StopLEListenCallback& callback,
657 BluetoothAdvertisement::ErrorCode error_code) {
658 advertisment_ = nullptr;
659 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
660 }
661
662 void ArcBluetoothBridge::StopLEListen(const StopLEListenCallback& callback) {
663 if (!advertisment_) {
664 OnStopLEListenError(
665 callback,
666 BluetoothAdvertisement::ErrorCode::ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
667 return;
668 }
669 advertisment_->Unregister(base::Bind(&ArcBluetoothBridge::OnStopLEListenDone,
670 weak_factory_.GetWeakPtr(), callback),
671 base::Bind(&ArcBluetoothBridge::OnStopLEListenError,
672 weak_factory_.GetWeakPtr(), callback));
673 }
674
675 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
676 // We want to convert last digit of the identifier to int in base 16
677 int ArcBluetoothBridge::ConvertGattIdentifierToId(
678 const std::string identifier) const {
679 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16);
680 }
681
682 // Create GattDBElement and fill in common data for
683 // Gatt Service/Characteristic/Descriptor.
684 template <class T>
685 mojom::BluetoothGattDBElementPtr ArcBluetoothBridge::CreateGattDBElement(
686 const mojom::BluetoothGattDBAttributeType type,
687 const T* gattObject) const {
688 mojom::BluetoothGattDBElementPtr element =
689 mojom::BluetoothGattDBElement::New();
690 element->type = type;
691 element->uuid = mojom::BluetoothUUID::From(gattObject->GetUUID());
692 element->id = element->attribute_handle = element->start_handle =
693 element->end_handle =
694 ConvertGattIdentifierToId(gattObject->GetIdentifier());
695 element->properties = 0;
696 return element;
697 }
698
699 void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) {
700 if (!HasBluetoothInstance())
701 return;
702
703 BluetoothDevice* device =
704 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
705 mojo::Array<mojom::BluetoothGattDBElementPtr> db;
706 for (auto service : device->GetGattServices()) {
707 mojom::BluetoothGattDBElementPtr service_element = CreateGattDBElement<
708 device::BluetoothRemoteGattService>(
709 service->IsPrimary()
710 ? mojom::BluetoothGattDBAttributeType::BTGATT_DB_PRIMARY_SERVICE
711 : mojom::BluetoothGattDBAttributeType::BTGATT_DB_SECONDARY_SERVICE,
712 service);
713
714 const auto& characteristics = service->GetCharacteristics();
715 if (characteristics.size() > 0) {
716 const auto& descriptors = characteristics.back()->GetDescriptors();
717 service_element->start_handle =
718 ConvertGattIdentifierToId(characteristics.front()->GetIdentifier());
719 service_element->end_handle = ConvertGattIdentifierToId(
720 descriptors.size() > 0 ? descriptors.back()->GetIdentifier()
721 : characteristics.back()->GetIdentifier());
722 }
723 db.push_back(std::move(service_element));
724
725 for (auto characteristic : characteristics) {
palmer 2016/06/15 23:10:16 Nit: Could this (And line 733) be const auto&?
puthik_chromium 2016/06/16 00:03:34 There is no need. |characteristics| is already a v
726 mojom::BluetoothGattDBElementPtr characteristic_element =
727 CreateGattDBElement<device::BluetoothRemoteGattCharacteristic>(
728 mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC,
729 characteristic);
730 characteristic_element->properties = characteristic->GetProperties();
731 db.push_back(std::move(characteristic_element));
732
733 for (auto descriptor : characteristic->GetDescriptors()) {
734 db.push_back(CreateGattDBElement<device::BluetoothRemoteGattDescriptor>(
735 mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR,
736 descriptor));
737 }
738 }
739 }
740
741 arc_bridge_service()->bluetooth_instance()->OnGetGattDB(
742 std::move(remote_addr), std::move(db));
743 }
744
745 // Find Gatt Service/Characteristic/Descriptor from std::vector from UUID.
746 template <class T>
747 T* ArcBluetoothBridge::FindGattObjectFromUuid(
748 const std::vector<T*> gatt_objs,
749 const device::BluetoothUUID uuid) const {
750 auto it = std::find_if(gatt_objs.begin(), gatt_objs.end(),
751 [&](T* obj) { return obj->GetUUID() == uuid; });
752 if (it == gatt_objs.end())
753 return nullptr;
754 return *it;
755 }
756
757 BluetoothRemoteGattCharacteristic* ArcBluetoothBridge::FindGattCharacteristic(
758 mojom::BluetoothAddressPtr remote_addr,
759 mojom::BluetoothGattServiceIDPtr service_id,
760 mojom::BluetoothGattIDPtr char_id) const {
761 DCHECK(remote_addr);
762 DCHECK(service_id);
763 DCHECK(char_id);
764
765 BluetoothDevice* device =
766 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
767 if (!device)
768 return nullptr;
769
770 BluetoothRemoteGattService* service =
771 FindGattObjectFromUuid<BluetoothRemoteGattService>(
772 device->GetGattServices(), service_id->id->uuid.To<BluetoothUUID>());
773 if (!service)
774 return nullptr;
775
776 return FindGattObjectFromUuid<BluetoothRemoteGattCharacteristic>(
777 service->GetCharacteristics(), char_id->uuid.To<BluetoothUUID>());
778 }
779
780 BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor(
781 mojom::BluetoothAddressPtr remote_addr,
782 mojom::BluetoothGattServiceIDPtr service_id,
783 mojom::BluetoothGattIDPtr char_id,
784 mojom::BluetoothGattIDPtr desc_id) const {
785 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
786 std::move(remote_addr), std::move(service_id), std::move(char_id));
787 if (!characteristic)
788 return nullptr;
789
790 return FindGattObjectFromUuid<BluetoothRemoteGattDescriptor>(
791 characteristic->GetDescriptors(), desc_id->uuid.To<BluetoothUUID>());
792 }
793
794 // Same callback for both ReadGattCharacteristic and ReadGattDescriptor
795 void ArcBluetoothBridge::OnGattReadDone(
796 const GattReadCallback& callback,
797 const std::vector<uint8_t>& result) const {
798 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
799 gattValue->status = mojom::BluetoothGattStatus::GATT_SUCCESS;
800 gattValue->value = mojo::Array<uint8_t>::From(result);
801 callback.Run(std::move(gattValue));
802 }
803
804 void ArcBluetoothBridge::OnGattReadError(
805 const GattReadCallback& callback,
806 BluetoothGattService::GattErrorCode error_code) const {
807 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
808 gattValue->status = mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code);
809 gattValue->value = nullptr;
810
811 callback.Run(std::move(gattValue));
812 }
813
814 // Same callback for both WriteGattCharacteristic and WriteGattDescriptor
815 void ArcBluetoothBridge::OnGattWriteDone(
816 const GattWriteCallback& callback) const {
817 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
818 }
819
820 void ArcBluetoothBridge::OnGattWriteError(
821 const GattWriteCallback& callback,
822 BluetoothGattService::GattErrorCode error_code) const {
823 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
824 }
825
826 void ArcBluetoothBridge::ReadGattCharacteristic(
827 mojom::BluetoothAddressPtr remote_addr,
828 mojom::BluetoothGattServiceIDPtr service_id,
829 mojom::BluetoothGattIDPtr char_id,
830 const ReadGattCharacteristicCallback& callback) {
831 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
832 std::move(remote_addr), std::move(service_id), std::move(char_id));
833
834 DCHECK(characteristic);
835
836 DCHECK(characteristic->GetPermissions() &
palmer 2016/06/15 23:10:16 This is another repeated chunk of code could would
puthik_chromium 2016/06/16 00:03:33 I refactor the permission to be a const. This shou
837 (BluetoothGattCharacteristic::Permission::PERMISSION_READ |
838 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
839 BluetoothGattCharacteristic::Permission::
840 PERMISSION_READ_ENCRYPTED_AUTHENTICATED));
841
842 characteristic->ReadRemoteCharacteristic(
843 base::Bind(&ArcBluetoothBridge::OnGattReadDone,
844 weak_factory_.GetWeakPtr(), callback),
845 base::Bind(&ArcBluetoothBridge::OnGattReadError,
846 weak_factory_.GetWeakPtr(), callback));
847 }
848
849 void ArcBluetoothBridge::WriteGattCharacteristic(
850 mojom::BluetoothAddressPtr remote_addr,
851 mojom::BluetoothGattServiceIDPtr service_id,
852 mojom::BluetoothGattIDPtr char_id,
853 mojom::BluetoothGattValuePtr value,
854 const WriteGattCharacteristicCallback& callback) {
855 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
856 std::move(remote_addr), std::move(service_id), std::move(char_id));
857
858 DCHECK(characteristic);
859
860 DCHECK(characteristic->GetPermissions() &
861 (BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
862 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
863 BluetoothGattCharacteristic::Permission::
864 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED));
865
866 characteristic->WriteRemoteCharacteristic(
867 value->value.To<std::vector<uint8_t>>(),
868 base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
869 weak_factory_.GetWeakPtr(), callback),
870 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
871 weak_factory_.GetWeakPtr(), callback));
872 }
873
874 void ArcBluetoothBridge::ReadGattDescriptor(
875 mojom::BluetoothAddressPtr remote_addr,
876 mojom::BluetoothGattServiceIDPtr service_id,
877 mojom::BluetoothGattIDPtr char_id,
878 mojom::BluetoothGattIDPtr desc_id,
879 const ReadGattDescriptorCallback& callback) {
880 BluetoothRemoteGattDescriptor* descriptor =
881 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
882 std::move(char_id), std::move(desc_id));
883 DCHECK(descriptor);
884
885 DCHECK(descriptor->GetPermissions() &
886 (BluetoothGattCharacteristic::Permission::PERMISSION_READ |
887 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
888 BluetoothGattCharacteristic::Permission::
889 PERMISSION_READ_ENCRYPTED_AUTHENTICATED));
890
891 descriptor->ReadRemoteDescriptor(
892 base::Bind(&ArcBluetoothBridge::OnGattReadDone,
893 weak_factory_.GetWeakPtr(), callback),
894 base::Bind(&ArcBluetoothBridge::OnGattReadError,
895 weak_factory_.GetWeakPtr(), callback));
896 }
897
898 void ArcBluetoothBridge::WriteGattDescriptor(
899 mojom::BluetoothAddressPtr remote_addr,
900 mojom::BluetoothGattServiceIDPtr service_id,
901 mojom::BluetoothGattIDPtr char_id,
902 mojom::BluetoothGattIDPtr desc_id,
903 mojom::BluetoothGattValuePtr value,
904 const WriteGattDescriptorCallback& callback) {
905 BluetoothRemoteGattDescriptor* descriptor =
906 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
907 std::move(char_id), std::move(desc_id));
908 DCHECK(descriptor);
909
910 DCHECK(descriptor->GetPermissions() &
911 (BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
912 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
913 BluetoothGattCharacteristic::Permission::
914 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED));
915
916 descriptor->WriteRemoteDescriptor(
palmer 2016/06/15 23:10:16 So, a total of 4 functions that are all identical
puthik_chromium 2016/06/16 00:03:33 What this 4 functions do is just passing the reque
917 value->value.To<std::vector<uint8_t>>(),
918 base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
919 weak_factory_.GetWeakPtr(), callback),
920 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
921 weak_factory_.GetWeakPtr(), callback));
922 }
923
924 void ArcBluetoothBridge::OnGattNotifyStartDone(
925 const RegisterForGattNotificationCallback& callback,
926 const std::string char_string_id,
927 std::unique_ptr<BluetoothGattNotifySession> notify_session) {
928 notification_session_[char_string_id] = std::move(notify_session);
929 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
930 }
931
932 void ArcBluetoothBridge::OnGattNotifyStartError(
933 const RegisterForGattNotificationCallback& callback,
934 BluetoothGattService::GattErrorCode error_code) const {
935 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
936 }
937
938 void ArcBluetoothBridge::OnGattNotifyStopDone(
939 const DeregisterForGattNotificationCallback& callback) const {
940 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
941 }
942
943 void ArcBluetoothBridge::RegisterForGattNotification(
944 mojom::BluetoothAddressPtr remote_addr,
945 mojom::BluetoothGattServiceIDPtr service_id,
946 mojom::BluetoothGattIDPtr char_id,
947 const RegisterForGattNotificationCallback& callback) {
948 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
949 std::move(remote_addr), std::move(service_id), std::move(char_id));
950
951 if (!characteristic) {
952 LOG(WARNING) << __func__ << " Characteristic is not existed.";
953 return;
954 }
955
956 if (characteristic->IsNotifying()) {
957 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
958 return;
959 }
960
961 characteristic->StartNotifySession(
962 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone,
963 weak_factory_.GetWeakPtr(), callback,
964 characteristic->GetIdentifier()),
965 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartError,
966 weak_factory_.GetWeakPtr(), callback));
967 }
968
969 void ArcBluetoothBridge::DeregisterForGattNotification(
970 mojom::BluetoothAddressPtr remote_addr,
971 mojom::BluetoothGattServiceIDPtr service_id,
972 mojom::BluetoothGattIDPtr char_id,
973 const DeregisterForGattNotificationCallback& callback) {
974 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
975 std::move(remote_addr), std::move(service_id), std::move(char_id));
976
977 if (!characteristic) {
978 LOG(WARNING) << __func__ << " Characteristic is not existed.";
979 return;
980 }
981
982 if (!characteristic->IsNotifying()) {
983 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
984 return;
985 }
986
987 std::string char_id_str = characteristic->GetIdentifier();
988 std::unique_ptr<BluetoothGattNotifySession> notify =
989 std::move(notification_session_[char_id_str]);
990 notification_session_.erase(char_id_str);
991 notify->Stop(base::Bind(&ArcBluetoothBridge::OnGattNotifyStopDone,
992 weak_factory_.GetWeakPtr(), callback));
993 }
994
995 void ArcBluetoothBridge::ReadRemoteRssi(
996 mojom::BluetoothAddressPtr remote_addr,
997 const ReadRemoteRssiCallback& callback) {
998 BluetoothDevice* device =
999 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
1000 int rssi = device->GetInquiryRSSI();
1001 callback.Run(rssi);
1002 }
1003
464 void ArcBluetoothBridge::OnDiscoveryError() { 1004 void ArcBluetoothBridge::OnDiscoveryError() {
465 LOG(WARNING) << "failed to change discovery state"; 1005 LOG(WARNING) << "failed to change discovery state";
466 } 1006 }
467 1007
468 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { 1008 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const {
469 if (!HasBluetoothInstance()) 1009 if (!HasBluetoothInstance())
470 return; 1010 return;
471 1011
472 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged( 1012 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged(
473 mojom::BluetoothStatus::SUCCESS, std::move(addr), 1013 mojom::BluetoothStatus::SUCCESS, std::move(addr),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 } 1076 }
537 if (type == mojom::BluetoothPropertyType::ALL || 1077 if (type == mojom::BluetoothPropertyType::ALL ||
538 type == mojom::BluetoothPropertyType::BDADDR) { 1078 type == mojom::BluetoothPropertyType::BDADDR) {
539 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1079 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
540 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress())); 1080 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress()));
541 properties.push_back(std::move(btp)); 1081 properties.push_back(std::move(btp));
542 } 1082 }
543 if (type == mojom::BluetoothPropertyType::ALL || 1083 if (type == mojom::BluetoothPropertyType::ALL ||
544 type == mojom::BluetoothPropertyType::UUIDS) { 1084 type == mojom::BluetoothPropertyType::UUIDS) {
545 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1085 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
546 std::vector<device::BluetoothUUID> uuids = device->GetUUIDs(); 1086 std::vector<BluetoothUUID> uuids = device->GetUUIDs();
547 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results = 1087 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results =
548 mojo::Array<mojom::BluetoothUUIDPtr>::New(0); 1088 mojo::Array<mojom::BluetoothUUIDPtr>::New(0);
549 1089
550 for (size_t i = 0; i < uuids.size(); i++) { 1090 for (auto& uuid : uuids) {
551 uuid_results.push_back(mojom::BluetoothUUID::From(uuids[i])); 1091 uuid_results.push_back(mojom::BluetoothUUID::From(uuid));
552 } 1092 }
553 1093
554 btp->set_uuids(std::move(uuid_results)); 1094 btp->set_uuids(std::move(uuid_results));
555 properties.push_back(std::move(btp)); 1095 properties.push_back(std::move(btp));
556 } 1096 }
557 if (type == mojom::BluetoothPropertyType::ALL || 1097 if (type == mojom::BluetoothPropertyType::ALL ||
558 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { 1098 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) {
559 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1099 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
560 btp->set_device_class(device->GetBluetoothClass()); 1100 btp->set_device_class(device->GetBluetoothClass());
561 properties.push_back(std::move(btp)); 1101 properties.push_back(std::move(btp));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 properties.push_back(std::move(btp)); 1175 properties.push_back(std::move(btp));
636 } 1176 }
637 if (type == mojom::BluetoothPropertyType::ALL || 1177 if (type == mojom::BluetoothPropertyType::ALL ||
638 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) { 1178 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) {
639 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1179 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
640 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1180 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
641 1181
642 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices = 1182 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices =
643 mojo::Array<mojom::BluetoothAddressPtr>::New(0); 1183 mojo::Array<mojom::BluetoothAddressPtr>::New(0);
644 1184
645 for (size_t i = 0; i < devices.size(); i++) { 1185 for (auto device : devices) {
646 if (!devices[i]->IsPaired()) 1186 if (device->IsPaired())
647 continue; 1187 continue;
648 1188
649 mojom::BluetoothAddressPtr addr = 1189 mojom::BluetoothAddressPtr addr =
650 mojom::BluetoothAddress::From(devices[i]->GetAddress()); 1190 mojom::BluetoothAddress::From(device->GetAddress());
651 bonded_devices.push_back(std::move(addr)); 1191 bonded_devices.push_back(std::move(addr));
652 } 1192 }
653 1193
654 btp->set_bonded_devices(std::move(bonded_devices)); 1194 btp->set_bonded_devices(std::move(bonded_devices));
655 properties.push_back(std::move(btp)); 1195 properties.push_back(std::move(btp));
656 } 1196 }
657 if (type == mojom::BluetoothPropertyType::ALL || 1197 if (type == mojom::BluetoothPropertyType::ALL ||
658 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) { 1198 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) {
659 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1199 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
660 btp->set_discovery_timeout(120); 1200 btp->set_discovery_timeout(120);
661 properties.push_back(std::move(btp)); 1201 properties.push_back(std::move(btp));
662 } 1202 }
663 1203
664 return properties; 1204 return properties;
665 } 1205 }
666 1206
1207 // Android support 5 types of Advertising Data.
1208 // However Chrome didn't expose AdvertiseFlag and ManufacturerData.
1209 // So we will only expose local_name, service_uuids and service_data.
1210 // TODO(crbug.com/618442) Make Chrome expose missing data.
1211 mojo::Array<mojom::BluetoothAdvertisingDataPtr>
1212 ArcBluetoothBridge::GetAdvertisingData(BluetoothDevice* device) const {
1213 mojo::Array<mojom::BluetoothAdvertisingDataPtr> advertising_data;
1214
1215 // LocalName
1216 mojom::BluetoothAdvertisingDataPtr local_name =
1217 mojom::BluetoothAdvertisingData::New();
1218 local_name->set_local_name(base::UTF16ToUTF8(device->GetNameForDisplay()));
1219 advertising_data.push_back(std::move(local_name));
1220
1221 // ServiceUuid
1222 BluetoothDevice::UUIDList uuid_list = device->GetServiceDataUUIDs();
1223 if (uuid_list.size() > 0) {
1224 mojom::BluetoothAdvertisingDataPtr service_uuids =
1225 mojom::BluetoothAdvertisingData::New();
1226 service_uuids->set_service_uuids(
1227 mojo::Array<mojom::BluetoothUUIDPtr>::From(uuid_list));
1228 advertising_data.push_back(std::move(service_uuids));
1229 }
1230
1231 // Service data
1232 for (auto& uuid : uuid_list) {
1233 base::BinaryValue* data = device->GetServiceData(uuid);
1234 if (data->GetSize() == 0)
1235 continue;
1236 std::string data_str;
1237 if (!data->GetAsString(&data_str))
1238 continue;
1239
1240 mojom::BluetoothAdvertisingDataPtr service_data_element =
1241 mojom::BluetoothAdvertisingData::New();
1242 mojom::BluetoothServiceDataPtr service_data =
1243 mojom::BluetoothServiceData::New();
1244
1245 std::string uuid_str = uuid.canonical_value();
1246 // Convert xxxxyyyy-xxxx-xxxx-xxxx-xxxxxxxxxxxx to int16 yyyy
1247 service_data->uuid_16bit = std::stoi(uuid_str.substr(4, 4), nullptr, 16);
1248 for (auto& c : data_str) {
1249 service_data->data.push_back(c);
1250 }
1251 service_data_element->set_service_data(std::move(service_data));
1252 advertising_data.push_back(std::move(service_data_element));
1253 }
1254
1255 return advertising_data;
1256 }
1257
667 void ArcBluetoothBridge::SendCachedDevicesFound() const { 1258 void ArcBluetoothBridge::SendCachedDevicesFound() const {
668 // Send devices that have already been discovered, but aren't connected. 1259 // Send devices that have already been discovered, but aren't connected.
669 if (!HasBluetoothInstance()) 1260 if (!HasBluetoothInstance())
670 return; 1261 return;
671 1262
672 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1263 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
673 for (size_t i = 0; i < devices.size(); i++) { 1264 for (auto device : devices) {
674 if (devices[i]->IsPaired()) 1265 if (device->IsPaired())
675 continue; 1266 continue;
676 1267
677 mojo::Array<mojom::BluetoothPropertyPtr> properties = 1268 mojo::Array<mojom::BluetoothPropertyPtr> properties =
678 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, devices[i]); 1269 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
679 1270
680 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 1271 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
681 std::move(properties)); 1272 std::move(properties));
1273
1274 if (arc_bridge_service()->bluetooth_version() >= kMinBtleVersion) {
1275 mojom::BluetoothAddressPtr addr =
1276 mojom::BluetoothAddress::From(device->GetAddress());
1277 int rssi = device->GetInquiryRSSI();
1278 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
1279 GetAdvertisingData(device);
1280 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
1281 std::move(addr), rssi, std::move(adv_data));
1282 }
682 } 1283 }
683 } 1284 }
684 1285
685 bool ArcBluetoothBridge::HasBluetoothInstance() const { 1286 bool ArcBluetoothBridge::HasBluetoothInstance() const {
686 if (!arc_bridge_service()->bluetooth_instance()) { 1287 if (!arc_bridge_service()->bluetooth_instance()) {
687 LOG(WARNING) << "no Bluetooth instance available"; 1288 LOG(WARNING) << "no Bluetooth instance available";
688 return false; 1289 return false;
689 } 1290 }
690 1291
691 return true; 1292 return true;
692 } 1293 }
693 1294
694 void ArcBluetoothBridge::SendCachedPairedDevices() const { 1295 void ArcBluetoothBridge::SendCachedPairedDevices() const {
695 DCHECK(bluetooth_adapter_); 1296 DCHECK(bluetooth_adapter_);
1297 if (!HasBluetoothInstance())
1298 return;
696 1299
697 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1300 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
698 for (BluetoothDevice* device : devices) { 1301 for (auto device : devices) {
699 if (!device->IsPaired()) 1302 if (!device->IsPaired())
700 continue; 1303 continue;
701 1304
702 mojo::Array<mojom::BluetoothPropertyPtr> properties = 1305 mojo::Array<mojom::BluetoothPropertyPtr> properties =
703 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); 1306 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
704 1307
705 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 1308 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
706 std::move(properties)); 1309 std::move(properties));
707 1310
708 mojom::BluetoothAddressPtr addr = 1311 mojom::BluetoothAddressPtr addr =
709 mojom::BluetoothAddress::From(device->GetAddress()); 1312 mojom::BluetoothAddress::From(device->GetAddress());
710 1313
1314 if (arc_bridge_service()->bluetooth_version() >= kMinBtleVersion) {
1315 int rssi = device->GetInquiryRSSI();
1316 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
1317 GetAdvertisingData(device);
1318 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
1319 addr->Clone(), rssi, std::move(adv_data));
1320 }
1321
711 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING 1322 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING
712 // to 1323 // to
713 // make sure the bond state machine on Android is ready to take the 1324 // make sure the bond state machine on Android is ready to take the
714 // pair-done event. Otherwise the pair-done event will be dropped as an 1325 // pair-done event. Otherwise the pair-done event will be dropped as an
715 // invalid change of paired status. 1326 // invalid change of paired status.
716 OnPairing(addr->Clone()); 1327 OnPairing(addr->Clone());
717 OnPairedDone(std::move(addr)); 1328 OnPairedDone(std::move(addr));
718 } 1329 }
719 } 1330 }
720 1331
721 } // namespace arc 1332 } // namespace arc
OLDNEW
« no previous file with comments | « components/arc/bluetooth/arc_bluetooth_bridge.h ('k') | components/arc/bluetooth/bluetooth_type_converters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698