summaryrefslogtreecommitdiffstats
path: root/device/bluetooth/bluetooth_remote_gatt_service_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'device/bluetooth/bluetooth_remote_gatt_service_win.cc')
-rw-r--r--device/bluetooth/bluetooth_remote_gatt_service_win.cc171
1 files changed, 157 insertions, 14 deletions
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_win.cc b/device/bluetooth/bluetooth_remote_gatt_service_win.cc
index 7021703..19064eb 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_win.cc
+++ b/device/bluetooth/bluetooth_remote_gatt_service_win.cc
@@ -4,7 +4,14 @@
#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 {
+
BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin(
BluetoothDeviceWin* device,
base::FilePath service_path,
@@ -19,7 +26,10 @@ BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin(
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),
+ included_characteristics_discovered_(false),
+ weak_ptr_factory_(this) {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
DCHECK(!service_path_.empty());
DCHECK(service_uuid_.IsValid());
@@ -27,18 +37,24 @@ 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_);
+ service_identifier_ = device_->GetIdentifier() + "/" + service_uuid_.value() +
+ "_" + std::to_string(service_attribute_handle_);
Update();
}
-BluetoothRemoteGattServiceWin::~BluetoothRemoteGattServiceWin() {}
+BluetoothRemoteGattServiceWin::~BluetoothRemoteGattServiceWin() {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+
+ adapter_->NotifyGattServiceRemoved(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;
+ return service_identifier_;
}
BluetoothUUID BluetoothRemoteGattServiceWin::GetUUID() const {
@@ -59,19 +75,25 @@ BluetoothDevice* BluetoothRemoteGattServiceWin::GetDevice() const {
std::vector<BluetoothGattCharacteristic*>
BluetoothRemoteGattServiceWin::GetCharacteristics() const {
- NOTIMPLEMENTED();
- return std::vector<BluetoothGattCharacteristic*>();
+ std::vector<BluetoothGattCharacteristic*> has_characteristics;
+ for (const auto& c : included_characteristics_)
+ has_characteristics.push_back(c.second.get());
+ return has_characteristics;
}
std::vector<BluetoothGattService*>
BluetoothRemoteGattServiceWin::GetIncludedServices() const {
NOTIMPLEMENTED();
+ // TODO(crbug.com/590008): Needs implementation.
return std::vector<BluetoothGattService*>();
}
BluetoothGattCharacteristic* BluetoothRemoteGattServiceWin::GetCharacteristic(
const std::string& identifier) const {
- NOTIMPLEMENTED();
+ GattCharacteristicsMap::const_iterator it =
+ included_characteristics_.find(identifier);
+ if (it != included_characteristics_.end())
+ return it->second.get();
return nullptr;
}
@@ -101,13 +123,134 @@ void BluetoothRemoteGattServiceWin::Unregister(
error_callback.Run();
}
+void BluetoothRemoteGattServiceWin::GattCharacteristicDiscoveryComplete(
+ BluetoothRemoteGattCharacteristicWin* characteristic) {
+ DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
+ DCHECK(included_characteristics_.find(characteristic->GetIdentifier()) !=
+ included_characteristics_.end());
+
+ discovery_completed_included_charateristics_.insert(
+ characteristic->GetIdentifier());
+ adapter_->NotifyGattCharacteristicAdded(characteristic);
+ NotifyGattDiscoveryCompleteForServiceIfNecessary();
+}
+
void BluetoothRemoteGattServiceWin::Update() {
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
- NOTIMPLEMENTED();
+
+ task_manager_->PostGetGattIncludedCharacteristics(
+ service_path_, service_uuid_, service_attribute_handle_,
+ base::Bind(&BluetoothRemoteGattServiceWin::OnGetIncludedCharacteristics,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void BluetoothRemoteGattServiceWin::OnGetIncludedCharacteristics(
+ 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;
+ NotifyGattDiscoveryCompleteForServiceIfNecessary();
+}
+
+void BluetoothRemoteGattServiceWin::UpdateIncludedCharacteristics(
+ PBTH_LE_GATT_CHARACTERISTIC characteristics,
+ uint16_t num) {
+ if (num == 0) {
+ if (included_characteristics_.size() > 0) {
+ ClearIncludedCharacteristics();
+ adapter_->NotifyGattServiceChanged(this);
+ }
+ return;
+ }
+
+ // First, remove characteristics that no longer exist.
+ std::vector<std::string> to_be_removed;
+ for (const auto& c : included_characteristics_) {
+ if (!DoesCharacteristicExist(characteristics, num, c.second.get()))
+ to_be_removed.push_back(c.second->GetIdentifier());
+ }
+ for (const auto& id : to_be_removed) {
+ RemoveIncludedCharacteristic(id);
+ }
+
+ // Update previously known characteristics.
+ for (auto& c : included_characteristics_)
+ c.second->Update();
+
+ // Return if no new characteristics have been added.
+ if (included_characteristics_.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_characteristics_[characteristic_object->GetIdentifier()] =
+ make_scoped_ptr(characteristic_object);
+ }
+ }
+
+ if (included_characteristics_discovered_)
+ adapter_->NotifyGattServiceChanged(this);
+}
+
+void BluetoothRemoteGattServiceWin::
+ NotifyGattDiscoveryCompleteForServiceIfNecessary() {
+ if (discovery_completed_included_charateristics_.size() ==
+ included_characteristics_.size() &&
+ included_characteristics_discovered_ && !discovery_complete_notified_) {
+ adapter_->NotifyGattDiscoveryComplete(this);
+ discovery_complete_notified_ = true;
+ }
+}
+
+bool BluetoothRemoteGattServiceWin::IsCharacteristicDiscovered(
+ BTH_LE_UUID& uuid,
+ uint16_t attribute_handle) {
+ BluetoothUUID bt_uuid =
+ BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid(uuid);
+ for (const auto& c : included_characteristics_) {
+ if (bt_uuid == c.second->GetUUID() &&
+ attribute_handle == c.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 =
+ BluetoothTaskManagerWin::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_characteristics_.erase(identifier);
}
-uint16_t BluetoothRemoteGattServiceWin::GetAttributeHandle() {
- return service_attribute_handle_;
+void BluetoothRemoteGattServiceWin::ClearIncludedCharacteristics() {
+ discovery_completed_included_charateristics_.clear();
+ included_characteristics_.clear();
}
} // namespace device.