| 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
|
| index 0c93588b92d7d7f67b7968a5ec26145569265331..5e22f90458402404a569ef1017d329222142d4ee 100644
|
| --- a/device/bluetooth/bluetooth_remote_gatt_service_win.cc
|
| +++ b/device/bluetooth/bluetooth_remote_gatt_service_win.cc
|
| @@ -4,7 +4,233 @@
|
|
|
| #include "device/bluetooth/bluetooth_remote_gatt_service_win.h"
|
|
|
| +#include "base/bind.h"
|
| +#include "device/bluetooth/bluetooth_adapter_win.h"
|
| +#include "device/bluetooth/bluetooth_device_win.h"
|
| +#include "device/bluetooth/bluetooth_remote_gatt_characteristic_win.h"
|
| +#include "device/bluetooth/bluetooth_task_manager_win.h"
|
| +
|
| namespace device {
|
| +
|
| +void BluetoothRemoteGattServiceWin::NotifyServiceDiscComplIfNecessary() {
|
| + if (discovery_completed_included_charateristics_.size() ==
|
| + included_characteristic_.size() &&
|
| + discovery_completed_included_services_.size() ==
|
| + included_service_.size() &&
|
| + included_services_discovered_ && included_characteristics_discovered_ &&
|
| + !discovery_complete_notified_) {
|
| + if (is_primary_)
|
| + adapter_->NotifyGattDiscoveryComplete(this);
|
| + else
|
| + parent_service_->GattServiceDiscoverComplete(this);
|
| + discovery_complete_notified_ = true;
|
| + }
|
| +}
|
| +
|
| +bool BluetoothRemoteGattServiceWin::IsCharacteristicDiscovered(
|
| + BTH_LE_UUID& uuid,
|
| + uint16_t attribute_handle) {
|
| + BluetoothUUID bt_uuid =
|
| + task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(uuid);
|
| + for (const auto& cha : included_characteristic_) {
|
| + if (bt_uuid == cha.second->GetUUID() &&
|
| + attribute_handle == cha.second->GetAttributeHandle()) {
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool BluetoothRemoteGattServiceWin::DoesCharacteristicExist(
|
| + PBTH_LE_GATT_CHARACTERISTIC characteristics,
|
| + uint16_t num,
|
| + BluetoothRemoteGattCharacteristicWin* characteristic) {
|
| + for (uint16_t i = 0; i < num; i++) {
|
| + BluetoothUUID uuid = task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(
|
| + characteristics[i].CharacteristicUuid);
|
| + if (characteristic->GetUUID() == uuid &&
|
| + characteristic->GetAttributeHandle() ==
|
| + characteristics[i].AttributeHandle) {
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::RemoveIncludedCharacteristic(
|
| + std::string identifier) {
|
| + discovery_completed_included_charateristics_.erase(identifier);
|
| + included_characteristic_.erase(identifier);
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::ClearIncludedCharacteristics() {
|
| + discovery_completed_included_charateristics_.clear();
|
| + included_characteristic_.clear();
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::UpdateIncludedCharacteristics(
|
| + PBTH_LE_GATT_CHARACTERISTIC characteristics,
|
| + uint16_t num) {
|
| + if (num == 0) {
|
| + ClearIncludedCharacteristics();
|
| + return;
|
| + }
|
| +
|
| + // First, remove no longer existed characteristics.
|
| + std::vector<std::string> to_be_removed;
|
| + for (const auto& cha : included_characteristic_) {
|
| + if (!DoesCharacteristicExist(characteristics, num, cha.second.get()))
|
| + to_be_removed.push_back(cha.second->GetIdentifier());
|
| + }
|
| + for (auto id : to_be_removed) {
|
| + RemoveIncludedCharacteristic(id);
|
| + }
|
| +
|
| + // Update previously known characteristics.
|
| + for (auto& cha : included_characteristic_)
|
| + cha.second->Update();
|
| +
|
| + // Return if no new characteristics have been added.
|
| + if (included_characteristic_.size() == num)
|
| + return;
|
| +
|
| + // Add new characteristics.
|
| + for (uint16_t i = 0; i < num; i++) {
|
| + if (!IsCharacteristicDiscovered(characteristics[i].CharacteristicUuid,
|
| + characteristics[i].AttributeHandle)) {
|
| + PBTH_LE_GATT_CHARACTERISTIC info = new BTH_LE_GATT_CHARACTERISTIC();
|
| + *info = characteristics[i];
|
| + BluetoothRemoteGattCharacteristicWin* characteristic_object =
|
| + new BluetoothRemoteGattCharacteristicWin(this, info, ui_task_runner_);
|
| + included_characteristic_[characteristic_object->GetIdentifier()] =
|
| + make_scoped_ptr(characteristic_object);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::GetIncludedCharacteristicsCallback(
|
| + scoped_ptr<BTH_LE_GATT_CHARACTERISTIC> characteristics,
|
| + uint16_t num,
|
| + HRESULT hr) {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| +
|
| + UpdateIncludedCharacteristics(characteristics.get(), num);
|
| + included_characteristics_discovered_ = true;
|
| + NotifyServiceDiscComplIfNecessary();
|
| +}
|
| +
|
| +bool BluetoothRemoteGattServiceWin::IsServiceDiscovered(
|
| + BluetoothUUID& uuid,
|
| + uint16_t attribute_handle) {
|
| + for (const auto& ser : included_service_) {
|
| + if (uuid == ser.second->GetUUID() &&
|
| + attribute_handle == ser.second->GetAttributeHandle()) {
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool BluetoothRemoteGattServiceWin::DoesServiceExist(
|
| + PBTH_LE_GATT_SERVICE services,
|
| + uint16_t num,
|
| + BluetoothRemoteGattServiceWin* service) {
|
| + for (uint16_t i = 0; i < num; i++) {
|
| + BluetoothUUID uuid = task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(
|
| + services[i].ServiceUuid);
|
| + if (service->GetUUID() == uuid &&
|
| + service->GetAttributeHandle() == services[i].AttributeHandle) {
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::RemoveIncludedService(
|
| + std::string identifier) {
|
| + discovery_completed_included_services_.erase(identifier);
|
| + included_service_.erase(identifier);
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::ClearIncludedServices() {
|
| + discovery_completed_included_services_.clear();
|
| + included_service_.clear();
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::UpdateIncludedServices(
|
| + PBTH_LE_GATT_SERVICE services,
|
| + uint16_t num) {
|
| + if (num == 0) {
|
| + ClearIncludedServices();
|
| + return;
|
| + }
|
| +
|
| + // First, remove no longer exist included service.
|
| + std::vector<std::string> to_be_removed;
|
| + for (const auto& ser : included_service_) {
|
| + if (!DoesServiceExist(services, num, ser.second.get())) {
|
| + to_be_removed.push_back(ser.second->GetIdentifier());
|
| + }
|
| + }
|
| + for (auto id : to_be_removed)
|
| + RemoveIncludedService(id);
|
| +
|
| + // Update previously known included services.
|
| + for (auto& ser : included_service_)
|
| + ser.second->Update();
|
| +
|
| + // Return if no new services have been added.
|
| + if (included_service_.size() == num)
|
| + return;
|
| +
|
| + // Add new services.
|
| + for (uint16_t i = 0; i < num; i++) {
|
| + BluetoothUUID uuid = task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(
|
| + services[i].ServiceUuid);
|
| + if (!IsServiceDiscovered(uuid, services[i].AttributeHandle)) {
|
| + BluetoothRemoteGattServiceWin* service_object =
|
| + new BluetoothRemoteGattServiceWin(device_, service_path_, uuid,
|
| + services[i].AttributeHandle, false,
|
| + this, ui_task_runner_);
|
| + included_service_[service_object->GetIdentifier()] =
|
| + make_scoped_ptr(service_object);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::GetIncludedServicesCallback(
|
| + scoped_ptr<BTH_LE_GATT_SERVICE> services,
|
| + uint16_t num,
|
| + HRESULT hr) {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| +
|
| + UpdateIncludedServices(services.get(), num);
|
| + included_services_discovered_ = true;
|
| + NotifyServiceDiscComplIfNecessary();
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::GattServiceDiscoverComplete(
|
| + BluetoothRemoteGattServiceWin* service) {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| + DCHECK(included_service_.find(service->GetIdentifier()) !=
|
| + included_service_.end());
|
| +
|
| + discovery_completed_included_services_.insert(service->GetIdentifier());
|
| + NotifyServiceDiscComplIfNecessary();
|
| +}
|
| +
|
| +void BluetoothRemoteGattServiceWin::GattCharacteristicDiscoverComplete(
|
| + BluetoothRemoteGattCharacteristicWin* characteristic) {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| + DCHECK(included_characteristic_.find(characteristic->GetIdentifier()) !=
|
| + included_characteristic_.end());
|
| +
|
| + discovery_completed_included_charateristics_.insert(
|
| + characteristic->GetIdentifier());
|
| + adapter_->NotifyGattCharacteristicAdded(characteristic);
|
| + NotifyServiceDiscComplIfNecessary();
|
| +}
|
| +
|
| BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin(
|
| BluetoothDeviceWin* device,
|
| base::FilePath service_path,
|
| @@ -13,13 +239,15 @@ BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin(
|
| bool is_primary,
|
| BluetoothRemoteGattServiceWin* parent_service,
|
| scoped_refptr<base::SequencedTaskRunner>& ui_task_runner)
|
| - : service_path_(service_path),
|
| - device_(device),
|
| + : device_(device),
|
| + service_path_(service_path),
|
| service_uuid_(service_uuid),
|
| service_attribute_handle_(service_attribute_handle),
|
| is_primary_(is_primary),
|
| parent_service_(parent_service),
|
| - ui_task_runner_(ui_task_runner) {
|
| + ui_task_runner_(ui_task_runner),
|
| + discovery_complete_notified_(false),
|
| + weak_ptr_factory_(this) {
|
| DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| DCHECK(!service_path_.empty());
|
| DCHECK(service_uuid_.IsValid());
|
| @@ -27,10 +255,21 @@ BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin(
|
| DCHECK(device_);
|
| if (!is_primary_)
|
| DCHECK(parent_service_);
|
| + adapter_ = static_cast<BluetoothAdapterWin*>(device_->GetAdapter());
|
| + DCHECK(adapter_);
|
| + task_manager_ = adapter_->GetWinBluetoothTaskManager();
|
| + DCHECK(task_manager_);
|
| +
|
| Update();
|
| }
|
|
|
| -BluetoothRemoteGattServiceWin::~BluetoothRemoteGattServiceWin() {}
|
| +BluetoothRemoteGattServiceWin::~BluetoothRemoteGattServiceWin() {
|
| + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| +
|
| + // Only notify adapter for primary service.
|
| + if (is_primary_)
|
| + adapter_->NotifyGattServiceRemoved(this);
|
| +}
|
|
|
| std::string BluetoothRemoteGattServiceWin::GetIdentifier() const {
|
| std::string identifier =
|
| @@ -59,19 +298,26 @@ BluetoothDevice* BluetoothRemoteGattServiceWin::GetDevice() const {
|
|
|
| std::vector<BluetoothGattCharacteristic*>
|
| BluetoothRemoteGattServiceWin::GetCharacteristics() const {
|
| - NOTIMPLEMENTED();
|
| - return std::vector<BluetoothGattCharacteristic*>();
|
| + std::vector<BluetoothGattCharacteristic*> has_characteristics;
|
| + for (const auto& cha : included_characteristic_)
|
| + has_characteristics.push_back(cha.second.get());
|
| + return has_characteristics;
|
| }
|
|
|
| std::vector<BluetoothGattService*>
|
| BluetoothRemoteGattServiceWin::GetIncludedServices() const {
|
| - NOTIMPLEMENTED();
|
| - return std::vector<BluetoothGattService*>();
|
| + std::vector<BluetoothGattService*> has_services;
|
| + for (const auto& ser : included_service_)
|
| + has_services.push_back(ser.second.get());
|
| + return has_services;
|
| }
|
|
|
| BluetoothGattCharacteristic* BluetoothRemoteGattServiceWin::GetCharacteristic(
|
| const std::string& identifier) const {
|
| - NOTIMPLEMENTED();
|
| + GattCharacteristicsMap::const_iterator it =
|
| + included_characteristic_.find(identifier);
|
| + if (it != included_characteristic_.end())
|
| + return it->second.get();
|
| return nullptr;
|
| }
|
|
|
| @@ -103,11 +349,16 @@ void BluetoothRemoteGattServiceWin::Unregister(
|
|
|
| void BluetoothRemoteGattServiceWin::Update() {
|
| DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
| - NOTIMPLEMENTED();
|
| -}
|
|
|
| -uint16_t BluetoothRemoteGattServiceWin::GetAttributeHandle() {
|
| - return service_attribute_handle_;
|
| + 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.
|
| +} // namespace device.
|
|
|