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 #include "service/common/bluetooth/gatt_identifier.h"
18 
19 #include "service/common/bluetooth/util/address_helper.h"
20 
21 namespace bluetooth {
22 
23 namespace {
24 
25 const int kInvalidInstanceId = -1;
26 
27 }  // namespace
28 
29 // static
CreateServiceId(const std::string & device_address,int id,const UUID & uuid,bool is_primary)30 std::unique_ptr<GattIdentifier> GattIdentifier::CreateServiceId(
31     const std::string& device_address,
32     int id, const UUID& uuid,
33     bool is_primary) {
34   if (id < 0 ||
35       (!device_address.empty() && !util::IsAddressValid(device_address)))
36     return nullptr;
37 
38   std::unique_ptr<GattIdentifier> gatt_id(new GattIdentifier());
39 
40   gatt_id->device_address_ = device_address;
41   gatt_id->service_uuid_ = uuid;
42   gatt_id->service_instance_id_ = id;
43   gatt_id->is_primary_ = is_primary;
44 
45   return gatt_id;
46 }
47 
48 // static
CreateCharacteristicId(int id,const UUID & uuid,const GattIdentifier & service_id)49 std::unique_ptr<GattIdentifier> GattIdentifier::CreateCharacteristicId(
50     int id, const UUID& uuid,
51     const GattIdentifier& service_id) {
52   if (!service_id.IsService())
53     return nullptr;
54 
55   std::unique_ptr<GattIdentifier> gatt_id(new GattIdentifier(service_id));
56 
57   gatt_id->char_uuid_ = uuid;
58   gatt_id->char_instance_id_ = id;
59 
60   return gatt_id;
61 }
62 
63 // static
CreateDescriptorId(int id,const UUID & uuid,const GattIdentifier & char_id)64 std::unique_ptr<GattIdentifier> GattIdentifier::CreateDescriptorId(
65     int id, const UUID& uuid,
66     const GattIdentifier& char_id) {
67   if (!char_id.IsCharacteristic())
68     return nullptr;
69 
70   std::unique_ptr<GattIdentifier> gatt_id(new GattIdentifier(char_id));
71 
72   gatt_id->desc_uuid_ = uuid;
73   gatt_id->desc_instance_id_ = id;
74 
75   return gatt_id;
76 }
77 
78 // Copy constructor and assignment operator.
GattIdentifier()79 GattIdentifier::GattIdentifier()
80   : is_primary_(false),
81     service_instance_id_(kInvalidInstanceId),
82     char_instance_id_(kInvalidInstanceId),
83     desc_instance_id_(kInvalidInstanceId) {
84 }
85 
GattIdentifier(const GattIdentifier & other)86 GattIdentifier::GattIdentifier(const GattIdentifier& other) {
87   device_address_ = other.device_address_;
88   is_primary_ = other.is_primary_;
89   service_uuid_ = other.service_uuid_;
90   char_uuid_ = other.char_uuid_;
91   desc_uuid_ = other.desc_uuid_;
92   service_instance_id_ = other.service_instance_id_;
93   service_instance_id_ = other.service_instance_id_;
94   char_instance_id_ = other.char_instance_id_;
95   desc_instance_id_ = other.desc_instance_id_;
96 }
97 
GattIdentifier(const std::string & device_address,bool is_primary,const UUID & service_uuid,const UUID & characteristic_uuid,const UUID & descriptor_uuid,int service_instance_id,int characteristic_instance_id,int descriptor_instance_id)98 GattIdentifier::GattIdentifier(
99     const std::string& device_address,
100     bool is_primary,
101     const UUID& service_uuid,
102     const UUID& characteristic_uuid,
103     const UUID& descriptor_uuid,
104     int service_instance_id,
105     int characteristic_instance_id,
106     int descriptor_instance_id)
107     : device_address_(device_address),
108       is_primary_(is_primary),
109       service_uuid_(service_uuid),
110       char_uuid_(characteristic_uuid),
111       desc_uuid_(descriptor_uuid),
112       service_instance_id_(service_instance_id),
113       char_instance_id_(characteristic_instance_id),
114       desc_instance_id_(descriptor_instance_id) {
115 }
116 
operator =(const GattIdentifier & other)117 GattIdentifier& GattIdentifier::operator=(const GattIdentifier& other) {
118   if (*this == other)
119     return *this;
120 
121   device_address_ = other.device_address_;
122   is_primary_ = other.is_primary_;
123   service_uuid_ = other.service_uuid_;
124   char_uuid_ = other.char_uuid_;
125   desc_uuid_ = other.desc_uuid_;
126   service_instance_id_ = other.service_instance_id_;
127   char_instance_id_ = other.char_instance_id_;
128   desc_instance_id_ = other.desc_instance_id_;
129 
130   return *this;
131 }
132 
Equals(const GattIdentifier & other) const133 bool GattIdentifier::Equals(const GattIdentifier& other) const {
134   return (device_address_ == other.device_address_ &&
135       is_primary_ == other.is_primary_ &&
136       service_uuid_ == other.service_uuid_ &&
137       char_uuid_ == other.char_uuid_ &&
138       desc_uuid_ == other.desc_uuid_ &&
139       service_instance_id_ == other.service_instance_id_ &&
140       char_instance_id_ == other.char_instance_id_ &&
141       desc_instance_id_ == other.desc_instance_id_);
142 }
143 
operator ==(const GattIdentifier & rhs) const144 bool GattIdentifier::operator==(const GattIdentifier& rhs) const {
145   return Equals(rhs);
146 }
147 
operator !=(const GattIdentifier & rhs) const148 bool GattIdentifier::operator!=(const GattIdentifier& rhs) const {
149   return !Equals(rhs);
150 }
151 
IsService() const152 bool GattIdentifier::IsService() const {
153   return (service_instance_id_ != kInvalidInstanceId &&
154           char_instance_id_ == kInvalidInstanceId &&
155           desc_instance_id_ == kInvalidInstanceId);
156 }
157 
IsCharacteristic() const158 bool GattIdentifier::IsCharacteristic() const {
159   return (service_instance_id_ != kInvalidInstanceId &&
160           char_instance_id_ != kInvalidInstanceId &&
161           desc_instance_id_ == kInvalidInstanceId);
162 }
163 
IsDescriptor() const164 bool GattIdentifier::IsDescriptor() const {
165   return (service_instance_id_ != kInvalidInstanceId &&
166           char_instance_id_ != kInvalidInstanceId &&
167           desc_instance_id_ != kInvalidInstanceId);
168 }
169 
GetOwningServiceId() const170 std::unique_ptr<GattIdentifier> GattIdentifier::GetOwningServiceId() const {
171   if (IsService())
172     return nullptr;
173 
174   return CreateServiceId(
175       device_address_, service_instance_id_, service_uuid_, is_primary_);
176 }
177 
178 std::unique_ptr<GattIdentifier>
GetOwningCharacteristicId() const179 GattIdentifier::GetOwningCharacteristicId() const {
180   if (!IsDescriptor())
181     return nullptr;
182 
183   std::unique_ptr<GattIdentifier> service_id = GetOwningServiceId();
184 
185   return CreateCharacteristicId(char_instance_id_, char_uuid_, *service_id);
186 }
187 
188 }  // namespace bluetooth
189