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/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
15 #include "base/sequenced_task_runner.h" | 15 #include "base/sequenced_task_runner.h" |
16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
17 #include "base/strings/sys_string_conversions.h" | 17 #include "base/strings/sys_string_conversions.h" |
18 #include "base/threading/sequenced_worker_pool.h" | 18 #include "base/threading/sequenced_worker_pool.h" |
19 #include "device/bluetooth/bluetooth_classic_win.h" | 19 #include "device/bluetooth/bluetooth_classic_win.h" |
20 #include "device/bluetooth/bluetooth_device.h" | 20 #include "device/bluetooth/bluetooth_device.h" |
21 #include "device/bluetooth/bluetooth_init_win.h" | 21 #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" | 22 #include "device/bluetooth/bluetooth_service_record_win.h" |
24 #include "net/base/winsock_init.h" | 23 #include "net/base/winsock_init.h" |
25 | 24 |
26 namespace { | 25 namespace { |
27 | 26 |
28 const int kNumThreadsInWorkerPool = 3; | 27 const int kNumThreadsInWorkerPool = 3; |
29 const char kBluetoothThreadName[] = "BluetoothPollingThreadWin"; | 28 const char kBluetoothThreadName[] = "BluetoothPollingThreadWin"; |
30 const int kMaxNumDeviceAddressChar = 127; | 29 const int kMaxNumDeviceAddressChar = 127; |
31 const int kServiceDiscoveryResultBufferSize = 5000; | 30 const int kServiceDiscoveryResultBufferSize = 5000; |
32 | 31 |
(...skipping 13 matching lines...) Expand all Loading... |
46 btha.rgBytes[5], | 45 btha.rgBytes[5], |
47 btha.rgBytes[4], | 46 btha.rgBytes[4], |
48 btha.rgBytes[3], | 47 btha.rgBytes[3], |
49 btha.rgBytes[2], | 48 btha.rgBytes[2], |
50 btha.rgBytes[1], | 49 btha.rgBytes[1], |
51 btha.rgBytes[0]); | 50 btha.rgBytes[0]); |
52 DCHECK_EQ(result, device::BluetoothDevice::CanonicalizeAddress(result)); | 51 DCHECK_EQ(result, device::BluetoothDevice::CanonicalizeAddress(result)); |
53 return result; | 52 return result; |
54 } | 53 } |
55 | 54 |
56 device::BluetoothUUID BluetoothLowEnergyUuidToBluetoothUuid( | 55 bool BluetoothUUIDToWinBLEUUID(const device::BluetoothUUID& uuid, |
57 const BTH_LE_UUID& bth_le_uuid) { | 56 BTH_LE_UUID* out_win_uuid) { |
58 if (bth_le_uuid.IsShortUuid) { | 57 if (!uuid.IsValid()) |
59 std::string uuid_hex = | 58 return false; |
60 base::StringPrintf("%04x", bth_le_uuid.Value.ShortUuid); | 59 |
61 return device::BluetoothUUID(uuid_hex); | 60 if (uuid.format() == device::BluetoothUUID::kFormat16Bit) { |
| 61 out_win_uuid->IsShortUuid = true; |
| 62 unsigned int data = 0; |
| 63 int result = sscanf_s(uuid.value().c_str(), "%04x", &data); |
| 64 if (result != 1) |
| 65 return false; |
| 66 out_win_uuid->Value.ShortUuid = data; |
62 } else { | 67 } else { |
63 return device::BluetoothUUID( | 68 out_win_uuid->IsShortUuid = false; |
64 base::StringPrintf("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", | 69 unsigned int data[11]; |
65 bth_le_uuid.Value.LongUuid.Data1, | 70 int result = |
66 bth_le_uuid.Value.LongUuid.Data2, | 71 sscanf_s(uuid.value().c_str(), |
67 bth_le_uuid.Value.LongUuid.Data3, | 72 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", &data[0], |
68 bth_le_uuid.Value.LongUuid.Data4[0], | 73 &data[1], &data[2], &data[3], &data[4], &data[5], &data[6], |
69 bth_le_uuid.Value.LongUuid.Data4[1], | 74 &data[7], &data[8], &data[9], &data[10]); |
70 bth_le_uuid.Value.LongUuid.Data4[2], | 75 if (result != 11) |
71 bth_le_uuid.Value.LongUuid.Data4[3], | 76 return false; |
72 bth_le_uuid.Value.LongUuid.Data4[4], | 77 out_win_uuid->Value.LongUuid.Data1 = data[0]; |
73 bth_le_uuid.Value.LongUuid.Data4[5], | 78 out_win_uuid->Value.LongUuid.Data2 = data[1]; |
74 bth_le_uuid.Value.LongUuid.Data4[6], | 79 out_win_uuid->Value.LongUuid.Data3 = data[2]; |
75 bth_le_uuid.Value.LongUuid.Data4[7])); | 80 out_win_uuid->Value.LongUuid.Data4[0] = data[3]; |
| 81 out_win_uuid->Value.LongUuid.Data4[1] = data[4]; |
| 82 out_win_uuid->Value.LongUuid.Data4[2] = data[5]; |
| 83 out_win_uuid->Value.LongUuid.Data4[3] = data[6]; |
| 84 out_win_uuid->Value.LongUuid.Data4[4] = data[7]; |
| 85 out_win_uuid->Value.LongUuid.Data4[5] = data[8]; |
| 86 out_win_uuid->Value.LongUuid.Data4[6] = data[9]; |
| 87 out_win_uuid->Value.LongUuid.Data4[7] = data[10]; |
76 } | 88 } |
| 89 |
| 90 return true; |
77 } | 91 } |
78 | 92 |
79 // Populates bluetooth adapter state using adapter_handle. | 93 // Populates bluetooth adapter state using adapter_handle. |
80 void GetAdapterState(HANDLE adapter_handle, | 94 void GetAdapterState(HANDLE adapter_handle, |
81 device::BluetoothTaskManagerWin::AdapterState* state) { | 95 device::BluetoothTaskManagerWin::AdapterState* state) { |
82 std::string name; | 96 std::string name; |
83 std::string address; | 97 std::string address; |
84 bool powered = false; | 98 bool powered = false; |
85 BLUETOOTH_RADIO_INFO adapter_info = {sizeof(BLUETOOTH_RADIO_INFO)}; | 99 BLUETOOTH_RADIO_INFO adapter_info = {sizeof(BLUETOOTH_RADIO_INFO)}; |
86 if (adapter_handle && | 100 if (adapter_handle && |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 : ui_task_runner_(ui_task_runner), | 156 : ui_task_runner_(ui_task_runner), |
143 adapter_handle_(NULL), | 157 adapter_handle_(NULL), |
144 discovering_(false), | 158 discovering_(false), |
145 current_logging_batch_count_(0) {} | 159 current_logging_batch_count_(0) {} |
146 | 160 |
147 BluetoothTaskManagerWin::~BluetoothTaskManagerWin() { | 161 BluetoothTaskManagerWin::~BluetoothTaskManagerWin() { |
148 win::BluetoothLowEnergyWrapper::DeleteInstance(); | 162 win::BluetoothLowEnergyWrapper::DeleteInstance(); |
149 win::BluetoothClassicWrapper::DeleteInstance(); | 163 win::BluetoothClassicWrapper::DeleteInstance(); |
150 } | 164 } |
151 | 165 |
| 166 BluetoothUUID BluetoothTaskManagerWin::BluetoothLowEnergyUuidToBluetoothUuid( |
| 167 const BTH_LE_UUID& bth_le_uuid) { |
| 168 if (bth_le_uuid.IsShortUuid) { |
| 169 std::string uuid_hex = |
| 170 base::StringPrintf("%04x", bth_le_uuid.Value.ShortUuid); |
| 171 return BluetoothUUID(uuid_hex); |
| 172 } else { |
| 173 return BluetoothUUID(base::StringPrintf( |
| 174 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", |
| 175 bth_le_uuid.Value.LongUuid.Data1, bth_le_uuid.Value.LongUuid.Data2, |
| 176 bth_le_uuid.Value.LongUuid.Data3, bth_le_uuid.Value.LongUuid.Data4[0], |
| 177 bth_le_uuid.Value.LongUuid.Data4[1], |
| 178 bth_le_uuid.Value.LongUuid.Data4[2], |
| 179 bth_le_uuid.Value.LongUuid.Data4[3], |
| 180 bth_le_uuid.Value.LongUuid.Data4[4], |
| 181 bth_le_uuid.Value.LongUuid.Data4[5], |
| 182 bth_le_uuid.Value.LongUuid.Data4[6], |
| 183 bth_le_uuid.Value.LongUuid.Data4[7])); |
| 184 } |
| 185 } |
| 186 |
152 void BluetoothTaskManagerWin::AddObserver(Observer* observer) { | 187 void BluetoothTaskManagerWin::AddObserver(Observer* observer) { |
153 DCHECK(observer); | 188 DCHECK(observer); |
154 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 189 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
155 observers_.AddObserver(observer); | 190 observers_.AddObserver(observer); |
156 } | 191 } |
157 | 192 |
158 void BluetoothTaskManagerWin::RemoveObserver(Observer* observer) { | 193 void BluetoothTaskManagerWin::RemoveObserver(Observer* observer) { |
159 DCHECK(observer); | 194 DCHECK(observer); |
160 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 195 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
161 observers_.RemoveObserver(observer); | 196 observers_.RemoveObserver(observer); |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 if (!win::BluetoothClassicWrapper::GetInstance()->FindDeviceClose(handle)) { | 509 if (!win::BluetoothClassicWrapper::GetInstance()->FindDeviceClose(handle)) { |
475 LogPollingError("Error calling BluetoothFindDeviceClose", | 510 LogPollingError("Error calling BluetoothFindDeviceClose", |
476 win::BluetoothClassicWrapper::GetInstance()->LastError()); | 511 win::BluetoothClassicWrapper::GetInstance()->LastError()); |
477 return false; | 512 return false; |
478 } | 513 } |
479 return true; | 514 return true; |
480 } | 515 } |
481 | 516 |
482 bool BluetoothTaskManagerWin::SearchLowEnergyDevices( | 517 bool BluetoothTaskManagerWin::SearchLowEnergyDevices( |
483 ScopedVector<DeviceState>* device_list) { | 518 ScopedVector<DeviceState>* device_list) { |
484 if (!win::IsBluetoothLowEnergySupported()) | 519 if (!win::BluetoothLowEnergyWrapper::GetInstance() |
| 520 ->IsBluetoothLowEnergySupported()) { |
485 return true; // Bluetooth LE not supported is not an error. | 521 return true; // Bluetooth LE not supported is not an error. |
| 522 } |
486 | 523 |
487 ScopedVector<win::BluetoothLowEnergyDeviceInfo> btle_devices; | 524 ScopedVector<win::BluetoothLowEnergyDeviceInfo> btle_devices; |
488 std::string error; | 525 std::string error; |
489 bool success = | 526 bool success = |
490 win::BluetoothLowEnergyWrapper::GetInstance() | 527 win::BluetoothLowEnergyWrapper::GetInstance() |
491 ->EnumerateKnownBluetoothLowEnergyDevices(&btle_devices, &error); | 528 ->EnumerateKnownBluetoothLowEnergyDevices(&btle_devices, &error); |
492 if (!success) { | 529 if (!success) { |
493 LogPollingError(error.c_str(), 0); | 530 LogPollingError(error.c_str(), 0); |
494 return false; | 531 return false; |
495 } | 532 } |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 LogPollingError("Error calling WSALookupServiceEnd", last_error); | 673 LogPollingError("Error calling WSALookupServiceEnd", last_error); |
637 return last_error; | 674 return last_error; |
638 } | 675 } |
639 | 676 |
640 return ERROR_SUCCESS; | 677 return ERROR_SUCCESS; |
641 } | 678 } |
642 | 679 |
643 bool BluetoothTaskManagerWin::DiscoverLowEnergyDeviceServices( | 680 bool BluetoothTaskManagerWin::DiscoverLowEnergyDeviceServices( |
644 const base::FilePath& device_path, | 681 const base::FilePath& device_path, |
645 ScopedVector<ServiceRecordState>* service_record_states) { | 682 ScopedVector<ServiceRecordState>* service_record_states) { |
646 if (!win::IsBluetoothLowEnergySupported()) | 683 if (!win::BluetoothLowEnergyWrapper::GetInstance() |
| 684 ->IsBluetoothLowEnergySupported()) { |
647 return true; // Bluetooth LE not supported is not an error. | 685 return true; // Bluetooth LE not supported is not an error. |
| 686 } |
648 | 687 |
649 std::string error; | 688 std::string error; |
650 ScopedVector<win::BluetoothLowEnergyServiceInfo> services; | 689 ScopedVector<win::BluetoothLowEnergyServiceInfo> services; |
651 bool success = win::BluetoothLowEnergyWrapper::GetInstance() | 690 bool success = win::BluetoothLowEnergyWrapper::GetInstance() |
652 ->EnumerateKnownBluetoothLowEnergyServices( | 691 ->EnumerateKnownBluetoothLowEnergyServices( |
653 device_path, &services, &error); | 692 device_path, &services, &error); |
654 if (!success) { | 693 if (!success) { |
655 LogPollingError(error.c_str(), 0); | 694 LogPollingError(error.c_str(), 0); |
656 return false; | 695 return false; |
657 } | 696 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 service_record_state->path = gatt_service_device->path; | 759 service_record_state->path = gatt_service_device->path; |
721 break; | 760 break; |
722 } | 761 } |
723 } | 762 } |
724 } | 763 } |
725 } | 764 } |
726 | 765 |
727 return true; | 766 return true; |
728 } | 767 } |
729 | 768 |
| 769 void BluetoothTaskManagerWin::GetGattIncludedCharacteristics( |
| 770 base::FilePath service_path, |
| 771 BluetoothUUID uuid, |
| 772 uint16_t attribute_handle, |
| 773 const GetGattIncludedCharacteristicsCallback& callback) { |
| 774 HRESULT hr = S_OK; |
| 775 scoped_ptr<BTH_LE_GATT_CHARACTERISTIC> win_characteristics_info; |
| 776 uint16_t number_of_charateristics = 0; |
| 777 |
| 778 BTH_LE_GATT_SERVICE win_service; |
| 779 if (BluetoothUUIDToWinBLEUUID(uuid, &(win_service.ServiceUuid))) { |
| 780 win_service.AttributeHandle = attribute_handle; |
| 781 hr = win::BluetoothLowEnergyWrapper::GetInstance() |
| 782 ->ReadCharacteristicsOfAService(service_path, &win_service, |
| 783 &win_characteristics_info, |
| 784 &number_of_charateristics); |
| 785 } else { |
| 786 hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER); |
| 787 } |
| 788 |
| 789 ui_task_runner_->PostTask( |
| 790 FROM_HERE, base::Bind(callback, base::Passed(&win_characteristics_info), |
| 791 number_of_charateristics, hr)); |
| 792 } |
| 793 |
| 794 void BluetoothTaskManagerWin::PostGetGattIncludedCharacteristics( |
| 795 const base::FilePath& service_path, |
| 796 const BluetoothUUID& uuid, |
| 797 uint16_t attribute_handle, |
| 798 const GetGattIncludedCharacteristicsCallback& callback) { |
| 799 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 800 bluetooth_task_runner_->PostTask( |
| 801 FROM_HERE, |
| 802 base::Bind(&BluetoothTaskManagerWin::GetGattIncludedCharacteristics, this, |
| 803 service_path, uuid, attribute_handle, callback)); |
| 804 } |
| 805 |
730 } // namespace device | 806 } // namespace device |
OLD | NEW |