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 |