123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- // Copyright 2016 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/memory/ptr_util.h"
- #include "base/strings/utf_string_conversions.h"
- #include "device/bluetooth/device.h"
- #include "device/bluetooth/public/mojom/gatt_result_type_converter.h"
- #include "mojo/public/cpp/bindings/self_owned_receiver.h"
- namespace bluetooth {
- Device::~Device() {
- adapter_->RemoveObserver(this);
- }
- // static
- void Device::Create(scoped_refptr<device::BluetoothAdapter> adapter,
- std::unique_ptr<device::BluetoothGattConnection> connection,
- mojo::PendingReceiver<mojom::Device> receiver) {
- auto device_impl =
- base::WrapUnique(new Device(adapter, std::move(connection)));
- auto* device_ptr = device_impl.get();
- device_ptr->receiver_ =
- mojo::MakeSelfOwnedReceiver(std::move(device_impl), std::move(receiver));
- }
- // static
- mojom::DeviceInfoPtr Device::ConstructDeviceInfoStruct(
- const device::BluetoothDevice* device) {
- mojom::DeviceInfoPtr device_info = mojom::DeviceInfo::New();
- device_info->name = device->GetName();
- device_info->name_for_display =
- base::UTF16ToUTF8(device->GetNameForDisplay());
- device_info->address = device->GetAddress();
- device_info->is_gatt_connected = device->IsGattConnected();
- if (device->GetInquiryRSSI()) {
- device_info->rssi = mojom::RSSIWrapper::New();
- device_info->rssi->value = device->GetInquiryRSSI().value();
- }
- std::vector<device::BluetoothUUID> service_uuids;
- for (auto& uuid : device->GetUUIDs())
- service_uuids.push_back(uuid);
- device_info->service_uuids = service_uuids;
- for (auto const& it : device->GetManufacturerData())
- device_info->manufacturer_data_map.insert_or_assign(it.first, it.second);
- for (auto const& it : device->GetServiceData())
- device_info->service_data_map.insert_or_assign(it.first, it.second);
- return device_info;
- }
- void Device::DeviceChanged(device::BluetoothAdapter* adapter,
- device::BluetoothDevice* device) {
- if (device->GetAddress() != GetAddress()) {
- return;
- }
- if (!device->IsGattConnected()) {
- receiver_->Close();
- }
- }
- void Device::GattServicesDiscovered(device::BluetoothAdapter* adapter,
- device::BluetoothDevice* device) {
- if (device->GetAddress() != GetAddress()) {
- return;
- }
- std::vector<base::OnceClosure> requests;
- requests.swap(pending_services_requests_);
- for (base::OnceClosure& request : requests) {
- std::move(request).Run();
- }
- }
- void Device::Disconnect() {
- receiver_->Close();
- }
- void Device::GetInfo(GetInfoCallback callback) {
- device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
- DCHECK(device);
- std::move(callback).Run(ConstructDeviceInfoStruct(device));
- }
- void Device::GetServices(GetServicesCallback callback) {
- device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
- DCHECK(device);
- if (device->IsGattServicesDiscoveryComplete()) {
- GetServicesImpl(std::move(callback));
- return;
- }
- // pending_services_requests_ is owned by Device, so base::Unretained is
- // safe.
- pending_services_requests_.push_back(base::BindOnce(
- &Device::GetServicesImpl, base::Unretained(this), std::move(callback)));
- }
- void Device::GetCharacteristics(const std::string& service_id,
- GetCharacteristicsCallback callback) {
- device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
- DCHECK(device);
- device::BluetoothRemoteGattService* service =
- device->GetGattService(service_id);
- if (service == nullptr) {
- std::move(callback).Run(absl::nullopt);
- return;
- }
- std::vector<mojom::CharacteristicInfoPtr> characteristics;
- for (const auto* characteristic : service->GetCharacteristics()) {
- mojom::CharacteristicInfoPtr characteristic_info =
- mojom::CharacteristicInfo::New();
- characteristic_info->id = characteristic->GetIdentifier();
- characteristic_info->uuid = characteristic->GetUUID();
- characteristic_info->properties = characteristic->GetProperties();
- characteristics.push_back(std::move(characteristic_info));
- }
- std::move(callback).Run(std::move(characteristics));
- }
- void Device::ReadValueForCharacteristic(
- const std::string& service_id,
- const std::string& characteristic_id,
- ReadValueForCharacteristicCallback callback) {
- device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
- DCHECK(device);
- device::BluetoothRemoteGattService* service =
- device->GetGattService(service_id);
- if (service == nullptr) {
- std::move(callback).Run(mojom::GattResult::SERVICE_NOT_FOUND,
- absl::nullopt /* value */);
- return;
- }
- device::BluetoothRemoteGattCharacteristic* characteristic =
- service->GetCharacteristic(characteristic_id);
- if (characteristic == nullptr) {
- std::move(callback).Run(mojom::GattResult::CHARACTERISTIC_NOT_FOUND,
- absl::nullopt /* value */);
- return;
- }
- characteristic->ReadRemoteCharacteristic(
- base::BindOnce(&Device::OnReadRemoteCharacteristic,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
- }
- void Device::WriteValueForCharacteristic(
- const std::string& service_id,
- const std::string& characteristic_id,
- const std::vector<uint8_t>& value,
- WriteValueForCharacteristicCallback callback) {
- device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
- DCHECK(device);
- device::BluetoothRemoteGattService* service =
- device->GetGattService(service_id);
- if (service == nullptr) {
- std::move(callback).Run(mojom::GattResult::SERVICE_NOT_FOUND);
- return;
- }
- device::BluetoothRemoteGattCharacteristic* characteristic =
- service->GetCharacteristic(characteristic_id);
- if (characteristic == nullptr) {
- std::move(callback).Run(mojom::GattResult::CHARACTERISTIC_NOT_FOUND);
- return;
- }
- auto split_callback = base::SplitOnceCallback(std::move(callback));
- characteristic->DeprecatedWriteRemoteCharacteristic(
- value,
- base::BindOnce(&Device::OnWriteRemoteCharacteristic,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(split_callback.first)),
- base::BindOnce(&Device::OnWriteRemoteCharacteristicError,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(split_callback.second)));
- }
- void Device::GetDescriptors(const std::string& service_id,
- const std::string& characteristic_id,
- GetDescriptorsCallback callback) {
- device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
- if (!device) {
- std::move(callback).Run(absl::nullopt);
- return;
- }
- device::BluetoothRemoteGattService* service =
- device->GetGattService(service_id);
- if (!service) {
- std::move(callback).Run(absl::nullopt);
- return;
- }
- device::BluetoothRemoteGattCharacteristic* characteristic =
- service->GetCharacteristic(characteristic_id);
- if (!characteristic) {
- std::move(callback).Run(absl::nullopt);
- return;
- }
- std::vector<mojom::DescriptorInfoPtr> descriptors;
- for (const auto* descriptor : characteristic->GetDescriptors()) {
- mojom::DescriptorInfoPtr descriptor_info = mojom::DescriptorInfo::New();
- descriptor_info->id = descriptor->GetIdentifier();
- descriptor_info->uuid = descriptor->GetUUID();
- descriptor_info->last_known_value = descriptor->GetValue();
- descriptors.push_back(std::move(descriptor_info));
- }
- std::move(callback).Run(std::move(descriptors));
- }
- void Device::ReadValueForDescriptor(const std::string& service_id,
- const std::string& characteristic_id,
- const std::string& descriptor_id,
- ReadValueForDescriptorCallback callback) {
- device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
- DCHECK(device);
- device::BluetoothRemoteGattService* service =
- device->GetGattService(service_id);
- if (!service) {
- std::move(callback).Run(mojom::GattResult::SERVICE_NOT_FOUND,
- absl::nullopt /* value */);
- return;
- }
- device::BluetoothRemoteGattCharacteristic* characteristic =
- service->GetCharacteristic(characteristic_id);
- if (!characteristic) {
- std::move(callback).Run(mojom::GattResult::CHARACTERISTIC_NOT_FOUND,
- absl::nullopt /* value */);
- return;
- }
- device::BluetoothRemoteGattDescriptor* descriptor =
- characteristic->GetDescriptor(descriptor_id);
- if (!descriptor) {
- std::move(callback).Run(mojom::GattResult::DESCRIPTOR_NOT_FOUND,
- absl::nullopt /* value */);
- return;
- }
- descriptor->ReadRemoteDescriptor(
- base::BindOnce(&Device::OnReadRemoteDescriptor,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
- }
- void Device::WriteValueForDescriptor(const std::string& service_id,
- const std::string& characteristic_id,
- const std::string& descriptor_id,
- const std::vector<uint8_t>& value,
- WriteValueForDescriptorCallback callback) {
- device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
- DCHECK(device);
- device::BluetoothRemoteGattService* service =
- device->GetGattService(service_id);
- if (!service) {
- std::move(callback).Run(mojom::GattResult::SERVICE_NOT_FOUND);
- return;
- }
- device::BluetoothRemoteGattCharacteristic* characteristic =
- service->GetCharacteristic(characteristic_id);
- if (!characteristic) {
- std::move(callback).Run(mojom::GattResult::CHARACTERISTIC_NOT_FOUND);
- return;
- }
- device::BluetoothRemoteGattDescriptor* descriptor =
- characteristic->GetDescriptor(descriptor_id);
- if (!descriptor) {
- std::move(callback).Run(mojom::GattResult::DESCRIPTOR_NOT_FOUND);
- return;
- }
- auto split_callback = base::SplitOnceCallback(std::move(callback));
- descriptor->WriteRemoteDescriptor(
- value,
- base::BindOnce(&Device::OnWriteRemoteDescriptor,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(split_callback.first)),
- base::BindOnce(&Device::OnWriteRemoteDescriptorError,
- weak_ptr_factory_.GetWeakPtr(),
- std::move(split_callback.second)));
- }
- Device::Device(scoped_refptr<device::BluetoothAdapter> adapter,
- std::unique_ptr<device::BluetoothGattConnection> connection)
- : adapter_(std::move(adapter)), connection_(std::move(connection)) {
- adapter_->AddObserver(this);
- }
- void Device::GetServicesImpl(GetServicesCallback callback) {
- device::BluetoothDevice* device = adapter_->GetDevice(GetAddress());
- DCHECK(device);
- std::vector<mojom::ServiceInfoPtr> services;
- for (const device::BluetoothRemoteGattService* service :
- device->GetGattServices()) {
- services.push_back(ConstructServiceInfoStruct(*service));
- }
- std::move(callback).Run(std::move(services));
- }
- mojom::ServiceInfoPtr Device::ConstructServiceInfoStruct(
- const device::BluetoothRemoteGattService& service) {
- mojom::ServiceInfoPtr service_info = mojom::ServiceInfo::New();
- service_info->id = service.GetIdentifier();
- service_info->uuid = service.GetUUID();
- service_info->is_primary = service.IsPrimary();
- return service_info;
- }
- void Device::OnReadRemoteCharacteristic(
- ReadValueForCharacteristicCallback callback,
- absl::optional<device::BluetoothGattService::GattErrorCode> error_code,
- const std::vector<uint8_t>& value) {
- if (error_code.has_value()) {
- std::move(callback).Run(
- mojo::ConvertTo<mojom::GattResult>(error_code.value()),
- absl::nullopt /* value */);
- return;
- }
- std::move(callback).Run(mojom::GattResult::SUCCESS, std::move(value));
- }
- void Device::OnWriteRemoteCharacteristic(
- WriteValueForCharacteristicCallback callback) {
- std::move(callback).Run(mojom::GattResult::SUCCESS);
- }
- void Device::OnWriteRemoteCharacteristicError(
- WriteValueForCharacteristicCallback callback,
- device::BluetoothGattService::GattErrorCode error_code) {
- std::move(callback).Run(mojo::ConvertTo<mojom::GattResult>(error_code));
- }
- void Device::OnReadRemoteDescriptor(
- ReadValueForDescriptorCallback callback,
- absl::optional<device::BluetoothGattService::GattErrorCode> error_code,
- const std::vector<uint8_t>& value) {
- if (error_code.has_value()) {
- std::move(callback).Run(
- mojo::ConvertTo<mojom::GattResult>(error_code.value()),
- /*value=*/absl::nullopt);
- return;
- }
- std::move(callback).Run(mojom::GattResult::SUCCESS, std::move(value));
- }
- void Device::OnWriteRemoteDescriptor(WriteValueForDescriptorCallback callback) {
- std::move(callback).Run(mojom::GattResult::SUCCESS);
- }
- void Device::OnWriteRemoteDescriptorError(
- WriteValueForDescriptorCallback callback,
- device::BluetoothGattService::GattErrorCode error_code) {
- std::move(callback).Run(mojo::ConvertTo<mojom::GattResult>(error_code));
- }
- const std::string& Device::GetAddress() {
- return connection_->GetDeviceAddress();
- }
- } // namespace bluetooth
|