OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_task_manager_win.h" | 5 #include "device/bluetooth/bluetooth_task_manager_win.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <winsock2.h> | 8 #include <winsock2.h> |
9 | 9 |
10 #include <string> | 10 #include <string> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/files/file.h" |
13 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
14 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
15 #include "base/sequenced_task_runner.h" | 16 #include "base/sequenced_task_runner.h" |
16 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
17 #include "base/strings/sys_string_conversions.h" | 18 #include "base/strings/sys_string_conversions.h" |
18 #include "base/threading/sequenced_worker_pool.h" | 19 #include "base/threading/sequenced_worker_pool.h" |
19 #include "base/win/scoped_handle.h" | 20 #include "base/win/scoped_handle.h" |
20 #include "device/bluetooth/bluetooth_device.h" | 21 #include "device/bluetooth/bluetooth_device.h" |
21 #include "device/bluetooth/bluetooth_init_win.h" | 22 #include "device/bluetooth/bluetooth_init_win.h" |
22 #include "device/bluetooth/bluetooth_low_energy_win.h" | |
23 #include "device/bluetooth/bluetooth_service_record_win.h" | 23 #include "device/bluetooth/bluetooth_service_record_win.h" |
24 #include "net/base/winsock_init.h" | 24 #include "net/base/winsock_init.h" |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 const int kNumThreadsInWorkerPool = 3; | 28 const int kNumThreadsInWorkerPool = 3; |
29 const char kBluetoothThreadName[] = "BluetoothPollingThreadWin"; | 29 const char kBluetoothThreadName[] = "BluetoothPollingThreadWin"; |
30 const int kMaxNumDeviceAddressChar = 127; | 30 const int kMaxNumDeviceAddressChar = 127; |
31 const int kServiceDiscoveryResultBufferSize = 5000; | 31 const int kServiceDiscoveryResultBufferSize = 5000; |
32 | 32 |
(...skipping 13 matching lines...) Expand all Loading... |
46 btha.rgBytes[5], | 46 btha.rgBytes[5], |
47 btha.rgBytes[4], | 47 btha.rgBytes[4], |
48 btha.rgBytes[3], | 48 btha.rgBytes[3], |
49 btha.rgBytes[2], | 49 btha.rgBytes[2], |
50 btha.rgBytes[1], | 50 btha.rgBytes[1], |
51 btha.rgBytes[0]); | 51 btha.rgBytes[0]); |
52 DCHECK_EQ(result, device::BluetoothDevice::CanonicalizeAddress(result)); | 52 DCHECK_EQ(result, device::BluetoothDevice::CanonicalizeAddress(result)); |
53 return result; | 53 return result; |
54 } | 54 } |
55 | 55 |
56 device::BluetoothUUID BluetoothLowEnergyUuidToBluetoothUuid( | |
57 const BTH_LE_UUID& bth_le_uuid) { | |
58 if (bth_le_uuid.IsShortUuid) { | |
59 std::string uuid_hex = | |
60 base::StringPrintf("%04x", bth_le_uuid.Value.ShortUuid); | |
61 return device::BluetoothUUID(uuid_hex); | |
62 } else { | |
63 return device::BluetoothUUID( | |
64 base::StringPrintf("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", | |
65 bth_le_uuid.Value.LongUuid.Data1, | |
66 bth_le_uuid.Value.LongUuid.Data2, | |
67 bth_le_uuid.Value.LongUuid.Data3, | |
68 bth_le_uuid.Value.LongUuid.Data4[0], | |
69 bth_le_uuid.Value.LongUuid.Data4[1], | |
70 bth_le_uuid.Value.LongUuid.Data4[2], | |
71 bth_le_uuid.Value.LongUuid.Data4[3], | |
72 bth_le_uuid.Value.LongUuid.Data4[4], | |
73 bth_le_uuid.Value.LongUuid.Data4[5], | |
74 bth_le_uuid.Value.LongUuid.Data4[6], | |
75 bth_le_uuid.Value.LongUuid.Data4[7])); | |
76 } | |
77 } | |
78 | |
79 // Populates bluetooth adapter state using adapter_handle. | 56 // Populates bluetooth adapter state using adapter_handle. |
80 void GetAdapterState(HANDLE adapter_handle, | 57 void GetAdapterState(HANDLE adapter_handle, |
81 device::BluetoothTaskManagerWin::AdapterState* state) { | 58 device::BluetoothTaskManagerWin::AdapterState* state) { |
82 std::string name; | 59 std::string name; |
83 std::string address; | 60 std::string address; |
84 bool powered = false; | 61 bool powered = false; |
85 BLUETOOTH_RADIO_INFO adapter_info = {sizeof(BLUETOOTH_RADIO_INFO)}; | 62 BLUETOOTH_RADIO_INFO adapter_info = {sizeof(BLUETOOTH_RADIO_INFO)}; |
86 if (adapter_handle && | 63 if (adapter_handle && |
87 ERROR_SUCCESS == BluetoothGetRadioInfo(adapter_handle, | 64 ERROR_SUCCESS == BluetoothGetRadioInfo(adapter_handle, |
88 &adapter_info)) { | 65 &adapter_info)) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 BluetoothTaskManagerWin::DeviceState::DeviceState() | 104 BluetoothTaskManagerWin::DeviceState::DeviceState() |
128 : visible(false), | 105 : visible(false), |
129 connected(false), | 106 connected(false), |
130 authenticated(false), | 107 authenticated(false), |
131 bluetooth_class(0) { | 108 bluetooth_class(0) { |
132 } | 109 } |
133 | 110 |
134 BluetoothTaskManagerWin::DeviceState::~DeviceState() { | 111 BluetoothTaskManagerWin::DeviceState::~DeviceState() { |
135 } | 112 } |
136 | 113 |
| 114 // static |
| 115 BluetoothUUID BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid( |
| 116 const BTH_LE_UUID& bth_le_uuid) { |
| 117 if (bth_le_uuid.IsShortUuid) { |
| 118 std::string uuid_hex = |
| 119 base::StringPrintf("%04x", bth_le_uuid.Value.ShortUuid); |
| 120 return device::BluetoothUUID(uuid_hex); |
| 121 } else { |
| 122 return device::BluetoothUUID(base::StringPrintf( |
| 123 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", |
| 124 bth_le_uuid.Value.LongUuid.Data1, bth_le_uuid.Value.LongUuid.Data2, |
| 125 bth_le_uuid.Value.LongUuid.Data3, bth_le_uuid.Value.LongUuid.Data4[0], |
| 126 bth_le_uuid.Value.LongUuid.Data4[1], |
| 127 bth_le_uuid.Value.LongUuid.Data4[2], |
| 128 bth_le_uuid.Value.LongUuid.Data4[3], |
| 129 bth_le_uuid.Value.LongUuid.Data4[4], |
| 130 bth_le_uuid.Value.LongUuid.Data4[5], |
| 131 bth_le_uuid.Value.LongUuid.Data4[6], |
| 132 bth_le_uuid.Value.LongUuid.Data4[7])); |
| 133 } |
| 134 } |
| 135 |
| 136 bool BluetoothTaskManagerWin::BluetoothUUIDToBLEUUIDWin( |
| 137 const BluetoothUUID& uuid, |
| 138 BTH_LE_UUID* win_uuid) { |
| 139 if (!uuid.IsValid()) |
| 140 return false; |
| 141 |
| 142 if (uuid.format() == BluetoothUUID::kFormat16Bit) { |
| 143 win_uuid->IsShortUuid = true; |
| 144 unsigned int data = 0; |
| 145 int result = sscanf_s(uuid.value().c_str(), "%04x", &data); |
| 146 if (result != 1) |
| 147 return false; |
| 148 win_uuid->Value.ShortUuid = data; |
| 149 } else { |
| 150 win_uuid->IsShortUuid = false; |
| 151 unsigned int data[11]; |
| 152 int result = |
| 153 sscanf_s(uuid.value().c_str(), |
| 154 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", &data[0], |
| 155 &data[1], &data[2], &data[3], &data[4], &data[5], &data[6], |
| 156 &data[7], &data[8], &data[9], &data[10]); |
| 157 if (result != 11) |
| 158 return false; |
| 159 win_uuid->Value.LongUuid.Data1 = data[0]; |
| 160 win_uuid->Value.LongUuid.Data2 = data[1]; |
| 161 win_uuid->Value.LongUuid.Data3 = data[2]; |
| 162 win_uuid->Value.LongUuid.Data4[0] = data[3]; |
| 163 win_uuid->Value.LongUuid.Data4[1] = data[4]; |
| 164 win_uuid->Value.LongUuid.Data4[2] = data[5]; |
| 165 win_uuid->Value.LongUuid.Data4[3] = data[6]; |
| 166 win_uuid->Value.LongUuid.Data4[4] = data[7]; |
| 167 win_uuid->Value.LongUuid.Data4[5] = data[8]; |
| 168 win_uuid->Value.LongUuid.Data4[6] = data[9]; |
| 169 win_uuid->Value.LongUuid.Data4[7] = data[10]; |
| 170 } |
| 171 |
| 172 return true; |
| 173 } |
| 174 |
137 BluetoothTaskManagerWin::BluetoothTaskManagerWin( | 175 BluetoothTaskManagerWin::BluetoothTaskManagerWin( |
138 scoped_refptr<base::SequencedTaskRunner> ui_task_runner) | 176 scoped_refptr<base::SequencedTaskRunner> ui_task_runner) |
139 : ui_task_runner_(ui_task_runner), | 177 : ui_task_runner_(ui_task_runner), |
140 discovering_(false), | 178 discovering_(false), |
141 current_logging_batch_count_(0) { | 179 current_logging_batch_count_(0) { |
142 } | 180 } |
143 | 181 |
144 BluetoothTaskManagerWin::~BluetoothTaskManagerWin() { | 182 BluetoothTaskManagerWin::~BluetoothTaskManagerWin() { |
145 } | 183 } |
146 | 184 |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 base::Bind(&BluetoothTaskManagerWin::OnDevicesPolled, | 442 base::Bind(&BluetoothTaskManagerWin::OnDevicesPolled, |
405 this, | 443 this, |
406 base::Owned(device_list.release()))); | 444 base::Owned(device_list.release()))); |
407 } | 445 } |
408 } | 446 } |
409 | 447 |
410 bool BluetoothTaskManagerWin::SearchDevices( | 448 bool BluetoothTaskManagerWin::SearchDevices( |
411 int timeout_multiplier, | 449 int timeout_multiplier, |
412 bool search_cached_devices_only, | 450 bool search_cached_devices_only, |
413 ScopedVector<DeviceState>* device_list) { | 451 ScopedVector<DeviceState>* device_list) { |
414 return SearchClassicDevices( | 452 return SearchClassicDevices(timeout_multiplier, search_cached_devices_only, |
415 timeout_multiplier, search_cached_devices_only, device_list) && | 453 device_list) && |
416 SearchLowEnergyDevices(device_list) && | 454 SearchLowEnergyDevices(device_list) && |
417 DiscoverServices(device_list, search_cached_devices_only); | 455 DiscoverServices(device_list, search_cached_devices_only); |
418 } | 456 } |
419 | 457 |
420 bool BluetoothTaskManagerWin::SearchClassicDevices( | 458 bool BluetoothTaskManagerWin::SearchClassicDevices( |
421 int timeout_multiplier, | 459 int timeout_multiplier, |
422 bool search_cached_devices_only, | 460 bool search_cached_devices_only, |
423 ScopedVector<DeviceState>* device_list) { | 461 ScopedVector<DeviceState>* device_list) { |
424 // Issues a device inquiry and waits for |timeout_multiplier| * 1.28 seconds. | 462 // Issues a device inquiry and waits for |timeout_multiplier| * 1.28 seconds. |
425 BLUETOOTH_DEVICE_SEARCH_PARAMS device_search_params; | 463 BLUETOOTH_DEVICE_SEARCH_PARAMS device_search_params; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 return true; | 510 return true; |
473 } | 511 } |
474 | 512 |
475 bool BluetoothTaskManagerWin::SearchLowEnergyDevices( | 513 bool BluetoothTaskManagerWin::SearchLowEnergyDevices( |
476 ScopedVector<DeviceState>* device_list) { | 514 ScopedVector<DeviceState>* device_list) { |
477 if (!win::IsBluetoothLowEnergySupported()) | 515 if (!win::IsBluetoothLowEnergySupported()) |
478 return true; // Bluetooth LE not supported is not an error. | 516 return true; // Bluetooth LE not supported is not an error. |
479 | 517 |
480 ScopedVector<win::BluetoothLowEnergyDeviceInfo> btle_devices; | 518 ScopedVector<win::BluetoothLowEnergyDeviceInfo> btle_devices; |
481 std::string error; | 519 std::string error; |
482 bool success = | 520 bool success = win::EnumerateKnownBluetoothLowEnergyDevices( |
483 win::EnumerateKnownBluetoothLowEnergyDevices(&btle_devices, &error); | 521 GUID_BLUETOOTHLE_DEVICE_INTERFACE, &btle_devices, &error); |
484 if (!success) { | 522 if (!success) { |
485 LogPollingError(error.c_str(), 0); | 523 LogPollingError(error.c_str(), 0); |
486 return false; | 524 return false; |
487 } | 525 } |
488 | 526 |
489 for (ScopedVector<win::BluetoothLowEnergyDeviceInfo>::iterator iter = | 527 for (ScopedVector<win::BluetoothLowEnergyDeviceInfo>::iterator iter = |
490 btle_devices.begin(); | 528 btle_devices.begin(); |
491 iter != btle_devices.end(); | 529 iter != btle_devices.end(); |
492 ++iter) { | 530 ++iter) { |
493 win::BluetoothLowEnergyDeviceInfo* device_info = (*iter); | 531 win::BluetoothLowEnergyDeviceInfo* device_info = (*iter); |
(...skipping 23 matching lines...) Expand all Loading... |
517 &(*iter)->service_record_states; | 555 &(*iter)->service_record_states; |
518 | 556 |
519 if ((*iter)->is_bluetooth_classic()) { | 557 if ((*iter)->is_bluetooth_classic()) { |
520 if (!DiscoverClassicDeviceServices(device->address, | 558 if (!DiscoverClassicDeviceServices(device->address, |
521 L2CAP_PROTOCOL_UUID, | 559 L2CAP_PROTOCOL_UUID, |
522 search_cached_services_only, | 560 search_cached_services_only, |
523 service_record_states)) { | 561 service_record_states)) { |
524 return false; | 562 return false; |
525 } | 563 } |
526 } else { | 564 } else { |
527 if (!DiscoverLowEnergyDeviceServices(device->path, | 565 if (!DiscoverLowEnergyDeviceServices(device->path, device->address, |
528 service_record_states)) { | 566 service_record_states)) { |
529 return false; | 567 return false; |
530 } | 568 } |
531 } | 569 } |
532 } | 570 } |
533 return true; | 571 return true; |
534 } | 572 } |
535 | 573 |
536 bool BluetoothTaskManagerWin::DiscoverClassicDeviceServices( | 574 bool BluetoothTaskManagerWin::DiscoverClassicDeviceServices( |
537 const std::string& device_address, | 575 const std::string& device_address, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 int last_error = WSAGetLastError(); | 661 int last_error = WSAGetLastError(); |
624 LogPollingError("Error calling WSALookupServiceEnd", last_error); | 662 LogPollingError("Error calling WSALookupServiceEnd", last_error); |
625 return last_error; | 663 return last_error; |
626 } | 664 } |
627 | 665 |
628 return ERROR_SUCCESS; | 666 return ERROR_SUCCESS; |
629 } | 667 } |
630 | 668 |
631 bool BluetoothTaskManagerWin::DiscoverLowEnergyDeviceServices( | 669 bool BluetoothTaskManagerWin::DiscoverLowEnergyDeviceServices( |
632 const base::FilePath& device_path, | 670 const base::FilePath& device_path, |
| 671 const std::string device_address, |
633 ScopedVector<ServiceRecordState>* service_record_states) { | 672 ScopedVector<ServiceRecordState>* service_record_states) { |
634 if (!win::IsBluetoothLowEnergySupported()) | 673 if (!win::IsBluetoothLowEnergySupported()) |
635 return true; // Bluetooth LE not supported is not an error. | 674 return true; // Bluetooth LE not supported is not an error. |
636 | 675 |
637 std::string error; | 676 std::string error; |
638 ScopedVector<win::BluetoothLowEnergyServiceInfo> services; | 677 ScopedVector<win::BluetoothLowEnergyServiceInfo> services; |
639 bool success = win::EnumerateKnownBluetoothLowEnergyServices( | 678 bool success = win::EnumerateKnownBluetoothLowEnergyServices( |
640 device_path, &services, &error); | 679 device_path, &services, &error); |
641 if (!success) { | 680 if (!success) { |
642 LogPollingError(error.c_str(), 0); | 681 LogPollingError(error.c_str(), 0); |
643 return false; | 682 return false; |
644 } | 683 } |
645 | 684 |
| 685 ScopedVector<win::BluetoothLowEnergyDeviceInfo> |
| 686 gatt_service_device_interfaces; |
| 687 success = win::EnumerateKnownBluetoothLowEnergyDevices( |
| 688 GUID_BLUETOOTH_GATT_SERVICE_DEVICE_INTERFACE, |
| 689 &gatt_service_device_interfaces, &error); |
| 690 if (!success) { |
| 691 LogPollingError(error.c_str(), 0); |
| 692 return false; |
| 693 } |
| 694 |
| 695 // Find BLE primary services correspond device paths. |
| 696 for (auto gatt_service_device_interface : gatt_service_device_interfaces) { |
| 697 if (BluetoothAddressToCanonicalString( |
| 698 gatt_service_device_interface->address) != device_address) { |
| 699 continue; |
| 700 } |
| 701 ScopedVector<win::BluetoothLowEnergyServiceInfo> gatt_services; |
| 702 if (!win::EnumerateKnownBluetoothLowEnergyServices( |
| 703 gatt_service_device_interface->path, &gatt_services, &error)) { |
| 704 LogPollingError(error.c_str(), 0); |
| 705 continue; |
| 706 } |
| 707 if (gatt_services.size() > 1) { |
| 708 LOG(WARNING) |
| 709 << "there are more than one primary service for a gatt service " |
| 710 "device interface"; |
| 711 } |
| 712 for (auto gatt_service : gatt_services) { |
| 713 std::string gatt_service_uuid = |
| 714 BluetoothLowEnergyUuidToBluetoothUuid(gatt_service->uuid) |
| 715 .canonical_value(); |
| 716 for (auto device_primary_service : services) { |
| 717 std::string device_primary_service_uuid = |
| 718 BluetoothLowEnergyUuidToBluetoothUuid(device_primary_service->uuid) |
| 719 .canonical_value(); |
| 720 if (gatt_service_uuid == device_primary_service_uuid) { |
| 721 device_primary_service->path = gatt_service_device_interface->path; |
| 722 } |
| 723 } |
| 724 } |
| 725 } |
| 726 |
646 for (ScopedVector<win::BluetoothLowEnergyServiceInfo>::iterator iter2 = | 727 for (ScopedVector<win::BluetoothLowEnergyServiceInfo>::iterator iter2 = |
647 services.begin(); | 728 services.begin(); |
648 iter2 != services.end(); | 729 iter2 != services.end(); |
649 ++iter2) { | 730 ++iter2) { |
650 ServiceRecordState* service_state = new ServiceRecordState(); | 731 ServiceRecordState* service_state = new ServiceRecordState(); |
651 service_state->gatt_uuid = | 732 service_state->gatt_uuid = |
652 BluetoothLowEnergyUuidToBluetoothUuid((*iter2)->uuid); | 733 BluetoothLowEnergyUuidToBluetoothUuid((*iter2)->uuid); |
| 734 service_state->gatt_attribute_handle = (*iter2)->attribute_handle; |
| 735 service_state->path = (*iter2)->path; |
653 service_record_states->push_back(service_state); | 736 service_record_states->push_back(service_state); |
654 } | 737 } |
655 return true; | 738 return true; |
656 } | 739 } |
657 | 740 |
| 741 void BluetoothTaskManagerWin::GetGattIncludedServices( |
| 742 base::FilePath service_path, |
| 743 BluetoothUUID uuid, |
| 744 uint16_t attribute_handle, |
| 745 const GetGattIncludedServicesCallback& callback) { |
| 746 HRESULT hr = S_OK; |
| 747 BTH_LE_GATT_SERVICE* win_services_info = nullptr; |
| 748 uint16_t number_of_services = 0; |
| 749 |
| 750 base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 751 if (!file.IsValid()) { |
| 752 hr = HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); |
| 753 goto Done; |
| 754 } |
| 755 |
| 756 BTH_LE_GATT_SERVICE win_service; |
| 757 if (!BluetoothUUIDToBLEUUIDWin(uuid, &(win_service.ServiceUuid))) { |
| 758 hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER); |
| 759 goto Done; |
| 760 } |
| 761 win_service.AttributeHandle = attribute_handle; |
| 762 hr = device::win::ReadIncludedServicesOfAService( |
| 763 file.GetPlatformFile(), &win_service, &win_services_info, |
| 764 &number_of_services); |
| 765 |
| 766 Done: |
| 767 ui_task_runner_->PostTask(FROM_HERE, |
| 768 base::Bind(callback, base::Owned(win_services_info), |
| 769 number_of_services, hr)); |
| 770 } |
| 771 |
| 772 void BluetoothTaskManagerWin::GetGattIncludedCharacteristics( |
| 773 base::FilePath service_path, |
| 774 BluetoothUUID uuid, |
| 775 uint16_t attribute_handle, |
| 776 const GetGattIncludedCharacteristicsCallback& callback) { |
| 777 HRESULT hr = S_OK; |
| 778 BTH_LE_GATT_CHARACTERISTIC* win_characteristics_info = nullptr; |
| 779 uint16_t number_of_charateristics = 0; |
| 780 |
| 781 base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 782 if (!file.IsValid()) { |
| 783 hr = HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); |
| 784 goto Done; |
| 785 } |
| 786 |
| 787 BTH_LE_GATT_SERVICE win_service; |
| 788 if (!BluetoothUUIDToBLEUUIDWin(uuid, &(win_service.ServiceUuid))) { |
| 789 hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER); |
| 790 goto Done; |
| 791 } |
| 792 win_service.AttributeHandle = attribute_handle; |
| 793 hr = device::win::ReadCharacteristicsOfAService( |
| 794 file.GetPlatformFile(), &win_service, &win_characteristics_info, |
| 795 &number_of_charateristics); |
| 796 |
| 797 Done: |
| 798 ui_task_runner_->PostTask( |
| 799 FROM_HERE, base::Bind(callback, base::Owned(win_characteristics_info), |
| 800 number_of_charateristics, hr)); |
| 801 } |
| 802 |
| 803 void BluetoothTaskManagerWin::ReadCharacteristicValue( |
| 804 base::FilePath service_path, |
| 805 BTH_LE_GATT_CHARACTERISTIC characteristic, |
| 806 const ReadCharacteristicValueCallback& callback) { |
| 807 HRESULT hr = S_OK; |
| 808 BTH_LE_GATT_CHARACTERISTIC_VALUE* win_characteristic_value = nullptr; |
| 809 |
| 810 base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 811 if (!file.IsValid()) { |
| 812 hr = HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); |
| 813 goto Done; |
| 814 } |
| 815 |
| 816 hr = device::win::ReadTheValueOfACharacteristic( |
| 817 file.GetPlatformFile(), (PBTH_LE_GATT_CHARACTERISTIC)(&characteristic), |
| 818 &win_characteristic_value); |
| 819 |
| 820 Done: |
| 821 ui_task_runner_->PostTask( |
| 822 FROM_HERE, |
| 823 base::Bind(callback, base::Owned(win_characteristic_value), hr)); |
| 824 } |
| 825 |
| 826 void BluetoothTaskManagerWin::WriteCharacteristicValue( |
| 827 base::FilePath service_path, |
| 828 BTH_LE_GATT_CHARACTERISTIC characteristic, |
| 829 std::vector<uint8_t> new_value, |
| 830 const HResultCallback& callback) { |
| 831 HRESULT hr = S_OK; |
| 832 base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ | |
| 833 base::File::FLAG_WRITE); |
| 834 if (!file.IsValid()) { |
| 835 hr = HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); |
| 836 goto Done; |
| 837 } |
| 838 |
| 839 ULONG length = (ULONG)(sizeof(ULONG) + new_value.size()); |
| 840 PBTH_LE_GATT_CHARACTERISTIC_VALUE win_new_value = |
| 841 (BTH_LE_GATT_CHARACTERISTIC_VALUE*)malloc(length); |
| 842 win_new_value->DataSize = (ULONG)new_value.size(); |
| 843 for (ULONG i = 0; i < new_value.size(); i++) { |
| 844 win_new_value->Data[i] = new_value[i]; |
| 845 } |
| 846 |
| 847 hr = device::win::WriteTheValueOfACharacteristic( |
| 848 file.GetPlatformFile(), (PBTH_LE_GATT_CHARACTERISTIC)(&characteristic), |
| 849 win_new_value); |
| 850 free(win_new_value); |
| 851 Done: |
| 852 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, hr)); |
| 853 } |
| 854 |
| 855 void BluetoothTaskManagerWin::ReliableWriteCharacteristicValue( |
| 856 base::FilePath service_path, |
| 857 BTH_LE_GATT_CHARACTERISTIC characteristic, |
| 858 std::vector<uint8_t> new_value, |
| 859 const HResultCallback& callback) { |
| 860 HRESULT hr = S_OK; |
| 861 base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ | |
| 862 base::File::FLAG_WRITE); |
| 863 if (!file.IsValid()) { |
| 864 hr = HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); |
| 865 goto Done; |
| 866 } |
| 867 |
| 868 ULONG length = (ULONG)(sizeof(ULONG) + new_value.size()); |
| 869 PBTH_LE_GATT_CHARACTERISTIC_VALUE win_new_value = |
| 870 (BTH_LE_GATT_CHARACTERISTIC_VALUE*)malloc(length); |
| 871 win_new_value->DataSize = (ULONG)new_value.size(); |
| 872 for (ULONG i = 0; i < new_value.size(); i++) { |
| 873 win_new_value->Data[i] = new_value[i]; |
| 874 } |
| 875 hr = device::win::ReliableWriteTheValueOfACharacteristic( |
| 876 file.GetPlatformFile(), (PBTH_LE_GATT_CHARACTERISTIC)(&characteristic), |
| 877 win_new_value); |
| 878 free(win_new_value); |
| 879 Done: |
| 880 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, hr)); |
| 881 } |
| 882 |
| 883 void BluetoothTaskManagerWin::GetGattIncludedDescriptors( |
| 884 base::FilePath service_path, |
| 885 BTH_LE_GATT_CHARACTERISTIC characteristic, |
| 886 const GetGattIncludedDescriptorsCallback& callback) { |
| 887 HRESULT hr = S_OK; |
| 888 BTH_LE_GATT_DESCRIPTOR* win_descriptors_info = nullptr; |
| 889 uint16_t number_of_descriptors = 0; |
| 890 |
| 891 base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 892 if (!file.IsValid()) { |
| 893 hr = HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); |
| 894 goto Done; |
| 895 } |
| 896 |
| 897 hr = device::win::ReadDescriptorsOfACharacteristic( |
| 898 file.GetPlatformFile(), (PBTH_LE_GATT_CHARACTERISTIC)(&characteristic), |
| 899 &win_descriptors_info, &number_of_descriptors); |
| 900 Done: |
| 901 ui_task_runner_->PostTask( |
| 902 FROM_HERE, base::Bind(callback, base::Owned(win_descriptors_info), |
| 903 number_of_descriptors, hr)); |
| 904 } |
| 905 |
| 906 void BluetoothTaskManagerWin::ReadDescriptorValue( |
| 907 base::FilePath service_path, |
| 908 BTH_LE_GATT_DESCRIPTOR descriptor, |
| 909 const ReadDescriptorValueCallback& callback) { |
| 910 HRESULT hr = S_OK; |
| 911 BTH_LE_GATT_DESCRIPTOR_VALUE* win_descriptor_value = nullptr; |
| 912 |
| 913 base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 914 if (!file.IsValid()) { |
| 915 hr = HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); |
| 916 goto Done; |
| 917 } |
| 918 |
| 919 hr = device::win::ReadTheValueOfADescriptor( |
| 920 file.GetPlatformFile(), (PBTH_LE_GATT_DESCRIPTOR)(&descriptor), |
| 921 &win_descriptor_value); |
| 922 |
| 923 Done: |
| 924 ui_task_runner_->PostTask(FROM_HERE, |
| 925 base::Bind(callback, win_descriptor_value, hr)); |
| 926 } |
| 927 |
| 928 void BluetoothTaskManagerWin::WriteDescriptorValue( |
| 929 base::FilePath service_path, |
| 930 BTH_LE_GATT_DESCRIPTOR descriptor, |
| 931 std::vector<uint8_t> new_value, |
| 932 const HResultCallback& callback) { |
| 933 HRESULT hr = S_OK; |
| 934 |
| 935 base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ | |
| 936 base::File::FLAG_WRITE); |
| 937 if (!file.IsValid()) { |
| 938 hr = HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); |
| 939 goto Done; |
| 940 } |
| 941 |
| 942 ULONG length = (ULONG)(sizeof(BTH_LE_GATT_DESCRIPTOR) + new_value.size()); |
| 943 PBTH_LE_GATT_DESCRIPTOR_VALUE win_descriptor_value = |
| 944 (PBTH_LE_GATT_DESCRIPTOR_VALUE)malloc(length); |
| 945 win_descriptor_value->DataSize = (ULONG)new_value.size(); |
| 946 for (ULONG i = 0; i < new_value.size(); i++) |
| 947 win_descriptor_value->Data[i] = new_value[i]; |
| 948 hr = device::win::WriteTheDescriptorValue( |
| 949 file.GetPlatformFile(), (PBTH_LE_GATT_DESCRIPTOR)(&descriptor), |
| 950 win_descriptor_value); |
| 951 free(win_descriptor_value); |
| 952 Done: |
| 953 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, hr)); |
| 954 } |
| 955 |
| 956 void BluetoothTaskManagerWin::RegisterCharacteristicValueChangedEvent( |
| 957 base::FilePath service_path, |
| 958 BTH_LE_GATT_CHARACTERISTIC characteristic, |
| 959 const GattEventRegistrationCallback& callback, |
| 960 PFNBLUETOOTH_GATT_EVENT_CALLBACK registered_callback, |
| 961 void* context) { |
| 962 HRESULT hr = S_OK; |
| 963 BLUETOOTH_GATT_EVENT_HANDLE event_handle = NULL; |
| 964 |
| 965 base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 966 if (!file.IsValid()) { |
| 967 hr = HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); |
| 968 goto Done; |
| 969 } |
| 970 |
| 971 BLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION event_parameter; |
| 972 memcpy(&(event_parameter.Characteristics[0]), &characteristic, |
| 973 sizeof(BTH_LE_GATT_CHARACTERISTIC)); |
| 974 event_parameter.NumCharacteristics = 1; |
| 975 hr = device::win::RegisterGattEvents( |
| 976 file.GetPlatformFile(), CharacteristicValueChangedEvent, &event_parameter, |
| 977 registered_callback, context, &event_handle); |
| 978 |
| 979 Done: |
| 980 ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, event_handle, hr)); |
| 981 } |
| 982 |
| 983 void BluetoothTaskManagerWin::PostGetGattIncludedServices( |
| 984 const base::FilePath& service_path, |
| 985 const BluetoothUUID& uuid, |
| 986 uint16_t attribute_handle, |
| 987 const GetGattIncludedServicesCallback& callback) { |
| 988 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 989 bluetooth_task_runner_->PostTask( |
| 990 FROM_HERE, |
| 991 base::Bind(&BluetoothTaskManagerWin::GetGattIncludedServices, this, |
| 992 service_path, uuid, attribute_handle, callback)); |
| 993 } |
| 994 |
| 995 void BluetoothTaskManagerWin::PostGetGattIncludedCharacteristics( |
| 996 const base::FilePath& service_path, |
| 997 const BluetoothUUID& uuid, |
| 998 uint16_t attribute_handle, |
| 999 const GetGattIncludedCharacteristicsCallback& callback) { |
| 1000 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 1001 bluetooth_task_runner_->PostTask( |
| 1002 FROM_HERE, |
| 1003 base::Bind(&BluetoothTaskManagerWin::GetGattIncludedCharacteristics, this, |
| 1004 service_path, uuid, attribute_handle, callback)); |
| 1005 } |
| 1006 |
| 1007 void BluetoothTaskManagerWin::PostReadCharacteristicValue( |
| 1008 const base::FilePath& service_path, |
| 1009 const PBTH_LE_GATT_CHARACTERISTIC characteristic, |
| 1010 const ReadCharacteristicValueCallback& callback) { |
| 1011 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 1012 bluetooth_task_runner_->PostTask( |
| 1013 FROM_HERE, base::Bind(&BluetoothTaskManagerWin::ReadCharacteristicValue, |
| 1014 this, service_path, *characteristic, callback)); |
| 1015 } |
| 1016 |
| 1017 void BluetoothTaskManagerWin::PostWriteCharacteristicValue( |
| 1018 const base::FilePath& service_path, |
| 1019 const PBTH_LE_GATT_CHARACTERISTIC characteristic, |
| 1020 const std::vector<uint8_t>& new_value, |
| 1021 const HResultCallback& callback) { |
| 1022 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 1023 bluetooth_task_runner_->PostTask( |
| 1024 FROM_HERE, |
| 1025 base::Bind(&BluetoothTaskManagerWin::WriteCharacteristicValue, this, |
| 1026 service_path, *characteristic, new_value, callback)); |
| 1027 } |
| 1028 |
| 1029 void BluetoothTaskManagerWin::PostReliableWriteCharacteristicValue( |
| 1030 const base::FilePath& service_path, |
| 1031 const PBTH_LE_GATT_CHARACTERISTIC characteristic, |
| 1032 const std::vector<uint8_t>& new_value, |
| 1033 const HResultCallback& callback) { |
| 1034 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 1035 bluetooth_task_runner_->PostTask( |
| 1036 FROM_HERE, |
| 1037 base::Bind(&BluetoothTaskManagerWin::WriteCharacteristicValue, this, |
| 1038 service_path, *characteristic, new_value, callback)); |
| 1039 } |
| 1040 |
| 1041 void BluetoothTaskManagerWin::PostGetGattIncludedDescriptors( |
| 1042 const base::FilePath& service_path, |
| 1043 const PBTH_LE_GATT_CHARACTERISTIC characteristic, |
| 1044 const GetGattIncludedDescriptorsCallback& callback) { |
| 1045 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 1046 bluetooth_task_runner_->PostTask( |
| 1047 FROM_HERE, |
| 1048 base::Bind(&BluetoothTaskManagerWin::GetGattIncludedDescriptors, this, |
| 1049 service_path, *characteristic, callback)); |
| 1050 } |
| 1051 |
| 1052 void BluetoothTaskManagerWin::PostReadDescriptorValue( |
| 1053 const base::FilePath& service_path, |
| 1054 const PBTH_LE_GATT_DESCRIPTOR descriptor, |
| 1055 const ReadDescriptorValueCallback& callback) { |
| 1056 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 1057 bluetooth_task_runner_->PostTask( |
| 1058 FROM_HERE, base::Bind(&BluetoothTaskManagerWin::ReadDescriptorValue, this, |
| 1059 service_path, *descriptor, callback)); |
| 1060 } |
| 1061 |
| 1062 void BluetoothTaskManagerWin::PostWriteDescriptorValue( |
| 1063 const base::FilePath& service_path, |
| 1064 const PBTH_LE_GATT_DESCRIPTOR descriptor, |
| 1065 const std::vector<uint8_t>& new_value, |
| 1066 const HResultCallback& callback) { |
| 1067 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 1068 bluetooth_task_runner_->PostTask( |
| 1069 FROM_HERE, |
| 1070 base::Bind(&BluetoothTaskManagerWin::WriteDescriptorValue, this, |
| 1071 service_path, *descriptor, new_value, callback)); |
| 1072 } |
| 1073 |
| 1074 void BluetoothTaskManagerWin::PostRegisterCharacteristicValueChangedEvent( |
| 1075 const base::FilePath& service_path, |
| 1076 const PBTH_LE_GATT_CHARACTERISTIC characteristic, |
| 1077 const GattEventRegistrationCallback& callback, |
| 1078 PFNBLUETOOTH_GATT_EVENT_CALLBACK registered_callback, |
| 1079 void* context) { |
| 1080 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 1081 bluetooth_task_runner_->PostTask( |
| 1082 FROM_HERE, |
| 1083 base::Bind( |
| 1084 &BluetoothTaskManagerWin::RegisterCharacteristicValueChangedEvent, |
| 1085 this, service_path, *characteristic, callback, registered_callback, |
| 1086 context)); |
| 1087 } |
| 1088 |
| 1089 void BluetoothTaskManagerWin::UnregisterCharacteristicValueChangedEvent( |
| 1090 BLUETOOTH_GATT_EVENT_HANDLE event_handle) { |
| 1091 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 1092 device::win::UnregisterGattEvent(event_handle); |
| 1093 } |
| 1094 |
658 } // namespace device | 1095 } // namespace device |
OLD | NEW |