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

Unified Diff: device/bluetooth/bluetooth_remote_gatt_service_win.cc

Issue 1606013002: BLE GATT service implementation in Chrome for Windows 8 and later (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update Build.gn Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
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.

Powered by Google App Engine
This is Rietveld 408576698