Chromium Code Reviews| 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 DWORD sdp_buffer_size = sizeof(sdp_buffer); | |
| 100 while (ERROR_SUCCESS == | |
| 101 WSALookupServiceNext( | |
| 102 sdp_handle, LUP_RETURN_ALL, &sdp_buffer_size, sdp_result_data)) { | |
| 103 ServiceRecordState* service_record_state = new ServiceRecordState(); | |
| 104 service_record_state->name = | |
| 105 base::SysWideToUTF8(sdp_result_data->lpszServiceInstanceName); | |
| 106 service_record_state->address = device_address; | |
| 107 for (uint64 i = 0; i < sdp_result_data->lpBlob->cbSize; i++) { | |
| 108 service_record_state->sdp_bytes.push_back( | |
| 109 sdp_result_data->lpBlob->pBlobData[i]); | |
| 110 } | |
| 111 service_record_states->push_back(service_record_state); | |
| 112 } | |
| 113 WSALookupServiceEnd(sdp_handle); | |
| 114 } | |
| 115 | |
| 74 } // namespace | 116 } // namespace |
| 75 | 117 |
| 76 namespace device { | 118 namespace device { |
| 77 | 119 |
| 78 // static | 120 // static |
| 79 const int BluetoothTaskManagerWin::kPollIntervalMs = 500; | 121 const int BluetoothTaskManagerWin::kPollIntervalMs = 500; |
| 80 | 122 |
| 81 BluetoothTaskManagerWin::BluetoothTaskManagerWin( | 123 BluetoothTaskManagerWin::BluetoothTaskManagerWin( |
| 82 scoped_refptr<base::SequencedTaskRunner> ui_task_runner) | 124 scoped_refptr<base::SequencedTaskRunner> ui_task_runner) |
| 83 : ui_task_runner_(ui_task_runner), | 125 : ui_task_runner_(ui_task_runner), |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 368 void BluetoothTaskManagerWin::DiscoverServices( | 410 void BluetoothTaskManagerWin::DiscoverServices( |
| 369 ScopedVector<DeviceState>* device_list) { | 411 ScopedVector<DeviceState>* device_list) { |
| 370 DCHECK(bluetooth_task_runner_->RunsTasksOnCurrentThread()); | 412 DCHECK(bluetooth_task_runner_->RunsTasksOnCurrentThread()); |
| 371 net::EnsureWinsockInit(); | 413 net::EnsureWinsockInit(); |
| 372 for (ScopedVector<DeviceState>::iterator iter = device_list->begin(); | 414 for (ScopedVector<DeviceState>::iterator iter = device_list->begin(); |
| 373 iter != device_list->end(); | 415 iter != device_list->end(); |
| 374 ++iter) { | 416 ++iter) { |
| 375 const std::string device_address = (*iter)->address; | 417 const std::string device_address = (*iter)->address; |
| 376 ScopedVector<ServiceRecordState>* service_record_states = | 418 ScopedVector<ServiceRecordState>* service_record_states = |
| 377 &(*iter)->service_record_states; | 419 &(*iter)->service_record_states; |
| 378 WSAQUERYSET sdp_query; | 420 |
| 379 ZeroMemory(&sdp_query, sizeof(sdp_query)); | 421 // TODO(rpaquay): Find a better way to enumerate registered protocols. |
| 380 sdp_query.dwSize = sizeof(sdp_query); | 422 DiscoverDeviceServices( |
| 381 GUID protocol = L2CAP_PROTOCOL_UUID; | 423 device_address, SDP_PROTOCOL_UUID, service_record_states); |
| 382 sdp_query.lpServiceClassId = &protocol; | 424 DiscoverDeviceServices( |
| 383 sdp_query.dwNameSpace = NS_BTH; | 425 device_address, UDP_PROTOCOL_UUID, service_record_states); |
| 384 wchar_t device_address_context[kMaxNumDeviceAddressChar]; | 426 DiscoverDeviceServices( |
| 385 std::size_t length = | 427 device_address, RFCOMM_PROTOCOL_UUID, service_record_states); |
| 386 base::SysUTF8ToWide("(" + device_address + ")").copy( | 428 DiscoverDeviceServices( |
| 387 device_address_context, kMaxNumDeviceAddressChar); | 429 device_address, TCP_PROTOCOL_UUID, service_record_states); |
| 388 device_address_context[length] = NULL; | 430 DiscoverDeviceServices( |
| 389 sdp_query.lpszContext = device_address_context; | 431 device_address, TCSBIN_PROTOCOL_UUID, service_record_states); |
| 390 HANDLE sdp_handle; | 432 DiscoverDeviceServices( |
| 391 if (ERROR_SUCCESS != | 433 device_address, TCSAT_PROTOCOL_UUID, service_record_states); |
| 392 WSALookupServiceBegin(&sdp_query, LUP_RETURN_ALL, &sdp_handle)) { | 434 DiscoverDeviceServices( |
| 393 return; | 435 device_address, OBEX_PROTOCOL_UUID, service_record_states); |
| 394 } | 436 DiscoverDeviceServices( |
| 395 char sdp_buffer[kServiceDiscoveryResultBufferSize]; | 437 device_address, IP_PROTOCOL_UUID, service_record_states); |
| 396 LPWSAQUERYSET sdp_result_data = reinterpret_cast<LPWSAQUERYSET>(sdp_buffer); | 438 DiscoverDeviceServices( |
| 397 DWORD sdp_buffer_size = sizeof(sdp_buffer); | 439 device_address, FTP_PROTOCOL_UUID, service_record_states); |
| 398 while (ERROR_SUCCESS == WSALookupServiceNext(sdp_handle, | 440 DiscoverDeviceServices( |
| 399 LUP_RETURN_ALL, | 441 device_address, HTTP_PROTOCOL_UUID, service_record_states); |
| 400 &sdp_buffer_size, | 442 DiscoverDeviceServices( |
| 401 sdp_result_data)) { | 443 device_address, WSP_PROTOCOL_UUID, service_record_states); |
| 402 ServiceRecordState* service_record_state = new ServiceRecordState(); | 444 DiscoverDeviceServices( |
| 403 service_record_state->name = | 445 device_address, BNEP_PROTOCOL_UUID, service_record_states); |
| 404 base::SysWideToUTF8(sdp_result_data->lpszServiceInstanceName); | 446 DiscoverDeviceServices( |
| 405 service_record_state->address = device_address; | 447 device_address, UPNP_PROTOCOL_UUID, service_record_states); |
| 406 for (uint64 i = 0; i < sdp_result_data->lpBlob->cbSize; i++) { | 448 DiscoverDeviceServices( |
| 407 service_record_state->sdp_bytes.push_back( | 449 device_address, HID_PROTOCOL_UUID, service_record_states); |
| 408 sdp_result_data->lpBlob->pBlobData[i]); | 450 DiscoverDeviceServices( |
| 409 } | 451 device_address, HCCC_PROTOCOL_UUID, service_record_states); |
| 410 service_record_states->push_back(service_record_state); | 452 DiscoverDeviceServices( |
| 411 } | 453 device_address, HCDC_PROTOCOL_UUID, service_record_states); |
| 412 WSALookupServiceEnd(sdp_handle); | 454 DiscoverDeviceServices( |
| 455 device_address, HN_PROTOCOL_UUID, service_record_states); | |
| 456 DiscoverDeviceServices( | |
| 457 device_address, AVCTP_PROTOCOL_UUID, service_record_states); | |
| 458 DiscoverDeviceServices( | |
| 459 device_address, AVDTP_PROTOCOL_UUID, service_record_states); | |
| 460 DiscoverDeviceServices( | |
| 461 device_address, CMPT_PROTOCOL_UUID, service_record_states); | |
| 462 DiscoverDeviceServices( | |
| 463 device_address, UDI_C_PLANE_PROTOCOL_UUID, service_record_states); | |
| 464 DiscoverDeviceServices( | |
| 465 device_address, L2CAP_PROTOCOL_UUID, service_record_states); | |
|
xiyuan
2014/03/17 22:55:11
It seems we only need enumerate L2CAP_PROTOCOL_UUI
rpaquay
2014/03/20 00:48:18
Done.
| |
| 466 | |
| 467 // TODO(rpaquay): Workaround issue where this profile is not discovered. | |
| 468 DiscoverDeviceServices( | |
| 469 device_address, OBEXObjectPushServiceClass_UUID, service_record_states); | |
| 413 } | 470 } |
| 414 } | 471 } |
| 415 | 472 |
| 416 } // namespace device | 473 } // namespace device |
| OLD | NEW |