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 <winsock2.h> | 7 #include <winsock2.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "net/base/winsock_init.h" | 23 #include "net/base/winsock_init.h" |
24 | 24 |
25 namespace { | 25 namespace { |
26 | 26 |
27 const int kNumThreadsInWorkerPool = 3; | 27 const int kNumThreadsInWorkerPool = 3; |
28 const char kBluetoothThreadName[] = "BluetoothPollingThreadWin"; | 28 const char kBluetoothThreadName[] = "BluetoothPollingThreadWin"; |
29 const int kMaxNumDeviceAddressChar = 127; | 29 const int kMaxNumDeviceAddressChar = 127; |
30 const int kServiceDiscoveryResultBufferSize = 5000; | 30 const int kServiceDiscoveryResultBufferSize = 5000; |
31 const int kMaxDeviceDiscoveryTimeout = 48; | 31 const int kMaxDeviceDiscoveryTimeout = 48; |
32 | 32 |
| 33 typedef device::BluetoothTaskManagerWin::ServiceRecordState ServiceRecordState; |
| 34 |
33 // Populates bluetooth adapter state using adapter_handle. | 35 // Populates bluetooth adapter state using adapter_handle. |
34 void GetAdapterState(HANDLE adapter_handle, | 36 void GetAdapterState(HANDLE adapter_handle, |
35 device::BluetoothTaskManagerWin::AdapterState* state) { | 37 device::BluetoothTaskManagerWin::AdapterState* state) { |
36 std::string name; | 38 std::string name; |
37 std::string address; | 39 std::string address; |
38 bool powered = false; | 40 bool powered = false; |
39 BLUETOOTH_RADIO_INFO adapter_info = { sizeof(BLUETOOTH_RADIO_INFO), 0 }; | 41 BLUETOOTH_RADIO_INFO adapter_info = { sizeof(BLUETOOTH_RADIO_INFO), 0 }; |
40 if (adapter_handle && | 42 if (adapter_handle && |
41 ERROR_SUCCESS == BluetoothGetRadioInfo(adapter_handle, | 43 ERROR_SUCCESS == BluetoothGetRadioInfo(adapter_handle, |
42 &adapter_info)) { | 44 &adapter_info)) { |
(...skipping 21 matching lines...) Expand all Loading... |
64 device_info.Address.rgBytes[3], | 66 device_info.Address.rgBytes[3], |
65 device_info.Address.rgBytes[2], | 67 device_info.Address.rgBytes[2], |
66 device_info.Address.rgBytes[1], | 68 device_info.Address.rgBytes[1], |
67 device_info.Address.rgBytes[0]); | 69 device_info.Address.rgBytes[0]); |
68 state->bluetooth_class = device_info.ulClassofDevice; | 70 state->bluetooth_class = device_info.ulClassofDevice; |
69 state->visible = true; | 71 state->visible = true; |
70 state->connected = !!device_info.fConnected; | 72 state->connected = !!device_info.fConnected; |
71 state->authenticated = !!device_info.fAuthenticated; | 73 state->authenticated = !!device_info.fAuthenticated; |
72 } | 74 } |
73 | 75 |
| 76 void DiscoverDeviceServices( |
| 77 const std::string& device_address, |
| 78 const GUID& protocol_uuid, |
| 79 ScopedVector<ServiceRecordState>* service_record_states) { |
| 80 // Bluetooth and WSAQUERYSET for Service Inquiry. See http://goo.gl/2v9pyt. |
| 81 WSAQUERYSET sdp_query; |
| 82 ZeroMemory(&sdp_query, sizeof(sdp_query)); |
| 83 sdp_query.dwSize = sizeof(sdp_query); |
| 84 GUID protocol = protocol_uuid; |
| 85 sdp_query.lpServiceClassId = &protocol; |
| 86 sdp_query.dwNameSpace = NS_BTH; |
| 87 wchar_t device_address_context[kMaxNumDeviceAddressChar]; |
| 88 std::size_t length = base::SysUTF8ToWide("(" + device_address + ")").copy( |
| 89 device_address_context, kMaxNumDeviceAddressChar); |
| 90 device_address_context[length] = NULL; |
| 91 sdp_query.lpszContext = device_address_context; |
| 92 HANDLE sdp_handle; |
| 93 if (ERROR_SUCCESS != |
| 94 WSALookupServiceBegin(&sdp_query, LUP_RETURN_ALL, &sdp_handle)) { |
| 95 return; |
| 96 } |
| 97 char sdp_buffer[kServiceDiscoveryResultBufferSize]; |
| 98 LPWSAQUERYSET sdp_result_data = reinterpret_cast<LPWSAQUERYSET>(sdp_buffer); |
| 99 while (true) { |
| 100 DWORD sdp_buffer_size = sizeof(sdp_buffer); |
| 101 if (ERROR_SUCCESS != |
| 102 WSALookupServiceNext( |
| 103 sdp_handle, LUP_RETURN_ALL, &sdp_buffer_size, sdp_result_data)) { |
| 104 break; |
| 105 } |
| 106 ServiceRecordState* service_record_state = new ServiceRecordState(); |
| 107 service_record_state->name = |
| 108 base::SysWideToUTF8(sdp_result_data->lpszServiceInstanceName); |
| 109 service_record_state->address = device_address; |
| 110 for (uint64 i = 0; i < sdp_result_data->lpBlob->cbSize; i++) { |
| 111 service_record_state->sdp_bytes.push_back( |
| 112 sdp_result_data->lpBlob->pBlobData[i]); |
| 113 } |
| 114 service_record_states->push_back(service_record_state); |
| 115 } |
| 116 WSALookupServiceEnd(sdp_handle); |
| 117 } |
| 118 |
74 } // namespace | 119 } // namespace |
75 | 120 |
76 namespace device { | 121 namespace device { |
77 | 122 |
78 // static | 123 // static |
79 const int BluetoothTaskManagerWin::kPollIntervalMs = 500; | 124 const int BluetoothTaskManagerWin::kPollIntervalMs = 500; |
80 | 125 |
81 BluetoothTaskManagerWin::BluetoothTaskManagerWin( | 126 BluetoothTaskManagerWin::BluetoothTaskManagerWin( |
82 scoped_refptr<base::SequencedTaskRunner> ui_task_runner) | 127 scoped_refptr<base::SequencedTaskRunner> ui_task_runner) |
83 : ui_task_runner_(ui_task_runner), | 128 : ui_task_runner_(ui_task_runner), |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 void BluetoothTaskManagerWin::DiscoverServices( | 413 void BluetoothTaskManagerWin::DiscoverServices( |
369 ScopedVector<DeviceState>* device_list) { | 414 ScopedVector<DeviceState>* device_list) { |
370 DCHECK(bluetooth_task_runner_->RunsTasksOnCurrentThread()); | 415 DCHECK(bluetooth_task_runner_->RunsTasksOnCurrentThread()); |
371 net::EnsureWinsockInit(); | 416 net::EnsureWinsockInit(); |
372 for (ScopedVector<DeviceState>::iterator iter = device_list->begin(); | 417 for (ScopedVector<DeviceState>::iterator iter = device_list->begin(); |
373 iter != device_list->end(); | 418 iter != device_list->end(); |
374 ++iter) { | 419 ++iter) { |
375 const std::string device_address = (*iter)->address; | 420 const std::string device_address = (*iter)->address; |
376 ScopedVector<ServiceRecordState>* service_record_states = | 421 ScopedVector<ServiceRecordState>* service_record_states = |
377 &(*iter)->service_record_states; | 422 &(*iter)->service_record_states; |
378 WSAQUERYSET sdp_query; | 423 |
379 ZeroMemory(&sdp_query, sizeof(sdp_query)); | 424 DiscoverDeviceServices( |
380 sdp_query.dwSize = sizeof(sdp_query); | 425 device_address, L2CAP_PROTOCOL_UUID, service_record_states); |
381 GUID protocol = L2CAP_PROTOCOL_UUID; | |
382 sdp_query.lpServiceClassId = &protocol; | |
383 sdp_query.dwNameSpace = NS_BTH; | |
384 wchar_t device_address_context[kMaxNumDeviceAddressChar]; | |
385 std::size_t length = | |
386 base::SysUTF8ToWide("(" + device_address + ")").copy( | |
387 device_address_context, kMaxNumDeviceAddressChar); | |
388 device_address_context[length] = NULL; | |
389 sdp_query.lpszContext = device_address_context; | |
390 HANDLE sdp_handle; | |
391 if (ERROR_SUCCESS != | |
392 WSALookupServiceBegin(&sdp_query, LUP_RETURN_ALL, &sdp_handle)) { | |
393 return; | |
394 } | |
395 char sdp_buffer[kServiceDiscoveryResultBufferSize]; | |
396 LPWSAQUERYSET sdp_result_data = reinterpret_cast<LPWSAQUERYSET>(sdp_buffer); | |
397 DWORD sdp_buffer_size = sizeof(sdp_buffer); | |
398 while (ERROR_SUCCESS == WSALookupServiceNext(sdp_handle, | |
399 LUP_RETURN_ALL, | |
400 &sdp_buffer_size, | |
401 sdp_result_data)) { | |
402 ServiceRecordState* service_record_state = new ServiceRecordState(); | |
403 service_record_state->name = | |
404 base::SysWideToUTF8(sdp_result_data->lpszServiceInstanceName); | |
405 service_record_state->address = device_address; | |
406 for (uint64 i = 0; i < sdp_result_data->lpBlob->cbSize; i++) { | |
407 service_record_state->sdp_bytes.push_back( | |
408 sdp_result_data->lpBlob->pBlobData[i]); | |
409 } | |
410 service_record_states->push_back(service_record_state); | |
411 } | |
412 WSALookupServiceEnd(sdp_handle); | |
413 } | 426 } |
414 } | 427 } |
415 | 428 |
416 } // namespace device | 429 } // namespace device |
OLD | NEW |