Chromium Code Reviews| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "device/bluetooth/bluetooth_adapter_win.h" | 8 #include "device/bluetooth/bluetooth_adapter_win.h" |
| 9 #include "device/bluetooth/bluetooth_gatt_notify_session_win.h" | |
| 9 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_win.h" | 10 #include "device/bluetooth/bluetooth_remote_gatt_descriptor_win.h" |
| 10 #include "device/bluetooth/bluetooth_remote_gatt_service_win.h" | 11 #include "device/bluetooth/bluetooth_remote_gatt_service_win.h" |
| 11 #include "device/bluetooth/bluetooth_task_manager_win.h" | 12 #include "device/bluetooth/bluetooth_task_manager_win.h" |
| 12 | 13 |
| 14 namespace { | |
| 15 | |
| 16 // Function to be registered to OS to monitor Bluetooth LE GATT event. | |
| 17 void OnGetGattEventWin(BTH_LE_GATT_EVENT_TYPE type, | |
| 18 PVOID event_parameter, | |
| 19 PVOID context) { | |
| 20 device::BluetoothRemoteGattCharacteristicWin* characteristic = | |
| 21 (device::BluetoothRemoteGattCharacteristicWin*)context; | |
| 22 characteristic->OnGetRemoteGattEvent(type, event_parameter); | |
| 23 } | |
| 24 | |
| 25 } // namespace | |
| 26 | |
| 13 namespace device { | 27 namespace device { |
| 14 | 28 |
| 15 BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin( | 29 BluetoothRemoteGattCharacteristicWin::BluetoothRemoteGattCharacteristicWin( |
| 16 BluetoothRemoteGattServiceWin* parent_service, | 30 BluetoothRemoteGattServiceWin* parent_service, |
| 17 BTH_LE_GATT_CHARACTERISTIC* characteristic_info, | 31 BTH_LE_GATT_CHARACTERISTIC* characteristic_info, |
| 18 scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) | 32 scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) |
| 19 : parent_service_(parent_service), | 33 : parent_service_(parent_service), |
| 20 characteristic_info_(characteristic_info), | 34 characteristic_info_(characteristic_info), |
| 21 ui_task_runner_(ui_task_runner), | 35 ui_task_runner_(ui_task_runner), |
| 22 characteristic_added_notified_(false), | 36 characteristic_added_notified_(false), |
| 23 characteristic_value_read_or_write_in_progress_(false), | 37 characteristic_value_read_or_write_in_progress_(false), |
| 38 number_of_active_notify_sessions_(0), | |
| 39 gatt_event_registeration_in_progress_(false), | |
| 40 gatt_event_handle_(NULL), | |
| 24 weak_ptr_factory_(this) { | 41 weak_ptr_factory_(this) { |
| 25 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 42 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 26 DCHECK(parent_service_); | 43 DCHECK(parent_service_); |
| 27 DCHECK(characteristic_info_); | 44 DCHECK(characteristic_info_); |
| 28 | 45 |
| 29 task_manager_ = | 46 task_manager_ = |
| 30 parent_service_->GetWinAdapter()->GetWinBluetoothTaskManager(); | 47 parent_service_->GetWinAdapter()->GetWinBluetoothTaskManager(); |
| 31 DCHECK(task_manager_); | 48 DCHECK(task_manager_); |
| 32 characteristic_uuid_ = | 49 characteristic_uuid_ = |
| 33 BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid( | 50 BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid( |
| 34 characteristic_info_->CharacteristicUuid); | 51 characteristic_info_->CharacteristicUuid); |
| 35 characteristic_identifier_ = | 52 characteristic_identifier_ = |
| 36 parent_service_->GetIdentifier() + "_" + | 53 parent_service_->GetIdentifier() + "_" + |
| 37 std::to_string(characteristic_info_->AttributeHandle); | 54 std::to_string(characteristic_info_->AttributeHandle); |
| 38 Update(); | 55 Update(); |
| 39 } | 56 } |
| 40 | 57 |
| 41 BluetoothRemoteGattCharacteristicWin::~BluetoothRemoteGattCharacteristicWin() { | 58 BluetoothRemoteGattCharacteristicWin::~BluetoothRemoteGattCharacteristicWin() { |
| 42 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 59 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 43 | 60 |
| 61 if (gatt_event_handle_ != NULL) { | |
| 62 task_manager_->UnregisterGattCharacteristicValueChangedEvent( | |
| 63 gatt_event_handle_); | |
| 64 gatt_event_handle_ = NULL; | |
| 65 } | |
| 44 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this); | 66 parent_service_->GetWinAdapter()->NotifyGattCharacteristicRemoved(this); |
| 45 } | 67 } |
| 46 | 68 |
| 47 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const { | 69 std::string BluetoothRemoteGattCharacteristicWin::GetIdentifier() const { |
| 48 return characteristic_identifier_; | 70 return characteristic_identifier_; |
| 49 } | 71 } |
| 50 | 72 |
| 51 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const { | 73 BluetoothUUID BluetoothRemoteGattCharacteristicWin::GetUUID() const { |
| 52 return characteristic_uuid_; | 74 return characteristic_uuid_; |
| 53 } | 75 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 | 120 |
| 99 if (characteristic_info_->IsReadable) | 121 if (characteristic_info_->IsReadable) |
| 100 permissions = permissions | PERMISSION_READ; | 122 permissions = permissions | PERMISSION_READ; |
| 101 if (characteristic_info_->IsWritable) | 123 if (characteristic_info_->IsWritable) |
| 102 permissions = permissions | PERMISSION_WRITE; | 124 permissions = permissions | PERMISSION_WRITE; |
| 103 | 125 |
| 104 return permissions; | 126 return permissions; |
| 105 } | 127 } |
| 106 | 128 |
| 107 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const { | 129 bool BluetoothRemoteGattCharacteristicWin::IsNotifying() const { |
| 108 NOTIMPLEMENTED(); | 130 return gatt_event_handle_ != NULL; |
| 109 return false; | |
| 110 } | 131 } |
| 111 | 132 |
| 112 std::vector<BluetoothGattDescriptor*> | 133 std::vector<BluetoothGattDescriptor*> |
| 113 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const { | 134 BluetoothRemoteGattCharacteristicWin::GetDescriptors() const { |
| 114 std::vector<BluetoothGattDescriptor*> descriptors; | 135 std::vector<BluetoothGattDescriptor*> descriptors; |
| 115 for (const auto& descriptor : included_descriptors_) | 136 for (const auto& descriptor : included_descriptors_) |
| 116 descriptors.push_back(descriptor.second.get()); | 137 descriptors.push_back(descriptor.second.get()); |
| 117 return descriptors; | 138 return descriptors; |
| 118 } | 139 } |
| 119 | 140 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 133 | 154 |
| 134 bool BluetoothRemoteGattCharacteristicWin::UpdateValue( | 155 bool BluetoothRemoteGattCharacteristicWin::UpdateValue( |
| 135 const std::vector<uint8_t>& value) { | 156 const std::vector<uint8_t>& value) { |
| 136 NOTIMPLEMENTED(); | 157 NOTIMPLEMENTED(); |
| 137 return false; | 158 return false; |
| 138 } | 159 } |
| 139 | 160 |
| 140 void BluetoothRemoteGattCharacteristicWin::StartNotifySession( | 161 void BluetoothRemoteGattCharacteristicWin::StartNotifySession( |
| 141 const NotifySessionCallback& callback, | 162 const NotifySessionCallback& callback, |
| 142 const ErrorCallback& error_callback) { | 163 const ErrorCallback& error_callback) { |
| 143 NOTIMPLEMENTED(); | 164 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 144 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_SUPPORTED); | 165 |
| 166 if (IsNotifying()) { | |
| 167 scoped_ptr<BluetoothGattNotifySessionWin> notify_session( | |
| 168 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr())); | |
| 169 ui_task_runner_->PostTask( | |
| 170 FROM_HERE, | |
| 171 base::Bind(callback, base::Passed(std::move(notify_session)))); | |
| 172 number_of_active_notify_sessions_++; | |
| 173 return; | |
| 174 } | |
| 175 | |
| 176 if (gatt_event_registeration_in_progress_) { | |
| 177 start_notify_session_callbacks_.push_back( | |
| 178 std::make_pair(callback, error_callback)); | |
| 179 return; | |
| 180 } | |
| 181 | |
|
ortuno
2016/03/09 16:54:00
You should check that the characteristic supports
gogerald1
2016/03/09 23:59:12
Done.
| |
| 182 start_notify_session_callbacks_.push_back( | |
| 183 std::make_pair(callback, error_callback)); | |
| 184 task_manager_->PostRegisterGattCharacteristicValueChangedEvent( | |
| 185 parent_service_->GetServicePath(), characteristic_info_.get(), | |
| 186 base::Bind( | |
| 187 &BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback, | |
| 188 weak_ptr_factory_.GetWeakPtr()), | |
| 189 &OnGetGattEventWin, (PVOID) this); | |
| 190 gatt_event_registeration_in_progress_ = true; | |
| 145 } | 191 } |
| 146 | 192 |
| 147 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( | 193 void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( |
| 148 const ValueCallback& callback, | 194 const ValueCallback& callback, |
| 149 const ErrorCallback& error_callback) { | 195 const ErrorCallback& error_callback) { |
| 150 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 196 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 151 | 197 |
| 152 if (!characteristic_info_.get()->IsReadable) { | 198 if (!characteristic_info_.get()->IsReadable) { |
| 153 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); | 199 error_callback.Run(BluetoothGattService::GATT_ERROR_NOT_PERMITTED); |
| 154 return; | 200 return; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 characteristic_value_read_or_write_in_progress_ = true; | 234 characteristic_value_read_or_write_in_progress_ = true; |
| 189 write_characteristic_value_callbacks_ = | 235 write_characteristic_value_callbacks_ = |
| 190 std::make_pair(callback, error_callback); | 236 std::make_pair(callback, error_callback); |
| 191 task_manager_->PostWriteGattCharacteristicValue( | 237 task_manager_->PostWriteGattCharacteristicValue( |
| 192 parent_service_->GetServicePath(), characteristic_info_.get(), new_value, | 238 parent_service_->GetServicePath(), characteristic_info_.get(), new_value, |
| 193 base::Bind(&BluetoothRemoteGattCharacteristicWin:: | 239 base::Bind(&BluetoothRemoteGattCharacteristicWin:: |
| 194 OnWriteRemoteCharacteristicValueCallback, | 240 OnWriteRemoteCharacteristicValueCallback, |
| 195 weak_ptr_factory_.GetWeakPtr())); | 241 weak_ptr_factory_.GetWeakPtr())); |
| 196 } | 242 } |
| 197 | 243 |
| 244 void BluetoothRemoteGattCharacteristicWin::OnGetRemoteGattEvent( | |
| 245 BTH_LE_GATT_EVENT_TYPE type, | |
| 246 PVOID event_parameter) { | |
| 247 if (type == CharacteristicValueChangedEvent) { | |
| 248 BLUETOOTH_GATT_VALUE_CHANGED_EVENT* event = | |
| 249 (BLUETOOTH_GATT_VALUE_CHANGED_EVENT*)event_parameter; | |
| 250 PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value_win = | |
| 251 event->CharacteristicValue; | |
| 252 scoped_ptr<std::vector<uint8_t>> new_value( | |
| 253 new std::vector<uint8_t>(new_value_win->DataSize)); | |
| 254 for (ULONG i = 0; i < new_value_win->DataSize; i++) | |
| 255 new_value->at(i) = new_value_win->Data[i]; | |
| 256 | |
| 257 ui_task_runner_->PostTask(FROM_HERE, | |
| 258 base::Bind(&BluetoothRemoteGattCharacteristicWin:: | |
| 259 OnGattCharacteristicValueChanged, | |
| 260 weak_ptr_factory_.GetWeakPtr(), | |
| 261 base::Passed(std::move(new_value)))); | |
| 262 return; | |
| 263 } | |
| 264 NOTREACHED(); | |
| 265 } | |
| 266 | |
| 198 void BluetoothRemoteGattCharacteristicWin::Update() { | 267 void BluetoothRemoteGattCharacteristicWin::Update() { |
| 199 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 268 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 200 | 269 |
| 201 task_manager_->PostGetGattIncludedDescriptors( | 270 task_manager_->PostGetGattIncludedDescriptors( |
| 202 parent_service_->GetServicePath(), characteristic_info_.get(), | 271 parent_service_->GetServicePath(), characteristic_info_.get(), |
| 203 base::Bind(&BluetoothRemoteGattCharacteristicWin:: | 272 base::Bind(&BluetoothRemoteGattCharacteristicWin:: |
| 204 OnGetIncludedDescriptorsCallback, | 273 OnGetIncludedDescriptorsCallback, |
| 205 weak_ptr_factory_.GetWeakPtr())); | 274 weak_ptr_factory_.GetWeakPtr())); |
| 206 } | 275 } |
| 207 | 276 |
| 208 uint16_t BluetoothRemoteGattCharacteristicWin::GetAttributeHandle() const { | 277 uint16_t BluetoothRemoteGattCharacteristicWin::GetAttributeHandle() const { |
| 209 return characteristic_info_->AttributeHandle; | 278 return characteristic_info_->AttributeHandle; |
| 210 } | 279 } |
| 211 | 280 |
| 281 void BluetoothRemoteGattCharacteristicWin::StopNotifySession() { | |
| 282 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
| 283 | |
| 284 if (!IsNotifying()) | |
| 285 return; | |
| 286 | |
| 287 if (number_of_active_notify_sessions_ > 1) { | |
| 288 number_of_active_notify_sessions_--; | |
| 289 return; | |
| 290 } | |
| 291 | |
| 292 task_manager_->UnregisterGattCharacteristicValueChangedEvent( | |
| 293 gatt_event_handle_); | |
| 294 gatt_event_handle_ = NULL; | |
| 295 number_of_active_notify_sessions_ = 0; | |
| 296 } | |
| 297 | |
| 212 void BluetoothRemoteGattCharacteristicWin::OnGetIncludedDescriptorsCallback( | 298 void BluetoothRemoteGattCharacteristicWin::OnGetIncludedDescriptorsCallback( |
| 213 scoped_ptr<BTH_LE_GATT_DESCRIPTOR> descriptors, | 299 scoped_ptr<BTH_LE_GATT_DESCRIPTOR> descriptors, |
| 214 uint16_t num, | 300 uint16_t num, |
| 215 HRESULT hr) { | 301 HRESULT hr) { |
| 216 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 302 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 217 | 303 |
| 218 UpdateIncludedDescriptors(descriptors.get(), num); | 304 UpdateIncludedDescriptors(descriptors.get(), num); |
| 219 if (!characteristic_added_notified_) { | 305 if (!characteristic_added_notified_) { |
| 220 characteristic_added_notified_ = true; | 306 characteristic_added_notified_ = true; |
| 221 parent_service_->GetWinAdapter()->NotifyGattCharacteristicAdded(this); | 307 parent_service_->GetWinAdapter()->NotifyGattCharacteristicAdded(this); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 if (FAILED(hr)) { | 403 if (FAILED(hr)) { |
| 318 callbacks.second.Run(HRESULTToGattErrorCode(hr)); | 404 callbacks.second.Run(HRESULTToGattErrorCode(hr)); |
| 319 } else { | 405 } else { |
| 320 callbacks.first.Run(); | 406 callbacks.first.Run(); |
| 321 } | 407 } |
| 322 characteristic_value_read_or_write_in_progress_ = false; | 408 characteristic_value_read_or_write_in_progress_ = false; |
| 323 } | 409 } |
| 324 | 410 |
| 325 BluetoothGattService::GattErrorCode | 411 BluetoothGattService::GattErrorCode |
| 326 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { | 412 BluetoothRemoteGattCharacteristicWin::HRESULTToGattErrorCode(HRESULT hr) { |
| 413 if (HRESULT_FROM_WIN32(ERROR_INVALID_USER_BUFFER) == hr) | |
| 414 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; | |
| 415 | |
| 327 switch (hr) { | 416 switch (hr) { |
| 328 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: | 417 case E_BLUETOOTH_ATT_READ_NOT_PERMITTED: |
| 329 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: | 418 case E_BLUETOOTH_ATT_WRITE_NOT_PERMITTED: |
| 330 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; | 419 return BluetoothGattService::GATT_ERROR_NOT_PERMITTED; |
| 331 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: | 420 case E_BLUETOOTH_ATT_UNKNOWN_ERROR: |
| 332 return BluetoothGattService::GATT_ERROR_UNKNOWN; | 421 return BluetoothGattService::GATT_ERROR_UNKNOWN; |
| 333 case ERROR_INVALID_USER_BUFFER: | |
| 334 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: | 422 case E_BLUETOOTH_ATT_INVALID_ATTRIBUTE_VALUE_LENGTH: |
| 335 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; | 423 return BluetoothGattService::GATT_ERROR_INVALID_LENGTH; |
| 424 case E_BLUETOOTH_ATT_REQUEST_NOT_SUPPORTED: | |
| 425 return BluetoothGattService::GATT_ERROR_NOT_SUPPORTED; | |
| 336 default: | 426 default: |
| 337 return BluetoothGattService::GATT_ERROR_FAILED; | 427 return BluetoothGattService::GATT_ERROR_FAILED; |
| 338 } | 428 } |
| 339 } | 429 } |
| 340 | 430 |
| 431 void BluetoothRemoteGattCharacteristicWin::OnGattCharacteristicValueChanged( | |
| 432 scoped_ptr<std::vector<uint8_t>> new_value) { | |
| 433 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
| 434 | |
| 435 characteristic_value_.assign(new_value->begin(), new_value->end()); | |
| 436 parent_service_->GetWinAdapter()->NotifyGattCharacteristicValueChanged( | |
| 437 this, characteristic_value_); | |
| 438 } | |
| 439 | |
| 440 void BluetoothRemoteGattCharacteristicWin::GattEventRegistrationCallback( | |
| 441 BLUETOOTH_GATT_EVENT_HANDLE event_handle, | |
| 442 HRESULT hr) { | |
| 443 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | |
| 444 | |
| 445 gatt_event_registeration_in_progress_ = false; | |
| 446 std::vector<std::pair<NotifySessionCallback, ErrorCallback>> callbacks; | |
| 447 callbacks.swap(start_notify_session_callbacks_); | |
| 448 if (SUCCEEDED(hr)) { | |
| 449 gatt_event_handle_ = event_handle; | |
| 450 for (const auto& callback : callbacks) { | |
| 451 callback.first.Run(make_scoped_ptr( | |
| 452 new BluetoothGattNotifySessionWin(weak_ptr_factory_.GetWeakPtr()))); | |
| 453 number_of_active_notify_sessions_++; | |
| 454 } | |
| 455 } else { | |
| 456 for (const auto& callback : callbacks) | |
| 457 callback.second.Run(HRESULTToGattErrorCode(hr)); | |
| 458 } | |
| 459 } | |
| 460 | |
| 341 } // namespace device. | 461 } // namespace device. |
| OLD | NEW |