Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: device/bluetooth/bluetooth_task_manager_win.cc

Issue 1606013002: BLE GATT service implementation in Chrome for Windows 8 and later (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update Build.gn Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698