| Index: device/bluetooth/bluetooth_remote_gatt_service_win.cc
|
| diff --git a/device/bluetooth/bluetooth_remote_gatt_service_win.cc b/device/bluetooth/bluetooth_remote_gatt_service_win.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9d56c46d7577f9af39890b0942b37eca6c225b77
|
| --- /dev/null
|
| +++ b/device/bluetooth/bluetooth_remote_gatt_service_win.cc
|
| @@ -0,0 +1,328 @@
|
| +// Copyright 2015 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 "device/bluetooth/bluetooth_remote_gatt_service_win.h"
|
| +
|
| +#include "base/bind.h"
|
| +
|
| +namespace device {
|
| +
|
| +void BluetoothRemoteGattServiceWin::NotifyServiceDiscComplIfNecessary() {
|
| + if (discovery_completed_included_charateristics_.size() ==
|
| + included_characteristic_objects_.size() &&
|
| + discovery_completed_included_services_.size() ==
|
| + included_service_objects_.size() &&
|
| + included_services_discovered_ && included_characteristics_discovered_ &&
|
| + !complete_notified_) {
|
| + if (is_primary_)
|
| + adapter_->NotifyGattDiscoveryCompleteForService(this);
|
| + else
|
| + parent_service_->NotifyGattServiceAdded(this);
|
| + complete_notified_ = true;
|
| + }
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::UpdateIncludedCharacteristics(
|
| + PBTH_LE_GATT_CHARACTERISTIC characteristics,
|
| + uint16_t num) {
|
| + if (num == 0) {
|
| + discovery_completed_included_charateristics_.clear();
|
| + included_characteristic_objects_.clear();
|
| + return;
|
| + }
|
| +
|
| + // Map of retreived characteristic uuid value to its index in
|
| + // |characteristics|.
|
| + std::map<std::string, uint16_t> current_characteristics;
|
| + for (uint16_t i = 0; i < num; i++) {
|
| + current_characteristics[task_manager_
|
| + ->BluetoothLowEnergyUuidToBluetoothUuid(
|
| + characteristics[i].CharacteristicUuid)
|
| + .value()] = i;
|
| + }
|
| +
|
| + // Map of known characteristics uuid value to its identifier.
|
| + std::map<std::string, std::string> known_characteristics;
|
| + // Remove no longer existed characteristics first.
|
| + if (included_characteristic_objects_.size() != 0) {
|
| + for (auto e : included_characteristic_objects_) {
|
| + known_characteristics[e.second->GetUUID().value()] = e.first;
|
| + }
|
| + std::vector<std::string> removed_characteristics;
|
| + for (auto e : known_characteristics) {
|
| + if (current_characteristics.find(e.first) ==
|
| + current_characteristics.end()) {
|
| + removed_characteristics.push_back(e.second);
|
| + }
|
| + }
|
| + for (auto identifier : removed_characteristics) {
|
| + discovery_completed_included_charateristics_.erase(identifier);
|
| + included_characteristic_objects_.erase(identifier);
|
| + }
|
| + // Update previously known characteristics.
|
| + for (auto e : included_characteristic_objects_)
|
| + e.second->Update();
|
| + }
|
| +
|
| + // Return if no new characteristics have been added.
|
| + if (included_characteristic_objects_.size() == num)
|
| + return;
|
| +
|
| + // Add new characteristics.
|
| + for (auto e : current_characteristics) {
|
| + if (known_characteristics.find(e.first) == known_characteristics.end()) {
|
| + PBTH_LE_GATT_CHARACTERISTIC info = new BTH_LE_GATT_CHARACTERISTIC();
|
| + *info = characteristics[e.second];
|
| + BluetoothRemoteGattCharacteristicWin* characteristic_object =
|
| + new BluetoothRemoteGattCharacteristicWin(this, info, ui_task_runner_);
|
| + included_characteristic_objects_.add(
|
| + characteristic_object->GetIdentifier(),
|
| + scoped_ptr<BluetoothRemoteGattCharacteristicWin>(
|
| + characteristic_object));
|
| + }
|
| + }
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::GetIncludedCharacteristicsCallback(
|
| + PBTH_LE_GATT_CHARACTERISTIC characteristics,
|
| + uint16_t num,
|
| + HRESULT hr) {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| + if (FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
|
| + return;
|
| + UpdateIncludedCharacteristics(characteristics, num);
|
| + included_characteristics_discovered_ = true;
|
| + NotifyServiceDiscComplIfNecessary();
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::UpdateIncludedServices(
|
| + PBTH_LE_GATT_SERVICE services,
|
| + uint16_t num) {
|
| + if (num == 0) {
|
| + discovery_completed_included_services_.clear();
|
| + included_service_objects_.clear();
|
| + return;
|
| + }
|
| +
|
| + // Map of retreived service uuid value to its index in
|
| + // |services|.
|
| + std::map<std::string, uint16_t> current_services;
|
| + for (uint16_t i = 0; i < num; i++) {
|
| + current_services[task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(
|
| + services[i].ServiceUuid)
|
| + .value()] = i;
|
| + }
|
| +
|
| + // Map of known services uuid value to its identifier.
|
| + std::map<std::string, std::string> known_services;
|
| + // Remove no longer existed services first.
|
| + if (included_service_objects_.size() != 0) {
|
| + for (auto e : included_service_objects_) {
|
| + known_services[e.second->GetUUID().value()] = e.first;
|
| + }
|
| + std::vector<std::string> removed_services;
|
| + for (auto e : known_services) {
|
| + if (current_services.find(e.first) == current_services.end()) {
|
| + removed_services.push_back(e.second);
|
| + }
|
| + }
|
| + for (auto identifier : removed_services) {
|
| + discovery_completed_included_services_.erase(identifier);
|
| + included_service_objects_.erase(identifier);
|
| + }
|
| + // Update previously known included services.
|
| + for (auto e : included_service_objects_)
|
| + e.second->Update();
|
| + }
|
| +
|
| + // Return if no new services have been added.
|
| + if (included_service_objects_.size() == num)
|
| + return;
|
| +
|
| + // Add new services.
|
| + for (auto e : current_services) {
|
| + if (known_services.find(e.first) == known_services.end()) {
|
| + BluetoothUUID uuid = task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(
|
| + services[e.second].ServiceUuid);
|
| + BluetoothRemoteGattServiceWin* service_object =
|
| + new BluetoothRemoteGattServiceWin(device_, service_path_, uuid,
|
| + services[e.second].AttributeHandle,
|
| + false, this, ui_task_runner_);
|
| + included_service_objects_.add(
|
| + service_object->GetIdentifier(),
|
| + scoped_ptr<BluetoothRemoteGattServiceWin>(service_object));
|
| + }
|
| + }
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::GetIncludedServicesCallback(
|
| + PBTH_LE_GATT_SERVICE services,
|
| + uint16_t num,
|
| + HRESULT hr) {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| + if (FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
|
| + return;
|
| + UpdateIncludedServices(services, num);
|
| + included_services_discovered_ = true;
|
| + NotifyServiceDiscComplIfNecessary();
|
| +}
|
| +
|
| +// Called by included service.
|
| +void BluetoothRemoteGattServiceWin::NotifyGattServiceAdded(
|
| + BluetoothRemoteGattServiceWin* service) {
|
| + discovery_completed_included_services_.insert(service->GetIdentifier());
|
| + NotifyServiceDiscComplIfNecessary();
|
| +}
|
| +
|
| +// Called by included characteristics.
|
| +void BluetoothRemoteGattServiceWin::NotifyGattCharacteristicAdded(
|
| + BluetoothRemoteGattCharacteristicWin* characteristic) {
|
| + discovery_completed_included_charateristics_.insert(
|
| + characteristic->GetIdentifier());
|
| + adapter_->NotifyGattCharacteristicAdded(characteristic);
|
| + NotifyServiceDiscComplIfNecessary();
|
| +}
|
| +
|
| +BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin(
|
| + BluetoothDeviceWin* device,
|
| + base::FilePath service_path,
|
| + BluetoothUUID service_uuid,
|
| + uint16_t service_attribute_handle,
|
| + bool is_primary,
|
| + BluetoothRemoteGattServiceWin* parent_service,
|
| + scoped_refptr<base::SequencedTaskRunner>& ui_task_runner)
|
| + : service_path_(service_path),
|
| + device_(device),
|
| + service_uuid_(service_uuid),
|
| + service_attribute_handle_(service_attribute_handle),
|
| + is_primary_(is_primary),
|
| + parent_service_(parent_service),
|
| + adapter_(nullptr),
|
| + task_manager_(nullptr),
|
| + complete_notified_(false),
|
| + included_services_discovered_(false),
|
| + included_characteristics_discovered_(false),
|
| + ui_task_runner_(ui_task_runner),
|
| + weak_ptr_factory_(this) {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| + discovery_completed_included_charateristics_.clear();
|
| + discovery_completed_included_services_.clear();
|
| + included_characteristic_objects_.clear();
|
| + included_service_objects_.clear();
|
| + adapter_ = const_cast<BluetoothAdapterWin*>(device_->GetAdapter());
|
| + task_manager_ = adapter_->GetWinBluetoothTaskManager();
|
| + DCHECK(device_);
|
| + if (!is_primary_)
|
| + DCHECK(parent_service_);
|
| + DCHECK(adapter_);
|
| + DCHECK(task_manager_);
|
| + Update();
|
| +}
|
| +
|
| +BluetoothRemoteGattServiceWin::~BluetoothRemoteGattServiceWin() {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| + included_service_objects_.clear();
|
| + included_characteristic_objects_.clear();
|
| + discovery_completed_included_charateristics_.clear();
|
| + discovery_completed_included_services_.clear();
|
| + included_services_discovered_ = false;
|
| + included_characteristics_discovered_ = false;
|
| +
|
| + // Only primary service notify adapter the service removed. The life cycle of
|
| + // included service is controlled by its parent service.
|
| + if (is_primary_)
|
| + adapter_->NotifyGattServiceRemoved(device_, this);
|
| +}
|
| +
|
| +std::string BluetoothRemoteGattServiceWin::GetIdentifier() const {
|
| + std::string identifier =
|
| + service_uuid_.value() + "_" + std::to_string(service_attribute_handle_);
|
| + if (is_primary_)
|
| + return device_->GetIdentifier() + "_" + identifier;
|
| + else
|
| + return parent_service_->GetIdentifier() + "_" + identifier;
|
| +}
|
| +
|
| +BluetoothUUID BluetoothRemoteGattServiceWin::GetUUID() const {
|
| + return const_cast<BluetoothUUID&>(service_uuid_);
|
| +}
|
| +
|
| +bool BluetoothRemoteGattServiceWin::IsLocal() const {
|
| + return false;
|
| +}
|
| +
|
| +bool BluetoothRemoteGattServiceWin::IsPrimary() const {
|
| + return is_primary_;
|
| +}
|
| +
|
| +BluetoothDevice* BluetoothRemoteGattServiceWin::GetDevice() const {
|
| + return device_;
|
| +}
|
| +
|
| +std::vector<BluetoothGattCharacteristic*>
|
| +BluetoothRemoteGattServiceWin::GetCharacteristics() const {
|
| + std::vector<BluetoothGattCharacteristic*> has_characteristics;
|
| + for (auto c : included_characteristic_objects_)
|
| + has_characteristics.push_back(c.second);
|
| + return has_characteristics;
|
| +}
|
| +
|
| +std::vector<BluetoothGattService*>
|
| +BluetoothRemoteGattServiceWin::GetIncludedServices() const {
|
| + std::vector<BluetoothGattService*> has_services;
|
| + for (auto s : included_service_objects_)
|
| + has_services.push_back(s.second);
|
| + return has_services;
|
| +}
|
| +
|
| +BluetoothGattCharacteristic* BluetoothRemoteGattServiceWin::GetCharacteristic(
|
| + const std::string& identifier) const {
|
| + GattCharacteristicsMap::const_iterator it =
|
| + included_characteristic_objects_.find(identifier);
|
| + if (it != included_characteristic_objects_.end())
|
| + return it->second;
|
| + return nullptr;
|
| +}
|
| +
|
| +bool BluetoothRemoteGattServiceWin::AddCharacteristic(
|
| + device::BluetoothGattCharacteristic* characteristic) {
|
| + NOTIMPLEMENTED();
|
| + return false;
|
| +}
|
| +
|
| +bool BluetoothRemoteGattServiceWin::AddIncludedService(
|
| + device::BluetoothGattService* service) {
|
| + NOTIMPLEMENTED();
|
| + return false;
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::Register(
|
| + const base::Closure& callback,
|
| + const ErrorCallback& error_callback) {
|
| + NOTIMPLEMENTED();
|
| + error_callback.Run();
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::Unregister(
|
| + const base::Closure& callback,
|
| + const ErrorCallback& error_callback) {
|
| + NOTIMPLEMENTED();
|
| + error_callback.Run();
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::Update() {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| +
|
| + task_manager_->PostGetGattIncludedServices(
|
| + service_path_, service_uuid_, service_attribute_handle_,
|
| + base::Bind(&BluetoothRemoteGattServiceWin::GetIncludedServicesCallback,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| + task_manager_->PostGetGattIncludedCharacteristics(
|
| + service_path_, service_uuid_, service_attribute_handle_,
|
| + base::Bind(
|
| + &BluetoothRemoteGattServiceWin::GetIncludedCharacteristicsCallback,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +} // namespace device.
|
|
|