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. device_address()84 const std::string& device_address() const { return device_address_; } is_primary()85 bool is_primary() const { return is_primary_; } service_uuid()86 const UUID& service_uuid() const { return service_uuid_; } characteristic_uuid()87 const UUID& characteristic_uuid() const { return char_uuid_; } descriptor_uuid()88 const UUID& descriptor_uuid() const { return desc_uuid_; } service_instance_id()89 int service_instance_id() const { return service_instance_id_; } characteristic_instance_id()90 int characteristic_instance_id() const { return char_instance_id_; } descriptor_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