Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(704)

Side by Side Diff: device/bluetooth/bluetooth_task_manager_win.cc

Issue 476823003: Fix Bluetooth Classic device polling issue. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address code review feedback. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/bluetooth/bluetooth_task_manager_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « device/bluetooth/bluetooth_task_manager_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698