OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "device/bluetooth/bluetooth_remote_gatt_service_win.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 |
| 9 namespace device { |
| 10 |
| 11 void BluetoothRemoteGattServiceWin::NotifyServiceDiscComplIfNecessary() { |
| 12 if (discovery_completed_included_charateristics_.size() == |
| 13 included_characteristic_objects_.size() && |
| 14 discovery_completed_included_services_.size() == |
| 15 included_service_objects_.size() && |
| 16 included_services_discovered_ && included_characteristics_discovered_ && |
| 17 !complete_notified_) { |
| 18 if (is_primary_) |
| 19 adapter_->NotifyGattDiscoveryCompleteForService(this); |
| 20 else |
| 21 parent_service_->NotifyGattServiceAdded(this); |
| 22 complete_notified_ = true; |
| 23 } |
| 24 } |
| 25 |
| 26 void BluetoothRemoteGattServiceWin::UpdateIncludedCharacteristics( |
| 27 PBTH_LE_GATT_CHARACTERISTIC characteristics, |
| 28 uint16_t num) { |
| 29 if (num == 0) { |
| 30 discovery_completed_included_charateristics_.clear(); |
| 31 included_characteristic_objects_.clear(); |
| 32 return; |
| 33 } |
| 34 |
| 35 // Map of retreived characteristic uuid value to its index in |
| 36 // |characteristics|. |
| 37 std::map<std::string, uint16_t> current_characteristics; |
| 38 for (uint16_t i = 0; i < num; i++) { |
| 39 current_characteristics[task_manager_ |
| 40 ->BluetoothLowEnergyUuidToBluetoothUuid( |
| 41 characteristics[i].CharacteristicUuid) |
| 42 .value()] = i; |
| 43 } |
| 44 |
| 45 // Map of known characteristics uuid value to its identifier. |
| 46 std::map<std::string, std::string> known_characteristics; |
| 47 // Remove no longer existed characteristics first. |
| 48 if (included_characteristic_objects_.size() != 0) { |
| 49 for (auto e : included_characteristic_objects_) { |
| 50 known_characteristics[e.second->GetUUID().value()] = e.first; |
| 51 } |
| 52 std::vector<std::string> removed_characteristics; |
| 53 for (auto e : known_characteristics) { |
| 54 if (current_characteristics.find(e.first) == |
| 55 current_characteristics.end()) { |
| 56 removed_characteristics.push_back(e.second); |
| 57 } |
| 58 } |
| 59 for (auto identifier : removed_characteristics) { |
| 60 discovery_completed_included_charateristics_.erase(identifier); |
| 61 included_characteristic_objects_.erase(identifier); |
| 62 } |
| 63 // Update previously known characteristics. |
| 64 for (auto e : included_characteristic_objects_) |
| 65 e.second->Update(); |
| 66 } |
| 67 |
| 68 // Return if no new characteristics have been added. |
| 69 if (included_characteristic_objects_.size() == num) |
| 70 return; |
| 71 |
| 72 // Add new characteristics. |
| 73 for (auto e : current_characteristics) { |
| 74 if (known_characteristics.find(e.first) == known_characteristics.end()) { |
| 75 PBTH_LE_GATT_CHARACTERISTIC info = new BTH_LE_GATT_CHARACTERISTIC(); |
| 76 *info = characteristics[e.second]; |
| 77 BluetoothRemoteGattCharacteristicWin* characteristic_object = |
| 78 new BluetoothRemoteGattCharacteristicWin(this, info, ui_task_runner_); |
| 79 included_characteristic_objects_.add( |
| 80 characteristic_object->GetIdentifier(), |
| 81 scoped_ptr<BluetoothRemoteGattCharacteristicWin>( |
| 82 characteristic_object)); |
| 83 } |
| 84 } |
| 85 } |
| 86 |
| 87 void BluetoothRemoteGattServiceWin::GetIncludedCharacteristicsCallback( |
| 88 PBTH_LE_GATT_CHARACTERISTIC characteristics, |
| 89 uint16_t num, |
| 90 HRESULT hr) { |
| 91 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 92 if (FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) |
| 93 return; |
| 94 UpdateIncludedCharacteristics(characteristics, num); |
| 95 included_characteristics_discovered_ = true; |
| 96 NotifyServiceDiscComplIfNecessary(); |
| 97 } |
| 98 |
| 99 void BluetoothRemoteGattServiceWin::UpdateIncludedServices( |
| 100 PBTH_LE_GATT_SERVICE services, |
| 101 uint16_t num) { |
| 102 if (num == 0) { |
| 103 discovery_completed_included_services_.clear(); |
| 104 included_service_objects_.clear(); |
| 105 return; |
| 106 } |
| 107 |
| 108 // Map of retreived service uuid value to its index in |
| 109 // |services|. |
| 110 std::map<std::string, uint16_t> current_services; |
| 111 for (uint16_t i = 0; i < num; i++) { |
| 112 current_services[task_manager_->BluetoothLowEnergyUuidToBluetoothUuid( |
| 113 services[i].ServiceUuid) |
| 114 .value()] = i; |
| 115 } |
| 116 |
| 117 // Map of known services uuid value to its identifier. |
| 118 std::map<std::string, std::string> known_services; |
| 119 // Remove no longer existed services first. |
| 120 if (included_service_objects_.size() != 0) { |
| 121 for (auto e : included_service_objects_) { |
| 122 known_services[e.second->GetUUID().value()] = e.first; |
| 123 } |
| 124 std::vector<std::string> removed_services; |
| 125 for (auto e : known_services) { |
| 126 if (current_services.find(e.first) == current_services.end()) { |
| 127 removed_services.push_back(e.second); |
| 128 } |
| 129 } |
| 130 for (auto identifier : removed_services) { |
| 131 discovery_completed_included_services_.erase(identifier); |
| 132 included_service_objects_.erase(identifier); |
| 133 } |
| 134 // Update previously known included services. |
| 135 for (auto e : included_service_objects_) |
| 136 e.second->Update(); |
| 137 } |
| 138 |
| 139 // Return if no new services have been added. |
| 140 if (included_service_objects_.size() == num) |
| 141 return; |
| 142 |
| 143 // Add new services. |
| 144 for (auto e : current_services) { |
| 145 if (known_services.find(e.first) == known_services.end()) { |
| 146 BluetoothUUID uuid = task_manager_->BluetoothLowEnergyUuidToBluetoothUuid( |
| 147 services[e.second].ServiceUuid); |
| 148 BluetoothRemoteGattServiceWin* service_object = |
| 149 new BluetoothRemoteGattServiceWin(device_, service_path_, uuid, |
| 150 services[e.second].AttributeHandle, |
| 151 false, this, ui_task_runner_); |
| 152 included_service_objects_.add( |
| 153 service_object->GetIdentifier(), |
| 154 scoped_ptr<BluetoothRemoteGattServiceWin>(service_object)); |
| 155 } |
| 156 } |
| 157 } |
| 158 |
| 159 void BluetoothRemoteGattServiceWin::GetIncludedServicesCallback( |
| 160 PBTH_LE_GATT_SERVICE services, |
| 161 uint16_t num, |
| 162 HRESULT hr) { |
| 163 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 164 if (FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) |
| 165 return; |
| 166 UpdateIncludedServices(services, num); |
| 167 included_services_discovered_ = true; |
| 168 NotifyServiceDiscComplIfNecessary(); |
| 169 } |
| 170 |
| 171 // Called by included service. |
| 172 void BluetoothRemoteGattServiceWin::NotifyGattServiceAdded( |
| 173 BluetoothRemoteGattServiceWin* service) { |
| 174 discovery_completed_included_services_.insert(service->GetIdentifier()); |
| 175 NotifyServiceDiscComplIfNecessary(); |
| 176 } |
| 177 |
| 178 // Called by included characteristics. |
| 179 void BluetoothRemoteGattServiceWin::NotifyGattCharacteristicAdded( |
| 180 BluetoothRemoteGattCharacteristicWin* characteristic) { |
| 181 discovery_completed_included_charateristics_.insert( |
| 182 characteristic->GetIdentifier()); |
| 183 adapter_->NotifyGattCharacteristicAdded(characteristic); |
| 184 NotifyServiceDiscComplIfNecessary(); |
| 185 } |
| 186 |
| 187 BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin( |
| 188 BluetoothDeviceWin* device, |
| 189 base::FilePath service_path, |
| 190 BluetoothUUID service_uuid, |
| 191 uint16_t service_attribute_handle, |
| 192 bool is_primary, |
| 193 BluetoothRemoteGattServiceWin* parent_service, |
| 194 scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) |
| 195 : service_path_(service_path), |
| 196 device_(device), |
| 197 service_uuid_(service_uuid), |
| 198 service_attribute_handle_(service_attribute_handle), |
| 199 is_primary_(is_primary), |
| 200 parent_service_(parent_service), |
| 201 adapter_(nullptr), |
| 202 task_manager_(nullptr), |
| 203 complete_notified_(false), |
| 204 included_services_discovered_(false), |
| 205 included_characteristics_discovered_(false), |
| 206 ui_task_runner_(ui_task_runner), |
| 207 weak_ptr_factory_(this) { |
| 208 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 209 discovery_completed_included_charateristics_.clear(); |
| 210 discovery_completed_included_services_.clear(); |
| 211 included_characteristic_objects_.clear(); |
| 212 included_service_objects_.clear(); |
| 213 adapter_ = const_cast<BluetoothAdapterWin*>(device_->GetAdapter()); |
| 214 task_manager_ = adapter_->GetWinBluetoothTaskManager(); |
| 215 DCHECK(device_); |
| 216 if (!is_primary_) |
| 217 DCHECK(parent_service_); |
| 218 DCHECK(adapter_); |
| 219 DCHECK(task_manager_); |
| 220 Update(); |
| 221 } |
| 222 |
| 223 BluetoothRemoteGattServiceWin::~BluetoothRemoteGattServiceWin() { |
| 224 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 225 included_service_objects_.clear(); |
| 226 included_characteristic_objects_.clear(); |
| 227 discovery_completed_included_charateristics_.clear(); |
| 228 discovery_completed_included_services_.clear(); |
| 229 included_services_discovered_ = false; |
| 230 included_characteristics_discovered_ = false; |
| 231 |
| 232 // Only primary service notify adapter the service removed. The life cycle of |
| 233 // included service is controlled by its parent service. |
| 234 if (is_primary_) |
| 235 adapter_->NotifyGattServiceRemoved(device_, this); |
| 236 } |
| 237 |
| 238 std::string BluetoothRemoteGattServiceWin::GetIdentifier() const { |
| 239 std::string identifier = |
| 240 service_uuid_.value() + "_" + std::to_string(service_attribute_handle_); |
| 241 if (is_primary_) |
| 242 return device_->GetIdentifier() + "_" + identifier; |
| 243 else |
| 244 return parent_service_->GetIdentifier() + "_" + identifier; |
| 245 } |
| 246 |
| 247 BluetoothUUID BluetoothRemoteGattServiceWin::GetUUID() const { |
| 248 return const_cast<BluetoothUUID&>(service_uuid_); |
| 249 } |
| 250 |
| 251 bool BluetoothRemoteGattServiceWin::IsLocal() const { |
| 252 return false; |
| 253 } |
| 254 |
| 255 bool BluetoothRemoteGattServiceWin::IsPrimary() const { |
| 256 return is_primary_; |
| 257 } |
| 258 |
| 259 BluetoothDevice* BluetoothRemoteGattServiceWin::GetDevice() const { |
| 260 return device_; |
| 261 } |
| 262 |
| 263 std::vector<BluetoothGattCharacteristic*> |
| 264 BluetoothRemoteGattServiceWin::GetCharacteristics() const { |
| 265 std::vector<BluetoothGattCharacteristic*> has_characteristics; |
| 266 for (auto c : included_characteristic_objects_) |
| 267 has_characteristics.push_back(c.second); |
| 268 return has_characteristics; |
| 269 } |
| 270 |
| 271 std::vector<BluetoothGattService*> |
| 272 BluetoothRemoteGattServiceWin::GetIncludedServices() const { |
| 273 std::vector<BluetoothGattService*> has_services; |
| 274 for (auto s : included_service_objects_) |
| 275 has_services.push_back(s.second); |
| 276 return has_services; |
| 277 } |
| 278 |
| 279 BluetoothGattCharacteristic* BluetoothRemoteGattServiceWin::GetCharacteristic( |
| 280 const std::string& identifier) const { |
| 281 GattCharacteristicsMap::const_iterator it = |
| 282 included_characteristic_objects_.find(identifier); |
| 283 if (it != included_characteristic_objects_.end()) |
| 284 return it->second; |
| 285 return nullptr; |
| 286 } |
| 287 |
| 288 bool BluetoothRemoteGattServiceWin::AddCharacteristic( |
| 289 device::BluetoothGattCharacteristic* characteristic) { |
| 290 NOTIMPLEMENTED(); |
| 291 return false; |
| 292 } |
| 293 |
| 294 bool BluetoothRemoteGattServiceWin::AddIncludedService( |
| 295 device::BluetoothGattService* service) { |
| 296 NOTIMPLEMENTED(); |
| 297 return false; |
| 298 } |
| 299 |
| 300 void BluetoothRemoteGattServiceWin::Register( |
| 301 const base::Closure& callback, |
| 302 const ErrorCallback& error_callback) { |
| 303 NOTIMPLEMENTED(); |
| 304 error_callback.Run(); |
| 305 } |
| 306 |
| 307 void BluetoothRemoteGattServiceWin::Unregister( |
| 308 const base::Closure& callback, |
| 309 const ErrorCallback& error_callback) { |
| 310 NOTIMPLEMENTED(); |
| 311 error_callback.Run(); |
| 312 } |
| 313 |
| 314 void BluetoothRemoteGattServiceWin::Update() { |
| 315 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 316 |
| 317 task_manager_->PostGetGattIncludedServices( |
| 318 service_path_, service_uuid_, service_attribute_handle_, |
| 319 base::Bind(&BluetoothRemoteGattServiceWin::GetIncludedServicesCallback, |
| 320 weak_ptr_factory_.GetWeakPtr())); |
| 321 task_manager_->PostGetGattIncludedCharacteristics( |
| 322 service_path_, service_uuid_, service_attribute_handle_, |
| 323 base::Bind( |
| 324 &BluetoothRemoteGattServiceWin::GetIncludedCharacteristicsCallback, |
| 325 weak_ptr_factory_.GetWeakPtr())); |
| 326 } |
| 327 |
| 328 } // namespace device. |
OLD | NEW |