Home | History | Annotate | Download | only in bluetooth
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2017 The Android Open Source Project
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 #pragma once
     20 
     21 #include <stdint.h>
     22 #include <array>
     23 #include <string>
     24 
     25 namespace bluetooth {
     26 
     27 // This class is representing Bluetooth UUIDs across whole stack.
     28 // Here are some general endianness rules:
     29 // 1. UUID is internally kept as as Big Endian.
     30 // 2. Bytes representing UUID coming from upper layers, Java or Binder, are Big
     31 //    Endian.
     32 // 3. Bytes representing UUID coming from lower layer, HCI packets, are Little
     33 //    Endian.
     34 // 4. UUID in storage is always string.
     35 class Uuid final {
     36  public:
     37   static constexpr size_t kNumBytes128 = 16;
     38   static constexpr size_t kNumBytes32 = 4;
     39   static constexpr size_t kNumBytes16 = 2;
     40 
     41   static constexpr size_t kString128BitLen = 36;
     42 
     43   static const Uuid kEmpty;  // 00000000-0000-0000-0000-000000000000
     44 
     45   using UUID128Bit = std::array<uint8_t, kNumBytes128>;
     46 
     47   Uuid() = default;
     48 
     49   // Creates and returns a random 128-bit UUID.
     50   static Uuid GetRandom();
     51 
     52   // Returns the shortest possible representation of this UUID in bytes. Either
     53   // kNumBytes16, kNumBytes32, or kNumBytes128
     54   size_t GetShortestRepresentationSize() const;
     55 
     56   // Returns true if this UUID can be represented as 16 bit.
     57   bool Is16Bit() const;
     58 
     59   // Returns 16 bit Little Endian representation of this UUID. Use
     60   // GetShortestRepresentationSize() or Is16Bit() before using this method.
     61   uint16_t As16Bit() const;
     62 
     63   // Returns 32 bit Little Endian representation of this UUID. Use
     64   // GetShortestRepresentationSize() before using this method.
     65   uint32_t As32Bit() const;
     66 
     67   // Converts string representing 128, 32, or 16 bit UUID in
     68   // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, xxxxxxxx, or xxxx format to UUID. If
     69   // set, optional is_valid parameter will be set to true if conversion is
     70   // successfull, false otherwise.
     71   static Uuid FromString(const std::string& uuid, bool* is_valid = nullptr);
     72 
     73   // Converts 16bit Little Endian representation of UUID to UUID
     74   static Uuid From16Bit(uint16_t uuid16bit);
     75 
     76   // Converts 32bit Little Endian representation of UUID to UUID
     77   static Uuid From32Bit(uint32_t uuid32bit);
     78 
     79   // Converts 128 bit Big Endian array representing UUID to UUID.
     80   static constexpr Uuid From128BitBE(const UUID128Bit& uuid) {
     81     Uuid u(uuid);
     82     return u;
     83   }
     84 
     85   // Converts 128 bit Big Endian array representing UUID to UUID. |uuid| points
     86   // to beginning of array.
     87   static Uuid From128BitBE(const uint8_t* uuid);
     88 
     89   // Converts 128 bit Little Endian array representing UUID to UUID.
     90   static Uuid From128BitLE(const UUID128Bit& uuid);
     91 
     92   // Converts 128 bit Little Endian array representing UUID to UUID. |uuid|
     93   // points to beginning of array.
     94   static Uuid From128BitLE(const uint8_t* uuid);
     95 
     96   // Returns 128 bit Little Endian representation of this UUID
     97   const UUID128Bit To128BitLE() const;
     98 
     99   // Returns 128 bit Big Endian representation of this UUID
    100   const UUID128Bit& To128BitBE() const;
    101 
    102   // Returns string representing this UUID in
    103   // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format, lowercase.
    104   std::string ToString() const;
    105 
    106   // Returns true if this UUID is equal to kEmpty
    107   bool IsEmpty() const;
    108 
    109   bool operator<(const Uuid& rhs) const;
    110   bool operator==(const Uuid& rhs) const;
    111   bool operator!=(const Uuid& rhs) const;
    112 
    113  private:
    114   constexpr Uuid(const UUID128Bit& val) : uu{val} {};
    115 
    116   // Network-byte-ordered ID (Big Endian).
    117   UUID128Bit uu;
    118 };
    119 }  // namespace bluetooth
    120 
    121 inline std::ostream& operator<<(std::ostream& os, const bluetooth::Uuid& a) {
    122   os << a.ToString();
    123   return os;
    124 }
    125 
    126 // Custom std::hash specialization so that bluetooth::UUID can be used as a key
    127 // in std::unordered_map.
    128 namespace std {
    129 
    130 template <>
    131 struct hash<bluetooth::Uuid> {
    132   std::size_t operator()(const bluetooth::Uuid& key) const {
    133     const auto& uuid_bytes = key.To128BitBE();
    134     std::hash<std::string> hash_fn;
    135     return hash_fn(std::string(reinterpret_cast<const char*>(uuid_bytes.data()),
    136                                uuid_bytes.size()));
    137   }
    138 };
    139 
    140 }  // namespace std
    141