1 // 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.
5 #include "device/bluetooth/bluetooth_uuid.h"
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/strings/string_util.h"
10 #include "ipc/ipc_message.h"
16 const char* kCommonUuidPostfix
= "-0000-1000-8000-00805f9b34fb";
17 const char* kCommonUuidPrefix
= "0000";
19 // Returns the canonical, 128-bit canonical, and the format of the UUID
20 // in |canonical|, |canonical_128|, and |format| based on |uuid|.
21 void 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.
27 canonical_128
->clear();
28 *format
= BluetoothUUID::kFormatInvalid
;
33 if (uuid
.size() < 11 && uuid
.find("0x") == 0)
34 uuid
= uuid
.substr(2);
36 if (!(uuid
.size() == 4 || uuid
.size() == 8 || uuid
.size() == 36))
39 for (size_t i
= 0; i
< uuid
.size(); ++i
) {
40 if (i
== 8 || i
== 13 || i
== 18 || i
== 23) {
44 if (!base::IsHexDigit(uuid
[i
]))
46 uuid
[i
] = base::ToLowerASCII(uuid
[i
]);
50 canonical
->assign(uuid
);
51 if (uuid
.size() == 4) {
52 canonical_128
->assign(kCommonUuidPrefix
+ uuid
+ kCommonUuidPostfix
);
53 *format
= BluetoothUUID::kFormat16Bit
;
54 } else if (uuid
.size() == 8) {
55 canonical_128
->assign(uuid
+ kCommonUuidPostfix
);
56 *format
= BluetoothUUID::kFormat32Bit
;
58 canonical_128
->assign(uuid
);
59 *format
= BluetoothUUID::kFormat128Bit
;
66 BluetoothUUID::BluetoothUUID(const std::string
& uuid
) {
67 GetCanonicalUuid(uuid
, &value_
, &canonical_value_
, &format_
);
70 BluetoothUUID::BluetoothUUID() : format_(kFormatInvalid
) {
73 BluetoothUUID::~BluetoothUUID() {
76 bool BluetoothUUID::IsValid() const {
77 return format_
!= kFormatInvalid
;
80 bool BluetoothUUID::operator<(const BluetoothUUID
& uuid
) const {
81 return canonical_value_
< uuid
.canonical_value_
;
84 bool BluetoothUUID::operator==(const BluetoothUUID
& uuid
) const {
85 return canonical_value_
== uuid
.canonical_value_
;
88 bool BluetoothUUID::operator!=(const BluetoothUUID
& uuid
) const {
89 return canonical_value_
!= uuid
.canonical_value_
;
92 void PrintTo(const BluetoothUUID
& uuid
, std::ostream
* out
) {
93 *out
<< uuid
.canonical_value();
98 void IPC::ParamTraits
<device::BluetoothUUID
>::Write(Message
* m
,
99 const param_type
& p
) {
100 m
->WriteString(p
.canonical_value());
103 bool IPC::ParamTraits
<device::BluetoothUUID
>::Read(const Message
* m
,
104 base::PickleIterator
* iter
,
107 if (!iter
->ReadString(&value
))
109 *r
= device::BluetoothUUID(value
);
110 // If the format isn't 128-bit, .value() would return a different answer than
111 // .canonical_value(). Then if browser-side code accidentally checks .value()
112 // against a 128-bit string literal, a hostile renderer could use the 16- or
113 // 32-bit format and evade the check.
114 return r
->format() == device::BluetoothUUID::kFormat128Bit
;
117 void IPC::ParamTraits
<device::BluetoothUUID
>::Log(const param_type
& p
,
119 l
->append(p
.canonical_value());