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 <iterator>
23 #include <utility>
24
25 #include "gatt/database_builder.h"
26
27 using bluetooth::Uuid;
28
29 namespace gatt {
30
31 namespace {
32 /* make_pair doesn't work well with EXPECT_EQ, have own helper instead */
make_pair_u16(uint16_t first,uint16_t second)33 inline std::pair<uint16_t, uint16_t> make_pair_u16(uint16_t first,
34 uint16_t second) {
35 return std::make_pair(first, second);
36 }
37
38 Uuid SERVICE_1_UUID = Uuid::FromString("00001800-0000-1000-8000-00805f9b34fb");
39 Uuid SERVICE_2_UUID = Uuid::FromString("00001801-0000-1000-8000-00805f9b34fb");
40 Uuid SERVICE_3_UUID = Uuid::FromString("0000180f-0000-1000-8000-00805f9b34fb");
41 Uuid SERVICE_4_UUID = Uuid::FromString("0000fef5-0000-1000-8000-00805f9b34fb");
42 Uuid SERVICE_5_UUID = Uuid::FromString("0000180a-0000-1000-8000-00805f9b34fb");
43 Uuid SERVICE_1_CHAR_1_UUID =
44 Uuid::FromString("00002a00-0000-1000-8000-00805f9b34fb");
45 Uuid SERVICE_1_CHAR_1_DESC_1_UUID =
46 Uuid::FromString("00002902-0000-1000-8000-00805f9b34fb");
47
48 } // namespace
49
50 /* Verify adding empty service works ok */
TEST(DatabaseBuilderTest,EmptyServiceAddTest)51 TEST(DatabaseBuilderTest, EmptyServiceAddTest) {
52 DatabaseBuilder builder;
53
54 EXPECT_FALSE(builder.InProgress());
55
56 // Simple database, just one empty
57 builder.AddService(0x0001, 0x0001, SERVICE_1_UUID, true);
58 EXPECT_FALSE(builder.StartNextServiceExploration());
59
60 Database result = builder.Build();
61
62 // verify that the returned database matches what was discovered
63 auto service = result.Services().begin();
64 EXPECT_EQ(service->handle, 0x0001);
65 EXPECT_EQ(service->end_handle, 0x0001);
66 EXPECT_EQ(service->is_primary, true);
67 EXPECT_EQ(service->uuid, SERVICE_1_UUID);
68 }
69
70 /* Verify adding service, characteristic and descriptor work */
TEST(DatabaseBuilderTest,DescriptorAddTest)71 TEST(DatabaseBuilderTest, DescriptorAddTest) {
72 DatabaseBuilder builder;
73
74 EXPECT_FALSE(builder.InProgress());
75
76 // Simple database, just one empty
77 builder.AddService(0x0001, 0x000f, SERVICE_1_UUID, true);
78 builder.AddCharacteristic(0x0002, 0x0003, SERVICE_1_CHAR_1_UUID, 0x02);
79 builder.AddDescriptor(0x0004, SERVICE_1_CHAR_1_DESC_1_UUID);
80
81 Database result = builder.Build();
82
83 // verify that the returned database matches what was discovered
84 auto service = result.Services().begin();
85 EXPECT_EQ(service->handle, 0x0001);
86 EXPECT_EQ(service->end_handle, 0x000f);
87 EXPECT_EQ(service->is_primary, true);
88 EXPECT_EQ(service->uuid, SERVICE_1_UUID);
89
90 EXPECT_EQ(service->characteristics[0].uuid, SERVICE_1_CHAR_1_UUID);
91 EXPECT_EQ(service->characteristics[0].declaration_handle, 0x0002);
92 EXPECT_EQ(service->characteristics[0].value_handle, 0x0003);
93 EXPECT_EQ(service->characteristics[0].properties, 0x02);
94
95 EXPECT_EQ(service->characteristics[0].descriptors[0].uuid,
96 SERVICE_1_CHAR_1_DESC_1_UUID);
97 EXPECT_EQ(service->characteristics[0].descriptors[0].handle, 0x0004);
98 }
99
100 /* This test verifies that DatabaseBuilder properly handle discovery of
101 * secondary service, that is added to the discovery queue from included service
102 * definition. Such service might come out of order. */
TEST(DatabaseBuilderTest,SecondaryServiceOutOfOrderTest)103 TEST(DatabaseBuilderTest, SecondaryServiceOutOfOrderTest) {
104 DatabaseBuilder builder;
105
106 EXPECT_FALSE(builder.InProgress());
107
108 // At start of discovery, builder will receive All services in order from
109 // lower layers.
110 builder.AddService(0x0001, 0x000f, SERVICE_1_UUID, true);
111 builder.AddService(0x0030, 0x003f, SERVICE_3_UUID, true);
112 builder.AddService(0x0050, 0x005f, SERVICE_5_UUID, true);
113
114 // First service skipped, no place for handles
115 EXPECT_TRUE(builder.StartNextServiceExploration());
116 EXPECT_EQ(builder.CurrentlyExploredService(), make_pair_u16(0x0001, 0x000f));
117
118 // For this test, content of first service is irrevelant
119
120 EXPECT_TRUE(builder.StartNextServiceExploration());
121 // Grabbing first service, to start Included Service and Characteristic
122 // discovery
123 EXPECT_EQ(builder.CurrentlyExploredService(), make_pair_u16(0x0030, 0x003f));
124
125 builder.AddIncludedService(0x0031, SERVICE_4_UUID, 0x0040, 0x004f);
126 builder.AddIncludedService(0x0032, SERVICE_2_UUID, 0x0020, 0x002f);
127
128 /* Secondary service exploration */
129 EXPECT_TRUE(builder.StartNextServiceExploration());
130 EXPECT_EQ(builder.CurrentlyExploredService(), make_pair_u16(0x0020, 0x002f));
131
132 /* Secondary service exploration */
133 EXPECT_TRUE(builder.StartNextServiceExploration());
134 EXPECT_EQ(builder.CurrentlyExploredService(), make_pair_u16(0x0040, 0x004f));
135
136 /* Back to primary service exploration */
137 EXPECT_TRUE(builder.StartNextServiceExploration());
138 EXPECT_EQ(builder.CurrentlyExploredService(), make_pair_u16(0x0050, 0x005f));
139
140 Database result = builder.Build();
141
142 // verify that the returned database matches what was discovered
143 auto service = result.Services().begin();
144 EXPECT_EQ(service->handle, 0x0001);
145 EXPECT_EQ(service->is_primary, true);
146 EXPECT_EQ(service->uuid, SERVICE_1_UUID);
147
148 service++;
149 EXPECT_EQ(service->handle, 0x0020);
150 EXPECT_EQ(service->end_handle, 0x002f);
151 EXPECT_EQ(service->uuid, SERVICE_2_UUID);
152 EXPECT_EQ(service->is_primary, false);
153
154 service++;
155 EXPECT_EQ(service->handle, 0x0030);
156 EXPECT_EQ(service->end_handle, 0x003f);
157 EXPECT_EQ(service->uuid, SERVICE_3_UUID);
158 EXPECT_EQ(service->is_primary, true);
159
160 service++;
161 EXPECT_EQ(service->handle, 0x0040);
162 EXPECT_EQ(service->uuid, SERVICE_4_UUID);
163 EXPECT_EQ(service->is_primary, false);
164
165 service++;
166 EXPECT_EQ(service->handle, 0x0050);
167 EXPECT_EQ(service->uuid, SERVICE_5_UUID);
168 EXPECT_EQ(service->is_primary, true);
169
170 service++;
171 ASSERT_EQ(service, result.Services().end());
172 }
173
174 } // namespace gatt