| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h" | 5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" |
| 10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 return nullptr; | 145 return nullptr; |
| 146 } | 146 } |
| 147 return static_cast<BluetoothRemoteGattDescriptor*>( | 147 return static_cast<BluetoothRemoteGattDescriptor*>( |
| 148 searched_pair->second.get()); | 148 searched_pair->second.get()); |
| 149 } | 149 } |
| 150 | 150 |
| 151 void BluetoothRemoteGattCharacteristicMac::ReadRemoteCharacteristic( | 151 void BluetoothRemoteGattCharacteristicMac::ReadRemoteCharacteristic( |
| 152 const ValueCallback& callback, | 152 const ValueCallback& callback, |
| 153 const ErrorCallback& error_callback) { | 153 const ErrorCallback& error_callback) { |
| 154 if (!IsReadable()) { | 154 if (!IsReadable()) { |
| 155 VLOG(1) << *this << ": Characteristic not readable."; |
| 155 base::ThreadTaskRunnerHandle::Get()->PostTask( | 156 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 156 FROM_HERE, | 157 FROM_HERE, |
| 157 base::Bind(error_callback, | 158 base::Bind(error_callback, |
| 158 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); | 159 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); |
| 159 return; | 160 return; |
| 160 } | 161 } |
| 161 if (characteristic_value_read_or_write_in_progress_) { | 162 if (characteristic_value_read_or_write_in_progress_) { |
| 163 VLOG(1) << *this << ": Characteristic read already in progress."; |
| 162 base::ThreadTaskRunnerHandle::Get()->PostTask( | 164 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 163 FROM_HERE, | 165 FROM_HERE, |
| 164 base::Bind(error_callback, | 166 base::Bind(error_callback, |
| 165 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); | 167 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); |
| 166 return; | 168 return; |
| 167 } | 169 } |
| 170 VLOG(1) << *this << ": Read characteristic."; |
| 168 characteristic_value_read_or_write_in_progress_ = true; | 171 characteristic_value_read_or_write_in_progress_ = true; |
| 169 read_characteristic_value_callbacks_ = | 172 read_characteristic_value_callbacks_ = |
| 170 std::make_pair(callback, error_callback); | 173 std::make_pair(callback, error_callback); |
| 171 [GetCBPeripheral() readValueForCharacteristic:cb_characteristic_]; | 174 [GetCBPeripheral() readValueForCharacteristic:cb_characteristic_]; |
| 172 } | 175 } |
| 173 | 176 |
| 174 void BluetoothRemoteGattCharacteristicMac::WriteRemoteCharacteristic( | 177 void BluetoothRemoteGattCharacteristicMac::WriteRemoteCharacteristic( |
| 175 const std::vector<uint8_t>& value, | 178 const std::vector<uint8_t>& value, |
| 176 const base::Closure& callback, | 179 const base::Closure& callback, |
| 177 const ErrorCallback& error_callback) { | 180 const ErrorCallback& error_callback) { |
| 178 if (!IsWritable()) { | 181 if (!IsWritable()) { |
| 182 VLOG(1) << *this << ": Characteristic not writable."; |
| 179 base::ThreadTaskRunnerHandle::Get()->PostTask( | 183 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 180 FROM_HERE, | 184 FROM_HERE, |
| 181 base::Bind(error_callback, | 185 base::Bind(error_callback, |
| 182 BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED)); | 186 BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED)); |
| 183 return; | 187 return; |
| 184 } | 188 } |
| 185 if (characteristic_value_read_or_write_in_progress_) { | 189 if (characteristic_value_read_or_write_in_progress_) { |
| 190 VLOG(1) << *this << ": Characteristic write already in progress."; |
| 186 base::ThreadTaskRunnerHandle::Get()->PostTask( | 191 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 187 FROM_HERE, | 192 FROM_HERE, |
| 188 base::Bind(error_callback, | 193 base::Bind(error_callback, |
| 189 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); | 194 BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS)); |
| 190 return; | 195 return; |
| 191 } | 196 } |
| 197 VLOG(1) << *this << ": Write characteristic."; |
| 192 characteristic_value_read_or_write_in_progress_ = true; | 198 characteristic_value_read_or_write_in_progress_ = true; |
| 193 write_characteristic_value_callbacks_ = | 199 write_characteristic_value_callbacks_ = |
| 194 std::make_pair(callback, error_callback); | 200 std::make_pair(callback, error_callback); |
| 195 base::scoped_nsobject<NSData> nsdata_value( | 201 base::scoped_nsobject<NSData> nsdata_value( |
| 196 [[NSData alloc] initWithBytes:value.data() length:value.size()]); | 202 [[NSData alloc] initWithBytes:value.data() length:value.size()]); |
| 197 CBCharacteristicWriteType write_type = GetCBWriteType(); | 203 CBCharacteristicWriteType write_type = GetCBWriteType(); |
| 198 [GetCBPeripheral() writeValue:nsdata_value | 204 [GetCBPeripheral() writeValue:nsdata_value |
| 199 forCharacteristic:cb_characteristic_ | 205 forCharacteristic:cb_characteristic_ |
| 200 type:write_type]; | 206 type:write_type]; |
| 201 if (write_type == CBCharacteristicWriteWithoutResponse) { | 207 if (write_type == CBCharacteristicWriteWithoutResponse) { |
| 202 base::ThreadTaskRunnerHandle::Get()->PostTask( | 208 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 203 FROM_HERE, | 209 FROM_HERE, |
| 204 base::Bind(&BluetoothRemoteGattCharacteristicMac::DidWriteValue, | 210 base::Bind(&BluetoothRemoteGattCharacteristicMac::DidWriteValue, |
| 205 base::Unretained(this), nil)); | 211 base::Unretained(this), nil)); |
| 206 } | 212 } |
| 207 } | 213 } |
| 208 | 214 |
| 209 void BluetoothRemoteGattCharacteristicMac::SubscribeToNotifications( | 215 void BluetoothRemoteGattCharacteristicMac::SubscribeToNotifications( |
| 210 BluetoothRemoteGattDescriptor* ccc_descriptor, | 216 BluetoothRemoteGattDescriptor* ccc_descriptor, |
| 211 const base::Closure& callback, | 217 const base::Closure& callback, |
| 212 const ErrorCallback& error_callback) { | 218 const ErrorCallback& error_callback) { |
| 219 VLOG(1) << *this << ": Subscribe to characteristic."; |
| 213 DCHECK(subscribe_to_notification_callbacks_.first.is_null()); | 220 DCHECK(subscribe_to_notification_callbacks_.first.is_null()); |
| 214 DCHECK(subscribe_to_notification_callbacks_.second.is_null()); | 221 DCHECK(subscribe_to_notification_callbacks_.second.is_null()); |
| 215 DCHECK(unsubscribe_from_notification_callbacks_.first.is_null()); | 222 DCHECK(unsubscribe_from_notification_callbacks_.first.is_null()); |
| 216 DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); | 223 DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); |
| 217 subscribe_to_notification_callbacks_ = | 224 subscribe_to_notification_callbacks_ = |
| 218 std::make_pair(callback, error_callback); | 225 std::make_pair(callback, error_callback); |
| 219 [GetCBPeripheral() setNotifyValue:YES | 226 [GetCBPeripheral() setNotifyValue:YES |
| 220 forCharacteristic:cb_characteristic_.get()]; | 227 forCharacteristic:cb_characteristic_.get()]; |
| 221 } | 228 } |
| 222 | 229 |
| 223 void BluetoothRemoteGattCharacteristicMac::UnsubscribeFromNotifications( | 230 void BluetoothRemoteGattCharacteristicMac::UnsubscribeFromNotifications( |
| 224 BluetoothRemoteGattDescriptor* ccc_descriptor, | 231 BluetoothRemoteGattDescriptor* ccc_descriptor, |
| 225 const base::Closure& callback, | 232 const base::Closure& callback, |
| 226 const ErrorCallback& error_callback) { | 233 const ErrorCallback& error_callback) { |
| 234 VLOG(1) << *this << ": Unsubscribe from characteristic."; |
| 227 DCHECK(subscribe_to_notification_callbacks_.first.is_null()); | 235 DCHECK(subscribe_to_notification_callbacks_.first.is_null()); |
| 228 DCHECK(subscribe_to_notification_callbacks_.second.is_null()); | 236 DCHECK(subscribe_to_notification_callbacks_.second.is_null()); |
| 229 DCHECK(unsubscribe_from_notification_callbacks_.first.is_null()); | 237 DCHECK(unsubscribe_from_notification_callbacks_.first.is_null()); |
| 230 DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); | 238 DCHECK(unsubscribe_from_notification_callbacks_.second.is_null()); |
| 231 unsubscribe_from_notification_callbacks_ = | 239 unsubscribe_from_notification_callbacks_ = |
| 232 std::make_pair(callback, error_callback); | 240 std::make_pair(callback, error_callback); |
| 233 [GetCBPeripheral() setNotifyValue:NO | 241 [GetCBPeripheral() setNotifyValue:NO |
| 234 forCharacteristic:cb_characteristic_.get()]; | 242 forCharacteristic:cb_characteristic_.get()]; |
| 235 } | 243 } |
| 236 | 244 |
| 237 void BluetoothRemoteGattCharacteristicMac::DiscoverDescriptors() { | 245 void BluetoothRemoteGattCharacteristicMac::DiscoverDescriptors() { |
| 246 VLOG(1) << *this << ": Discover descriptors."; |
| 238 is_discovery_complete_ = false; | 247 is_discovery_complete_ = false; |
| 239 [GetCBPeripheral() | 248 [GetCBPeripheral() |
| 240 discoverDescriptorsForCharacteristic:cb_characteristic_.get()]; | 249 discoverDescriptorsForCharacteristic:cb_characteristic_.get()]; |
| 241 } | 250 } |
| 242 | 251 |
| 243 void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) { | 252 void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) { |
| 244 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); | 253 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); |
| 245 // This method is called when the characteristic is read and when a | 254 // This method is called when the characteristic is read and when a |
| 246 // notification is received. | 255 // notification is received. |
| 247 if (characteristic_value_read_or_write_in_progress_) { | 256 if (characteristic_value_read_or_write_in_progress_) { |
| 248 std::pair<ValueCallback, ErrorCallback> callbacks; | 257 std::pair<ValueCallback, ErrorCallback> callbacks; |
| 249 callbacks.swap(read_characteristic_value_callbacks_); | 258 callbacks.swap(read_characteristic_value_callbacks_); |
| 250 characteristic_value_read_or_write_in_progress_ = false; | 259 characteristic_value_read_or_write_in_progress_ = false; |
| 251 if (error) { | 260 if (error) { |
| 252 VLOG(1) << "Bluetooth error while reading for characteristic, domain: " | 261 VLOG(1) << *this |
| 262 << ": Bluetooth error while reading for characteristic, domain: " |
| 253 << base::SysNSStringToUTF8(error.domain) | 263 << base::SysNSStringToUTF8(error.domain) |
| 254 << ", error code: " << error.code; | 264 << ", error code: " << error.code; |
| 255 BluetoothGattService::GattErrorCode error_code = | 265 BluetoothGattService::GattErrorCode error_code = |
| 256 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); | 266 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); |
| 257 callbacks.second.Run(error_code); | 267 callbacks.second.Run(error_code); |
| 258 return; | 268 return; |
| 259 } | 269 } |
| 270 VLOG(1) << *this << ": Read request arrived."; |
| 260 UpdateValue(); | 271 UpdateValue(); |
| 261 callbacks.first.Run(value_); | 272 callbacks.first.Run(value_); |
| 262 } else if (IsNotifying()) { | 273 } else if (IsNotifying()) { |
| 274 VLOG(1) << *this << ": Notification arrived."; |
| 263 UpdateValue(); | 275 UpdateValue(); |
| 264 gatt_service_->GetMacAdapter()->NotifyGattCharacteristicValueChanged( | 276 gatt_service_->GetMacAdapter()->NotifyGattCharacteristicValueChanged( |
| 265 this, value_); | 277 this, value_); |
| 266 } else { | 278 } else { |
| 267 // In case of buggy device, nothing should be done if receiving extra | 279 // In case of buggy device, nothing should be done if receiving extra |
| 268 // read confirmation. | 280 // read confirmation. |
| 269 VLOG(1) << "Characteristic value updated while having no pending read nor " | 281 VLOG(1) |
| 270 "notification."; | 282 << *this |
| 283 << ": Characteristic value updated while having no pending read nor " |
| 284 "notification."; |
| 271 } | 285 } |
| 272 } | 286 } |
| 273 | 287 |
| 274 void BluetoothRemoteGattCharacteristicMac::UpdateValue() { | 288 void BluetoothRemoteGattCharacteristicMac::UpdateValue() { |
| 275 NSData* nsdata_value = cb_characteristic_.get().value; | 289 NSData* nsdata_value = cb_characteristic_.get().value; |
| 276 const uint8_t* buffer = static_cast<const uint8_t*>(nsdata_value.bytes); | 290 const uint8_t* buffer = static_cast<const uint8_t*>(nsdata_value.bytes); |
| 277 value_.assign(buffer, buffer + nsdata_value.length); | 291 value_.assign(buffer, buffer + nsdata_value.length); |
| 278 } | 292 } |
| 279 | 293 |
| 280 void BluetoothRemoteGattCharacteristicMac::DidWriteValue(NSError* error) { | 294 void BluetoothRemoteGattCharacteristicMac::DidWriteValue(NSError* error) { |
| 281 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); | 295 CHECK_EQ(GetCBPeripheral().state, CBPeripheralStateConnected); |
| 282 if (!characteristic_value_read_or_write_in_progress_) { | 296 if (!characteristic_value_read_or_write_in_progress_) { |
| 283 // In case of buggy device, nothing should be done if receiving extra | 297 // In case of buggy device, nothing should be done if receiving extra |
| 284 // write confirmation. | 298 // write confirmation. |
| 285 VLOG(1) << "Write notification while no write operation pending."; | 299 VLOG(1) << *this |
| 300 << ": Write notification while no write operation pending."; |
| 286 return; | 301 return; |
| 287 } | 302 } |
| 288 std::pair<base::Closure, ErrorCallback> callbacks; | 303 std::pair<base::Closure, ErrorCallback> callbacks; |
| 289 callbacks.swap(write_characteristic_value_callbacks_); | 304 callbacks.swap(write_characteristic_value_callbacks_); |
| 290 characteristic_value_read_or_write_in_progress_ = false; | 305 characteristic_value_read_or_write_in_progress_ = false; |
| 291 if (error) { | 306 if (error) { |
| 292 VLOG(1) << "Bluetooth error while writing for characteristic, domain: " | 307 VLOG(1) << *this |
| 308 << ": Bluetooth error while writing for characteristic, domain: " |
| 293 << base::SysNSStringToUTF8(error.domain) | 309 << base::SysNSStringToUTF8(error.domain) |
| 294 << ", error code: " << error.code; | 310 << ", error code: " << error.code; |
| 295 BluetoothGattService::GattErrorCode error_code = | 311 BluetoothGattService::GattErrorCode error_code = |
| 296 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); | 312 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); |
| 297 callbacks.second.Run(error_code); | 313 callbacks.second.Run(error_code); |
| 298 return; | 314 return; |
| 299 } | 315 } |
| 316 VLOG(1) << *this << ": Write value succeeded."; |
| 300 callbacks.first.Run(); | 317 callbacks.first.Run(); |
| 301 } | 318 } |
| 302 | 319 |
| 303 void BluetoothRemoteGattCharacteristicMac::DidUpdateNotificationState( | 320 void BluetoothRemoteGattCharacteristicMac::DidUpdateNotificationState( |
| 304 NSError* error) { | 321 NSError* error) { |
| 305 PendingNotifyCallbacks reentrant_safe_callbacks; | 322 PendingNotifyCallbacks reentrant_safe_callbacks; |
| 306 if (!subscribe_to_notification_callbacks_.first.is_null()) { | 323 if (!subscribe_to_notification_callbacks_.first.is_null()) { |
| 307 DCHECK([GetCBCharacteristic() isNotifying] || error); | 324 DCHECK([GetCBCharacteristic() isNotifying] || error); |
| 308 reentrant_safe_callbacks.swap(subscribe_to_notification_callbacks_); | 325 reentrant_safe_callbacks.swap(subscribe_to_notification_callbacks_); |
| 309 } else if (!unsubscribe_from_notification_callbacks_.first.is_null()) { | 326 } else if (!unsubscribe_from_notification_callbacks_.first.is_null()) { |
| 310 DCHECK(![GetCBCharacteristic() isNotifying] || error); | 327 DCHECK(![GetCBCharacteristic() isNotifying] || error); |
| 311 reentrant_safe_callbacks.swap(unsubscribe_from_notification_callbacks_); | 328 reentrant_safe_callbacks.swap(unsubscribe_from_notification_callbacks_); |
| 312 } else { | 329 } else { |
| 313 VLOG(1) << "No pending notification update for characteristic " | 330 VLOG(1) << *this << ": No pending notification update for characteristic."; |
| 314 << GetUUID().value(); | |
| 315 return; | 331 return; |
| 316 } | 332 } |
| 317 if (error) { | 333 if (error) { |
| 318 VLOG(1) << "Bluetooth error while modifying notification state for " | 334 VLOG(1) << *this |
| 335 << ": Bluetooth error while modifying notification state for " |
| 319 "characteristic, domain: " | 336 "characteristic, domain: " |
| 320 << base::SysNSStringToUTF8(error.domain) | 337 << base::SysNSStringToUTF8(error.domain) |
| 321 << ", error code: " << error.code << ", localized description: " | 338 << ", error code: " << error.code << ", localized description: " |
| 322 << base::SysNSStringToUTF8(error.localizedDescription); | 339 << base::SysNSStringToUTF8(error.localizedDescription); |
| 323 BluetoothGattService::GattErrorCode error_code = | 340 BluetoothGattService::GattErrorCode error_code = |
| 324 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); | 341 BluetoothDeviceMac::GetGattErrorCodeFromNSError(error); |
| 325 reentrant_safe_callbacks.second.Run(error_code); | 342 reentrant_safe_callbacks.second.Run(error_code); |
| 326 return; | 343 return; |
| 327 } | 344 } |
| 328 reentrant_safe_callbacks.first.Run(); | 345 reentrant_safe_callbacks.first.Run(); |
| 329 } | 346 } |
| 330 | 347 |
| 331 void BluetoothRemoteGattCharacteristicMac::DidDiscoverDescriptors() { | 348 void BluetoothRemoteGattCharacteristicMac::DidDiscoverDescriptors() { |
| 332 DCHECK(!is_discovery_complete_); | 349 DCHECK(!is_discovery_complete_); |
| 350 VLOG(1) << *this << ": Did discover descriptors."; |
| 333 std::unordered_set<std::string> descriptor_identifier_to_remove; | 351 std::unordered_set<std::string> descriptor_identifier_to_remove; |
| 334 for (const auto& iter : gatt_descriptor_macs_) { | 352 for (const auto& iter : gatt_descriptor_macs_) { |
| 335 descriptor_identifier_to_remove.insert(iter.first); | 353 descriptor_identifier_to_remove.insert(iter.first); |
| 336 } | 354 } |
| 337 | 355 |
| 338 for (CBDescriptor* cb_descriptor in cb_characteristic_.get().descriptors) { | 356 for (CBDescriptor* cb_descriptor in cb_characteristic_.get().descriptors) { |
| 339 BluetoothRemoteGattDescriptorMac* gatt_descriptor_mac = | 357 BluetoothRemoteGattDescriptorMac* gatt_descriptor_mac = |
| 340 GetBluetoothRemoteGattDescriptorMac(cb_descriptor); | 358 GetBluetoothRemoteGattDescriptorMac(cb_descriptor); |
| 341 if (gatt_descriptor_mac) { | 359 if (gatt_descriptor_mac) { |
| 360 VLOG(1) << *gatt_descriptor_mac << ": Known descriptor."; |
| 342 const std::string& identifier = gatt_descriptor_mac->GetIdentifier(); | 361 const std::string& identifier = gatt_descriptor_mac->GetIdentifier(); |
| 343 descriptor_identifier_to_remove.erase(identifier); | 362 descriptor_identifier_to_remove.erase(identifier); |
| 344 continue; | 363 continue; |
| 345 } | 364 } |
| 346 gatt_descriptor_mac = | 365 gatt_descriptor_mac = |
| 347 new BluetoothRemoteGattDescriptorMac(this, cb_descriptor); | 366 new BluetoothRemoteGattDescriptorMac(this, cb_descriptor); |
| 348 const std::string& identifier = gatt_descriptor_mac->GetIdentifier(); | 367 const std::string& identifier = gatt_descriptor_mac->GetIdentifier(); |
| 349 auto result_iter = gatt_descriptor_macs_.insert( | 368 auto result_iter = gatt_descriptor_macs_.insert( |
| 350 {identifier, base::WrapUnique(gatt_descriptor_mac)}); | 369 {identifier, base::WrapUnique(gatt_descriptor_mac)}); |
| 351 DCHECK(result_iter.second); | 370 DCHECK(result_iter.second); |
| 352 GetMacAdapter()->NotifyGattDescriptorAdded(gatt_descriptor_mac); | 371 GetMacAdapter()->NotifyGattDescriptorAdded(gatt_descriptor_mac); |
| 372 VLOG(1) << *gatt_descriptor_mac << ": New descriptor."; |
| 353 } | 373 } |
| 354 | 374 |
| 355 for (const std::string& identifier : descriptor_identifier_to_remove) { | 375 for (const std::string& identifier : descriptor_identifier_to_remove) { |
| 356 auto pair_to_remove = gatt_descriptor_macs_.find(identifier); | 376 auto pair_to_remove = gatt_descriptor_macs_.find(identifier); |
| 357 std::unique_ptr<BluetoothRemoteGattDescriptorMac> descriptor_to_remove; | 377 std::unique_ptr<BluetoothRemoteGattDescriptorMac> descriptor_to_remove; |
| 378 VLOG(1) << *descriptor_to_remove << ": Removed descriptor."; |
| 358 pair_to_remove->second.swap(descriptor_to_remove); | 379 pair_to_remove->second.swap(descriptor_to_remove); |
| 359 gatt_descriptor_macs_.erase(pair_to_remove); | 380 gatt_descriptor_macs_.erase(pair_to_remove); |
| 360 GetMacAdapter()->NotifyGattDescriptorRemoved(descriptor_to_remove.get()); | 381 GetMacAdapter()->NotifyGattDescriptorRemoved(descriptor_to_remove.get()); |
| 361 } | 382 } |
| 362 is_discovery_complete_ = true; | 383 is_discovery_complete_ = true; |
| 363 } | 384 } |
| 364 | 385 |
| 365 bool BluetoothRemoteGattCharacteristicMac::IsReadable() const { | 386 bool BluetoothRemoteGattCharacteristicMac::IsReadable() const { |
| 366 return GetProperties() & BluetoothGattCharacteristic::PROPERTY_READ; | 387 return GetProperties() & BluetoothGattCharacteristic::PROPERTY_READ; |
| 367 } | 388 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 std::unique_ptr<BluetoothRemoteGattDescriptorMac>>& | 434 std::unique_ptr<BluetoothRemoteGattDescriptorMac>>& |
| 414 pair) { | 435 pair) { |
| 415 return pair.second->GetCBDescriptor() == cb_descriptor; | 436 return pair.second->GetCBDescriptor() == cb_descriptor; |
| 416 }); | 437 }); |
| 417 if (found == gatt_descriptor_macs_.end()) { | 438 if (found == gatt_descriptor_macs_.end()) { |
| 418 return nullptr; | 439 return nullptr; |
| 419 } else { | 440 } else { |
| 420 return found->second.get(); | 441 return found->second.get(); |
| 421 } | 442 } |
| 422 } | 443 } |
| 444 |
| 445 DEVICE_BLUETOOTH_EXPORT std::ostream& operator<<( |
| 446 std::ostream& out, |
| 447 const BluetoothRemoteGattCharacteristicMac& characteristic) { |
| 448 const BluetoothRemoteGattServiceMac* service_mac = |
| 449 static_cast<const BluetoothRemoteGattServiceMac*>( |
| 450 characteristic.GetService()); |
| 451 return out << "<BluetoothRemoteGattCharacteristicMac " |
| 452 << characteristic.GetUUID().canonical_value() << "/" |
| 453 << &characteristic |
| 454 << ", service: " << service_mac->GetUUID().canonical_value() << "/" |
| 455 << service_mac << ">"; |
| 456 } |
| 423 } // namespace device. | 457 } // namespace device. |
| OLD | NEW |