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

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: Add more code comment 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;
35 45
36 namespace arc { 46 namespace arc {
37 47
38 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) 48 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service)
39 : ArcService(bridge_service), binding_(this), weak_factory_(this) { 49 : ArcService(bridge_service), binding_(this), weak_factory_(this) {
40 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { 50 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
41 VLOG(1) << "registering bluetooth adapter"; 51 VLOG(1) << "registering bluetooth adapter";
42 BluetoothAdapterFactory::GetAdapter(base::Bind( 52 BluetoothAdapterFactory::GetAdapter(base::Bind(
43 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); 53 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr()));
44 } else { 54 } else {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 return; 108 return;
99 109
100 if (device->IsConnected()) 110 if (device->IsConnected())
101 return; 111 return;
102 112
103 mojo::Array<mojom::BluetoothPropertyPtr> properties = 113 mojo::Array<mojom::BluetoothPropertyPtr> properties =
104 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); 114 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
105 115
106 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 116 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
107 std::move(properties)); 117 std::move(properties));
118
119 mojom::BluetoothAddressPtr addr =
120 mojom::BluetoothAddress::From(device->GetAddress());
121 int rssi = device->GetInquiryRSSI();
122 mojo::Array<uint8_t> adv_data = GetAdvData(device);
123
124 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
Luis Héctor Chávez 2016/06/01 21:12:03 Version check? Same with all other calls you intro
125 std::move(addr), rssi, std::move(adv_data));
108 } 126 }
109 127
110 void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter, 128 void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter,
111 BluetoothDevice* device) { 129 BluetoothDevice* device) {
112 // TODO(smbarber): device properties changed; inform the container. 130 // TODO(smbarber): device properties changed; inform the container.
113 } 131 }
114 132
115 void ArcBluetoothBridge::DeviceAddressChanged(BluetoothAdapter* adapter, 133 void ArcBluetoothBridge::DeviceAddressChanged(BluetoothAdapter* adapter,
116 BluetoothDevice* device, 134 BluetoothDevice* device,
117 const std::string& old_address) { 135 const std::string& old_address) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 175
158 void ArcBluetoothBridge::GattServiceRemoved( 176 void ArcBluetoothBridge::GattServiceRemoved(
159 BluetoothAdapter* adapter, 177 BluetoothAdapter* adapter,
160 BluetoothDevice* device, 178 BluetoothDevice* device,
161 BluetoothRemoteGattService* service) { 179 BluetoothRemoteGattService* service) {
162 // Placeholder for GATT client functionality 180 // Placeholder for GATT client functionality
163 } 181 }
164 182
165 void ArcBluetoothBridge::GattServicesDiscovered(BluetoothAdapter* adapter, 183 void ArcBluetoothBridge::GattServicesDiscovered(BluetoothAdapter* adapter,
166 BluetoothDevice* device) { 184 BluetoothDevice* device) {
167 // Placeholder for GATT client functionality 185 if (!HasBluetoothInstance())
186 return;
187
188 mojom::BluetoothAddressPtr addr =
189 mojom::BluetoothAddress::From(device->GetAddress());
190
191 arc_bridge_service()->bluetooth_instance()->OnSearchComplete(
192 std::move(addr), mojom::BluetoothGattStatus::GATT_SUCCESS);
168 } 193 }
169 194
170 void ArcBluetoothBridge::GattDiscoveryCompleteForService( 195 void ArcBluetoothBridge::GattDiscoveryCompleteForService(
171 BluetoothAdapter* adapter, 196 BluetoothAdapter* adapter,
172 BluetoothRemoteGattService* service) { 197 BluetoothRemoteGattService* service) {
173 // Placeholder for GATT client functionality 198 // Placeholder for GATT client functionality
174 } 199 }
175 200
176 void ArcBluetoothBridge::GattServiceChanged( 201 void ArcBluetoothBridge::GattServiceChanged(
177 BluetoothAdapter* adapter, 202 BluetoothAdapter* adapter,
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 BluetoothDevice* device = 479 BluetoothDevice* device =
455 bluetooth_adapter_->GetDevice(addr->To<std::string>()); 480 bluetooth_adapter_->GetDevice(addr->To<std::string>());
456 if (!device) { 481 if (!device) {
457 callback.Run(false); 482 callback.Run(false);
458 return; 483 return;
459 } 484 }
460 485
461 callback.Run(device->IsConnected()); 486 callback.Run(device->IsConnected());
462 } 487 }
463 488
489 void ArcBluetoothBridge::StartLEScan() {
490 DCHECK(bluetooth_adapter_);
491 if (discovery_session_) {
492 LOG(ERROR) << "Discovery session already running; leaving alone";
493 SendCachedDevicesFound();
494 return;
495 }
496 BluetoothDiscoveryFilter* df = new BluetoothDiscoveryFilter(
497 BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
498 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(df);
499 bluetooth_adapter_->StartDiscoverySessionWithFilter(
500 std::move(discovery_filter),
501 base::Bind(&ArcBluetoothBridge::OnDiscoveryStarted,
502 weak_factory_.GetWeakPtr()),
503 base::Bind(&ArcBluetoothBridge::OnDiscoveryError,
504 weak_factory_.GetWeakPtr()));
505 }
506
507 void ArcBluetoothBridge::StopLEScan() {
508 CancelDiscovery();
509 }
510
511 void ArcBluetoothBridge::OnGattConnected(
512 mojom::BluetoothAddressPtr addr,
513 std::unique_ptr<BluetoothGattConnection> connection) const {
514 if (!HasBluetoothInstance())
515 return;
516
517 DCHECK(addr);
518
519 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
520 std::move(addr), true);
521 }
522
523 void ArcBluetoothBridge::OnGattConnectError(
524 mojom::BluetoothAddressPtr addr,
525 BluetoothDevice::ConnectErrorCode error_code) const {
526 if (!HasBluetoothInstance())
527 return;
528
529 DCHECK(addr);
530
531 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
532 std::move(addr), false);
533 }
534
535 void ArcBluetoothBridge::OnGattDisconnected(
536 mojom::BluetoothAddressPtr addr) const {
537 if (!HasBluetoothInstance())
538 return;
539
540 DCHECK(addr);
541
542 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
543 std::move(addr), false);
544 }
545
546 void ArcBluetoothBridge::ConnectLEDevice(
547 mojom::BluetoothAddressPtr remote_addr) {
548 if (!HasBluetoothInstance())
549 return;
550
551 BluetoothDevice* device =
552 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
553
554 if (device->IsConnected()) {
555 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
556 std::move(remote_addr), true);
557 return;
558 }
559
560 // Also pass disconnect callback in error case
561 // since it would be disconnected anyway.
562 mojom::BluetoothAddressPtr remote_addr1 = remote_addr.Clone();
563 device->CreateGattConnection(
564 base::Bind(&ArcBluetoothBridge::OnGattConnected,
565 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
566 base::Bind(&ArcBluetoothBridge::OnGattConnectError,
567 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr1)));
568 }
569
570 void ArcBluetoothBridge::DisconnectLEDevice(
571 mojom::BluetoothAddressPtr remote_addr) {
572 if (!HasBluetoothInstance())
573 return;
574
575 BluetoothDevice* device =
576 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
577
578 if (!device->IsConnected()) {
579 arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
580 std::move(remote_addr), false);
581 return;
582 }
583
584 mojom::BluetoothAddressPtr remote_addr1 = remote_addr.Clone();
585 device->Disconnect(
586 base::Bind(&ArcBluetoothBridge::OnGattDisconnected,
587 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
588 base::Bind(&ArcBluetoothBridge::OnGattDisconnected,
589 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr1)));
590 }
591
592 void ArcBluetoothBridge::SearchService(mojom::BluetoothAddressPtr remote_addr) {
593 if (!HasBluetoothInstance())
594 return;
595
596 BluetoothDevice* device =
597 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
598
599 // Call the callback if discovery is completed
600 if (device->IsGattServicesDiscoveryComplete()) {
601 arc_bridge_service()->bluetooth_instance()->OnSearchComplete(
602 std::move(remote_addr), mojom::BluetoothGattStatus::GATT_SUCCESS);
603 return;
604 }
605
606 // Discard result. Will call the callback when discovery is completed.
607 device->GetGattServices();
608 }
609
610 void ArcBluetoothBridge::OnStartLEListenDone(
611 const StartLEListenCallback& callback,
612 scoped_refptr<BluetoothAdvertisement> adv) {
613 advertisment_ = adv;
614 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
615 }
616
617 void ArcBluetoothBridge::OnStartLEListenError(
618 const StartLEListenCallback& callback,
619 BluetoothAdvertisement::ErrorCode error_code) {
620 advertisment_ = nullptr;
621 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
622 }
623
624 void ArcBluetoothBridge::StartLEListen(const StartLEListenCallback& callback) {
625 std::unique_ptr<BluetoothAdvertisement::Data> adv_data =
626 base::WrapUnique(new BluetoothAdvertisement::Data(
627 BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST));
628 adv_data->set_service_uuids(
629 base::WrapUnique(new BluetoothAdvertisement::UUIDList()));
630 adv_data->set_manufacturer_data(
631 base::WrapUnique(new BluetoothAdvertisement::ManufacturerData()));
632 adv_data->set_solicit_uuids(
633 base::WrapUnique(new BluetoothAdvertisement::UUIDList()));
634 adv_data->set_service_data(
635 base::WrapUnique(new BluetoothAdvertisement::ServiceData()));
636 bluetooth_adapter_->RegisterAdvertisement(
637 std::move(adv_data), base::Bind(&ArcBluetoothBridge::OnStartLEListenDone,
638 weak_factory_.GetWeakPtr(), callback),
639 base::Bind(&ArcBluetoothBridge::OnStartLEListenError,
640 weak_factory_.GetWeakPtr(), callback));
641 }
642
643 void ArcBluetoothBridge::OnStopLEListenDone(
644 const StopLEListenCallback& callback) {
645 advertisment_ = nullptr;
646 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
647 }
648
649 void ArcBluetoothBridge::OnStopLEListenError(
650 const StopLEListenCallback& callback,
651 BluetoothAdvertisement::ErrorCode error_code) {
652 advertisment_ = nullptr;
653 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
654 }
655
656 void ArcBluetoothBridge::StopLEListen(const StopLEListenCallback& callback) {
657 if (!advertisment_) {
658 OnStopLEListenError(
659 callback,
660 BluetoothAdvertisement::ErrorCode::ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
661 return;
662 }
663 advertisment_->Unregister(base::Bind(&ArcBluetoothBridge::OnStopLEListenDone,
664 weak_factory_.GetWeakPtr(), callback),
665 base::Bind(&ArcBluetoothBridge::OnStopLEListenError,
666 weak_factory_.GetWeakPtr(), callback));
667 }
668
669 void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) {
670 if (!HasBluetoothInstance())
671 return;
672
673 BluetoothDevice* device =
674 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
675 mojo::Array<mojom::BluetoothGattDBElementPtr> db;
676 for (auto& service : device->GetGattServices()) {
677 mojom::BluetoothGattDBElementPtr element =
678 mojom::BluetoothGattDBElement::New();
679
680 // Example: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
681 std::string id_str = service->GetIdentifier();
682
683 // Convert last digit of service id to int in base 16
684 int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
685
686 element->id = id;
687 element->uuid = mojom::BluetoothUUID::From(service->GetUUID());
688 if (service->IsPrimary()) {
689 element->type =
690 mojom::BluetoothGattDBAttributeType::BTGATT_DB_PRIMARY_SERVICE;
691 } else {
692 element->type =
693 mojom::BluetoothGattDBAttributeType::BTGATT_DB_SECONDARY_SERVICE;
694 }
695 element->attribute_handle = id;
696 std::vector<BluetoothRemoteGattCharacteristic*> characteristics =
697 service->GetCharacteristics();
698 if (characteristics.size() > 0) {
699 std::string first_id_str = characteristics.front()->GetIdentifier();
700 int first_id =
701 std::stoi(first_id_str.substr(first_id_str.size() - 4), nullptr, 16);
702 std::string last_id_str = characteristics.back()->GetIdentifier();
703 int last_id =
704 std::stoi(last_id_str.substr(last_id_str.size() - 4), nullptr, 16);
705 element->start_handle = first_id;
706 element->end_handle = last_id;
707 }
708 db.push_back(std::move(element));
709
710 for (auto& characteristic : characteristics) {
711 mojom::BluetoothGattDBElementPtr element =
712 mojom::BluetoothGattDBElement::New();
713 std::string id_str = characteristic->GetIdentifier();
714 int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
715 element->id = id;
716 element->uuid = mojom::BluetoothUUID::From(characteristic->GetUUID());
717 element->type =
718 mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC;
719 element->attribute_handle = id;
720 element->properties = characteristic->GetProperties();
721 db.push_back(std::move(element));
722
723 for (auto& descriptor : characteristic->GetDescriptors()) {
724 mojom::BluetoothGattDBElementPtr element =
725 mojom::BluetoothGattDBElement::New();
726 std::string id_str = descriptor->GetIdentifier();
727 int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
728 element->id = id;
729 element->uuid = mojom::BluetoothUUID::From(descriptor->GetUUID());
730 element->type =
731 mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR;
732 element->attribute_handle = id;
733 db.push_back(std::move(element));
734 }
735 }
736 }
737
738 arc_bridge_service()->bluetooth_instance()->OnGetGattDB(
739 std::move(remote_addr), std::move(db));
740 }
741
742 BluetoothRemoteGattCharacteristic* ArcBluetoothBridge::FindGattCharacteristic(
743 mojom::BluetoothAddressPtr remote_addr,
744 mojom::BluetoothGattServiceIDPtr service_id,
745 mojom::BluetoothGattIDPtr char_id) const {
746 DCHECK(remote_addr);
747 DCHECK(service_id);
748 DCHECK(char_id);
749
750 BluetoothDevice* device =
751 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
752 if (!device)
753 return nullptr;
754
755 BluetoothUUID serv_uuid = service_id->id->uuid.To<BluetoothUUID>();
756
757 BluetoothRemoteGattService* service = nullptr;
758 for (auto& s : device->GetGattServices()) {
759 if (s->GetUUID() == serv_uuid) {
760 service = s;
761 break;
762 }
763 }
764 if (!service)
765 return nullptr;
766
767 BluetoothUUID char_uuid = char_id->uuid.To<BluetoothUUID>();
768
769 for (auto& c : service->GetCharacteristics()) {
770 if (c->GetUUID() == char_uuid) {
771 return c;
772 }
773 }
774 return nullptr;
775 }
776
777 BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor(
778 mojom::BluetoothAddressPtr remote_addr,
779 mojom::BluetoothGattServiceIDPtr service_id,
780 mojom::BluetoothGattIDPtr char_id,
781 mojom::BluetoothGattIDPtr desc_id) const {
782 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
783 std::move(remote_addr), std::move(service_id), std::move(char_id));
784
785 if (!characteristic)
786 return nullptr;
787
788 BluetoothUUID desc_uuid = desc_id->uuid.To<BluetoothUUID>();
789 for (auto& d : characteristic->GetDescriptors()) {
790 if (d->GetUUID() == desc_uuid) {
791 return d;
792 }
793 }
794 return nullptr;
795 }
796
797 // same callback for both ReadGattCharacteristic and ReadGattDescriptor
798 void ArcBluetoothBridge::OnGattReadDone(
799 const GattReadCallback& callback,
800 const std::vector<uint8_t>& result) const {
801 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
802 gattValue->status = mojom::BluetoothGattStatus::GATT_SUCCESS;
803 gattValue->len = result.size();
804 gattValue->type = 0;
805 gattValue->value = mojo::Array<uint8_t>::From(result);
806 callback.Run(std::move(gattValue));
807 }
808
809 void ArcBluetoothBridge::OnGattReadError(
810 const GattReadCallback& callback,
811 BluetoothGattService::GattErrorCode error_code) const {
812 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
813 gattValue->status = mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code);
814 gattValue->len = 0;
815 gattValue->type = 0;
816 gattValue->value = nullptr;
817
818 callback.Run(std::move(gattValue));
819 }
820
821 // same callback for both WriteGattCharacteristic and WriteGattDescriptor
822 void ArcBluetoothBridge::OnGattWriteDone(
823 const GattWriteCallback& callback) const {
824 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
825 }
826
827 void ArcBluetoothBridge::OnGattWriteError(
828 const GattWriteCallback& callback,
829 BluetoothGattService::GattErrorCode error_code) const {
830 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
831 }
832
833 void ArcBluetoothBridge::ReadGattCharacteristic(
834 mojom::BluetoothAddressPtr remote_addr,
835 mojom::BluetoothGattServiceIDPtr service_id,
836 mojom::BluetoothGattIDPtr char_id,
837 const ReadGattCharacteristicCallback& callback) {
838 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
839 std::move(remote_addr), std::move(service_id), std::move(char_id));
840
841 DCHECK(characteristic);
842
843 DCHECK(characteristic->GetPermissions() &&
844 BluetoothGattCharacteristic::Permission::PERMISSION_READ);
845
846 characteristic->ReadRemoteCharacteristic(
847 base::Bind(&ArcBluetoothBridge::OnGattReadDone,
848 weak_factory_.GetWeakPtr(), callback),
849 base::Bind(&ArcBluetoothBridge::OnGattReadError,
850 weak_factory_.GetWeakPtr(), callback));
851 }
852
853 void ArcBluetoothBridge::WriteGattCharacteristic(
854 mojom::BluetoothAddressPtr remote_addr,
855 mojom::BluetoothGattServiceIDPtr service_id,
856 mojom::BluetoothGattIDPtr char_id,
857 mojom::BluetoothGattValuePtr value,
858 const WriteGattCharacteristicCallback& callback) {
859 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
860 std::move(remote_addr), std::move(service_id), std::move(char_id));
861
862 DCHECK(characteristic);
863
864 DCHECK(characteristic->GetPermissions() &&
865 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE);
866
867 std::vector<uint8_t> new_value = value->value.To<std::vector<uint8_t>>();
868
869 characteristic->WriteRemoteCharacteristic(
870 new_value, base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
871 weak_factory_.GetWeakPtr(), callback),
872 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
873 weak_factory_.GetWeakPtr(), callback));
874 }
875
876 void ArcBluetoothBridge::ReadGattDescriptor(
877 mojom::BluetoothAddressPtr remote_addr,
878 mojom::BluetoothGattServiceIDPtr service_id,
879 mojom::BluetoothGattIDPtr char_id,
880 mojom::BluetoothGattIDPtr desc_id,
881 const ReadGattDescriptorCallback& callback) {
882 BluetoothRemoteGattDescriptor* descriptor =
883 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
884 std::move(char_id), std::move(desc_id));
885 DCHECK(descriptor);
886
887 DCHECK(descriptor->GetPermissions() &&
888 BluetoothGattCharacteristic::Permission::PERMISSION_READ);
889
890 descriptor->ReadRemoteDescriptor(
891 base::Bind(&ArcBluetoothBridge::OnGattReadDone,
892 weak_factory_.GetWeakPtr(), callback),
893 base::Bind(&ArcBluetoothBridge::OnGattReadError,
894 weak_factory_.GetWeakPtr(), callback));
895 }
896
897 void ArcBluetoothBridge::WriteGattDescriptor(
898 mojom::BluetoothAddressPtr remote_addr,
899 mojom::BluetoothGattServiceIDPtr service_id,
900 mojom::BluetoothGattIDPtr char_id,
901 mojom::BluetoothGattIDPtr desc_id,
902 mojom::BluetoothGattValuePtr value,
903 const WriteGattDescriptorCallback& callback) {
904 BluetoothRemoteGattDescriptor* descriptor =
905 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
906 std::move(char_id), std::move(desc_id));
907 DCHECK(descriptor);
908
909 DCHECK(descriptor->GetPermissions() &&
910 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE);
911
912 std::vector<uint8_t> new_value = value->value.To<std::vector<uint8_t>>();
913
914 descriptor->WriteRemoteDescriptor(
915 new_value, base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
916 weak_factory_.GetWeakPtr(), callback),
917 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
918 weak_factory_.GetWeakPtr(), callback));
919 }
920
921 void ArcBluetoothBridge::OnGattNotifyStartDone(
922 const RegisterForGattNotificationCallback& callback,
923 const std::string char_string_id,
924 std::unique_ptr<BluetoothGattNotifySession> notify_session) {
925 notification_session_[char_string_id] = std::move(notify_session);
926 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
927 }
928
929 void ArcBluetoothBridge::OnGattNotifyStartError(
930 const RegisterForGattNotificationCallback& callback,
931 BluetoothGattService::GattErrorCode error_code) const {
932 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
933 }
934
935 void ArcBluetoothBridge::OnGattNotifyStopDone(
936 const DeregisterForGattNotificationCallback& callback) const {
937 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
938 }
939
940 void ArcBluetoothBridge::RegisterForGattNotification(
941 mojom::BluetoothAddressPtr remote_addr,
942 mojom::BluetoothGattServiceIDPtr service_id,
943 mojom::BluetoothGattIDPtr char_id,
944 const RegisterForGattNotificationCallback& callback) {
945 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
946 std::move(remote_addr), std::move(service_id), std::move(char_id));
947
948 DCHECK(characteristic);
949
950 if (characteristic->IsNotifying()) {
951 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
952 return;
953 }
954
955 characteristic->StartNotifySession(
956 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone,
957 weak_factory_.GetWeakPtr(), callback,
958 characteristic->GetIdentifier()),
959 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartError,
960 weak_factory_.GetWeakPtr(), callback));
961 }
962
963 void ArcBluetoothBridge::DeregisterForGattNotification(
964 mojom::BluetoothAddressPtr remote_addr,
965 mojom::BluetoothGattServiceIDPtr service_id,
966 mojom::BluetoothGattIDPtr char_id,
967 const DeregisterForGattNotificationCallback& callback) {
968 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
969 std::move(remote_addr), std::move(service_id), std::move(char_id));
970
971 DCHECK(characteristic);
972
973 if (!characteristic->IsNotifying()) {
974 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
975 return;
976 }
977
978 std::string char_id_str = characteristic->GetIdentifier();
979 std::unique_ptr<BluetoothGattNotifySession> notify =
980 std::move(notification_session_[char_id_str]);
981 notification_session_.erase(char_id_str);
982 notify->Stop(base::Bind(&ArcBluetoothBridge::OnGattNotifyStopDone,
983 weak_factory_.GetWeakPtr(), callback));
984 }
985
986 void ArcBluetoothBridge::ReadRemoteRssi(
987 mojom::BluetoothAddressPtr remote_addr,
988 const ReadRemoteRssiCallback& callback) {
989 BluetoothDevice* device =
990 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
991 int rssi = device->GetInquiryRSSI();
992 callback.Run(rssi);
993 }
994
464 void ArcBluetoothBridge::OnDiscoveryError() { 995 void ArcBluetoothBridge::OnDiscoveryError() {
465 LOG(WARNING) << "failed to change discovery state"; 996 LOG(WARNING) << "failed to change discovery state";
466 } 997 }
467 998
468 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { 999 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const {
469 if (!HasBluetoothInstance()) 1000 if (!HasBluetoothInstance())
470 return; 1001 return;
471 1002
472 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged( 1003 arc_bridge_service()->bluetooth_instance()->OnBondStateChanged(
473 mojom::BluetoothStatus::SUCCESS, std::move(addr), 1004 mojom::BluetoothStatus::SUCCESS, std::move(addr),
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 } 1065 }
535 if (type == mojom::BluetoothPropertyType::ALL || 1066 if (type == mojom::BluetoothPropertyType::ALL ||
536 type == mojom::BluetoothPropertyType::BDADDR) { 1067 type == mojom::BluetoothPropertyType::BDADDR) {
537 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1068 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
538 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress())); 1069 btp->set_bdaddr(mojom::BluetoothAddress::From(device->GetAddress()));
539 properties.push_back(std::move(btp)); 1070 properties.push_back(std::move(btp));
540 } 1071 }
541 if (type == mojom::BluetoothPropertyType::ALL || 1072 if (type == mojom::BluetoothPropertyType::ALL ||
542 type == mojom::BluetoothPropertyType::UUIDS) { 1073 type == mojom::BluetoothPropertyType::UUIDS) {
543 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1074 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
544 std::vector<device::BluetoothUUID> uuids = device->GetUUIDs(); 1075 std::vector<BluetoothUUID> uuids = device->GetUUIDs();
545 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results = 1076 mojo::Array<mojom::BluetoothUUIDPtr> uuid_results =
546 mojo::Array<mojom::BluetoothUUIDPtr>::New(0); 1077 mojo::Array<mojom::BluetoothUUIDPtr>::New(0);
547 1078
548 for (size_t i = 0; i < uuids.size(); i++) { 1079 for (auto& uuid : uuids) {
549 uuid_results.push_back(mojom::BluetoothUUID::From(uuids[i])); 1080 uuid_results.push_back(mojom::BluetoothUUID::From(uuid));
550 } 1081 }
551 1082
552 btp->set_uuids(std::move(uuid_results)); 1083 btp->set_uuids(std::move(uuid_results));
553 properties.push_back(std::move(btp)); 1084 properties.push_back(std::move(btp));
554 } 1085 }
555 if (type == mojom::BluetoothPropertyType::ALL || 1086 if (type == mojom::BluetoothPropertyType::ALL ||
556 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) { 1087 type == mojom::BluetoothPropertyType::CLASS_OF_DEVICE) {
557 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1088 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
558 btp->set_device_class(device->GetBluetoothClass()); 1089 btp->set_device_class(device->GetBluetoothClass());
559 properties.push_back(std::move(btp)); 1090 properties.push_back(std::move(btp));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 properties.push_back(std::move(btp)); 1162 properties.push_back(std::move(btp));
632 } 1163 }
633 if (type == mojom::BluetoothPropertyType::ALL || 1164 if (type == mojom::BluetoothPropertyType::ALL ||
634 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) { 1165 type == mojom::BluetoothPropertyType::ADAPTER_BONDED_DEVICES) {
635 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1166 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
636 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1167 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
637 1168
638 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices = 1169 mojo::Array<mojom::BluetoothAddressPtr> bonded_devices =
639 mojo::Array<mojom::BluetoothAddressPtr>::New(0); 1170 mojo::Array<mojom::BluetoothAddressPtr>::New(0);
640 1171
641 for (size_t i = 0; i < devices.size(); i++) { 1172 for (auto& device : devices) {
642 if (!devices[i]->IsPaired()) 1173 if (device->IsPaired())
643 continue; 1174 continue;
644 1175
645 mojom::BluetoothAddressPtr addr = 1176 mojom::BluetoothAddressPtr addr =
646 mojom::BluetoothAddress::From(devices[i]->GetAddress()); 1177 mojom::BluetoothAddress::From(device->GetAddress());
647 bonded_devices.push_back(std::move(addr)); 1178 bonded_devices.push_back(std::move(addr));
648 } 1179 }
649 1180
650 btp->set_bonded_devices(std::move(bonded_devices)); 1181 btp->set_bonded_devices(std::move(bonded_devices));
651 properties.push_back(std::move(btp)); 1182 properties.push_back(std::move(btp));
652 } 1183 }
653 if (type == mojom::BluetoothPropertyType::ALL || 1184 if (type == mojom::BluetoothPropertyType::ALL ||
654 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) { 1185 type == mojom::BluetoothPropertyType::ADAPTER_DISCOVERY_TIMEOUT) {
655 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1186 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
656 btp->set_discovery_timeout(120); 1187 btp->set_discovery_timeout(120);
657 properties.push_back(std::move(btp)); 1188 properties.push_back(std::move(btp));
658 } 1189 }
659 1190
660 return properties; 1191 return properties;
661 } 1192 }
662 1193
1194 mojo::Array<uint8_t> ArcBluetoothBridge::GetAdvData(
Luis Héctor Chávez 2016/06/01 21:12:03 eek, sending a blob. Is there absolutely no way to
1195 BluetoothDevice* device) const {
1196 std::vector<uint8_t> vec = std::vector<uint8_t>();
1197 int field_length;
1198
1199 // const int DATA_TYPE_FLAGS = 0x01;
1200 const int DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE = 0x07;
1201 const int DATA_TYPE_LOCAL_NAME_COMPLETE = 0x09;
1202 const int DATA_TYPE_TX_POWER_LEVEL = 0x0A;
1203 const int DATA_TYPE_SERVICE_DATA = 0x16;
1204 // const int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
1205
1206 // AdvertiseFlag
1207 // Flags Advertising Data Type
1208 // Bit0 – Indicates LE Limited Discoverable Mode
1209 // Bit1 – Indicates LE General Discoverable Mode
1210 // Bit2 – Indicates whether BR/EDR is supported.
1211 // Bit3 – Indicates whether LE and BR/EDR Controller operates simultaneously
1212 // Bit4 – Indicates whether LE and BR/EDR Host operates simultaneously
1213 // No need? Chrome do not expose this.
1214
1215 // ServiceUuid
1216 BluetoothDevice::UUIDList uuid_list = device->GetServiceDataUUIDs();
1217 if (uuid_list.size() > 0) {
1218 field_length = uuid_list.size() * 16 + 2;
1219 vec.push_back(field_length);
1220 vec.push_back(DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE);
1221
1222 for (auto& uuid : uuid_list) {
1223 std::string str = uuid.canonical_value();
1224 for (auto& c : str) {
1225 if (c == '-')
1226 continue;
1227 vec.push_back(c);
1228 }
1229 }
1230 }
1231
1232 // LocalName
1233 std::string name = base::UTF16ToUTF8(device->GetName());
1234 field_length = name.size() + 2;
1235 vec.push_back(field_length);
1236 vec.push_back(DATA_TYPE_LOCAL_NAME_COMPLETE);
1237 for (auto& c : name) {
1238 vec.push_back(c);
1239 }
1240
1241 // txPowerLevel
1242 vec.push_back(3);
1243 vec.push_back(DATA_TYPE_TX_POWER_LEVEL);
1244 vec.push_back(device->GetInquiryTxPower());
1245
1246 // Service data
1247 for (auto& uuid : uuid_list) {
1248 base::BinaryValue* data = device->GetServiceData(uuid);
1249 if (data->GetSize() == 0)
1250 continue;
1251 std::string data_str;
1252 if (!data->GetAsString(&data_str))
1253 continue;
1254
1255 vec.push_back(2 + data->GetSize());
1256 vec.push_back(DATA_TYPE_SERVICE_DATA);
1257 for (auto& c : data_str) {
1258 vec.push_back(c);
1259 }
1260 }
1261
1262 // ManufactureData
1263 // No need? Chrome do not expose this.
1264
1265 vec.push_back(0);
1266
1267 return mojo::Array<uint8_t>::From(vec);
1268 }
1269
663 void ArcBluetoothBridge::SendCachedDevicesFound() const { 1270 void ArcBluetoothBridge::SendCachedDevicesFound() const {
664 // Send devices that have already been discovered, but aren't connected. 1271 // Send devices that have already been discovered, but aren't connected.
665 if (!HasBluetoothInstance()) 1272 if (!HasBluetoothInstance())
666 return; 1273 return;
667 1274
668 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1275 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
669 for (size_t i = 0; i < devices.size(); i++) { 1276 for (auto& device : devices) {
670 if (devices[i]->IsPaired()) 1277 if (device->IsPaired())
671 continue; 1278 continue;
672 1279
673 mojo::Array<mojom::BluetoothPropertyPtr> properties = 1280 mojo::Array<mojom::BluetoothPropertyPtr> properties =
674 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, devices[i]); 1281 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
675 1282
676 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 1283 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
677 std::move(properties)); 1284 std::move(properties));
1285
1286 mojom::BluetoothAddressPtr addr =
1287 mojom::BluetoothAddress::From(device->GetAddress());
1288 int rssi = device->GetInquiryRSSI();
1289
1290 mojo::Array<uint8_t> adv_data = GetAdvData(device);
1291
1292 arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
1293 std::move(addr), rssi, std::move(adv_data));
678 } 1294 }
679 } 1295 }
680 1296
681 bool ArcBluetoothBridge::HasBluetoothInstance() const { 1297 bool ArcBluetoothBridge::HasBluetoothInstance() const {
682 if (!arc_bridge_service()->bluetooth_instance()) { 1298 if (!arc_bridge_service()->bluetooth_instance()) {
683 LOG(WARNING) << "no Bluetooth instance available"; 1299 LOG(WARNING) << "no Bluetooth instance available";
684 return false; 1300 return false;
685 } 1301 }
686 1302
687 return true; 1303 return true;
688 } 1304 }
689 1305
690 void ArcBluetoothBridge::SendCachedPairedDevices() const { 1306 void ArcBluetoothBridge::SendCachedPairedDevices() const {
691 DCHECK(bluetooth_adapter_); 1307 DCHECK(bluetooth_adapter_);
1308 if (!HasBluetoothInstance())
1309 return;
692 1310
693 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); 1311 BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
694 for (BluetoothDevice* device : devices) { 1312 for (auto& device : devices) {
695 if (!device->IsPaired()) 1313 if (!device->IsPaired())
696 continue; 1314 continue;
697 1315
698 mojo::Array<mojom::BluetoothPropertyPtr> properties = 1316 mojo::Array<mojom::BluetoothPropertyPtr> properties =
699 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device); 1317 GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
700 1318
701 arc_bridge_service()->bluetooth_instance()->OnDeviceFound( 1319 arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
702 std::move(properties)); 1320 std::move(properties));
703 1321
704 mojom::BluetoothAddressPtr addr = 1322 mojom::BluetoothAddressPtr addr =
705 mojom::BluetoothAddress::From(device->GetAddress()); 1323 mojom::BluetoothAddress::From(device->GetAddress());
706 1324
707 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING 1325 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING
708 // to 1326 // to
709 // make sure the bond state machine on Android is ready to take the 1327 // make sure the bond state machine on Android is ready to take the
710 // pair-done event. Otherwise the pair-done event will be dropped as an 1328 // pair-done event. Otherwise the pair-done event will be dropped as an
711 // invalid change of paired status. 1329 // invalid change of paired status.
712 OnPairing(addr->Clone()); 1330 OnPairing(addr->Clone());
713 OnPairedDone(std::move(addr)); 1331 OnPairedDone(std::move(addr));
714 } 1332 }
715 } 1333 }
716 1334
717 } // namespace arc 1335 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698