1611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//
2611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//  Copyright (C) 2015 Google, Inc.
3611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//
4611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//  Licensed under the Apache License, Version 2.0 (the "License");
5611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//  you may not use this file except in compliance with the License.
6611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//  You may obtain a copy of the License at:
7611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//
8611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//  http://www.apache.org/licenses/LICENSE-2.0
9611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//
10611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//  Unless required by applicable law or agreed to in writing, software
11611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//  distributed under the License is distributed on an "AS IS" BASIS,
12611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//  See the License for the specific language governing permissions and
14611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//  limitations under the License.
15611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge//
16fe6dd2a72b0f6d761821e75b048c13eb9ecd19acArman Uguray
17611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge#pragma once
18611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
19611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge#include <array>
20611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge#include <string>
21611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
22a961da5e2e7aeef05c703e77a36e56afe4d454f7Christopher Wiley// TODO: Find places that break include what you use and remove this.
23a961da5e2e7aeef05c703e77a36e56afe4d454f7Christopher Wiley#include <base/logging.h>
24234138e2606dd7a54fbcc540643511abc0a3598dArman Uguray#include <hardware/bluetooth.h>
25611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
26611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidgenamespace bluetooth {
27611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
28fe6dd2a72b0f6d761821e75b048c13eb9ecd19acArman Ugurayclass UUID {
29611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge public:
30de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  static constexpr size_t kNumBytes128 = 16;
31de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  static constexpr size_t kNumBytes32 = 4;
32de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  static constexpr size_t kNumBytes16 = 2;
33611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
34e9c82dca471da42c5a5dddb4582b70b3681758afArman Uguray  typedef std::array<uint8_t, kNumBytes16> UUID16Bit;
35e9c82dca471da42c5a5dddb4582b70b3681758afArman Uguray  typedef std::array<uint8_t, kNumBytes32> UUID32Bit;
36e9c82dca471da42c5a5dddb4582b70b3681758afArman Uguray  typedef std::array<uint8_t, kNumBytes128> UUID128Bit;
37e9c82dca471da42c5a5dddb4582b70b3681758afArman Uguray
38e9c82dca471da42c5a5dddb4582b70b3681758afArman Uguray  // Creates and returns a random 128-bit UUID.
39e9c82dca471da42c5a5dddb4582b70b3681758afArman Uguray  static UUID GetRandom();
40611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
4157dcd7e47681d3f452ab0f2b34f413af9be51e9eArman Uguray  // Creates and returns a UUID in which all 128 bits are equal to 0.
4257dcd7e47681d3f452ab0f2b34f413af9be51e9eArman Uguray  static UUID GetNil();
4357dcd7e47681d3f452ab0f2b34f413af9be51e9eArman Uguray
4457dcd7e47681d3f452ab0f2b34f413af9be51e9eArman Uguray  // Creates and returns a UUID in which all 128 bits are equal to 1.
4557dcd7e47681d3f452ab0f2b34f413af9be51e9eArman Uguray  static UUID GetMax();
4657dcd7e47681d3f452ab0f2b34f413af9be51e9eArman Uguray
47611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge  // Construct a Bluetooth 'base' UUID.
48fe6dd2a72b0f6d761821e75b048c13eb9ecd19acArman Uguray  UUID();
49611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
50611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge  // BlueDroid constructor.
51fe6dd2a72b0f6d761821e75b048c13eb9ecd19acArman Uguray  explicit UUID(const bt_uuid_t& uuid);
52611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
53611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge  // String constructor. Only hex ASCII accepted.
54de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  explicit UUID(std::string uuid);
55611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
56611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge  // std::array variants constructors.
57e9c82dca471da42c5a5dddb4582b70b3681758afArman Uguray  explicit UUID(const UUID16Bit& uuid);
58e9c82dca471da42c5a5dddb4582b70b3681758afArman Uguray  explicit UUID(const UUID32Bit& uuid);
59e9c82dca471da42c5a5dddb4582b70b3681758afArman Uguray  explicit UUID(const UUID128Bit& uuid);
60611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
61611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge  // Provide the full network-byte-ordered blob.
62de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  UUID128Bit GetFullBigEndian() const;
63611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
64611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge  // Provide blob in Little endian (BlueDroid expects this).
65de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  UUID128Bit GetFullLittleEndian() const;
66611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
67611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge  // Helper for bluedroid LE type.
68de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  bt_uuid_t GetBlueDroid() const;
69611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
70c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray  // Returns a string representation for the UUID.
71c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray  std::string ToString() const;
72c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray
73de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  // Returns whether or not this UUID was initialized correctly.
74de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  bool is_valid() const { return is_valid_; }
75de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray
76de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  // Returns the shortest possible representation of this UUID in bytes.
77de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  size_t GetShortestRepresentationSize() const;
78de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray
79fe6dd2a72b0f6d761821e75b048c13eb9ecd19acArman Uguray  bool operator<(const UUID& rhs) const;
80fe6dd2a72b0f6d761821e75b048c13eb9ecd19acArman Uguray  bool operator==(const UUID& rhs) const;
8157dcd7e47681d3f452ab0f2b34f413af9be51e9eArman Uguray  inline bool operator!=(const UUID& rhs) const {
8257dcd7e47681d3f452ab0f2b34f413af9be51e9eArman Uguray    return !(*this == rhs);
8357dcd7e47681d3f452ab0f2b34f413af9be51e9eArman Uguray  }
84611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
85611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge private:
86611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge  void InitializeDefault();
87de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray
88611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge  // Network-byte-ordered ID.
89fe6dd2a72b0f6d761821e75b048c13eb9ecd19acArman Uguray  UUID128Bit id_;
90de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray
91de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  // True if this UUID was initialized with a correct representation.
92de5cc7034275bf0dfc0124d07b28c70ec634aed7Arman Uguray  bool is_valid_;
93611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge};
94611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge
95611fcf98316e28425abe28dbcc07b8d037653ceeIan Coolidge}  // namespace bluetooth
96f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
97f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray// Custom std::hash specialization so that bluetooth::UUID can be used as a key
98f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray// in std::unordered_map.
99f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguraynamespace std {
100f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
101f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguraytemplate<>
102f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguraystruct hash<bluetooth::UUID> {
103f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  std::size_t operator()(const bluetooth::UUID& key) const {
104f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray    const auto& uuid_bytes = key.GetFullBigEndian();
105a961da5e2e7aeef05c703e77a36e56afe4d454f7Christopher Wiley    std::hash<std::string> hash_fn;
106a961da5e2e7aeef05c703e77a36e56afe4d454f7Christopher Wiley    return hash_fn(std::string((char *)uuid_bytes.data(), uuid_bytes.size()));
107f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray  }
108f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray};
109f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray
110f8711f2e95343f2c9673ab4ffc0bebbdba16c452Arman Uguray}  // namespace std
111