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, std::vector<uint8_t>& bytes);
65 };
66 
67 struct IncludedService;
68 struct Characteristic;
69 struct Descriptor;
70 
71 struct Service {
72   uint16_t handle;
73   bluetooth::Uuid uuid;
74   bool is_primary;
75   uint16_t end_handle;
76   std::vector<IncludedService> included_services;
77   std::vector<Characteristic> characteristics;
78 };
79 
80 struct IncludedService {
81   uint16_t handle; /* definition handle */
82   bluetooth::Uuid uuid;
83   uint16_t start_handle; /* start handle of included service */
84   uint16_t end_handle;   /* end handle of included service */
85 };
86 
87 struct Characteristic {
88   uint16_t declaration_handle;
89   bluetooth::Uuid uuid;
90   uint16_t value_handle;
91   uint8_t properties;
92   std::vector<Descriptor> descriptors;
93 };
94 
95 struct Descriptor {
96   uint16_t handle;
97   bluetooth::Uuid uuid;
98   /* set and used for «Characteristic Extended Properties» only */
99   uint16_t characteristic_extended_properties;
100 };
101 
102 class DatabaseBuilder;
103 
104 class Database {
105 public:
106   /* Return true if there are no services in this database. */
IsEmpty()107   bool IsEmpty() const { return services.empty(); }
108 
109   /* Clear the GATT database. This method forces relocation to ensure no extra
110    * space is used unnecesarly */
Clear()111   void Clear() { std::list<Service>().swap(services); }
112 
113   /* Return list of services available in this database */
Services()114   const std::list<Service>& Services() const { return services; }
115 
116   std::string ToString() const;
117 
118   std::vector<gatt::StoredAttribute> Serialize() const;
119 
120   static Database Deserialize(const std::vector<gatt::StoredAttribute>& nv_attr, bool* success);
121 
122   /* Return 128 bit unique identifier of this GATT database */
123   Octet16 Hash() const;
124 
125   friend class DatabaseBuilder;
126 
127 private:
128   std::list<Service> services;
129 };
130 
131 /* Find a service that should contain handle. Helper method for internal use
132  * inside gatt namespace.*/
133 Service* FindService(std::list<Service>& services, uint16_t handle);
134 
135 }  // namespace gatt
136