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

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: Remove std:move for temporary 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::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->value = mojo::Array<uint8_t>::From(result);
835 callback.Run(std::move(gattValue));
836 }
837
838 void ArcBluetoothBridge::OnGattReadError(
839 const GattReadCallback& callback,
840 BluetoothGattService::GattErrorCode error_code) const {
841 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
842 gattValue->status = mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code);
843 gattValue->len = 0;
844 gattValue->value = nullptr;
845
846 callback.Run(std::move(gattValue));
847 }
848
849 // same callback for both WriteGattCharacteristic and WriteGattDescriptor
850 void ArcBluetoothBridge::OnGattWriteDone(
851 const GattWriteCallback& callback) const {
852 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
853 }
854
855 void ArcBluetoothBridge::OnGattWriteError(
856 const GattWriteCallback& callback,
857 BluetoothGattService::GattErrorCode error_code) const {
858 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
859 }
860
861 void ArcBluetoothBridge::ReadGattCharacteristic(
862 mojom::BluetoothAddressPtr remote_addr,
863 mojom::BluetoothGattServiceIDPtr service_id,
864 mojom::BluetoothGattIDPtr char_id,
865 const ReadGattCharacteristicCallback& callback) {
866 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
867 std::move(remote_addr), std::move(service_id), std::move(char_id));
868
869 DCHECK(characteristic);
870
871 DCHECK(characteristic->GetPermissions() &
872 (BluetoothGattCharacteristic::Permission::PERMISSION_READ |
873 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
874 BluetoothGattCharacteristic::Permission::
875 PERMISSION_READ_ENCRYPTED_AUTHENTICATED));
876
877 characteristic->ReadRemoteCharacteristic(
878 base::Bind(&ArcBluetoothBridge::OnGattReadDone,
879 weak_factory_.GetWeakPtr(), callback),
880 base::Bind(&ArcBluetoothBridge::OnGattReadError,
881 weak_factory_.GetWeakPtr(), callback));
882 }
883
884 void ArcBluetoothBridge::WriteGattCharacteristic(
885 mojom::BluetoothAddressPtr remote_addr,
886 mojom::BluetoothGattServiceIDPtr service_id,
887 mojom::BluetoothGattIDPtr char_id,
888 mojom::BluetoothGattValuePtr value,
889 const WriteGattCharacteristicCallback& callback) {
890 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
891 std::move(remote_addr), std::move(service_id), std::move(char_id));
892
893 DCHECK(characteristic);
894
895 DCHECK(characteristic->GetPermissions() &
896 (BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
897 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
898 BluetoothGattCharacteristic::Permission::
899 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED));
900
901 characteristic->WriteRemoteCharacteristic(
902 value->value.To<std::vector<uint8_t>>(),
903 base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
904 weak_factory_.GetWeakPtr(), callback),
905 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
906 weak_factory_.GetWeakPtr(), callback));
907 }
908
909 void ArcBluetoothBridge::ReadGattDescriptor(
910 mojom::BluetoothAddressPtr remote_addr,
911 mojom::BluetoothGattServiceIDPtr service_id,
912 mojom::BluetoothGattIDPtr char_id,
913 mojom::BluetoothGattIDPtr desc_id,
914 const ReadGattDescriptorCallback& callback) {
915 BluetoothRemoteGattDescriptor* descriptor =
916 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
917 std::move(char_id), std::move(desc_id));
918 DCHECK(descriptor);
919
920 DCHECK(descriptor->GetPermissions() &
921 (BluetoothGattCharacteristic::Permission::PERMISSION_READ |
922 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
923 BluetoothGattCharacteristic::Permission::
924 PERMISSION_READ_ENCRYPTED_AUTHENTICATED));
925
926 descriptor->ReadRemoteDescriptor(
927 base::Bind(&ArcBluetoothBridge::OnGattReadDone,
928 weak_factory_.GetWeakPtr(), callback),
929 base::Bind(&ArcBluetoothBridge::OnGattReadError,
930 weak_factory_.GetWeakPtr(), callback));
931 }
932
933 void ArcBluetoothBridge::WriteGattDescriptor(
934 mojom::BluetoothAddressPtr remote_addr,
935 mojom::BluetoothGattServiceIDPtr service_id,
936 mojom::BluetoothGattIDPtr char_id,
937 mojom::BluetoothGattIDPtr desc_id,
938 mojom::BluetoothGattValuePtr value,
939 const WriteGattDescriptorCallback& callback) {
940 BluetoothRemoteGattDescriptor* descriptor =
941 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
942 std::move(char_id), std::move(desc_id));
943 DCHECK(descriptor);
944
945 DCHECK(descriptor->GetPermissions() &
946 (BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
947 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
948 BluetoothGattCharacteristic::Permission::
949 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED));
950
951 descriptor->WriteRemoteDescriptor(
952 value->value.To<std::vector<uint8_t>>(),
953 base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
954 weak_factory_.GetWeakPtr(), callback),
955 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
956 weak_factory_.GetWeakPtr(), callback));
957 }
958
959 void ArcBluetoothBridge::OnGattNotifyStartDone(
960 const RegisterForGattNotificationCallback& callback,
961 const std::string char_string_id,
962 std::unique_ptr<BluetoothGattNotifySession> notify_session) {
963 notification_session_[char_string_id] = std::move(notify_session);
964 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
965 }
966
967 void ArcBluetoothBridge::OnGattNotifyStartError(
968 const RegisterForGattNotificationCallback& callback,
969 BluetoothGattService::GattErrorCode error_code) const {
970 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
971 }
972
973 void ArcBluetoothBridge::OnGattNotifyStopDone(
974 const DeregisterForGattNotificationCallback& callback) const {
975 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
976 }
977
978 void ArcBluetoothBridge::RegisterForGattNotification(
979 mojom::BluetoothAddressPtr remote_addr,
980 mojom::BluetoothGattServiceIDPtr service_id,
981 mojom::BluetoothGattIDPtr char_id,
982 const RegisterForGattNotificationCallback& callback) {
983 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
984 std::move(remote_addr), std::move(service_id), std::move(char_id));
985
986 if (!characteristic) {
987 LOG(WARNING) << __func__ << " Characteristic is not existed.";
988 return;
989 }
990
991 if (characteristic->IsNotifying()) {
992 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
993 return;
994 }
995
996 characteristic->StartNotifySession(
997 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone,
998 weak_factory_.GetWeakPtr(), callback,
999 characteristic->GetIdentifier()),
1000 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartError,
1001 weak_factory_.GetWeakPtr(), callback));
1002 }
1003
1004 void ArcBluetoothBridge::DeregisterForGattNotification(
1005 mojom::BluetoothAddressPtr remote_addr,
1006 mojom::BluetoothGattServiceIDPtr service_id,
1007 mojom::BluetoothGattIDPtr char_id,
1008 const DeregisterForGattNotificationCallback& callback) {
1009 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
1010 std::move(remote_addr), std::move(service_id), std::move(char_id));
1011
1012 if (!characteristic) {
1013 LOG(WARNING) << __func__ << " Characteristic is not existed.";
1014 return;
1015 }
1016
1017 if (!characteristic->IsNotifying()) {
1018 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1019 return;
1020 }
1021
1022 std::string char_id_str = characteristic->GetIdentifier();
1023 std::unique_ptr<BluetoothGattNotifySession> notify =
1024 std::move(notification_session_[char_id_str]);
1025 notification_session_.erase(char_id_str);
1026 notify->Stop(base::Bind(&ArcBluetoothBridge::OnGattNotifyStopDone,
1027 weak_factory_.GetWeakPtr(), callback));
1028 }
1029
1030 void ArcBluetoothBridge::ReadRemoteRssi(
1031 mojom::BluetoothAddressPtr remote_addr,
1032 const ReadRemoteRssiCallback& callback) {
1033 BluetoothDevice* device =
1034 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
1035 int rssi = device->GetInquiryRSSI();
1036 callback.Run(rssi);
1037 }
1038
464 void ArcBluetoothBridge::OnDiscoveryError() { 1039 void ArcBluetoothBridge::OnDiscoveryError() {
465 LOG(WARNING) << "failed to change discovery state"; 1040 LOG(WARNING) << "failed to change discovery state";
466 } 1041 }
467 1042
468 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { 1043 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const {
469 if (!HasBluetoothInstance()) 1044 if (!HasBluetoothInstance())
470 return; 1045 return;
471 1046
472 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged( 1047 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged(
473 mojom::BluetoothStatus::SUCCESS, std::move(addr), 1048 mojom::BluetoothStatus::SUCCESS, std::move(addr),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 } 1111 }
537 if (type == mojom::BluetoothPropertyType::ALL || 1112 if (type == mojom::BluetoothPropertyType::ALL ||
538 type == mojom::BluetoothPropertyType::BDADDR) { 1113 type == mojom::BluetoothPropertyType::BDADDR) {
539 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1114 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
540 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress())); 1115 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress()));
541 properties.push_back(std::move(btp)); 1116 properties.push_back(std::move(btp));
542 } 1117 }
543 if (type == mojom::BluetoothPropertyType::ALL || 1118 if (type == mojom::BluetoothPropertyType::ALL ||
544 type == mojom::BluetoothPropertyType::UUIDS) { 1119 type == mojom::BluetoothPropertyType::UUIDS) {
545 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1120 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
546 std::vector<device::BluetoothUUID> uuids = device->GetUUIDs(); 1121 std::vector<BluetoothUUID> uuids = device->GetUUIDs();
547 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results = 1122 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results =
548 mojo::Array<mojom::BluetoothUUIDPtr>::New(0); 1123 mojo::Array<mojom::BluetoothUUIDPtr>::New(0);
549 1124
550 for (size_t i = 0; i < uuids.size(); i++) { 1125 for (auto& uuid : uuids) {
551 uuid_results.push_back(mojom::BluetoothUUID::From(uuids[i])); 1126 uuid_results.push_back(mojom::BluetoothUUID::From(uuid));
552 } 1127 }
553 1128
554 btp->set_uuids(std::move(uuid_results)); 1129 btp->set_uuids(std::move(uuid_results));
555 properties.push_back(std::move(btp)); 1130 properties.push_back(std::move(btp));
556 } 1131 }
557 if (type == mojom::BluetoothPropertyType::ALL || 1132 if (type == mojom::BluetoothPropertyType::ALL ||
558 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { 1133 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) {
559 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1134 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
560 btp->set_device_class(device->GetBluetoothClass()); 1135 btp->set_device_class(device->GetBluetoothClass());
561 properties.push_back(std::move(btp)); 1136 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)); 1210 properties.push_back(std::move(btp));
636 } 1211 }
637 if (type == mojom::BluetoothPropertyType::ALL || 1212 if (type == mojom::BluetoothPropertyType::ALL ||
638 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) { 1213 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) {
639 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1214 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
640 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1215 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
641 1216
642 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices = 1217 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices =
643 mojo::Array<mojom::BluetoothAddressPtr>::New(0); 1218 mojo::Array<mojom::BluetoothAddressPtr>::New(0);
644 1219
645 for (size_t i = 0; i < devices.size(); i++) { 1220 for (auto device : devices) {
646 if (!devices[i]->IsPaired()) 1221 if (device->IsPaired())
647 continue; 1222 continue;
648 1223
649 mojom::BluetoothAddressPtr addr = 1224 mojom::BluetoothAddressPtr addr =
650 mojom::BluetoothAddress::From(devices[i]->GetAddress()); 1225 mojom::BluetoothAddress::From(device->GetAddress());
651 bonded_devices.push_back(std::move(addr)); 1226 bonded_devices.push_back(std::move(addr));
652 } 1227 }
653 1228
654 btp->set_bonded_devices(std::move(bonded_devices)); 1229 btp->set_bonded_devices(std::move(bonded_devices));
655 properties.push_back(std::move(btp)); 1230 properties.push_back(std::move(btp));
656 } 1231 }
657 if (type == mojom::BluetoothPropertyType::ALL || 1232 if (type == mojom::BluetoothPropertyType::ALL ||
658 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) { 1233 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) {
659 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1234 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
660 btp->set_discovery_timeout(120); 1235 btp->set_discovery_timeout(120);
661 properties.push_back(std::move(btp)); 1236 properties.push_back(std::move(btp));
662 } 1237 }
663 1238
664 return properties; 1239 return properties;
665 } 1240 }
666 1241
1242 // Android support 5 types of Advertising Data.
1243 // However Chrome didn't expose AdvertiseFlag and ManufacturerData.
1244 // So we will only expose local_name, service_uuids and service_data.
1245 // TODO(crbug.com/618442) Make Chrome expose missing data.
1246 mojo::Array<mojom::BluetoothAdvertisingDataPtr>
1247 ArcBluetoothBridge::GetAdvertisingData(BluetoothDevice* device) const {
1248 mojo::Array<mojom::BluetoothAdvertisingDataPtr> advertising_data;
1249
1250 // LocalName
1251 mojom::BluetoothAdvertisingDataPtr local_name =
1252 mojom::BluetoothAdvertisingData::New();
1253 local_name->set_local_name(base::UTF16ToUTF8(device->GetNameForDisplay()));
1254 advertising_data.push_back(std::move(local_name));
1255
1256 // ServiceUuid
1257 BluetoothDevice::UUIDList uuid_list = device->GetServiceDataUUIDs();
1258 if (uuid_list.size() > 0) {
1259 mojom::BluetoothAdvertisingDataPtr service_uuids =
1260 mojom::BluetoothAdvertisingData::New();
1261 service_uuids->set_service_uuids(
1262 mojo::Array<mojom::BluetoothUUIDPtr>::From(uuid_list));
1263 advertising_data.push_back(std::move(service_uuids));
1264 }
1265
1266 // Service data
1267 for (auto& uuid : uuid_list) {
1268 base::BinaryValue* data = device->GetServiceData(uuid);
1269 if (data->GetSize() == 0)
1270 continue;
1271 std::string data_str;
1272 if (!data->GetAsString(&data_str))
1273 continue;
1274
1275 mojom::BluetoothAdvertisingDataPtr service_data_element =
1276 mojom::BluetoothAdvertisingData::New();
1277 mojom::BluetoothServiceDataPtr service_data =
1278 mojom::BluetoothServiceData::New();
1279
1280 std::string uuid_str = uuid.canonical_value();
1281 // Convert xxxxyyyy-xxxx-xxxx-xxxx-xxxxxxxxxxxx to int16 yyyy
1282 service_data->uuid_16bit = std::stoi(uuid_str.substr(4, 4), nullptr, 16);
1283 for (auto& c : data_str) {
1284 service_data->data.push_back(c);
1285 }
1286 service_data_element->set_service_data(std::move(service_data));
1287 advertising_data.push_back(std::move(service_data_element));
1288 }
1289
1290 return advertising_data;
1291 }
1292
667 void ArcBluetoothBridge::SendCachedDevicesFound() const { 1293 void ArcBluetoothBridge::SendCachedDevicesFound() const {
668 // Send devices that have already been discovered, but aren't connected. 1294 // Send devices that have already been discovered, but aren't connected.
669 if (!HasBluetoothInstance()) 1295 if (!HasBluetoothInstance())
670 return; 1296 return;
671 1297
672 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1298 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
673 for (size_t i = 0; i < devices.size(); i++) { 1299 for (auto device : devices) {
674 if (devices[i]->IsPaired()) 1300 if (device->IsPaired())
675 continue; 1301 continue;
676 1302
677 mojo::Array<mojom::BluetoothPropertyPtr> properties = 1303 mojo::Array<mojom::BluetoothPropertyPtr> properties =
678 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, devices[i]); 1304 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
679 1305
680 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 1306 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
681 std::move(properties)); 1307 std::move(properties));
1308
1309 if (arc_bridge_service()->bluetooth_version() >= kMinBtleVersion) {
1310 mojom::BluetoothAddressPtr addr =
1311 mojom::BluetoothAddress::From(device->GetAddress());
1312 int rssi = device->GetInquiryRSSI();
1313 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
1314 GetAdvertisingData(device);
1315 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
1316 std::move(addr), rssi, std::move(adv_data));
1317 }
682 } 1318 }
683 } 1319 }
684 1320
685 bool ArcBluetoothBridge::HasBluetoothInstance() const { 1321 bool ArcBluetoothBridge::HasBluetoothInstance() const {
686 if (!arc_bridge_service()->bluetooth_instance()) { 1322 if (!arc_bridge_service()->bluetooth_instance()) {
687 LOG(WARNING) << "no Bluetooth instance available"; 1323 LOG(WARNING) << "no Bluetooth instance available";
688 return false; 1324 return false;
689 } 1325 }
690 1326
691 return true; 1327 return true;
692 } 1328 }
693 1329
694 void ArcBluetoothBridge::SendCachedPairedDevices() const { 1330 void ArcBluetoothBridge::SendCachedPairedDevices() const {
695 DCHECK(bluetooth_adapter_); 1331 DCHECK(bluetooth_adapter_);
1332 if (!HasBluetoothInstance())
1333 return;
696 1334
697 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1335 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
698 for (BluetoothDevice* device : devices) { 1336 for (auto device : devices) {
699 if (!device->IsPaired()) 1337 if (!device->IsPaired())
700 continue; 1338 continue;
701 1339
702 mojo::Array<mojom::BluetoothPropertyPtr> properties = 1340 mojo::Array<mojom::BluetoothPropertyPtr> properties =
703 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); 1341 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
704 1342
705 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 1343 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
706 std::move(properties)); 1344 std::move(properties));
707 1345
708 mojom::BluetoothAddressPtr addr = 1346 mojom::BluetoothAddressPtr addr =
709 mojom::BluetoothAddress::From(device->GetAddress()); 1347 mojom::BluetoothAddress::From(device->GetAddress());
710 1348
1349 if (arc_bridge_service()->bluetooth_version() >= kMinBtleVersion) {
1350 int rssi = device->GetInquiryRSSI();
1351 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
1352 GetAdvertisingData(device);
1353 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
1354 addr->Clone(), rssi, std::move(adv_data));
1355 }
1356
711 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING 1357 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING
712 // to 1358 // to
713 // make sure the bond state machine on Android is ready to take the 1359 // 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 1360 // pair-done event. Otherwise the pair-done event will be dropped as an
715 // invalid change of paired status. 1361 // invalid change of paired status.
716 OnPairing(addr->Clone()); 1362 OnPairing(addr->Clone());
717 OnPairedDone(std::move(addr)); 1363 OnPairedDone(std::move(addr));
718 } 1364 }
719 } 1365 }
720 1366
721 } // namespace arc 1367 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698