| 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 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 } | 530 } |
| 531 } | 531 } |
| 532 return true; | 532 return true; |
| 533 } | 533 } |
| 534 | 534 |
| 535 bool BluetoothTaskManagerWin::DiscoverClassicDeviceServices( | 535 bool BluetoothTaskManagerWin::DiscoverClassicDeviceServices( |
| 536 const std::string& device_address, | 536 const std::string& device_address, |
| 537 const GUID& protocol_uuid, | 537 const GUID& protocol_uuid, |
| 538 bool search_cached_services_only, | 538 bool search_cached_services_only, |
| 539 ScopedVector<ServiceRecordState>* service_record_states) { | 539 ScopedVector<ServiceRecordState>* service_record_states) { |
| 540 int error_code = |
| 541 DiscoverClassicDeviceServicesWorker(device_address, |
| 542 protocol_uuid, |
| 543 search_cached_services_only, |
| 544 service_record_states); |
| 545 // If the device is "offline", no services are returned when specifying |
| 546 // "LUP_FLUSHCACHE". Try again without flushing the cache so that the list |
| 547 // of previously known services is returned. |
| 548 if (!search_cached_services_only && |
| 549 (error_code == WSASERVICE_NOT_FOUND || error_code == WSANO_DATA)) { |
| 550 error_code = DiscoverClassicDeviceServicesWorker( |
| 551 device_address, protocol_uuid, true, service_record_states); |
| 552 } |
| 553 |
| 554 return (error_code == ERROR_SUCCESS); |
| 555 } |
| 556 |
| 557 int BluetoothTaskManagerWin::DiscoverClassicDeviceServicesWorker( |
| 558 const std::string& device_address, |
| 559 const GUID& protocol_uuid, |
| 560 bool search_cached_services_only, |
| 561 ScopedVector<ServiceRecordState>* service_record_states) { |
| 540 // Bluetooth and WSAQUERYSET for Service Inquiry. See http://goo.gl/2v9pyt. | 562 // Bluetooth and WSAQUERYSET for Service Inquiry. See http://goo.gl/2v9pyt. |
| 541 WSAQUERYSET sdp_query; | 563 WSAQUERYSET sdp_query; |
| 542 ZeroMemory(&sdp_query, sizeof(sdp_query)); | 564 ZeroMemory(&sdp_query, sizeof(sdp_query)); |
| 543 sdp_query.dwSize = sizeof(sdp_query); | 565 sdp_query.dwSize = sizeof(sdp_query); |
| 544 GUID protocol = protocol_uuid; | 566 GUID protocol = protocol_uuid; |
| 545 sdp_query.lpServiceClassId = &protocol; | 567 sdp_query.lpServiceClassId = &protocol; |
| 546 sdp_query.dwNameSpace = NS_BTH; | 568 sdp_query.dwNameSpace = NS_BTH; |
| 547 wchar_t device_address_context[kMaxNumDeviceAddressChar]; | 569 wchar_t device_address_context[kMaxNumDeviceAddressChar]; |
| 548 std::size_t length = base::SysUTF8ToWide("(" + device_address + ")").copy( | 570 std::size_t length = base::SysUTF8ToWide("(" + device_address + ")").copy( |
| 549 device_address_context, kMaxNumDeviceAddressChar); | 571 device_address_context, kMaxNumDeviceAddressChar); |
| 550 device_address_context[length] = NULL; | 572 device_address_context[length] = NULL; |
| 551 sdp_query.lpszContext = device_address_context; | 573 sdp_query.lpszContext = device_address_context; |
| 552 DWORD control_flags = LUP_RETURN_ALL; | 574 DWORD control_flags = LUP_RETURN_ALL; |
| 553 // See http://goo.gl/t1Hulo: "Applications should generally specify | 575 // See http://goo.gl/t1Hulo: "Applications should generally specify |
| 554 // LUP_FLUSHCACHE. This flag instructs the system to ignore any cached | 576 // LUP_FLUSHCACHE. This flag instructs the system to ignore any cached |
| 555 // information and establish an over-the-air SDP connection to the specified | 577 // information and establish an over-the-air SDP connection to the specified |
| 556 // device to perform the SDP search. This non-cached operation may take | 578 // device to perform the SDP search. This non-cached operation may take |
| 557 // several seconds (whereas a cached search returns quickly)." | 579 // several seconds (whereas a cached search returns quickly)." |
| 558 // In summary, we need to specify LUP_FLUSHCACHE if we want to obtain the list | 580 // In summary, we need to specify LUP_FLUSHCACHE if we want to obtain the list |
| 559 // of services for devices which have not been discovered before. | 581 // of services for devices which have not been discovered before. |
| 560 if (!search_cached_services_only) | 582 if (!search_cached_services_only) |
| 561 control_flags |= LUP_FLUSHCACHE; | 583 control_flags |= LUP_FLUSHCACHE; |
| 562 HANDLE sdp_handle; | 584 HANDLE sdp_handle; |
| 563 if (ERROR_SUCCESS != | 585 if (ERROR_SUCCESS != |
| 564 WSALookupServiceBegin(&sdp_query, control_flags, &sdp_handle)) { | 586 WSALookupServiceBegin(&sdp_query, control_flags, &sdp_handle)) { |
| 565 LogPollingError("Error calling WSALookupServiceBegin", WSAGetLastError()); | 587 int last_error = WSAGetLastError(); |
| 566 return false; | 588 // If the device is "offline", no services are returned when specifying |
| 589 // "LUP_FLUSHCACHE". Don't log error in that case. |
| 590 if (!search_cached_services_only && |
| 591 (last_error == WSASERVICE_NOT_FOUND || last_error == WSANO_DATA)) { |
| 592 return last_error; |
| 593 } |
| 594 LogPollingError("Error calling WSALookupServiceBegin", last_error); |
| 595 return last_error; |
| 567 } | 596 } |
| 568 char sdp_buffer[kServiceDiscoveryResultBufferSize]; | 597 char sdp_buffer[kServiceDiscoveryResultBufferSize]; |
| 569 LPWSAQUERYSET sdp_result_data = reinterpret_cast<LPWSAQUERYSET>(sdp_buffer); | 598 LPWSAQUERYSET sdp_result_data = reinterpret_cast<LPWSAQUERYSET>(sdp_buffer); |
| 570 while (true) { | 599 while (true) { |
| 571 DWORD sdp_buffer_size = sizeof(sdp_buffer); | 600 DWORD sdp_buffer_size = sizeof(sdp_buffer); |
| 572 if (ERROR_SUCCESS != | 601 if (ERROR_SUCCESS != |
| 573 WSALookupServiceNext( | 602 WSALookupServiceNext( |
| 574 sdp_handle, control_flags, &sdp_buffer_size, sdp_result_data)) { | 603 sdp_handle, control_flags, &sdp_buffer_size, sdp_result_data)) { |
| 575 int last_error = WSAGetLastError(); | 604 int last_error = WSAGetLastError(); |
| 576 if (last_error == WSA_E_NO_MORE || last_error == WSAENOMORE) { | 605 if (last_error == WSA_E_NO_MORE || last_error == WSAENOMORE) { |
| 577 break; | 606 break; |
| 578 } | 607 } |
| 579 LogPollingError("Error calling WSALookupServiceNext", last_error); | 608 LogPollingError("Error calling WSALookupServiceNext", last_error); |
| 580 WSALookupServiceEnd(sdp_handle); | 609 WSALookupServiceEnd(sdp_handle); |
| 581 return false; | 610 return last_error; |
| 582 } | 611 } |
| 583 ServiceRecordState* service_record_state = new ServiceRecordState(); | 612 ServiceRecordState* service_record_state = new ServiceRecordState(); |
| 584 service_record_state->name = | 613 service_record_state->name = |
| 585 base::SysWideToUTF8(sdp_result_data->lpszServiceInstanceName); | 614 base::SysWideToUTF8(sdp_result_data->lpszServiceInstanceName); |
| 586 for (uint64 i = 0; i < sdp_result_data->lpBlob->cbSize; i++) { | 615 for (uint64 i = 0; i < sdp_result_data->lpBlob->cbSize; i++) { |
| 587 service_record_state->sdp_bytes.push_back( | 616 service_record_state->sdp_bytes.push_back( |
| 588 sdp_result_data->lpBlob->pBlobData[i]); | 617 sdp_result_data->lpBlob->pBlobData[i]); |
| 589 } | 618 } |
| 590 service_record_states->push_back(service_record_state); | 619 service_record_states->push_back(service_record_state); |
| 591 } | 620 } |
| 592 if (ERROR_SUCCESS != WSALookupServiceEnd(sdp_handle)) { | 621 if (ERROR_SUCCESS != WSALookupServiceEnd(sdp_handle)) { |
| 593 LogPollingError("Error calling WSALookupServiceEnd", WSAGetLastError()); | 622 int last_error = WSAGetLastError(); |
| 594 return false; | 623 LogPollingError("Error calling WSALookupServiceEnd", last_error); |
| 624 return last_error; |
| 595 } | 625 } |
| 596 | 626 |
| 597 return true; | 627 return ERROR_SUCCESS; |
| 598 } | 628 } |
| 599 | 629 |
| 600 bool BluetoothTaskManagerWin::DiscoverLowEnergyDeviceServices( | 630 bool BluetoothTaskManagerWin::DiscoverLowEnergyDeviceServices( |
| 601 const base::FilePath& device_path, | 631 const base::FilePath& device_path, |
| 602 ScopedVector<ServiceRecordState>* service_record_states) { | 632 ScopedVector<ServiceRecordState>* service_record_states) { |
| 603 if (!win::IsBluetoothLowEnergySupported()) | 633 if (!win::IsBluetoothLowEnergySupported()) |
| 604 return true; // Bluetooth LE not supported is not an error. | 634 return true; // Bluetooth LE not supported is not an error. |
| 605 | 635 |
| 606 std::string error; | 636 std::string error; |
| 607 ScopedVector<win::BluetoothLowEnergyServiceInfo> services; | 637 ScopedVector<win::BluetoothLowEnergyServiceInfo> services; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 618 ++iter2) { | 648 ++iter2) { |
| 619 ServiceRecordState* service_state = new ServiceRecordState(); | 649 ServiceRecordState* service_state = new ServiceRecordState(); |
| 620 service_state->gatt_uuid = | 650 service_state->gatt_uuid = |
| 621 BluetoothLowEnergyUuidToBluetoothUuid((*iter2)->uuid); | 651 BluetoothLowEnergyUuidToBluetoothUuid((*iter2)->uuid); |
| 622 service_record_states->push_back(service_state); | 652 service_record_states->push_back(service_state); |
| 623 } | 653 } |
| 624 return true; | 654 return true; |
| 625 } | 655 } |
| 626 | 656 |
| 627 } // namespace device | 657 } // namespace device |
| OLD | NEW |