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_CACHE_H
17 #define GATT_CACHE_H
18 
19 #include <cstdint>
20 #include <map>
21 #include <string>
22 #include <vector>
23 #include "base_def.h"
24 #include "bt_uuid.h"
25 #include "gatt_data.h"
26 
27 namespace OHOS {
28 namespace bluetooth {
29 class GattCache {
30 public:
31     struct IncludeService {
32         uint16_t handle_ = 0;
33         uint16_t startHandle_ = 0;
34         uint16_t endHandle_ = 0;
35         Uuid uuid_ = {};
36 
IncludeServiceIncludeService37         explicit IncludeService(const Service &src)
38             : handle_(src.handle_), startHandle_(src.startHandle_), endHandle_(src.endHandle_), uuid_(src.uuid_)
39         {}
IncludeServiceIncludeService40         IncludeService(uint16_t handle, uint16_t startHandle, uint16_t endHandle, const Uuid uuid)
41             : handle_(handle), startHandle_(startHandle), endHandle_(endHandle), uuid_(uuid)
42         {}
IncludeServiceIncludeService43         IncludeService(uint16_t handle, uint16_t startHandle, uint16_t endHandle)
44             : handle_(handle), startHandle_(startHandle), endHandle_(endHandle)
45         {}
IncludeServiceIncludeService46         explicit IncludeService(const Uuid uuid) : uuid_(uuid)
47         {}
48     };
49 
50     struct Descriptor {
51         uint16_t handle_ = 0;
52         Uuid uuid_ = {};
53 
DescriptorDescriptor54         Descriptor(uint16_t handle, const Uuid uuid) : handle_(handle), uuid_(uuid)
55         {}
56     };
57 
58     struct Characteristic {
59         uint8_t properties_ = 0;
60         uint16_t handle_ = 0;
61         uint16_t valueHandle_ = 0;
62         std::map<uint16_t, Descriptor> descriptors_ = {};
63         Uuid uuid_ = {};
64 
CharacteristicCharacteristic65         Characteristic(uint16_t handle, uint8_t properties, uint16_t valueHandle, const Uuid uuid)
66             : properties_(properties), handle_(handle), valueHandle_(valueHandle), uuid_(uuid)
67         {}
68     };
69 
70     struct Service {
71         bool isPrimary_ = true;
72         uint16_t handle_ = 0;
73         uint16_t endHandle_ = 0;
74         std::vector<IncludeService> includeServices_ = {};
75         std::map<uint16_t, Characteristic> characteristics_ = {};
76         Uuid uuid_ = {};
77 
ServiceService78         Service()
79         {}
80 
ServiceService81         Service(bool isPrimary, uint16_t handle, uint16_t endHandle, const Uuid uuid)
82             : isPrimary_(isPrimary), handle_(handle), endHandle_(endHandle), uuid_(uuid)
83         {}
84     };
85     using Descriptors = std::pair<std::map<uint16_t, GattCache::Descriptor> *, uint16_t>;
86 
GattCache()87     GattCache()
88     {}
~GattCache()89     ~GattCache()
90     {}
91     void Clear();
92     void AddService(const Service &service);
93     int AddIncludeService(uint16_t serviceHandle, const IncludeService &includeService);
94     int AddCharacteristic(uint16_t serviceHandle, const Characteristic &characteristic);
95     int AddDescriptor(uint16_t cccHandle, const Descriptor &descriptor);
96     std::map<uint16_t, Service> &GetServices();
97     std::vector<IncludeService> *GetIncludeServices(uint16_t serviceHandle);
98     std::map<uint16_t, Characteristic> *GetCharacteristics(uint16_t serviceHandle);
99     Descriptors GetDescriptors(uint16_t cccHandle);
100     const GattCache::Characteristic *GetCharacteristic(int16_t valueHandle);
101     const GattCache::Descriptor *GetDescriptor(int16_t valueHandle);
102     uint16_t GetCharacteristicEndHandle(uint16_t serviceHandle, uint16_t cccHandle) const;
103 
104     int StoredToFile(const GattDevice& address) const;
105     int LoadFromFile(const GattDevice& address);
106 
107     GattCache(GattCache &&src) = default;
108     GattCache &operator=(GattCache &&src) = default;
109 
110 private:
111     struct StorageBlob {
112         uint16_t handle_;
113         Uuid type_;
114 
115         union {
116             struct {
117                 Uuid uuid_;
118                 uint16_t endHandle_;
119             } service_;
120 
121             struct {
122                 uint16_t handle_;
123                 uint16_t endHandle_;
124                 Uuid uuid_;
125             } includeService_;
126 
127             struct {
128                 uint8_t properties_;
129                 uint16_t valueHandle_;
130                 Uuid uuid_;
131             } characteristic_;
132         } value_;
133     };
134 
135     static const std::string GATT_STORAGE_PRIFIX;
136 
137     // service handle <-> struct Service
138     std::map<uint16_t, Service> services_ = {};
139     // value handle <-> (service handle, parent handle)
140     // if value handle belong to descriptor, parent handle is characteristic handle witch descriptor belong to.
141     // else parent handle is characteristic handle.
142     std::map<uint16_t, std::pair<uint16_t, uint16_t>> valueHandleMap_ = {};
143 
144     static std::string GenerateGattCacheFileName(const GattDevice &address);
145     int WriteStorageBlobToFile(const GattDevice& address, std::vector<StorageBlob> &blob) const;
146     std::vector<StorageBlob> ReadStorageBlobFromFile(const GattDevice &address) const;
147 
148     BT_DISALLOW_COPY_AND_ASSIGN(GattCache);
149 };
150 }  // namespace bluetooth
151 }  // namespace OHOS
152 
153 #endif  // !GATT_CACHE_H