summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authorarmansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-06 10:23:07 +0000
committerarmansito@chromium.org <armansito@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-06 10:23:07 +0000
commit6e26d08a43a3a0126f5ff22a2f886597f8d304e3 (patch)
tree6c290e54d99d2b27defd2bd2c47696bb4565263d /device
parent07f04ffcf26b301ff73d617aae62cee4d2919968 (diff)
downloadchromium_src-6e26d08a43a3a0126f5ff22a2f886597f8d304e3.zip
chromium_src-6e26d08a43a3a0126f5ff22a2f886597f8d304e3.tar.gz
chromium_src-6e26d08a43a3a0126f5ff22a2f886597f8d304e3.tar.bz2
device/bluetooth: Introduce class bluetooth_utils::UUID.
Added an opaque container for Bluetooth universally unique identifiers, which are internally represented as a string. The class abstracts away conversion from 16 and 32-bit UUIDs to the 128-bit format using the existing bluetooth_utils::CanonicalUuid function. This provides a more simple object oriented interface for passing around UUIDs. BUG=340524 TEST=device_unittests Review URL: https://codereview.chromium.org/154883002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249333 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'device')
-rw-r--r--device/bluetooth/bluetooth_utils.cc94
-rw-r--r--device/bluetooth/bluetooth_utils.h78
-rw-r--r--device/bluetooth/bluetooth_utils_unittest.cc101
3 files changed, 229 insertions, 44 deletions
diff --git a/device/bluetooth/bluetooth_utils.cc b/device/bluetooth/bluetooth_utils.cc
index b1f9f781..df0c875 100644
--- a/device/bluetooth/bluetooth_utils.cc
+++ b/device/bluetooth/bluetooth_utils.cc
@@ -10,49 +10,103 @@
#include "base/logging.h"
#include "base/strings/string_util.h"
-namespace {
-static const char* kCommonUuidPostfix = "-0000-1000-8000-00805f9b34fb";
-static const char* kCommonUuidPrefix = "0000";
-static const int kUuidSize = 36;
-} // namespace
-
namespace device {
namespace bluetooth_utils {
-std::string CanonicalUuid(std::string uuid) {
+namespace {
+
+const char* kCommonUuidPostfix = "-0000-1000-8000-00805f9b34fb";
+const char* kCommonUuidPrefix = "0000";
+const int kUuidSize = 36;
+
+// Returns the canonical, 128-bit canonical, and the format of the UUID
+// in |canonical|, |canonical_128|, and |format| based on |uuid|.
+void GetCanonicalUuid(std::string uuid,
+ std::string* canonical,
+ std::string* canonical_128,
+ UUID::Format* format) {
+ // Initialize the values for the failure case.
+ canonical->clear();
+ canonical_128->clear();
+ *format = UUID::kFormatInvalid;
+
if (uuid.empty())
- return std::string();
+ return;
if (uuid.size() < 11 && uuid.find("0x") == 0)
uuid = uuid.substr(2);
if (!(uuid.size() == 4 || uuid.size() == 8 || uuid.size() == 36))
- return std::string();
+ return;
if (uuid.size() == 4 || uuid.size() == 8) {
for (size_t i = 0; i < uuid.size(); ++i) {
if (!IsHexDigit(uuid[i]))
- return std::string();
+ return;
}
-
- if (uuid.size() == 4)
- return kCommonUuidPrefix + uuid + kCommonUuidPostfix;
-
- return uuid + kCommonUuidPostfix;
+ if (uuid.size() == 4) {
+ canonical->assign(uuid);
+ canonical_128->assign(kCommonUuidPrefix + uuid + kCommonUuidPostfix);
+ *format = UUID::kFormat16Bit;
+ return;
+ }
+ canonical->assign(uuid);
+ canonical_128->assign(uuid + kCommonUuidPostfix);
+ *format = UUID::kFormat32Bit;
+ return;
}
- std::string uuid_result(uuid);
for (int i = 0; i < kUuidSize; ++i) {
if (i == 8 || i == 13 || i == 18 || i == 23) {
if (uuid[i] != '-')
- return std::string();
+ return;
} else {
if (!IsHexDigit(uuid[i]))
- return std::string();
- uuid_result[i] = tolower(uuid[i]);
+ return;
+ uuid[i] = tolower(uuid[i]);
}
}
- return uuid_result;
+
+ canonical->assign(uuid);
+ canonical_128->assign(uuid);
+ *format = UUID::kFormat128Bit;
+}
+
+} // namespace
+
+
+UUID::UUID(const std::string& uuid) {
+ GetCanonicalUuid(uuid, &value_, &canonical_value_, &format_);
+}
+
+UUID::UUID() : format_(kFormatInvalid) {
+}
+
+UUID::~UUID() {
+}
+
+bool UUID::IsValid() const {
+ return format_ != kFormatInvalid;
+}
+
+bool UUID::operator<(const UUID& uuid) const {
+ return canonical_value_ < uuid.canonical_value_;
+}
+
+bool UUID::operator==(const UUID& uuid) const {
+ return canonical_value_ == uuid.canonical_value_;
+}
+
+bool UUID::operator!=(const UUID& uuid) const {
+ return canonical_value_ != uuid.canonical_value_;
+}
+
+std::string CanonicalUuid(std::string uuid) {
+ std::string value;
+ std::string canonical_value;
+ UUID::Format format;
+ GetCanonicalUuid(uuid, &value, &canonical_value, &format);
+ return canonical_value;
}
} // namespace bluetooth_utils
diff --git a/device/bluetooth/bluetooth_utils.h b/device/bluetooth/bluetooth_utils.h
index 09951601..44b52b1 100644
--- a/device/bluetooth/bluetooth_utils.h
+++ b/device/bluetooth/bluetooth_utils.h
@@ -12,6 +12,84 @@
namespace device {
namespace bluetooth_utils {
+// Opaque wrapper around a Bluetooth UUID. Instances of UUID represent the
+// 128-bit universally unique identifiers (UUIDs) of profiles and attributes
+// used in Bluetooth based communication, such as a peripheral's services,
+// characteristics, and characteristic descriptors. An instance are
+// constructed using a string representing 16, 32, or 128 bit UUID formats.
+class UUID {
+ public:
+ // Possible representation formats used during construction.
+ enum Format {
+ kFormatInvalid,
+ kFormat16Bit,
+ kFormat32Bit,
+ kFormat128Bit
+ };
+
+ // Single argument constructor. |uuid| can be a 16, 32, or 128 bit UUID
+ // represented as a 4, 8, or 36 character string with the following
+ // formats:
+ // XXXX
+ // 0xXXXX
+ // XXXXXXXX
+ // 0xXXXXXXXX
+ // XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+ //
+ // 16 and 32 bit UUIDs will be internally converted to a 128 bit UUID using
+ // the base UUID defined in the Bluetooth specification, hence custom UUIDs
+ // should be provided in the 128-bit format. If |uuid| is in an unsupported
+ // format, the result might be invalid. Use IsValid to check for validity
+ // after construction.
+ explicit UUID(const std::string& uuid);
+ ~UUID();
+
+ // Returns true, if the UUID is in a valid canonical format.
+ bool IsValid() const;
+
+ // Returns the representation format of the UUID. This reflects the format
+ // that was provided during construction.
+ Format format() const { return format_; }
+
+ // Returns the value of the UUID as a string. The representation format is
+ // based on what was passed in during construction. For the supported sizes,
+ // this representation can have the following formats:
+ // - 16 bit: XXXX
+ // - 32 bit: XXXXXXXX
+ // - 128 bit: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+ // where X is a lowercase hex digit.
+ const std::string& value() const { return value_; }
+
+ // Returns the underlying 128-bit value as a string in the following format:
+ // XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+ // where X is a lowercase hex digit.
+ const std::string& canonical_value() const { return canonical_value_; }
+
+ // Permit sufficient comparison to allow a UUID to be used as a key in a
+ // std::map.
+ bool operator<(const UUID& uuid) const;
+
+ // Equality operators.
+ bool operator==(const UUID& uuid) const;
+ bool operator!=(const UUID& uuid) const;
+
+ private:
+ UUID();
+
+ // String representation of the UUID that was used during construction. For
+ // the supported sizes, this representation can have the following formats:
+ // - 16 bit: XXXX
+ // - 32 bit: XXXXXXXX
+ // - 128 bit: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+ Format format_;
+ std::string value_;
+
+ // The 128-bit string representation of the UUID.
+ std::string canonical_value_;
+};
+
+// DEPRECATED. Use bluetooth_utils::UUID instead.
+//
// Takes a 4, 8 or 36 character UUID, validates it and returns it in 36
// character format with all hex digits lower case. If |uuid| is invalid, the
// empty string is returned.
diff --git a/device/bluetooth/bluetooth_utils_unittest.cc b/device/bluetooth/bluetooth_utils_unittest.cc
index 46d5f34..07c63b5 100644
--- a/device/bluetooth/bluetooth_utils_unittest.cc
+++ b/device/bluetooth/bluetooth_utils_unittest.cc
@@ -7,47 +7,100 @@
#include "testing/gtest/include/gtest/gtest.h"
namespace device {
+namespace bluetooth_utils {
TEST(BluetoothUtilsTest, CanonicalUuid) {
// Does nothing for an already canonical UUID
EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb",
- bluetooth_utils::CanonicalUuid("00001101-0000-1000-8000-00805f9b34fb"));
+ CanonicalUuid("00001101-0000-1000-8000-00805f9b34fb"));
// Rejects misformatted
- EXPECT_EQ("", bluetooth_utils::CanonicalUuid("1101a"));
- EXPECT_EQ("", bluetooth_utils::CanonicalUuid("Z101"));
- EXPECT_EQ("", bluetooth_utils::CanonicalUuid("0000-1101"));
- EXPECT_EQ("", bluetooth_utils::CanonicalUuid("0000Z101"));
- EXPECT_EQ("",
- bluetooth_utils::CanonicalUuid("0001101-0000-1000-8000-00805f9b34fb"));
- EXPECT_EQ("",
- bluetooth_utils::CanonicalUuid("Z0001101-0000-1000-8000-00805f9b34fb"));
- EXPECT_EQ("",
- bluetooth_utils::CanonicalUuid("00001101 0000-1000-8000-00805f9b34fb"));
- EXPECT_EQ("",
- bluetooth_utils::CanonicalUuid("00001101-0000:1000-8000-00805f9b34fb"));
- EXPECT_EQ("",
- bluetooth_utils::CanonicalUuid("00001101-0000-1000;8000-00805f9b34fb"));
- EXPECT_EQ("",
- bluetooth_utils::CanonicalUuid("00001101-0000-1000-8000000805f9b34fb"));
+ EXPECT_EQ("", CanonicalUuid("1101a"));
+ EXPECT_EQ("", CanonicalUuid("Z101"));
+ EXPECT_EQ("", CanonicalUuid("0000-1101"));
+ EXPECT_EQ("", CanonicalUuid("0000Z101"));
+ EXPECT_EQ("", CanonicalUuid("0001101-0000-1000-8000-00805f9b34fb"));
+ EXPECT_EQ("", CanonicalUuid("Z0001101-0000-1000-8000-00805f9b34fb"));
+ EXPECT_EQ("", CanonicalUuid("00001101 0000-1000-8000-00805f9b34fb"));
+ EXPECT_EQ("", CanonicalUuid("00001101-0000:1000-8000-00805f9b34fb"));
+ EXPECT_EQ("", CanonicalUuid("00001101-0000-1000;8000-00805f9b34fb"));
+ EXPECT_EQ("", CanonicalUuid("00001101-0000-1000-8000000805f9b34fb"));
// Lower case
EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb",
- bluetooth_utils::CanonicalUuid("00001101-0000-1000-8000-00805F9B34FB"));
+ CanonicalUuid("00001101-0000-1000-8000-00805F9B34FB"));
// Short to full
EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb",
- bluetooth_utils::CanonicalUuid("1101"));
+ CanonicalUuid("1101"));
EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb",
- bluetooth_utils::CanonicalUuid("0x1101"));
+ CanonicalUuid("0x1101"));
EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb",
- bluetooth_utils::CanonicalUuid("00001101"));
+ CanonicalUuid("00001101"));
EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb",
- bluetooth_utils::CanonicalUuid("0x00001101"));
+ CanonicalUuid("0x00001101"));
// No 0x prefix on 36 character
- EXPECT_EQ("",
- bluetooth_utils::CanonicalUuid("0x00001101-0000-1000-8000-00805f9b34fb"));
+ EXPECT_EQ("", CanonicalUuid("0x00001101-0000-1000-8000-00805f9b34fb"));
}
+TEST(BluetoothUtilsTest, UUID) {
+ const char kValid128Bit0[] = "12345678-1234-5678-9abc-def123456789";
+ const char kValid128Bit1[] = "00001101-0000-1000-8000-00805f9b34fb";
+ const char kInvalid36Char[] = "1234567-1234-5678-9abc-def123456789";
+ const char kInvalid4Char[] = "Z101";
+ const char kValid16Bit[] = "0x1101";
+ const char kValid32Bit[] = "00001101";
+
+ // Valid 128-bit custom UUID.
+ UUID uuid0(kValid128Bit0);
+ EXPECT_TRUE(uuid0.IsValid());
+ EXPECT_EQ(UUID::kFormat128Bit, uuid0.format());
+ EXPECT_EQ(uuid0.value(), uuid0.canonical_value());
+
+ // Valid 128-bit UUID.
+ UUID uuid1(kValid128Bit1);
+ EXPECT_TRUE(uuid1.IsValid());
+ EXPECT_EQ(UUID::kFormat128Bit, uuid1.format());
+ EXPECT_EQ(uuid1.value(), uuid1.canonical_value());
+
+ EXPECT_NE(uuid0, uuid1);
+
+ // Invalid 128-bit UUID.
+ UUID uuid2(kInvalid36Char);
+ EXPECT_FALSE(uuid2.IsValid());
+ EXPECT_EQ(UUID::kFormatInvalid, uuid2.format());
+ EXPECT_TRUE(uuid2.value().empty());
+ EXPECT_TRUE(uuid2.canonical_value().empty());
+
+ // Invalid 16-bit UUID.
+ UUID uuid3(kInvalid4Char);
+ EXPECT_FALSE(uuid3.IsValid());
+ EXPECT_EQ(UUID::kFormatInvalid, uuid3.format());
+ EXPECT_TRUE(uuid3.value().empty());
+ EXPECT_TRUE(uuid3.canonical_value().empty());
+
+ // Valid 16-bit UUID.
+ UUID uuid4(kValid16Bit);
+ EXPECT_TRUE(uuid4.IsValid());
+ EXPECT_EQ(UUID::kFormat16Bit, uuid4.format());
+ EXPECT_NE(uuid4.value(), uuid4.canonical_value());
+ EXPECT_EQ("1101", uuid4.value());
+ EXPECT_EQ(kValid128Bit1, uuid4.canonical_value());
+
+ // Valid 32-bit UUID.
+ UUID uuid5(kValid32Bit);
+ EXPECT_TRUE(uuid5.IsValid());
+ EXPECT_EQ(UUID::kFormat32Bit, uuid5.format());
+ EXPECT_NE(uuid5.value(), uuid5.canonical_value());
+ EXPECT_EQ("00001101", uuid5.value());
+ EXPECT_EQ(kValid128Bit1, uuid5.canonical_value());
+
+ // uuid4, uuid5, and uuid1 are equivalent.
+ EXPECT_EQ(uuid4, uuid5);
+ EXPECT_EQ(uuid1, uuid4);
+ EXPECT_EQ(uuid1, uuid5);
+}
+
+} // namespace bluetooth_utils
} // namespace device