Home | History | Annotate | Download | only in bluetooth
      1 //
      2 //  Copyright (C) 2015 Google, Inc.
      3 //
      4 //  Licensed under the Apache License, Version 2.0 (the "License");
      5 //  you may not use this file except in compliance with the License.
      6 //  You may obtain a copy of the License at:
      7 //
      8 //  http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 //  Unless required by applicable law or agreed to in writing, software
     11 //  distributed under the License is distributed on an "AS IS" BASIS,
     12 //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 //  See the License for the specific language governing permissions and
     14 //  limitations under the License.
     15 //
     16 
     17 #pragma once
     18 
     19 #include <memory>
     20 #include <string>
     21 
     22 #include <bluetooth/uuid.h>
     23 
     24 namespace bluetooth {
     25 
     26 // Used to uniquely identify a GATT object/attribute
     27 // (service/characteristic/descriptor/include entry) after it has been
     28 // registered with the stack. Each registered object will be assigned a GATT
     29 // identifier that the callers may use in future callbacks.
     30 //
     31 // For local services, the uniqueness of each identifier is guaranteed only
     32 // within the registered GATT server that they exist in.
     33 class GattIdentifier final {
     34  public:
     35   // Static initialization methods. These return NULL if invalid parameters are
     36   // given.
     37   static std::unique_ptr<GattIdentifier> CreateServiceId(
     38       const std::string& device_address,
     39       int id,
     40       const UUID& uuid,
     41       bool is_primary);
     42   static std::unique_ptr<GattIdentifier> CreateCharacteristicId(
     43       int id, const UUID& uuid,
     44       const GattIdentifier& service_id);
     45   static std::unique_ptr<GattIdentifier> CreateDescriptorId(
     46       int id, const UUID& uuid,
     47       const GattIdentifier& characteristic_id);
     48 
     49   // Constructors and assignment operator.
     50   GattIdentifier();
     51   GattIdentifier(
     52       const std::string& device_address,
     53       bool is_primary,
     54       const UUID& service_uuid,
     55       const UUID& characteristic_uuid,
     56       const UUID& descriptor_uuid,
     57       int service_instance_id,
     58       int characteristic_instance_id,
     59       int descriptor_instance_id);
     60   ~GattIdentifier() = default;
     61   GattIdentifier(const GattIdentifier& other);
     62   GattIdentifier& operator=(const GattIdentifier& other);
     63 
     64 
     65   // Comparison function and operator.
     66   bool Equals(const GattIdentifier& other) const;
     67   bool operator==(const GattIdentifier& rhs) const;
     68   bool operator!=(const GattIdentifier& rhs) const;
     69 
     70   // Functions to verify the type of attribute represented by this identifier.
     71   bool IsService() const;
     72   bool IsCharacteristic() const;
     73   bool IsDescriptor() const;
     74 
     75   // For characteristics and descriptors, this returns the identifier of the
     76   // owning service. For services, this returns NULL.
     77   std::unique_ptr<GattIdentifier> GetOwningServiceId() const;
     78 
     79   // For descriptors, this returns the identifier of the owning characteristic.
     80   // For services and characteristics, this returns NULL.
     81   std::unique_ptr<GattIdentifier> GetOwningCharacteristicId() const;
     82 
     83   // Getters for internal fields.
     84   const std::string& device_address() const { return device_address_; }
     85   bool is_primary() const { return is_primary_; }
     86   const UUID& service_uuid() const { return service_uuid_; }
     87   const UUID& characteristic_uuid() const { return char_uuid_; }
     88   const UUID& descriptor_uuid() const { return desc_uuid_; }
     89   int service_instance_id() const { return service_instance_id_; }
     90   int characteristic_instance_id() const { return char_instance_id_; }
     91   int descriptor_instance_id() const { return desc_instance_id_; }
     92 
     93  private:
     94   friend struct std::hash<bluetooth::GattIdentifier>;
     95 
     96   // NOTE: Don't forget to update the std::hash specialization below if you
     97   // update any of the instance variables in this class.
     98 
     99   // The BD_ADDR of the device associated with the attribute.
    100   std::string device_address_;
    101 
    102   // An instance ID value of -1 means that it is unitialized. For example, a
    103   // service ID would have -1 for characteristic and descriptor instance IDs.
    104   bool is_primary_;
    105   UUID service_uuid_;
    106   UUID char_uuid_;
    107   UUID desc_uuid_;
    108   int service_instance_id_;
    109   int char_instance_id_;
    110   int desc_instance_id_;
    111 };
    112 
    113 }  // namespace bluetooth
    114 
    115 // Custom std::hash specialization so that bluetooth::GattIdentifier can be used
    116 // as a key in std::unordered_map.
    117 namespace std {
    118 
    119 template<>
    120 struct hash<bluetooth::GattIdentifier> {
    121   std::size_t operator()(const bluetooth::GattIdentifier& key) const {
    122     std::size_t seed = 0;
    123 
    124     hash_combine(seed, key.device_address_);
    125     hash_combine(seed, key.is_primary_);
    126     hash_combine(seed, key.service_uuid_);
    127     hash_combine(seed, key.char_uuid_);
    128     hash_combine(seed, key.desc_uuid_);
    129     hash_combine(seed, key.service_instance_id_);
    130     hash_combine(seed, key.char_instance_id_);
    131     hash_combine(seed, key.desc_instance_id_);
    132 
    133     return seed;
    134   }
    135 
    136  private:
    137   template<typename T>
    138   inline void hash_combine(std::size_t& seed, const T& v) const {
    139     std::hash<T> hasher;
    140     seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
    141   }
    142 };
    143 
    144 }  // namespace std
    145