2 // Copyright (C) 2015 Google, Inc.
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:
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include "service/uuid.h"
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.
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 {
35 // Static initialization methods. These return NULL if invalid parameters are
37 static std::unique_ptr<GattIdentifier> CreateServiceId(
38 const std::string& device_address,
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);
49 // Constructors and assignment operator.
52 const std::string& device_address,
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);
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;
70 // Functions to verify the type of attribute represented by this identifier.
71 bool IsService() const;
72 bool IsCharacteristic() const;
73 bool IsDescriptor() const;
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;
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;
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_; }
94 friend struct std::hash<bluetooth::GattIdentifier>;
96 // NOTE: Don't forget to update the std::hash specialization below if you
97 // update any of the instance variables in this class.
99 // The BD_ADDR of the device associated with the attribute.
100 std::string device_address_;
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.
108 int service_instance_id_;
109 int char_instance_id_;
110 int desc_instance_id_;
113 } // namespace bluetooth
115 // Custom std::hash specialization so that bluetooth::GattIdentifier can be used
116 // as a key in std::unordered_map.
120 struct hash<bluetooth::GattIdentifier> {
121 std::size_t operator()(const bluetooth::GattIdentifier& key) const {
122 std::size_t seed = 0;
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_);
138 inline void hash_combine(std::size_t& seed, const T& v) const {
140 seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);