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.
4
5#include "device/bluetooth/bluetooth_uuid.h"
6
7#include "base/basictypes.h"
8#include "base/logging.h"
9#include "base/strings/string_util.h"
10
11namespace device {
12
13namespace {
14
15const char* kCommonUuidPostfix = "-0000-1000-8000-00805f9b34fb";
16const char* kCommonUuidPrefix = "0000";
17
18// Returns the canonical, 128-bit canonical, and the format of the UUID
19// in |canonical|, |canonical_128|, and |format| based on |uuid|.
20void GetCanonicalUuid(std::string uuid,
21                      std::string* canonical,
22                      std::string* canonical_128,
23                      BluetoothUUID::Format* format) {
24  // Initialize the values for the failure case.
25  canonical->clear();
26  canonical_128->clear();
27  *format = BluetoothUUID::kFormatInvalid;
28
29  if (uuid.empty())
30    return;
31
32  if (uuid.size() < 11 && uuid.find("0x") == 0)
33    uuid = uuid.substr(2);
34
35  if (!(uuid.size() == 4 || uuid.size() == 8 || uuid.size() == 36))
36    return;
37
38  for (size_t i = 0; i < uuid.size(); ++i) {
39    if (i == 8 || i == 13 || i == 18 || i == 23) {
40      if (uuid[i] != '-')
41        return;
42    } else {
43      if (!IsHexDigit(uuid[i]))
44        return;
45      uuid[i] = base::ToLowerASCII(uuid[i]);
46    }
47  }
48
49  canonical->assign(uuid);
50  if (uuid.size() == 4) {
51    canonical_128->assign(kCommonUuidPrefix + uuid + kCommonUuidPostfix);
52    *format = BluetoothUUID::kFormat16Bit;
53  } else if (uuid.size() == 8) {
54    canonical_128->assign(uuid + kCommonUuidPostfix);
55    *format = BluetoothUUID::kFormat32Bit;
56  } else {
57    canonical_128->assign(uuid);
58    *format = BluetoothUUID::kFormat128Bit;
59  }
60}
61
62}  // namespace
63
64
65BluetoothUUID::BluetoothUUID(const std::string& uuid) {
66  GetCanonicalUuid(uuid, &value_, &canonical_value_, &format_);
67}
68
69BluetoothUUID::BluetoothUUID() : format_(kFormatInvalid) {
70}
71
72BluetoothUUID::~BluetoothUUID() {
73}
74
75bool BluetoothUUID::IsValid() const {
76  return format_ != kFormatInvalid;
77}
78
79bool BluetoothUUID::operator<(const BluetoothUUID& uuid) const {
80  return canonical_value_ < uuid.canonical_value_;
81}
82
83bool BluetoothUUID::operator==(const BluetoothUUID& uuid) const {
84  return canonical_value_ == uuid.canonical_value_;
85}
86
87bool BluetoothUUID::operator!=(const BluetoothUUID& uuid) const {
88  return canonical_value_ != uuid.canonical_value_;
89}
90
91void PrintTo(const BluetoothUUID& uuid, std::ostream* out) {
92  *out << uuid.canonical_value();
93}
94
95}  // namespace device
96