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