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