diff options
author | youngki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-20 01:09:51 +0000 |
---|---|---|
committer | youngki@chromium.org <youngki@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-20 01:09:51 +0000 |
commit | 47c72649498d249e23e3f688f83f021a8a053f99 (patch) | |
tree | c86b470a735c84638d579855affa886c0d08790f /device | |
parent | 515274968ee4b3be3564231d923dccff5b0e5858 (diff) | |
download | chromium_src-47c72649498d249e23e3f688f83f021a8a053f99.zip chromium_src-47c72649498d249e23e3f688f83f021a8a053f99.tar.gz chromium_src-47c72649498d249e23e3f688f83f021a8a053f99.tar.bz2 |
Implemented BluetoothServiceRecordWin.
I am not sure if unittest is worthwhile for BluetoothServiceRecordWin since the raw byte stream that BluetoothServiceRecordWin is getting is very windows-specific.. I could get some byte dumps and use that to implement a simple unittest that just verifies that we are parsing uuid correctly, but I am not sure if that's worthwhile.
BUG=135470
Review URL: https://chromiumcodereview.appspot.com/11969030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@177861 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'device')
-rw-r--r-- | device/bluetooth/bluetooth_includes_win.h | 20 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_service_record_win.cc | 130 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_service_record_win.h | 25 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_service_record_win_unittest.cc | 66 | ||||
-rw-r--r-- | device/bluetooth/bluetooth_task_manager_win.cc | 9 | ||||
-rw-r--r-- | device/device.gyp | 4 |
6 files changed, 246 insertions, 8 deletions
diff --git a/device/bluetooth/bluetooth_includes_win.h b/device/bluetooth/bluetooth_includes_win.h new file mode 100644 index 0000000..ed9bd6b --- /dev/null +++ b/device/bluetooth/bluetooth_includes_win.h @@ -0,0 +1,20 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_BLUETOOTH_BLUETOOTH_INCLUDES_WIN_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_INCLUDES_WIN_H_ + +// windows.h needs to be included before BluetoothAPIs.h. +#include <windows.h> + +#include <BluetoothAPIs.h> +#if defined(_WIN32_WINNT_WIN8) && _MSC_VER < 1700 +// The Windows 8 SDK defines FACILITY_VISUALCPP in winerror.h. +#undef FACILITY_VISUALCPP +#endif +#include <delayimp.h> + +#pragma comment(lib, "Bthprops.lib") + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_INCLUDES_WIN_H_
\ No newline at end of file diff --git a/device/bluetooth/bluetooth_service_record_win.cc b/device/bluetooth/bluetooth_service_record_win.cc new file mode 100644 index 0000000..54e5fbd --- /dev/null +++ b/device/bluetooth/bluetooth_service_record_win.cc @@ -0,0 +1,130 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device/bluetooth/bluetooth_service_record_win.h" + +#include <string> + +#include "base/basictypes.h" +#include "base/stringprintf.h" +#include "device/bluetooth/bluetooth_includes_win.h" +#include "device/bluetooth/bluetooth_utils.h" + +namespace { + +const uint16 kProtocolDescriptorListId = 4; +const uint16 kRfcommUuid = 3; +const uint16 kUuidId = 1; + +bool AdvanceToSdpType(const SDP_ELEMENT_DATA& sequence_data, + SDP_TYPE type, + HBLUETOOTH_CONTAINER_ELEMENT* element, + SDP_ELEMENT_DATA* sdp_data) { + while (ERROR_SUCCESS == BluetoothSdpGetContainerElementData( + sequence_data.data.sequence.value, + sequence_data.data.sequence.length, + element, + sdp_data)) { + if (sdp_data->type == type) { + return true; + } + } + return false; +} + +void ExtractChannels(const SDP_ELEMENT_DATA& protocol_descriptor_list_data, + bool* supports_rfcomm, + uint8* rfcomm_channel) { + HBLUETOOTH_CONTAINER_ELEMENT sequence_element = NULL; + SDP_ELEMENT_DATA sequence_data; + while (AdvanceToSdpType(protocol_descriptor_list_data, + SDP_TYPE_SEQUENCE, + &sequence_element, + &sequence_data)) { + HBLUETOOTH_CONTAINER_ELEMENT inner_sequence_element = NULL; + SDP_ELEMENT_DATA inner_sequence_data; + if (AdvanceToSdpType(sequence_data, + SDP_TYPE_UUID, + &inner_sequence_element, + &inner_sequence_data) && + inner_sequence_data.data.uuid32 == kRfcommUuid && + AdvanceToSdpType(sequence_data, + SDP_TYPE_UINT, + &inner_sequence_element, + &inner_sequence_data) && + inner_sequence_data.specificType == SDP_ST_UINT8) { + *rfcomm_channel = inner_sequence_data.data.uint8; + *supports_rfcomm = true; + } + } +} + +void ExtractUuid(const SDP_ELEMENT_DATA& uuid_data, std::string* uuid) { + HBLUETOOTH_CONTAINER_ELEMENT inner_uuid_element = NULL; + SDP_ELEMENT_DATA inner_uuid_data; + if (AdvanceToSdpType(uuid_data, + SDP_TYPE_UUID, + &inner_uuid_element, + &inner_uuid_data)) { + if (inner_uuid_data.specificType == SDP_ST_UUID16) { + std::string uuid_hex = + base::StringPrintf("%04x", inner_uuid_data.data.uuid16); + *uuid = device::bluetooth_utils::CanonicalUuid(uuid_hex); + } else if (inner_uuid_data.specificType == SDP_ST_UUID32) { + std::string uuid_hex = + base::StringPrintf("%08x", inner_uuid_data.data.uuid32); + *uuid = device::bluetooth_utils::CanonicalUuid(uuid_hex); + } else if (inner_uuid_data.specificType == SDP_ST_UUID128) { + *uuid = base::StringPrintf( + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + inner_uuid_data.data.uuid128.Data1, + inner_uuid_data.data.uuid128.Data2, + inner_uuid_data.data.uuid128.Data3, + inner_uuid_data.data.uuid128.Data4[0], + inner_uuid_data.data.uuid128.Data4[1], + inner_uuid_data.data.uuid128.Data4[2], + inner_uuid_data.data.uuid128.Data4[3], + inner_uuid_data.data.uuid128.Data4[4], + inner_uuid_data.data.uuid128.Data4[5], + inner_uuid_data.data.uuid128.Data4[6], + inner_uuid_data.data.uuid128.Data4[7]); + } else { + uuid->clear(); + } + } +} + +} // namespace + +namespace device { + +BluetoothServiceRecordWin::BluetoothServiceRecordWin( + const std::string& name, + const std::string& address, + uint64 blob_size, + uint8* blob_data) { + name_ = name; + address_ = address; + supports_rfcomm_ = false; + SDP_ELEMENT_DATA protocol_descriptor_list_data; + if (ERROR_SUCCESS == BluetoothSdpGetAttributeValue( + blob_data, + blob_size, + kProtocolDescriptorListId, + &protocol_descriptor_list_data)) { + ExtractChannels(protocol_descriptor_list_data, + &supports_rfcomm_, + &rfcomm_channel_); + } + SDP_ELEMENT_DATA uuid_data; + if (ERROR_SUCCESS == BluetoothSdpGetAttributeValue( + blob_data, + blob_size, + kUuidId, + &uuid_data)) { + ExtractUuid(uuid_data, &uuid_); + } +} + +} // namespace device
\ No newline at end of file diff --git a/device/bluetooth/bluetooth_service_record_win.h b/device/bluetooth/bluetooth_service_record_win.h new file mode 100644 index 0000000..bf631b5 --- /dev/null +++ b/device/bluetooth/bluetooth_service_record_win.h @@ -0,0 +1,25 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_BLUETOOTH_BLUETOOTH_SERVICE_RECORD_WIN_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_SERVICE_RECORD_WIN_H_ + +#include <string> + +#include "base/basictypes.h" +#include "device/bluetooth/bluetooth_service_record.h" + +namespace device { + +class BluetoothServiceRecordWin : public BluetoothServiceRecord { + public: + BluetoothServiceRecordWin(const std::string& name, + const std::string& address, + uint64 blob_size, + uint8* blob_data); +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_SERVICE_RECORD_WIN_H_ diff --git a/device/bluetooth/bluetooth_service_record_win_unittest.cc b/device/bluetooth/bluetooth_service_record_win_unittest.cc new file mode 100644 index 0000000..ee2b419 --- /dev/null +++ b/device/bluetooth/bluetooth_service_record_win_unittest.cc @@ -0,0 +1,66 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/basictypes.h" +#include "base/string_number_conversions.h" +#include "device/bluetooth/bluetooth_service_record_win.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const char kTestNoRfcommSdpBytes[] = + "35510900000a00010001090001350319110a09000435103506190100090019350619001909" + "010209000535031910020900093508350619110d090102090100250c417564696f20536f75" + "726365090311090001"; +const int kTestNoRfcommSdpBytesSize = sizeof(kTestNoRfcommSdpBytes) / 2; +const char kTestNoRfcommSdpUuid[] = "0000110a-0000-1000-8000-00805f9b34fb"; + +const char kTestRfcommSdpBytes[] = + "354b0900000a000100030900013506191112191203090004350c3503190100350519000308" + "0b090005350319100209000935083506191108090100090100250d566f6963652047617465" + "776179"; +const int kTestRfcommSdpBytesSize = sizeof(kTestRfcommSdpBytes) / 2; +const char kTestRfcommSdpUuid[] = "00001112-0000-1000-8000-00805f9b34fb"; +const int kTestRfcommChannel = 11; + +} // namespace + +namespace device { + +class BluetoothServiceRecordWinTest : public testing::Test { + protected: + void ConvertSdpBytes(const char* sdp_hex_char, uint8* sdp_bytes_array) { + std::vector<uint8> sdp_bytes_vector; + base::HexStringToBytes(sdp_hex_char, &sdp_bytes_vector); + std::copy(sdp_bytes_vector.begin(), + sdp_bytes_vector.end(), + sdp_bytes_array); + } +}; + +TEST_F(BluetoothServiceRecordWinTest, NoRfcommSdp) { + uint8 sdp_bytes_array[kTestNoRfcommSdpBytesSize]; + ConvertSdpBytes(kTestNoRfcommSdpBytes, sdp_bytes_array); + BluetoothServiceRecordWin service_record("NoRfcommSdp", + "Service Address", + kTestNoRfcommSdpBytesSize, + sdp_bytes_array); + EXPECT_STREQ(kTestNoRfcommSdpUuid, service_record.uuid().c_str()); + EXPECT_FALSE(service_record.SupportsRfcomm()); +} + + +TEST_F(BluetoothServiceRecordWinTest, RfcommSdp) { + uint8 sdp_bytes_array[kTestRfcommSdpBytesSize]; + ConvertSdpBytes(kTestRfcommSdpBytes, sdp_bytes_array); + BluetoothServiceRecordWin service_record("RfcommSdp", + "Service Address", + kTestRfcommSdpBytesSize, + sdp_bytes_array); + EXPECT_STREQ(kTestRfcommSdpUuid, service_record.uuid().c_str()); + EXPECT_TRUE(service_record.SupportsRfcomm()); + EXPECT_EQ(kTestRfcommChannel, service_record.rfcomm_channel()); +} + +} // namespace device
\ No newline at end of file diff --git a/device/bluetooth/bluetooth_task_manager_win.cc b/device/bluetooth/bluetooth_task_manager_win.cc index b124139..144682f6 100644 --- a/device/bluetooth/bluetooth_task_manager_win.cc +++ b/device/bluetooth/bluetooth_task_manager_win.cc @@ -4,12 +4,6 @@ #include "device/bluetooth/bluetooth_task_manager_win.h" -#include <BluetoothAPIs.h> -#if defined(_WIN32_WINNT_WIN8) && _MSC_VER < 1700 -// The Windows 8 SDK defines FACILITY_VISUALCPP in winerror.h. -#undef FACILITY_VISUALCPP -#endif -#include <delayimp.h> #include <string> #include "base/bind.h" @@ -21,8 +15,7 @@ #include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_restrictions.h" #include "base/win/scoped_handle.h" - -#pragma comment(lib, "Bthprops.lib") +#include "device/bluetooth/bluetooth_includes_win.h" namespace { diff --git a/device/device.gyp b/device/device.gyp index bc54b76..7d3af8e 100644 --- a/device/device.gyp +++ b/device/device.gyp @@ -30,11 +30,14 @@ 'bluetooth/bluetooth_device_chromeos.h', 'bluetooth/bluetooth_device_win.cc', 'bluetooth/bluetooth_device_win.h', + 'bluetooth/bluetooth_includes_win.h', 'bluetooth/bluetooth_out_of_band_pairing_data.h', 'bluetooth/bluetooth_service_record.cc', 'bluetooth/bluetooth_service_record.h', 'bluetooth/bluetooth_service_record_chromeos.cc', 'bluetooth/bluetooth_service_record_chromeos.h', + 'bluetooth/bluetooth_service_record_win.cc', + 'bluetooth/bluetooth_service_record_win.h', 'bluetooth/bluetooth_socket.h', 'bluetooth/bluetooth_socket_chromeos.cc', 'bluetooth/bluetooth_socket_chromeos.h', @@ -138,6 +141,7 @@ 'bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc', 'bluetooth/bluetooth_adapter_win_unittest.cc', 'bluetooth/bluetooth_service_record_chromeos_unittest.cc', + 'bluetooth/bluetooth_service_record_win_unittest.cc', 'bluetooth/bluetooth_task_manager_win_unittest.cc', 'bluetooth/bluetooth_utils_unittest.cc', 'test/device_test_suite.cc', |