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_win.h" | 5 #include "device/bluetooth/bluetooth_remote_gatt_characteristic_win.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 | 51 |
52 if (gatt_event_handle_ != nullptr) { | 52 if (gatt_event_handle_ != nullptr) { |
53 task_manager_->PostUnregisterGattCharacteristicValueChangedEvent( | 53 task_manager_->PostUnregisterGattCharacteristicValueChangedEvent( |
54 gatt_event_handle_); | 54 gatt_event_handle_); |
55 gatt_event_handle_ = nullptr; | 55 gatt_event_handle_ = nullptr; |
56 } | 56 } |
57 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this); | 57 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this); |
58 | 58 |
59 // Clear pending StartNotifySession callbacks. | 59 // Clear pending StartNotifySession callbacks. |
60 for (const auto& callback : start_notify_session_callbacks_) | 60 for (const auto& callback : start_notify_session_callbacks_) |
61 callback.second.Run(BluetoothGattService::GATT_ERROR_FAILED); | 61 callback.second.Run(BluetoothRemoteGattService::GATT_ERROR_FAILED); |
62 } | 62 } |
63 | 63 |
64 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const { | 64 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const { |
65 return characteristic_identifier_; | 65 return characteristic_identifier_; |
66 } | 66 } |
67 | 67 |
68 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const { | 68 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const { |
69 return characteristic_uuid_; | 69 return characteristic_uuid_; |
70 } | 70 } |
71 | 71 |
72 bool BluetoothRemoteGattCharacteristicWin::IsLocal() const { | |
73 return false; | |
74 } | |
75 | |
76 std::vector<uint8_t>& BluetoothRemoteGattCharacteristicWin::GetValue() const { | 72 std::vector<uint8_t>& BluetoothRemoteGattCharacteristicWin::GetValue() const { |
77 return const_cast<std::vector<uint8_t>&>(characteristic_value_); | 73 return const_cast<std::vector<uint8_t>&>(characteristic_value_); |
78 } | 74 } |
79 | 75 |
80 BluetoothGattService* BluetoothRemoteGattCharacteristicWin::GetService() const { | 76 BluetoothRemoteGattService* BluetoothRemoteGattCharacteristicWin::GetService() |
| 77 const { |
81 return parent_service_; | 78 return parent_service_; |
82 } | 79 } |
83 | 80 |
84 BluetoothGattCharacteristic::Properties | 81 BluetoothRemoteGattCharacteristic::Properties |
85 BluetoothRemoteGattCharacteristicWin::GetProperties() const { | 82 BluetoothRemoteGattCharacteristicWin::GetProperties() const { |
86 BluetoothGattCharacteristic::Properties properties = PROPERTY_NONE; | 83 BluetoothRemoteGattCharacteristic::Properties properties = PROPERTY_NONE; |
87 | 84 |
88 if (characteristic_info_->IsBroadcastable) | 85 if (characteristic_info_->IsBroadcastable) |
89 properties = properties | PROPERTY_BROADCAST; | 86 properties = properties | PROPERTY_BROADCAST; |
90 if (characteristic_info_->IsReadable) | 87 if (characteristic_info_->IsReadable) |
91 properties = properties | PROPERTY_READ; | 88 properties = properties | PROPERTY_READ; |
92 if (characteristic_info_->IsWritableWithoutResponse) | 89 if (characteristic_info_->IsWritableWithoutResponse) |
93 properties = properties | PROPERTY_WRITE_WITHOUT_RESPONSE; | 90 properties = properties | PROPERTY_WRITE_WITHOUT_RESPONSE; |
94 if (characteristic_info_->IsWritable) | 91 if (characteristic_info_->IsWritable) |
95 properties = properties | PROPERTY_WRITE; | 92 properties = properties | PROPERTY_WRITE; |
96 if (characteristic_info_->IsNotifiable) | 93 if (characteristic_info_->IsNotifiable) |
97 properties = properties | PROPERTY_NOTIFY; | 94 properties = properties | PROPERTY_NOTIFY; |
98 if (characteristic_info_->IsIndicatable) | 95 if (characteristic_info_->IsIndicatable) |
99 properties = properties | PROPERTY_INDICATE; | 96 properties = properties | PROPERTY_INDICATE; |
100 if (characteristic_info_->IsSignedWritable) | 97 if (characteristic_info_->IsSignedWritable) |
101 properties = properties | PROPERTY_AUTHENTICATED_SIGNED_WRITES; | 98 properties = properties | PROPERTY_AUTHENTICATED_SIGNED_WRITES; |
102 if (characteristic_info_->HasExtendedProperties) | 99 if (characteristic_info_->HasExtendedProperties) |
103 properties = properties | PROPERTY_EXTENDED_PROPERTIES; | 100 properties = properties | PROPERTY_EXTENDED_PROPERTIES; |
104 | 101 |
105 // TODO(crbug.com/589304): Information about PROPERTY_RELIABLE_WRITE and | 102 // TODO(crbug.com/589304): Information about PROPERTY_RELIABLE_WRITE and |
106 // PROPERTY_WRITABLE_AUXILIARIES is not available in characteristic_info_ | 103 // PROPERTY_WRITABLE_AUXILIARIES is not available in characteristic_info_ |
107 // (BTH_LE_GATT_CHARACTERISTIC). | 104 // (BTH_LE_GATT_CHARACTERISTIC). |
108 | 105 |
109 return properties; | 106 return properties; |
110 } | 107 } |
111 | 108 |
112 BluetoothGattCharacteristic::Permissions | 109 BluetoothRemoteGattCharacteristic::Permissions |
113 BluetoothRemoteGattCharacteristicWin::GetPermissions() const { | 110 BluetoothRemoteGattCharacteristicWin::GetPermissions() const { |
114 BluetoothGattCharacteristic::Permissions permissions = PERMISSION_NONE; | 111 BluetoothRemoteGattCharacteristic::Permissions permissions = PERMISSION_NONE; |
115 | 112 |
116 if (characteristic_info_->IsReadable) | 113 if (characteristic_info_->IsReadable) |
117 permissions = permissions | PERMISSION_READ; | 114 permissions = permissions | PERMISSION_READ; |
118 if (characteristic_info_->IsWritable) | 115 if (characteristic_info_->IsWritable) |
119 permissions = permissions | PERMISSION_WRITE; | 116 permissions = permissions | PERMISSION_WRITE; |
120 | 117 |
121 return permissions; | 118 return permissions; |
122 } | 119 } |
123 | 120 |
124 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const { | 121 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const { |
125 return gatt_event_handle_ != nullptr; | 122 return gatt_event_handle_ != nullptr; |
126 } | 123 } |
127 | 124 |
128 std::vector<BluetoothGattDescriptor*> | 125 std::vector<BluetoothRemoteGattDescriptor*> |
129 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const { | 126 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const { |
130 std::vector<BluetoothGattDescriptor*> descriptors; | 127 std::vector<BluetoothRemoteGattDescriptor*> descriptors; |
131 for (const auto& descriptor : included_descriptors_) | 128 for (const auto& descriptor : included_descriptors_) |
132 descriptors.push_back(descriptor.second.get()); | 129 descriptors.push_back(descriptor.second.get()); |
133 return descriptors; | 130 return descriptors; |
134 } | 131 } |
135 | 132 |
136 BluetoothGattDescriptor* BluetoothRemoteGattCharacteristicWin::GetDescriptor( | 133 BluetoothRemoteGattDescriptor* |
| 134 BluetoothRemoteGattCharacteristicWin::GetDescriptor( |
137 const std::string& identifier) const { | 135 const std::string& identifier) const { |
138 GattDescriptorMap::const_iterator it = included_descriptors_.find(identifier); | 136 GattDescriptorMap::const_iterator it = included_descriptors_.find(identifier); |
139 if (it != included_descriptors_.end()) | 137 if (it != included_descriptors_.end()) |
140 return it->second.get(); | 138 return it->second.get(); |
141 return nullptr; | 139 return nullptr; |
142 } | 140 } |
143 | 141 |
144 bool BluetoothRemoteGattCharacteristicWin::AddDescriptor( | |
145 BluetoothGattDescriptor* descriptor) { | |
146 NOTIMPLEMENTED(); | |
147 return false; | |
148 } | |
149 | |
150 bool BluetoothRemoteGattCharacteristicWin::UpdateValue( | |
151 const std::vector<uint8_t>& value) { | |
152 NOTIMPLEMENTED(); | |
153 return false; | |
154 } | |
155 | |
156 void BluetoothRemoteGattCharacteristicWin::StartNotifySession( | 142 void BluetoothRemoteGattCharacteristicWin::StartNotifySession( |
157 const NotifySessionCallback& callback, | 143 const NotifySessionCallback& callback, |
158 const ErrorCallback& error_callback) { | 144 const ErrorCallback& error_callback) { |
159 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 145 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
160 | 146 |
161 if (IsNotifying()) { | 147 if (IsNotifying()) { |
162 std::unique_ptr<BluetoothGattNotifySessionWin> notify_session( | 148 std::unique_ptr<BluetoothGattNotifySessionWin> notify_session( |
163 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr())); | 149 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr())); |
164 ui_task_runner_->PostTask( | 150 ui_task_runner_->PostTask( |
165 FROM_HERE, | 151 FROM_HERE, |
166 base::Bind(callback, base::Passed(std::move(notify_session)))); | 152 base::Bind(callback, base::Passed(std::move(notify_session)))); |
167 return; | 153 return; |
168 } | 154 } |
169 | 155 |
170 if (!characteristic_info_->IsNotifiable && | 156 if (!characteristic_info_->IsNotifiable && |
171 !characteristic_info_->IsIndicatable) { | 157 !characteristic_info_->IsIndicatable) { |
172 ui_task_runner_->PostTask( | 158 ui_task_runner_->PostTask( |
173 FROM_HERE, base::Bind(error_callback, | 159 FROM_HERE, |
174 BluetoothGattService::GATT_ERROR_NOT_SUPPORTED)); | 160 base::Bind(error_callback, |
| 161 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); |
175 return; | 162 return; |
176 } | 163 } |
177 | 164 |
178 std::vector<BluetoothGattDescriptor*> ccc_descriptors = GetDescriptorsByUUID( | 165 std::vector<BluetoothRemoteGattDescriptor*> ccc_descriptors = |
179 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()); | 166 GetDescriptorsByUUID(BluetoothRemoteGattDescriptor:: |
| 167 ClientCharacteristicConfigurationUuid()); |
180 if (ccc_descriptors.size() < 1) { | 168 if (ccc_descriptors.size() < 1) { |
181 ui_task_runner_->PostTask( | 169 ui_task_runner_->PostTask( |
182 FROM_HERE, base::Bind(error_callback, | 170 FROM_HERE, |
183 BluetoothGattService::GATT_ERROR_NOT_SUPPORTED)); | 171 base::Bind(error_callback, |
| 172 BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED)); |
184 return; | 173 return; |
185 } | 174 } |
186 if (ccc_descriptors.size() > 1) { | 175 if (ccc_descriptors.size() > 1) { |
187 ui_task_runner_->PostTask( | 176 ui_task_runner_->PostTask( |
188 FROM_HERE, | 177 FROM_HERE, base::Bind(error_callback, |
189 base::Bind(error_callback, BluetoothGattService::GATT_ERROR_FAILED)); | 178 BluetoothRemoteGattService::GATT_ERROR_FAILED)); |
190 return; | 179 return; |
191 } | 180 } |
192 | 181 |
193 start_notify_session_callbacks_.push_back( | 182 start_notify_session_callbacks_.push_back( |
194 std::make_pair(callback, error_callback)); | 183 std::make_pair(callback, error_callback)); |
195 if (gatt_event_registeration_in_progress_) | 184 if (gatt_event_registeration_in_progress_) |
196 return; | 185 return; |
197 | 186 |
198 task_manager_->PostRegisterGattCharacteristicValueChangedEvent( | 187 task_manager_->PostRegisterGattCharacteristicValueChangedEvent( |
199 parent_service_->GetServicePath(), characteristic_info_.get(), | 188 parent_service_->GetServicePath(), characteristic_info_.get(), |
200 static_cast<BluetoothRemoteGattDescriptorWin*>(ccc_descriptors[0]) | 189 static_cast<BluetoothRemoteGattDescriptorWin*>(ccc_descriptors[0]) |
201 ->GetWinDescriptorInfo(), | 190 ->GetWinDescriptorInfo(), |
202 base::Bind( | 191 base::Bind( |
203 &BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback, | 192 &BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback, |
204 weak_ptr_factory_.GetWeakPtr()), | 193 weak_ptr_factory_.GetWeakPtr()), |
205 base::Bind(&BluetoothRemoteGattCharacteristicWin:: | 194 base::Bind(&BluetoothRemoteGattCharacteristicWin:: |
206 OnGattCharacteristicValueChanged, | 195 OnGattCharacteristicValueChanged, |
207 weak_ptr_factory_.GetWeakPtr())); | 196 weak_ptr_factory_.GetWeakPtr())); |
208 gatt_event_registeration_in_progress_ = true; | 197 gatt_event_registeration_in_progress_ = true; |
209 } | 198 } |
210 | 199 |
211 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( | 200 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( |
212 const ValueCallback& callback, | 201 const ValueCallback& callback, |
213 const ErrorCallback& error_callback) { | 202 const ErrorCallback& error_callback) { |
214 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 203 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
215 | 204 |
216 if (!characteristic_info_.get()->IsReadable) { | 205 if (!characteristic_info_.get()->IsReadable) { |
217 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); | 206 error_callback.Run(BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED); |
218 return; | 207 return; |
219 } | 208 } |
220 | 209 |
221 if (characteristic_value_read_or_write_in_progress_) { | 210 if (characteristic_value_read_or_write_in_progress_) { |
222 error_callback.Run(BluetoothGattService::GATT_ERROR_IN_PROGRESS); | 211 error_callback.Run(BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS); |
223 return; | 212 return; |
224 } | 213 } |
225 | 214 |
226 characteristic_value_read_or_write_in_progress_ = true; | 215 characteristic_value_read_or_write_in_progress_ = true; |
227 read_characteristic_value_callbacks_ = | 216 read_characteristic_value_callbacks_ = |
228 std::make_pair(callback, error_callback); | 217 std::make_pair(callback, error_callback); |
229 task_manager_->PostReadGattCharacteristicValue( | 218 task_manager_->PostReadGattCharacteristicValue( |
230 parent_service_->GetServicePath(), characteristic_info_.get(), | 219 parent_service_->GetServicePath(), characteristic_info_.get(), |
231 base::Bind(&BluetoothRemoteGattCharacteristicWin:: | 220 base::Bind(&BluetoothRemoteGattCharacteristicWin:: |
232 OnReadRemoteCharacteristicValueCallback, | 221 OnReadRemoteCharacteristicValueCallback, |
233 weak_ptr_factory_.GetWeakPtr())); | 222 weak_ptr_factory_.GetWeakPtr())); |
234 } | 223 } |
235 | 224 |
236 void BluetoothRemoteGattCharacteristicWin::WriteRemoteCharacteristic( | 225 void BluetoothRemoteGattCharacteristicWin::WriteRemoteCharacteristic( |
237 const std::vector<uint8_t>& new_value, | 226 const std::vector<uint8_t>& new_value, |
238 const base::Closure& callback, | 227 const base::Closure& callback, |
239 const ErrorCallback& error_callback) { | 228 const ErrorCallback& error_callback) { |
240 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 229 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
241 | 230 |
242 if (!characteristic_info_.get()->IsWritable) { | 231 if (!characteristic_info_.get()->IsWritable) { |
243 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); | 232 error_callback.Run(BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED); |
244 return; | 233 return; |
245 } | 234 } |
246 | 235 |
247 if (characteristic_value_read_or_write_in_progress_) { | 236 if (characteristic_value_read_or_write_in_progress_) { |
248 error_callback.Run(BluetoothGattService::GATT_ERROR_IN_PROGRESS); | 237 error_callback.Run(BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS); |
249 return; | 238 return; |
250 } | 239 } |
251 | 240 |
252 characteristic_value_read_or_write_in_progress_ = true; | 241 characteristic_value_read_or_write_in_progress_ = true; |
253 write_characteristic_value_callbacks_ = | 242 write_characteristic_value_callbacks_ = |
254 std::make_pair(callback, error_callback); | 243 std::make_pair(callback, error_callback); |
255 task_manager_->PostWriteGattCharacteristicValue( | 244 task_manager_->PostWriteGattCharacteristicValue( |
256 parent_service_->GetServicePath(), characteristic_info_.get(), new_value, | 245 parent_service_->GetServicePath(), characteristic_info_.get(), new_value, |
257 base::Bind(&BluetoothRemoteGattCharacteristicWin:: | 246 base::Bind(&BluetoothRemoteGattCharacteristicWin:: |
258 OnWriteRemoteCharacteristicValueCallback, | 247 OnWriteRemoteCharacteristicValueCallback, |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 std::pair<base::Closure, ErrorCallback> callbacks; | 370 std::pair<base::Closure, ErrorCallback> callbacks; |
382 callbacks.swap(write_characteristic_value_callbacks_); | 371 callbacks.swap(write_characteristic_value_callbacks_); |
383 if (FAILED(hr)) { | 372 if (FAILED(hr)) { |
384 callbacks.second.Run(HRESULTToGattErrorCode(hr)); | 373 callbacks.second.Run(HRESULTToGattErrorCode(hr)); |
385 } else { | 374 } else { |
386 callbacks.first.Run(); | 375 callbacks.first.Run(); |
387 } | 376 } |
388 characteristic_value_read_or_write_in_progress_ = false; | 377 characteristic_value_read_or_write_in_progress_ = false; |
389 } | 378 } |
390 | 379 |
391 BluetoothGattService::GattErrorCode | 380 BluetoothRemoteGattService::GattErrorCode |
392 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { | 381 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { |
393 if (HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER) == hr) | 382 if (HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER) == hr) |
394 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; | 383 return BluetoothRemoteGattService::GATT_ERROR_INVALID_LENGTH; |
395 | 384 |
396 switch (hr) { | 385 switch (hr) { |
397 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: | 386 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: |
398 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: | 387 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: |
399 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; | 388 return BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED; |
400 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: | 389 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: |
401 return BluetoothGattService::GATT_ERROR_UNKNOWN; | 390 return BluetoothRemoteGattService::GATT_ERROR_UNKNOWN; |
402 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: | 391 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: |
403 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; | 392 return BluetoothRemoteGattService::GATT_ERROR_INVALID_LENGTH; |
404 case E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED: | 393 case E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED: |
405 return BluetoothGattService::GATT_ERROR_NOT_SUPPORTED; | 394 return BluetoothRemoteGattService::GATT_ERROR_NOT_SUPPORTED; |
406 default: | 395 default: |
407 return BluetoothGattService::GATT_ERROR_FAILED; | 396 return BluetoothRemoteGattService::GATT_ERROR_FAILED; |
408 } | 397 } |
409 } | 398 } |
410 | 399 |
411 void BluetoothRemoteGattCharacteristicWin::OnGattCharacteristicValueChanged( | 400 void BluetoothRemoteGattCharacteristicWin::OnGattCharacteristicValueChanged( |
412 std::unique_ptr<std::vector<uint8_t>> new_value) { | 401 std::unique_ptr<std::vector<uint8_t>> new_value) { |
413 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 402 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
414 | 403 |
415 characteristic_value_.assign(new_value->begin(), new_value->end()); | 404 characteristic_value_.assign(new_value->begin(), new_value->end()); |
416 parent_service_->GetWinAdapter()->NotifyGattCharacteristicValueChanged( | 405 parent_service_->GetWinAdapter()->NotifyGattCharacteristicValueChanged( |
417 this, characteristic_value_); | 406 this, characteristic_value_); |
(...skipping 21 matching lines...) Expand all Loading... |
439 | 428 |
440 void BluetoothRemoteGattCharacteristicWin::ClearIncludedDescriptors() { | 429 void BluetoothRemoteGattCharacteristicWin::ClearIncludedDescriptors() { |
441 // Explicitly reset to null to ensure that calling GetDescriptor() on the | 430 // Explicitly reset to null to ensure that calling GetDescriptor() on the |
442 // removed descriptor in GattDescriptorRemoved() returns null. | 431 // removed descriptor in GattDescriptorRemoved() returns null. |
443 for (auto& entry : included_descriptors_) | 432 for (auto& entry : included_descriptors_) |
444 entry.second.reset(); | 433 entry.second.reset(); |
445 included_descriptors_.clear(); | 434 included_descriptors_.clear(); |
446 } | 435 } |
447 | 436 |
448 } // namespace device. | 437 } // namespace device. |
OLD | NEW |