1 /*
2  * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef GATT_DATABASE_H
17 #define GATT_DATABASE_H
18 
19 #include <cstddef>
20 #include <cstdint>
21 #include <list>
22 #include <map>
23 #include <memory>
24 #include <set>
25 #include <vector>
26 #include "base_def.h"
27 #include "bt_uuid.h"
28 #include "gatt_data.h"
29 #include "securec.h"
30 
31 namespace OHOS {
32 namespace bluetooth {
33 class GattDatabase {
34 public:
35     struct AttributeValue {
36         std::unique_ptr<uint8_t[]> value_;
37         size_t length_;
38 
AttributeValueAttributeValue39         AttributeValue() : value_(nullptr), length_(0)
40         {}
41 
AttributeValueAttributeValue42         AttributeValue(uint8_t **value, size_t length) : value_(nullptr), length_(length)
43         {
44             value_.reset(*value);
45             *value = nullptr;
46         }
47 
48         AttributeValue(const AttributeValue &src) = delete;
49 
50         AttributeValue &operator=(const AttributeValue &src)
51         {
52             if (this != &src) {
53                 auto tmp = std::make_unique<uint8_t[]>(src.length_);
54                 if (tmp) {
55                     length_ = src.length_;
56                     value_ = std::move(tmp);
57                     (void)memcpy_s(value_.get(), length_, src.value_.get(), length_);
58                 }
59             }
60             return *this;
61         }
62 
AttributeValueAttributeValue63         AttributeValue(AttributeValue &&src) noexcept : value_(std::move(src.value_)), length_(src.length_)
64         {
65             src.length_ = 0;
66         }
67 
68         AttributeValue &operator=(AttributeValue &&src) noexcept
69         {
70             if (this != &src) {
71                 value_ = std::move(src.value_);
72                 length_ = src.length_;
73                 src.length_ = 0;
74             }
75             return *this;
76         }
77 
SetValueAttributeValue78         bool SetValue(const uint8_t *value, size_t length)
79         {
80             length_ = length;
81             value_ = std::make_unique<uint8_t[]>(length_);
82             if (memcpy_s(value_.get(), length_, value, length_) != EOK) {
83                 return false;
84             }
85             return true;
86         }
87 
~AttributeValueAttributeValue88         ~AttributeValue()
89         {}
90     };
91 
92     struct AttributeEntity {
93         uint8_t permissions_;
94         uint16_t handle_;
95         AttributeValue value_;
96         Uuid type_;
AttributeEntityAttributeEntity97         AttributeEntity(uint8_t permissions, uint16_t handle, const Uuid &uuid)
98             : permissions_(permissions), handle_(handle), value_(), type_(uuid)
99         {}
100 
SetValueAttributeEntity101         bool SetValue(const uint8_t *value, size_t length)
102         {
103             return value_.SetValue(value, length);
104         }
105 
106         AttributeEntity(const AttributeEntity &) = delete;
107         AttributeEntity &operator=(const AttributeEntity &) = default;
108         AttributeEntity(AttributeEntity &&) = default;
109         AttributeEntity &operator=(AttributeEntity &&) = default;
110     };
111 
112     struct Descriptor {
113         uint8_t permissions_;
114         uint16_t handle_;
115         AttributeValue value_;
116         Uuid uuid_;
DescriptorDescriptor117         explicit Descriptor(const bluetooth::Descriptor &src)
118             : permissions_(src.permissions_), handle_(src.handle_), value_(), uuid_(src.uuid_)
119         {}
120 
121         Descriptor(const Descriptor &) = delete;
122         Descriptor &operator=(const Descriptor &) = default;
123         Descriptor(Descriptor &&) = default;
124         Descriptor &operator=(Descriptor &&) = default;
125     };
126 
127     struct Characteristic {
128         uint8_t properties_;
129         uint16_t handle_;
130         uint16_t valueHandle_;
131         uint16_t endHandle_;
132         std::map<uint16_t, Descriptor> descriptors_;
133         Uuid uuid_;
134 
CharacteristicCharacteristic135         explicit Characteristic(const bluetooth::Characteristic &src)
136             : properties_(src.properties_),
137               handle_(src.handle_),
138               valueHandle_(src.valueHandle_),
139               endHandle_(),
140               descriptors_(),
141               uuid_(src.uuid_)
142         {}
143 
144         Characteristic(const Characteristic &) = delete;
145         Characteristic &operator=(const Characteristic &) = default;
146         Characteristic(Characteristic &&) = default;
147         Characteristic &operator=(Characteristic &&) = default;
148     };
149 
150     struct IncludeService {
151         uint16_t handle_;
152         uint16_t startHandle_;
153         uint16_t endHandle_;
154         Uuid uuid_;
155 
IncludeServiceIncludeService156         explicit IncludeService(const bluetooth::Service &src)
157             : handle_(src.handle_), startHandle_(src.startHandle_), endHandle_(src.endHandle_), uuid_(src.uuid_)
158         {}
159     };
160 
161     struct Service {
162         bool isPrimary_;
163         uint16_t handle_;
164         uint16_t endHandle_;
165         std::vector<IncludeService> includeServices_;
166         std::map<uint16_t, Characteristic> characteristics_;
167         Uuid uuid_;
168 
ServiceService169         Service(uint16_t handle, uint16_t endHandle, const Uuid uuid)
170             : isPrimary_(false),
171               handle_(handle),
172               endHandle_(endHandle),
173               includeServices_(),
174               characteristics_(),
175               uuid_(uuid)
176         {}
177 
ServiceService178         explicit Service(const bluetooth::Service &src)
179             : isPrimary_(src.isPrimary_),
180               handle_(src.handle_),
181               endHandle_(src.endHandle_),
182               includeServices_(),
183               characteristics_(),
184               uuid_(src.uuid_)
185         {}
186 
187         Service(const Service &) = delete;
188         Service &operator=(const Service &) = default;
189         Service(Service &&) = default;
190         Service &operator=(Service &&) = default;
191     };
192 
193     using GattAttributeEntity = std::optional<std::reference_wrapper<GattDatabase::AttributeEntity>>;
194 
195     GattDatabase();
~GattDatabase()196     ~GattDatabase()
197     {}
198     int AddService(bluetooth::Service &service);
199     int DeleteService(uint16_t handle);
200     void RemoveAllServices();
201     int SetValueByHandle(uint16_t handle, AttributeValue &value);
202     const std::map<uint16_t, Service> &GetServices() const;
203     const std::vector<IncludeService> *GetIncludeServices(uint16_t serviceHandle);
204     const GattDatabase::IncludeService *GetIncludeService(uint16_t serviceHandle);
205     const std::map<uint16_t, Characteristic> *GetCharacteristics(uint16_t serviceHandle);
206     const std::map<uint16_t, Descriptor> *GetDescriptors(uint16_t cccHandle);
207     const GattDatabase::Service *GetService(uint16_t handle);
208     GattDatabase::Characteristic *GetCharacteristic(uint16_t valueHandle);
209     const GattDatabase::Descriptor *GetDescriptor(uint16_t valueHandle);
210     GattAttributeEntity GetValueByHandle(const uint16_t handle);
211     int CheckLegalityOfServiceDefinition(bluetooth::Service &service);
212 
213 private:
214     static int CountDescriptorByUuid(const std::vector<bluetooth::Descriptor> &descriptors, const Uuid &uuid);
215     std::pair<uint16_t, uint16_t> CalculateAndAssignHandle(const bluetooth::Service &service);
216     void ReleaseHandle(Service &service);
217     bool IsReferenced(uint16_t handle) const;
218     int CheckIncludeServicesLegality(bluetooth::Service &service) const;
219     int CheckCharacteristicsLegality(const bluetooth::Service &service) const;
220     int CheckDescriptorsLegality(const bluetooth::Characteristic &characteristic) const;
221     bool CheckRestrictedGattBasedService(const bluetooth::Service &service);
222 
223     // available handle [handle, handle]
224     std::list<std::pair<uint16_t, uint16_t>> availableHandles_ = {};
225     // service handle <-> Service entity
226     std::map<uint16_t, Service> services_ = {};
227     // value handle <-> Attribute entity
228     std::map<uint16_t, AttributeEntity> attributes_ = {};
229     // value handle <-> (service handle, parent handle)
230     // if value handle belong to descriptor, parent handle is characteristic handle witch descriptor belong to.
231     // else parent handle is characteristic handle.
232     std::map<uint16_t, std::pair<uint16_t, uint16_t>> valueHandleMap_ = {};
233     std::set<uint16_t> restrictedGattBasedService_ = {};
234 
235     BT_DISALLOW_COPY_AND_ASSIGN(GattDatabase);
236     BT_DISALLOW_MOVE_AND_ASSIGN(GattDatabase);
237 };
238 }  // namespace bluetooth
239 }  // namespace OHOS
240 
241 #endif  // !GATT_DATABASE_H
242