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
21namespace bluetooth {
22
23namespace {
24
25const int kInvalidInstanceId = -1;
26
27}  // namespace
28
29// static
30std::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
49std::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
64std::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.
79GattIdentifier::GattIdentifier()
80  : is_primary_(false),
81    service_instance_id_(kInvalidInstanceId),
82    char_instance_id_(kInvalidInstanceId),
83    desc_instance_id_(kInvalidInstanceId) {
84}
85
86GattIdentifier::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
98GattIdentifier::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
117GattIdentifier& 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
133bool 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
144bool GattIdentifier::operator==(const GattIdentifier& rhs) const {
145  return Equals(rhs);
146}
147
148bool GattIdentifier::operator!=(const GattIdentifier& rhs) const {
149  return !Equals(rhs);
150}
151
152bool GattIdentifier::IsService() const {
153  return (service_instance_id_ != kInvalidInstanceId &&
154          char_instance_id_ == kInvalidInstanceId &&
155          desc_instance_id_ == kInvalidInstanceId);
156}
157
158bool GattIdentifier::IsCharacteristic() const {
159  return (service_instance_id_ != kInvalidInstanceId &&
160          char_instance_id_ != kInvalidInstanceId &&
161          desc_instance_id_ == kInvalidInstanceId);
162}
163
164bool GattIdentifier::IsDescriptor() const {
165  return (service_instance_id_ != kInvalidInstanceId &&
166          char_instance_id_ != kInvalidInstanceId &&
167          desc_instance_id_ != kInvalidInstanceId);
168}
169
170std::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
178std::unique_ptr<GattIdentifier>
179GattIdentifier::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