blob: b35094deba169ab202a92d118bb5d02027b38c18 [file] [log] [blame]
armansito@chromium.org7d8c5ee2014-04-04 13:10:38 +09001// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "device/bluetooth/bluetooth_uuid.h"
6
avi7171ac72015-12-23 04:26:52 +09007#include <stddef.h>
8
armansito@chromium.org7d8c5ee2014-04-04 13:10:38 +09009#include "base/logging.h"
10#include "base/strings/string_util.h"
11
12namespace device {
13
14namespace {
15
thestigd7954912016-07-14 07:36:34 +090016const char kCommonUuidPostfix[] = "-0000-1000-8000-00805f9b34fb";
17const char kCommonUuidPrefix[] = "0000";
armansito@chromium.org7d8c5ee2014-04-04 13:10:38 +090018
19// Returns the canonical, 128-bit canonical, and the format of the UUID
20// in |canonical|, |canonical_128|, and |format| based on |uuid|.
21void GetCanonicalUuid(std::string uuid,
22 std::string* canonical,
23 std::string* canonical_128,
24 BluetoothUUID::Format* format) {
25 // Initialize the values for the failure case.
26 canonical->clear();
27 canonical_128->clear();
28 *format = BluetoothUUID::kFormatInvalid;
29
30 if (uuid.empty())
31 return;
32
thestigd7954912016-07-14 07:36:34 +090033 if (uuid.size() < 11 &&
34 base::StartsWith(uuid, "0x", base::CompareCase::SENSITIVE)) {
armansito@chromium.org7d8c5ee2014-04-04 13:10:38 +090035 uuid = uuid.substr(2);
thestigd7954912016-07-14 07:36:34 +090036 }
armansito@chromium.org7d8c5ee2014-04-04 13:10:38 +090037
38 if (!(uuid.size() == 4 || uuid.size() == 8 || uuid.size() == 36))
39 return;
40
isherman@chromium.org2ce9afc2014-05-14 23:22:45 +090041 for (size_t i = 0; i < uuid.size(); ++i) {
armansito@chromium.org7d8c5ee2014-04-04 13:10:38 +090042 if (i == 8 || i == 13 || i == 18 || i == 23) {
43 if (uuid[i] != '-')
44 return;
45 } else {
brettw6ff92f62015-06-24 09:39:02 +090046 if (!base::IsHexDigit(uuid[i]))
armansito@chromium.org7d8c5ee2014-04-04 13:10:38 +090047 return;
isherman@chromium.orga39170e2014-05-16 11:01:28 +090048 uuid[i] = base::ToLowerASCII(uuid[i]);
armansito@chromium.org7d8c5ee2014-04-04 13:10:38 +090049 }
50 }
51
52 canonical->assign(uuid);
isherman@chromium.org2ce9afc2014-05-14 23:22:45 +090053 if (uuid.size() == 4) {
54 canonical_128->assign(kCommonUuidPrefix + uuid + kCommonUuidPostfix);
55 *format = BluetoothUUID::kFormat16Bit;
56 } else if (uuid.size() == 8) {
57 canonical_128->assign(uuid + kCommonUuidPostfix);
58 *format = BluetoothUUID::kFormat32Bit;
59 } else {
60 canonical_128->assign(uuid);
61 *format = BluetoothUUID::kFormat128Bit;
62 }
armansito@chromium.org7d8c5ee2014-04-04 13:10:38 +090063}
64
65} // namespace
66
67
68BluetoothUUID::BluetoothUUID(const std::string& uuid) {
69 GetCanonicalUuid(uuid, &value_, &canonical_value_, &format_);
70}
71
72BluetoothUUID::BluetoothUUID() : format_(kFormatInvalid) {
73}
74
75BluetoothUUID::~BluetoothUUID() {
76}
77
78bool BluetoothUUID::IsValid() const {
79 return format_ != kFormatInvalid;
80}
81
82bool BluetoothUUID::operator<(const BluetoothUUID& uuid) const {
83 return canonical_value_ < uuid.canonical_value_;
84}
85
86bool BluetoothUUID::operator==(const BluetoothUUID& uuid) const {
87 return canonical_value_ == uuid.canonical_value_;
88}
89
90bool BluetoothUUID::operator!=(const BluetoothUUID& uuid) const {
91 return canonical_value_ != uuid.canonical_value_;
92}
93
armansito@chromium.orgb4b51562014-04-10 22:32:55 +090094void PrintTo(const BluetoothUUID& uuid, std::ostream* out) {
95 *out << uuid.canonical_value();
96}
97
armansito@chromium.org7d8c5ee2014-04-04 13:10:38 +090098} // namespace device