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

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: 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 std::move(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::OnGattConnected(
524 mojom::BluetoothAddressPtr addr,
525 std::unique_ptr<BluetoothGattConnection> connection) 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), true);
538 }
539
540 void ArcBluetoothBridge::OnGattConnectError(
541 mojom::BluetoothAddressPtr addr,
542 BluetoothDevice::ConnectErrorCode error_code) const {
543 if (!HasBluetoothInstance())
544 return;
545
546 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
547 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
548 return;
549 }
550
551 DCHECK(addr);
552
553 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
554 std::move(addr), false);
555 }
556
557 void ArcBluetoothBridge::OnGattDisconnected(
558 mojom::BluetoothAddressPtr addr) const {
559 if (!HasBluetoothInstance())
560 return;
561
562 if (arc_bridge_service()->bluetooth_version() < kMinBtleVersion) {
563 LOG(WARNING) << "Bluetooth instance is too old and does not support BTLE";
564 return;
565 }
566
567 DCHECK(addr);
568
569 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
570 std::move(addr), false);
571 }
572
573 void ArcBluetoothBridge::ConnectLEDevice(
574 mojom::BluetoothAddressPtr remote_addr) {
575 if (!HasBluetoothInstance())
576 return;
577
578 BluetoothDevice* device =
579 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
580 DCHECK(device);
581
582 if (device->IsConnected()) {
583 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
584 std::move(remote_addr), true);
585 return;
586 }
587
588 // Also pass disconnect callback in error case
589 // since it would be disconnected anyway.
590 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
591 device->CreateGattConnection(
592 base::Bind(&ArcBluetoothBridge::OnGattConnected,
593 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
594 base::Bind(&ArcBluetoothBridge::OnGattConnectError,
595 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone)));
596 }
597
598 void ArcBluetoothBridge::DisconnectLEDevice(
599 mojom::BluetoothAddressPtr remote_addr) {
600 if (!HasBluetoothInstance())
601 return;
602
603 BluetoothDevice* device =
604 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
605 DCHECK(device);
606
607 if (!device->IsConnected()) {
608 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
609 std::move(remote_addr), false);
610 return;
611 }
612
613 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
614 device->Disconnect(
615 base::Bind(&ArcBluetoothBridge::OnGattDisconnected,
616 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
617 base::Bind(&ArcBluetoothBridge::OnGattDisconnected,
618 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone)));
619 }
620
621 void ArcBluetoothBridge::SearchService(mojom::BluetoothAddressPtr remote_addr) {
622 if (!HasBluetoothInstance())
623 return;
624
625 BluetoothDevice* device =
626 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
627 DCHECK(device);
628
629 // Call the callback if discovery is completed
630 if (device->IsGattServicesDiscoveryComplete()) {
631 arc_bridge_service()->bluetooth_instance()->OnSearchComplete(
632 std::move(remote_addr), mojom::BluetoothGattStatus::GATT_SUCCESS);
633 return;
634 }
635
636 // Discard result. Will call the callback when discovery is completed.
637 device->GetGattServices();
638 }
639
640 void ArcBluetoothBridge::OnStartLEListenDone(
641 const StartLEListenCallback& callback,
642 scoped_refptr<BluetoothAdvertisement> adv) {
643 advertisment_ = adv;
644 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
645 }
646
647 void ArcBluetoothBridge::OnStartLEListenError(
648 const StartLEListenCallback& callback,
649 BluetoothAdvertisement::ErrorCode error_code) {
650 advertisment_ = nullptr;
651 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
652 }
653
654 void ArcBluetoothBridge::StartLEListen(const StartLEListenCallback& callback) {
655 std::unique_ptr<BluetoothAdvertisement::Data> adv_data =
656 base::WrapUnique(new BluetoothAdvertisement::Data(
657 BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST));
658 bluetooth_adapter_->RegisterAdvertisement(
659 std::move(adv_data), base::Bind(&ArcBluetoothBridge::OnStartLEListenDone,
660 weak_factory_.GetWeakPtr(), callback),
661 base::Bind(&ArcBluetoothBridge::OnStartLEListenError,
662 weak_factory_.GetWeakPtr(), callback));
663 }
664
665 void ArcBluetoothBridge::OnStopLEListenDone(
666 const StopLEListenCallback& callback) {
667 advertisment_ = nullptr;
668 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
669 }
670
671 void ArcBluetoothBridge::OnStopLEListenError(
672 const StopLEListenCallback& callback,
673 BluetoothAdvertisement::ErrorCode error_code) {
674 advertisment_ = nullptr;
675 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
676 }
677
678 void ArcBluetoothBridge::StopLEListen(const StopLEListenCallback& callback) {
679 if (!advertisment_) {
680 OnStopLEListenError(
681 callback,
682 BluetoothAdvertisement::ErrorCode::ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
683 return;
684 }
685 advertisment_->Unregister(base::Bind(&ArcBluetoothBridge::OnStopLEListenDone,
686 weak_factory_.GetWeakPtr(), callback),
687 base::Bind(&ArcBluetoothBridge::OnStopLEListenError,
688 weak_factory_.GetWeakPtr(), callback));
689 }
690
691 void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) {
692 if (!HasBluetoothInstance())
693 return;
694
695 BluetoothDevice* device =
696 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
697 mojo::Array<mojom::BluetoothGattDBElementPtr> db;
698 for (auto service : device->GetGattServices()) {
699 mojom::BluetoothGattDBElementPtr service_element =
700 mojom::BluetoothGattDBElement::New();
701
702 // Example: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
703 std::string id_str = service->GetIdentifier();
704
705 // Convert last digit of service id to int in base 16
706 int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
707
708 service_element->id = id;
709 service_element->uuid = mojom::BluetoothUUID::From(service->GetUUID());
710 if (service->IsPrimary()) {
711 service_element->type =
712 mojom::BluetoothGattDBAttributeType::BTGATT_DB_PRIMARY_SERVICE;
713 } else {
714 service_element->type =
715 mojom::BluetoothGattDBAttributeType::BTGATT_DB_SECONDARY_SERVICE;
716 }
717 service_element->attribute_handle = id;
718 const auto& characteristics = service->GetCharacteristics();
719 if (characteristics.size() > 0) {
720 std::string first_id_str = characteristics.front()->GetIdentifier();
721 int first_id =
722 std::stoi(first_id_str.substr(first_id_str.size() - 4), nullptr, 16);
723
724 const auto& descriptors = characteristics.back()->GetDescriptors();
725 std::string last_id_str;
726 if (descriptors.size() > 0) {
727 last_id_str = descriptors.back()->GetIdentifier();
728 } else {
729 last_id_str = characteristics.back()->GetIdentifier();
730 }
731 int last_id =
732 std::stoi(last_id_str.substr(last_id_str.size() - 4), nullptr, 16);
733 service_element->start_handle = first_id;
734 service_element->end_handle = last_id;
735 }
736 db.push_back(std::move(service_element));
737
738 for (auto characteristic : characteristics) {
739 mojom::BluetoothGattDBElementPtr characteristic_element =
740 mojom::BluetoothGattDBElement::New();
741 std::string id_str = characteristic->GetIdentifier();
742 int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
743 characteristic_element->id = id;
744 characteristic_element->uuid =
745 mojom::BluetoothUUID::From(characteristic->GetUUID());
746 characteristic_element->type =
747 mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC;
748 characteristic_element->attribute_handle = id;
749 characteristic_element->properties = characteristic->GetProperties();
750 db.push_back(std::move(characteristic_element));
751
752 for (auto descriptor : characteristic->GetDescriptors()) {
753 mojom::BluetoothGattDBElementPtr descriptor_element =
754 mojom::BluetoothGattDBElement::New();
755 std::string id_str = descriptor->GetIdentifier();
756 int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
757 descriptor_element->id = id;
758 descriptor_element->uuid =
759 mojom::BluetoothUUID::From(descriptor->GetUUID());
760 descriptor_element->type =
761 mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR;
762 descriptor_element->attribute_handle = id;
763 db.push_back(std::move(descriptor_element));
764 }
765 }
766 }
767
768 arc_bridge_service()->bluetooth_instance()->OnGetGattDB(
769 std::move(remote_addr), std::move(db));
770 }
771
772 BluetoothRemoteGattCharacteristic* ArcBluetoothBridge::FindGattCharacteristic(
773 mojom::BluetoothAddressPtr remote_addr,
774 mojom::BluetoothGattServiceIDPtr service_id,
775 mojom::BluetoothGattIDPtr char_id) const {
776 DCHECK(remote_addr);
777 DCHECK(service_id);
778 DCHECK(char_id);
779
780 BluetoothDevice* device =
781 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
782 if (!device)
783 return nullptr;
784
785 BluetoothUUID serv_uuid = service_id->id->uuid.To<BluetoothUUID>();
786 const auto& services = device->GetGattServices();
787 auto service_it = std::find_if(
788 services.begin(), services.end(),
789 [&](BluetoothRemoteGattService* s) { return s->GetUUID() == serv_uuid; });
790 if (service_it == services.end())
791 return nullptr;
792
793 BluetoothUUID char_uuid = char_id->uuid.To<BluetoothUUID>();
794 const auto& characteristics = (*service_it)->GetCharacteristics();
795 auto characteristic_it =
796 std::find_if(characteristics.begin(), characteristics.end(),
797 [&](BluetoothRemoteGattCharacteristic* c) {
798 return c->GetUUID() == char_uuid;
799 });
800 if (characteristic_it == characteristics.end())
801 return nullptr;
802 return *characteristic_it;
803 }
804
805 BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor(
806 mojom::BluetoothAddressPtr remote_addr,
807 mojom::BluetoothGattServiceIDPtr service_id,
808 mojom::BluetoothGattIDPtr char_id,
809 mojom::BluetoothGattIDPtr desc_id) const {
810 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
811 std::move(remote_addr), std::move(service_id), std::move(char_id));
812
813 if (!characteristic)
814 return nullptr;
815
816 BluetoothUUID desc_uuid = desc_id->uuid.To<BluetoothUUID>();
817 const auto& descriptors = characteristic->GetDescriptors();
818 auto descriptor_it = std::find_if(descriptors.begin(), descriptors.end(),
819 [&](BluetoothRemoteGattDescriptor* d) {
820 return d->GetUUID() == desc_uuid;
821 });
822 if (descriptor_it == descriptors.end())
823 return nullptr;
824 return *descriptor_it;
825 }
826
827 // Same callback for both ReadGattCharacteristic and ReadGattDescriptor
828 void ArcBluetoothBridge::OnGattReadDone(
829 const GattReadCallback& callback,
830 const std::vector<uint8_t>& result) const {
831 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
832 gattValue->status = mojom::BluetoothGattStatus::GATT_SUCCESS;
833 gattValue->len = result.size();
834 gattValue->type = 0;
835 gattValue->value = mojo::Array<uint8_t>::From(result);
836 callback.Run(std::move(gattValue));
837 }
838
839 void ArcBluetoothBridge::OnGattReadError(
840 const GattReadCallback& callback,
841 BluetoothGattService::GattErrorCode error_code) const {
842 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
843 gattValue->status = mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code);
844 gattValue->len = 0;
845 gattValue->type = 0;
846 gattValue->value = nullptr;
847
848 callback.Run(std::move(gattValue));
849 }
850
851 // same callback for both WriteGattCharacteristic and WriteGattDescriptor
852 void ArcBluetoothBridge::OnGattWriteDone(
853 const GattWriteCallback& callback) const {
854 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
855 }
856
857 void ArcBluetoothBridge::OnGattWriteError(
858 const GattWriteCallback& callback,
859 BluetoothGattService::GattErrorCode error_code) const {
860 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
861 }
862
863 void ArcBluetoothBridge::ReadGattCharacteristic(
864 mojom::BluetoothAddressPtr remote_addr,
865 mojom::BluetoothGattServiceIDPtr service_id,
866 mojom::BluetoothGattIDPtr char_id,
867 const ReadGattCharacteristicCallback& callback) {
868 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
869 std::move(remote_addr), std::move(service_id), std::move(char_id));
870
871 DCHECK(characteristic);
872
873 DCHECK(characteristic->GetPermissions() &
874 (BluetoothGattCharacteristic::Permission::PERMISSION_READ |
875 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
876 BluetoothGattCharacteristic::Permission::
877 PERMISSION_READ_ENCRYPTED_AUTHENTICATED));
878
879 characteristic->ReadRemoteCharacteristic(
880 base::Bind(&ArcBluetoothBridge::OnGattReadDone,
881 weak_factory_.GetWeakPtr(), callback),
882 base::Bind(&ArcBluetoothBridge::OnGattReadError,
883 weak_factory_.GetWeakPtr(), callback));
884 }
885
886 void ArcBluetoothBridge::WriteGattCharacteristic(
887 mojom::BluetoothAddressPtr remote_addr,
888 mojom::BluetoothGattServiceIDPtr service_id,
889 mojom::BluetoothGattIDPtr char_id,
890 mojom::BluetoothGattValuePtr value,
891 const WriteGattCharacteristicCallback& callback) {
892 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
893 std::move(remote_addr), std::move(service_id), std::move(char_id));
894
895 DCHECK(characteristic);
896
897 DCHECK(characteristic->GetPermissions() &
898 (BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
899 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
900 BluetoothGattCharacteristic::Permission::
901 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED));
902
903 characteristic->WriteRemoteCharacteristic(
904 value->value.To<std::vector<uint8_t>>(),
905 base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
906 weak_factory_.GetWeakPtr(), callback),
907 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
908 weak_factory_.GetWeakPtr(), callback));
909 }
910
911 void ArcBluetoothBridge::ReadGattDescriptor(
912 mojom::BluetoothAddressPtr remote_addr,
913 mojom::BluetoothGattServiceIDPtr service_id,
914 mojom::BluetoothGattIDPtr char_id,
915 mojom::BluetoothGattIDPtr desc_id,
916 const ReadGattDescriptorCallback& callback) {
917 BluetoothRemoteGattDescriptor* descriptor =
918 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
919 std::move(char_id), std::move(desc_id));
920 DCHECK(descriptor);
921
922 DCHECK(descriptor->GetPermissions() &
923 (BluetoothGattCharacteristic::Permission::PERMISSION_READ |
924 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
925 BluetoothGattCharacteristic::Permission::
926 PERMISSION_READ_ENCRYPTED_AUTHENTICATED));
927
928 descriptor->ReadRemoteDescriptor(
929 base::Bind(&ArcBluetoothBridge::OnGattReadDone,
930 weak_factory_.GetWeakPtr(), callback),
931 base::Bind(&ArcBluetoothBridge::OnGattReadError,
932 weak_factory_.GetWeakPtr(), callback));
933 }
934
935 void ArcBluetoothBridge::WriteGattDescriptor(
936 mojom::BluetoothAddressPtr remote_addr,
937 mojom::BluetoothGattServiceIDPtr service_id,
938 mojom::BluetoothGattIDPtr char_id,
939 mojom::BluetoothGattIDPtr desc_id,
940 mojom::BluetoothGattValuePtr value,
941 const WriteGattDescriptorCallback& callback) {
942 BluetoothRemoteGattDescriptor* descriptor =
943 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
944 std::move(char_id), std::move(desc_id));
945 DCHECK(descriptor);
946
947 DCHECK(descriptor->GetPermissions() &
948 (BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
949 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
950 BluetoothGattCharacteristic::Permission::
951 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED));
952
953 descriptor->WriteRemoteDescriptor(
954 value->value.To<std::vector<uint8_t>>(),
955 base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
956 weak_factory_.GetWeakPtr(), callback),
957 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
958 weak_factory_.GetWeakPtr(), callback));
959 }
960
961 void ArcBluetoothBridge::OnGattNotifyStartDone(
962 const RegisterForGattNotificationCallback& callback,
963 const std::string char_string_id,
964 std::unique_ptr<BluetoothGattNotifySession> notify_session) {
965 notification_session_[char_string_id] = std::move(notify_session);
966 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
967 }
968
969 void ArcBluetoothBridge::OnGattNotifyStartError(
970 const RegisterForGattNotificationCallback& callback,
971 BluetoothGattService::GattErrorCode error_code) const {
972 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
973 }
974
975 void ArcBluetoothBridge::OnGattNotifyStopDone(
976 const DeregisterForGattNotificationCallback& callback) const {
977 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
978 }
979
980 void ArcBluetoothBridge::RegisterForGattNotification(
981 mojom::BluetoothAddressPtr remote_addr,
982 mojom::BluetoothGattServiceIDPtr service_id,
983 mojom::BluetoothGattIDPtr char_id,
984 const RegisterForGattNotificationCallback& callback) {
985 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
986 std::move(remote_addr), std::move(service_id), std::move(char_id));
987
988 if (!characteristic) {
989 LOG(WARNING) << __func__ << " Characteristic is not existed.";
990 return;
991 }
992
993 if (characteristic->IsNotifying()) {
994 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
995 return;
996 }
997
998 characteristic->StartNotifySession(
999 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone,
1000 weak_factory_.GetWeakPtr(), callback,
1001 characteristic->GetIdentifier()),
1002 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartError,
1003 weak_factory_.GetWeakPtr(), callback));
1004 }
1005
1006 void ArcBluetoothBridge::DeregisterForGattNotification(
1007 mojom::BluetoothAddressPtr remote_addr,
1008 mojom::BluetoothGattServiceIDPtr service_id,
1009 mojom::BluetoothGattIDPtr char_id,
1010 const DeregisterForGattNotificationCallback& callback) {
1011 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
1012 std::move(remote_addr), std::move(service_id), std::move(char_id));
1013
1014 if (!characteristic) {
1015 LOG(WARNING) << __func__ << " Characteristic is not existed.";
1016 return;
1017 }
1018
1019 if (!characteristic->IsNotifying()) {
1020 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1021 return;
1022 }
1023
1024 std::string char_id_str = characteristic->GetIdentifier();
1025 std::unique_ptr<BluetoothGattNotifySession> notify =
1026 std::move(notification_session_[char_id_str]);
1027 notification_session_.erase(char_id_str);
1028 notify->Stop(base::Bind(&ArcBluetoothBridge::OnGattNotifyStopDone,
1029 weak_factory_.GetWeakPtr(), callback));
1030 }
1031
1032 void ArcBluetoothBridge::ReadRemoteRssi(
1033 mojom::BluetoothAddressPtr remote_addr,
1034 const ReadRemoteRssiCallback& callback) {
1035 BluetoothDevice* device =
1036 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
1037 int rssi = device->GetInquiryRSSI();
1038 callback.Run(rssi);
1039 }
1040
464 void ArcBluetoothBridge::OnDiscoveryError() { 1041 void ArcBluetoothBridge::OnDiscoveryError() {
465 LOG(WARNING) << "failed to change discovery state"; 1042 LOG(WARNING) << "failed to change discovery state";
466 } 1043 }
467 1044
468 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { 1045 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const {
469 if (!HasBluetoothInstance()) 1046 if (!HasBluetoothInstance())
470 return; 1047 return;
471 1048
472 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged( 1049 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged(
473 mojom::BluetoothStatus::SUCCESS, std::move(addr), 1050 mojom::BluetoothStatus::SUCCESS, std::move(addr),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 } 1113 }
537 if (type == mojom::BluetoothPropertyType::ALL || 1114 if (type == mojom::BluetoothPropertyType::ALL ||
538 type == mojom::BluetoothPropertyType::BDADDR) { 1115 type == mojom::BluetoothPropertyType::BDADDR) {
539 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1116 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
540 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress())); 1117 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress()));
541 properties.push_back(std::move(btp)); 1118 properties.push_back(std::move(btp));
542 } 1119 }
543 if (type == mojom::BluetoothPropertyType::ALL || 1120 if (type == mojom::BluetoothPropertyType::ALL ||
544 type == mojom::BluetoothPropertyType::UUIDS) { 1121 type == mojom::BluetoothPropertyType::UUIDS) {
545 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1122 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
546 std::vector<device::BluetoothUUID> uuids = device->GetUUIDs(); 1123 std::vector<BluetoothUUID> uuids = device->GetUUIDs();
547 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results = 1124 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results =
548 mojo::Array<mojom::BluetoothUUIDPtr>::New(0); 1125 mojo::Array<mojom::BluetoothUUIDPtr>::New(0);
549 1126
550 for (size_t i = 0; i < uuids.size(); i++) { 1127 for (auto& uuid : uuids) {
551 uuid_results.push_back(mojom::BluetoothUUID::From(uuids[i])); 1128 uuid_results.push_back(mojom::BluetoothUUID::From(uuid));
552 } 1129 }
553 1130
554 btp->set_uuids(std::move(uuid_results)); 1131 btp->set_uuids(std::move(uuid_results));
555 properties.push_back(std::move(btp)); 1132 properties.push_back(std::move(btp));
556 } 1133 }
557 if (type == mojom::BluetoothPropertyType::ALL || 1134 if (type == mojom::BluetoothPropertyType::ALL ||
558 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { 1135 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) {
559 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1136 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
560 btp->set_device_class(device->GetBluetoothClass()); 1137 btp->set_device_class(device->GetBluetoothClass());
561 properties.push_back(std::move(btp)); 1138 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)); 1212 properties.push_back(std::move(btp));
636 } 1213 }
637 if (type == mojom::BluetoothPropertyType::ALL || 1214 if (type == mojom::BluetoothPropertyType::ALL ||
638 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) { 1215 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) {
639 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1216 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
640 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1217 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
641 1218
642 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices = 1219 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices =
643 mojo::Array<mojom::BluetoothAddressPtr>::New(0); 1220 mojo::Array<mojom::BluetoothAddressPtr>::New(0);
644 1221
645 for (size_t i = 0; i < devices.size(); i++) { 1222 for (auto device : devices) {
646 if (!devices[i]->IsPaired()) 1223 if (device->IsPaired())
647 continue; 1224 continue;
648 1225
649 mojom::BluetoothAddressPtr addr = 1226 mojom::BluetoothAddressPtr addr =
650 mojom::BluetoothAddress::From(devices[i]->GetAddress()); 1227 mojom::BluetoothAddress::From(device->GetAddress());
651 bonded_devices.push_back(std::move(addr)); 1228 bonded_devices.push_back(std::move(addr));
652 } 1229 }
653 1230
654 btp->set_bonded_devices(std::move(bonded_devices)); 1231 btp->set_bonded_devices(std::move(bonded_devices));
655 properties.push_back(std::move(btp)); 1232 properties.push_back(std::move(btp));
656 } 1233 }
657 if (type == mojom::BluetoothPropertyType::ALL || 1234 if (type == mojom::BluetoothPropertyType::ALL ||
658 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) { 1235 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) {
659 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1236 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
660 btp->set_discovery_timeout(120); 1237 btp->set_discovery_timeout(120);
661 properties.push_back(std::move(btp)); 1238 properties.push_back(std::move(btp));
662 } 1239 }
663 1240
664 return properties; 1241 return properties;
665 } 1242 }
666 1243
1244 // Android support 5 types of Advertising Data.
1245 // However Chrome didn't expose AdvertiseFlag and ManufactureData.
1246 // So we will only expose local_name, service_uuids and service_data.
1247 // TODO(crbug.com/618442) Make Chrome expose missing data.
1248 mojo::Array<mojom::BluetoothAdvertisingDataPtr>
1249 ArcBluetoothBridge::GetAdvertisingData(BluetoothDevice* device) const {
1250 mojo::Array<mojom::BluetoothAdvertisingDataPtr> advertising_data;
1251
1252 // LocalName
1253 mojom::BluetoothAdvertisingDataPtr local_name =
1254 mojom::BluetoothAdvertisingData::New();
1255 local_name->set_local_name(base::UTF16ToUTF8(device->GetNameForDisplay()));
1256 advertising_data.push_back(std::move(local_name));
1257
1258 // ServiceUuid
1259 BluetoothDevice::UUIDList uuid_list = device->GetServiceDataUUIDs();
1260 if (uuid_list.size() > 0) {
1261 mojom::BluetoothAdvertisingDataPtr service_uuids =
1262 mojom::BluetoothAdvertisingData::New();
1263 service_uuids->set_service_uuids(
1264 mojo::Array<mojom::BluetoothUUIDPtr>::From(uuid_list));
1265 advertising_data.push_back(std::move(service_uuids));
1266 }
1267
1268 // Service data
1269 for (auto& uuid : uuid_list) {
1270 base::BinaryValue* data = device->GetServiceData(uuid);
1271 if (data->GetSize() == 0)
1272 continue;
1273 std::string data_str;
1274 if (!data->GetAsString(&data_str))
1275 continue;
1276
1277 mojom::BluetoothAdvertisingDataPtr service_data_element =
1278 mojom::BluetoothAdvertisingData::New();
1279 mojom::BluetoothServiceDataPtr service_data =
1280 mojom::BluetoothServiceData::New();
1281
1282 std::string uuid_str = uuid.canonical_value();
1283 // Convert xxxxyyyy-xxxx-xxxx-xxxx-xxxxxxxxxxxx to int16 yyyy
1284 service_data->uuid_16bit = std::stoi(uuid_str.substr(4, 4), nullptr, 16);
1285 for (auto& c : data_str) {
1286 service_data->data.push_back(c);
1287 }
1288 service_data_element->set_service_data(std::move(service_data));
1289 advertising_data.push_back(std::move(service_data_element));
1290 }
1291
1292 return advertising_data;
1293 }
1294
667 void ArcBluetoothBridge::SendCachedDevicesFound() const { 1295 void ArcBluetoothBridge::SendCachedDevicesFound() const {
668 // Send devices that have already been discovered, but aren't connected. 1296 // Send devices that have already been discovered, but aren't connected.
669 if (!HasBluetoothInstance()) 1297 if (!HasBluetoothInstance())
670 return; 1298 return;
671 1299
672 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1300 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
673 for (size_t i = 0; i < devices.size(); i++) { 1301 for (auto device : devices) {
674 if (devices[i]->IsPaired()) 1302 if (device->IsPaired())
675 continue; 1303 continue;
676 1304
677 mojo::Array<mojom::BluetoothPropertyPtr> properties = 1305 mojo::Array<mojom::BluetoothPropertyPtr> properties =
678 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, devices[i]); 1306 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
679 1307
680 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 1308 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
681 std::move(properties)); 1309 std::move(properties));
1310
1311 if (arc_bridge_service()->bluetooth_version() >= kMinBtleVersion) {
1312 mojom::BluetoothAddressPtr addr =
1313 mojom::BluetoothAddress::From(device->GetAddress());
1314 int rssi = device->GetInquiryRSSI();
1315 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
1316 GetAdvertisingData(device);
1317 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
1318 std::move(addr), rssi, std::move(adv_data));
1319 }
682 } 1320 }
683 } 1321 }
684 1322
685 bool ArcBluetoothBridge::HasBluetoothInstance() const { 1323 bool ArcBluetoothBridge::HasBluetoothInstance() const {
686 if (!arc_bridge_service()->bluetooth_instance()) { 1324 if (!arc_bridge_service()->bluetooth_instance()) {
687 LOG(WARNING) << "no Bluetooth instance available"; 1325 LOG(WARNING) << "no Bluetooth instance available";
688 return false; 1326 return false;
689 } 1327 }
690 1328
691 return true; 1329 return true;
692 } 1330 }
693 1331
694 void ArcBluetoothBridge::SendCachedPairedDevices() const { 1332 void ArcBluetoothBridge::SendCachedPairedDevices() const {
695 DCHECK(bluetooth_adapter_); 1333 DCHECK(bluetooth_adapter_);
1334 if (!HasBluetoothInstance())
1335 return;
696 1336
697 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1337 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
698 for (BluetoothDevice* device : devices) { 1338 for (auto device : devices) {
699 if (!device->IsPaired()) 1339 if (!device->IsPaired())
700 continue; 1340 continue;
701 1341
702 mojo::Array<mojom::BluetoothPropertyPtr> properties = 1342 mojo::Array<mojom::BluetoothPropertyPtr> properties =
703 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); 1343 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
704 1344
705 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 1345 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
706 std::move(properties)); 1346 std::move(properties));
707 1347
708 mojom::BluetoothAddressPtr addr = 1348 mojom::BluetoothAddressPtr addr =
709 mojom::BluetoothAddress::From(device->GetAddress()); 1349 mojom::BluetoothAddress::From(device->GetAddress());
710 1350
1351 if (arc_bridge_service()->bluetooth_version() >= kMinBtleVersion) {
1352 int rssi = device->GetInquiryRSSI();
1353 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
1354 GetAdvertisingData(device);
1355 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
1356 addr->Clone(), rssi, std::move(adv_data));
1357 }
1358
711 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING 1359 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING
712 // to 1360 // to
713 // make sure the bond state machine on Android is ready to take the 1361 // 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 1362 // pair-done event. Otherwise the pair-done event will be dropped as an
715 // invalid change of paired status. 1363 // invalid change of paired status.
716 OnPairing(addr->Clone()); 1364 OnPairing(addr->Clone());
717 OnPairedDone(std::move(addr)); 1365 OnPairedDone(std::move(addr));
718 } 1366 }
719 } 1367 }
720 1368
721 } // namespace arc 1369 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698