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 |