1 /******************************************************************************
2  *
3  *  Copyright 2018 The Android Open Source Project
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #pragma once
20 
21 #include <list>
22 #include <string>
23 #include <vector>
24 
25 #include "stack/include/bt_octets.h"
26 #include "types/bluetooth/uuid.h"
27 
28 namespace gatt {
29 constexpr uint16_t HANDLE_MIN = 0x0001;
30 constexpr uint16_t HANDLE_MAX = 0xffff;
31 
32 /* Representation of GATT attribute for storage */
33 struct StoredAttribute {
34   // kSizeOnDisk includes two padding bytes for backward compatibility.
35   static constexpr size_t kSizeOnDisk = 38;
36   uint16_t handle;
37   bluetooth::Uuid type;
38 
39   union {
40     /* primary or secondary service definition */
41     struct {
42       bluetooth::Uuid uuid;
43       uint16_t end_handle;
44     } service;
45 
46     /* included service definition */
47     struct {
48       uint16_t handle;
49       uint16_t end_handle;
50       bluetooth::Uuid uuid;
51     } included_service;
52 
53     /* characteristic definition */
54     struct {
55       uint8_t properties;
56       uint16_t value_handle;
57       bluetooth::Uuid uuid;
58     } characteristic;
59 
60     /* for descriptor we store value only for
61      * «Characteristic Extended Properties» */
62     uint16_t characteristic_extended_properties;
63   } value;
64   static void SerializeStoredAttribute(const StoredAttribute& attr,
65                                        std::vector<uint8_t>& bytes);
66 };
67 
68 struct IncludedService;
69 struct Characteristic;
70 struct Descriptor;
71 
72 struct Service {
73   uint16_t handle;
74   bluetooth::Uuid uuid;
75   bool is_primary;
76   uint16_t end_handle;
77   std::vector<IncludedService> included_services;
78   std::vector<Characteristic> characteristics;
79 };
80 
81 struct IncludedService {
82   uint16_t handle; /* definition handle */
83   bluetooth::Uuid uuid;
84   uint16_t start_handle; /* start handle of included service */
85   uint16_t end_handle;   /* end handle of included service */
86 };
87 
88 struct Characteristic {
89   uint16_t declaration_handle;
90   bluetooth::Uuid uuid;
91   uint16_t value_handle;
92   uint8_t properties;
93   std::vector<Descriptor> descriptors;
94 };
95 
96 struct Descriptor {
97   uint16_t handle;
98   bluetooth::Uuid uuid;
99   /* set and used for «Characteristic Extended Properties» only */
100   uint16_t characteristic_extended_properties;
101 };
102 
103 class DatabaseBuilder;
104 
105 class Database {
106  public:
107   /* Return true if there are no services in this database. */
IsEmpty()108   bool IsEmpty() const { return services.empty(); }
109 
110   /* Clear the GATT database. This method forces relocation to ensure no extra
111    * space is used unnecesarly */
Clear()112   void Clear() { std::list<Service>().swap(services); }
113 
114   /* Return list of services available in this database */
Services()115   const std::list<Service>& Services() const { return services; }
116 
117   std::string ToString() const;
118 
119   std::vector<gatt::StoredAttribute> Serialize() const;
120 
121   static Database Deserialize(const std::vector<gatt::StoredAttribute>& nv_attr,
122                               bool* success);
123 
124   /* Return 128 bit unique identifier of this GATT database */
125   Octet16 Hash() const;
126 
127   friend class DatabaseBuilder;
128 
129  private:
130   std::list<Service> services;
131 };
132 
133 /* Find a service that should contain handle. Helper method for internal use
134  * inside gatt namespace.*/
135 Service* FindService(std::list<Service>& services, uint16_t handle);
136 
137 }  // namespace gatt
138