• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <gtest/gtest.h>
20 
21 #include <base/logging.h>
22 #include <base/strings/string_number_conversions.h>
23 #include "gatt/database.h"
24 #include "gatt/database_builder.h"
25 #include "stack/include/gattdefs.h"
26 
27 using bluetooth::Uuid;
28 
29 namespace gatt {
30 
31 namespace {
32 const Uuid PRIMARY_SERVICE = Uuid::From16Bit(GATT_UUID_PRI_SERVICE);
33 const Uuid SECONDARY_SERVICE = Uuid::From16Bit(GATT_UUID_SEC_SERVICE);
34 const Uuid INCLUDE = Uuid::From16Bit(GATT_UUID_INCLUDE_SERVICE);
35 const Uuid CHARACTERISTIC = Uuid::From16Bit(GATT_UUID_CHAR_DECLARE);
36 
37 Uuid SERVICE_1_UUID = Uuid::FromString("1800");
38 Uuid SERVICE_2_UUID = Uuid::FromString("1801");
39 Uuid SERVICE_1_CHAR_1_UUID = Uuid::FromString("2a00");
40 Uuid SERVICE_1_CHAR_1_DESC_1_UUID = Uuid::FromString("2902");
41 }  // namespace
42 
43 /* This test makes sure that each possible GATT cache element is properly
44  * serialized into StoredAttribute */
TEST(GattDatabaseTest,serialize_deserialize_binary_test)45 TEST(GattDatabaseTest, serialize_deserialize_binary_test) {
46   DatabaseBuilder builder;
47   builder.AddService(0x0001, 0x000f, SERVICE_1_UUID, true);
48   builder.AddService(0x0010, 0x001f, SERVICE_2_UUID, false);
49   builder.AddIncludedService(0x0002, SERVICE_2_UUID, 0x0010, 0x001f);
50   builder.AddCharacteristic(0x0003, 0x0004, SERVICE_1_CHAR_1_UUID, 0x02);
51   builder.AddDescriptor(0x0005, SERVICE_1_CHAR_1_DESC_1_UUID);
52 
53   Database db = builder.Build();
54   std::vector<StoredAttribute> serialized = db.Serialize();
55 
56   // Primary Service
57   EXPECT_EQ(serialized[0].handle, 0x0001);
58   EXPECT_EQ(serialized[0].type, PRIMARY_SERVICE);
59   EXPECT_EQ(serialized[0].value.service.uuid, SERVICE_1_UUID);
60   EXPECT_EQ(serialized[0].value.service.end_handle, 0x000f);
61 
62   // Secondary Service
63   EXPECT_EQ(serialized[1].handle, 0x0010);
64   EXPECT_EQ(serialized[1].type, SECONDARY_SERVICE);
65   EXPECT_EQ(serialized[1].value.service.uuid, SERVICE_2_UUID);
66   EXPECT_EQ(serialized[1].value.service.end_handle, 0x001f);
67 
68   // Included Service
69   EXPECT_EQ(serialized[2].handle, 0x0002);
70   EXPECT_EQ(serialized[2].type, INCLUDE);
71   EXPECT_EQ(serialized[2].value.included_service.handle, 0x0010);
72   EXPECT_EQ(serialized[2].value.included_service.end_handle, 0x001f);
73   EXPECT_EQ(serialized[2].value.included_service.uuid, SERVICE_2_UUID);
74 
75   // Characteristic
76   EXPECT_EQ(serialized[3].handle, 0x0003);
77   EXPECT_EQ(serialized[3].type, CHARACTERISTIC);
78   EXPECT_EQ(serialized[3].value.characteristic.properties, 0x02);
79   EXPECT_EQ(serialized[3].value.characteristic.value_handle, 0x0004);
80   EXPECT_EQ(serialized[3].value.characteristic.uuid, SERVICE_1_CHAR_1_UUID);
81 
82   // Descriptor
83   EXPECT_EQ(serialized[4].handle, 0x0005);
84   EXPECT_EQ(serialized[4].type, SERVICE_1_CHAR_1_DESC_1_UUID);
85 }
86 
87 /* This test makes sure that Service represented in StoredAttribute have proper
88  * binary format. */
TEST(GattCacheTest,stored_attribute_to_binary_service_test)89 TEST(GattCacheTest, stored_attribute_to_binary_service_test) {
90   StoredAttribute attr;
91 
92   /* make sure padding at end of union is cleared */
93   memset(&attr, 0, sizeof(attr));
94 
95   attr = {
96       .handle = 0x0001,
97       .type = PRIMARY_SERVICE,
98       .value = {.service = {.uuid = Uuid::FromString("1800"),
99                             .end_handle = 0x001c}},
100   };
101 
102   constexpr size_t len = sizeof(StoredAttribute);
103   // clang-format off
104   uint8_t binary_form[len] = {
105       /*handle */ 0x01, 0x00,
106       /* type*/ 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB,
107       /* service uuid */ 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB,
108       /* end handle */ 0x1C, 0x00,
109       /* cleared padding at end of union*/ 0x00, 0x00};
110   // clang-format on
111 
112   // useful for debugging:
113   // LOG(ERROR) << " " << base::HexEncode(&attr, len);
114   EXPECT_EQ(memcmp(binary_form, &attr, len), 0);
115 }
116 
117 /* This test makes sure that Service represented in StoredAttribute have proper
118  * binary format. */
TEST(GattCacheTest,stored_attribute_to_binary_included_service_test)119 TEST(GattCacheTest, stored_attribute_to_binary_included_service_test) {
120   StoredAttribute attr;
121 
122   /* make sure padding at end of union is cleared */
123   memset(&attr, 0, sizeof(attr));
124 
125   attr = {
126       .handle = 0x0001,
127       .type = INCLUDE,
128       .value = {.included_service =
129                     {
130                         .handle = 0x0010,
131                         .end_handle = 0x001f,
132                         .uuid = Uuid::FromString("1801"),
133                     }},
134   };
135 
136   constexpr size_t len = sizeof(StoredAttribute);
137   // clang-format off
138   uint8_t binary_form[len] = {
139       /*handle */ 0x01, 0x00,
140       /* type*/ 0x00, 0x00, 0x28, 0x02, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB,
141       /* handle */ 0x10, 0x00,
142       /* end handle */ 0x1f, 0x00,
143       /* service uuid */ 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
144   // clang-format on
145 
146   // useful for debugging:
147   // LOG(ERROR) << " " << base::HexEncode(&attr, len);
148   EXPECT_EQ(memcmp(binary_form, &attr, len), 0);
149 }
150 
151 /* This test makes sure that Characteristic represented in StoredAttribute have
152  * proper binary format. */
TEST(GattCacheTest,stored_attribute_to_binary_characteristic_test)153 TEST(GattCacheTest, stored_attribute_to_binary_characteristic_test) {
154   StoredAttribute attr;
155 
156   /* make sure padding at end of union is cleared */
157   memset(&attr, 0, sizeof(attr));
158 
159   attr = {
160       .handle = 0x0002,
161       .type = CHARACTERISTIC,
162       .value = {.characteristic = {.properties = 0x02,
163                                    .value_handle = 0x0003,
164                                    .uuid = Uuid::FromString("2a00")}},
165   };
166 
167   constexpr size_t len = sizeof(StoredAttribute);
168   // clang-format off
169   uint8_t binary_form[len] = {
170       /*handle */ 0x02, 0x00,
171       /* type */ 0x00, 0x00, 0x28, 0x03, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB,
172       /* properties */ 0x02,
173       /* after properties there is one byte padding. This might cause troube
174          on other platforms, investigate if it's ever a problem */ 0x00,
175       /* value handle */ 0x03, 0x00,
176       /* uuid */ 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
177   // clang-format on
178 
179   // useful for debugging:
180   // LOG(ERROR) << " " << base::HexEncode(&attr, len);
181   EXPECT_EQ(memcmp(binary_form, &attr, len), 0);
182 }
183 
184 /* This test makes sure that Descriptor represented in StoredAttribute have
185  * proper binary format. */
TEST(GattCacheTest,stored_attribute_to_binary_descriptor_test)186 TEST(GattCacheTest, stored_attribute_to_binary_descriptor_test) {
187   StoredAttribute attr;
188 
189   /* make sure padding at end of union is cleared */
190   memset(&attr, 0, sizeof(attr));
191 
192   attr = {.handle = 0x0003, .type = Uuid::FromString("2902"), .value = {}};
193 
194   constexpr size_t len = sizeof(StoredAttribute);
195   // clang-format off
196   uint8_t binary_form[len] = {
197       /*handle */ 0x03, 0x00,
198       /* type */ 0x00, 0x00, 0x29, 0x02, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB,
199       /* clear padding    */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200                              0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
201   // clang-format on
202 
203   // useful for debugging:
204   // LOG(ERROR) << " " << base::HexEncode(&attr, len);
205   EXPECT_EQ(memcmp(binary_form, &attr, len), 0);
206 }
207 }  // namespace gatt