1 /*
2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "storage_helper.h"
18
19 #include <gtest/gtest.h>
20
21 using bluetooth::le_audio::LeAudioDevice;
22
23 namespace bluetooth::le_audio {
24
GetTestAddress(uint8_t index)25 static RawAddress GetTestAddress(uint8_t index) {
26 EXPECT_LT(index, UINT8_MAX);
27 RawAddress result = {{0xC0, 0xDE, 0xC0, 0xDE, 0x00, index}};
28 return result;
29 }
30
31 class StorageHelperTest : public ::testing::Test {};
32
TEST(StorageHelperTest,DeserializeSinkPacs)33 TEST(StorageHelperTest, DeserializeSinkPacs) {
34 // clang-format off
35 const std::vector<uint8_t> validSinkPack = {
36 0x00, // Magic
37 0x01, // Num of PACs
38 0x02, 0x12, // handle
39 0x03, 0x12, // cc handle
40 0x02, // Number of records in PAC
41 0x1e, // PAC entry size
42 0x06, 0x00, 0x00, 0x00, 0x00, // Codec Id
43 0x13, // Codec specific cap. size
44 0x03, 0x01, 0x04, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x01, 0x05, 0x04, 0x1e, 0x00, 0x1e, 0x00, 0x02, 0x05, 0x01, // Codec specific capa
45 0x04, // Metadata size
46 0x03, 0x01, 0xff, 0x0f, // Metadata
47 0x1e, //
48 0x06, 0x00, 0x00, 0x00, 0x00, // Codec ID
49 0x13, // Codec specific cap. size
50 0x03, 0x01, 0x20, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x01, 0x05, 0x04, 0x3c, 0x00, 0x3c, 0x00, 0x02, 0x05, 0x01, // Codec specific capa
51 0x04, // Codec specific capa
52 0x03, 0x01, 0xff, 0x0f, // Metadata
53 };
54
55 const std::vector<uint8_t> invalidSinkPackNumOfPacs = {
56 0x00, // Magic
57 0x05, // Num of PACs
58 0x02, 0x12, // handle
59 0x03, 0x12, // cc handle
60 0x01, // Number of records in PAC
61 0x1e, // PAC entry size
62 0x06, 0x00, 0x00, 0x00, 0x00, // Codec Id
63 0x13, // Codec specific cap. size
64 0x03, 0x01, 0x04, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x01, 0x05, 0x04, 0x1e, 0x00, 0x1e, 0x00, 0x02, 0x05, 0x01, // Codec specific capa
65 0x04, // Metadata size
66 0x03, 0x01, 0xff, 0x0f, // Metadata
67 0x1e, //
68 0x06, 0x00, 0x00, 0x00, 0x00, // Codec ID
69 0x13, // Codec specific cap. size
70 0x03, 0x01, 0x20, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x01, 0x05, 0x04, 0x3c, 0x00, 0x3c, 0x00, 0x02, 0x05, 0x01, // Codec specific capa
71 0x04, // Codec specific capa
72 0x03, 0x01, 0xff, 0x0f, // Metadata
73 };
74
75 const std::vector<uint8_t> invalidSinkPackMagic = {
76 0x01, // Magic
77 0x01, // Num of PACs
78 0x02, 0x12, // handle
79 0x03, 0x12, // cc handle
80 0x02, // Number of records in PAC
81 0x1e, // PAC entry size
82 0x06, 0x00, 0x00, 0x00, 0x00, // Codec Id
83 0x13, // Codec specific cap. size
84 0x03, 0x01, 0x04, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x01, 0x05, 0x04, 0x1e, 0x00, 0x1e, 0x00, 0x02, 0x05, 0x01, // Codec specific capa
85 0x04, // Metadata size
86 0x03, 0x01, 0xff, 0x0f, // Metadata
87 0x1e, //
88 0x06, 0x00, 0x00, 0x00, 0x00, // Codec ID
89 0x13, // Codec specific cap. size
90 0x03, 0x01, 0x20, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x01, 0x05, 0x04, 0x3c, 0x00, 0x3c, 0x00, 0x02, 0x05, 0x01, // Codec specific capa
91 0x04, // Codec specific capa
92 0x03, 0x01, 0xff, 0x0f, // Metadata
93 };
94 // clang-format on
95
96 RawAddress test_address0 = GetTestAddress(0);
97 LeAudioDevice leAudioDevice(test_address0, DeviceConnectState::DISCONNECTED);
98 ASSERT_TRUE(DeserializeSinkPacs(&leAudioDevice, validSinkPack));
99 std::vector<uint8_t> serialize;
100 ASSERT_TRUE(SerializeSinkPacs(&leAudioDevice, serialize));
101 ASSERT_TRUE(serialize == validSinkPack);
102
103 ASSERT_FALSE(DeserializeSinkPacs(&leAudioDevice, invalidSinkPackMagic));
104 ASSERT_FALSE(DeserializeSinkPacs(&leAudioDevice, invalidSinkPackNumOfPacs));
105 }
106
TEST(StorageHelperTest,DeserializeSourcePacs)107 TEST(StorageHelperTest, DeserializeSourcePacs) {
108 // clang-format off
109 const std::vector<uint8_t> validSourcePack = {
110 0x00, // Magic
111 0x01, // Num of PACs
112 0x08, 0x12, // handle
113 0x09, 0x12, // cc handle
114 0x02, // Number of records in PAC
115 0x1e, // PAC entry size
116 0x06, 0x00, 0x00, 0x00, 0x00, // Codec Id
117 0x13, // Codec specific cap. size
118 0x03, 0x01, 0x04, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x01, 0x05, 0x04, 0x1e, 0x00, 0x1e, 0x00, 0x02, 0x05, 0x01,
119 0x04, // Metadata size
120 0x03, 0x01, 0x03, 0x00, // Metadata
121 0x1e, // PAC entry size
122 0x06, 0x00, 0x00, 0x00, 0x00, // Codec Id
123 0x13, // Codec specific cap. size
124 0x03, 0x01, 0x20, 0x00, 0x02, 0x02, 0x01, 0x02, // Codec specific capa
125 0x03, 0x01, 0x05, 0x04, 0x3c, 0x00, 0x3c, 0x00, // Codec specific capa
126 0x02, 0x05, 0x01, // Codec specific capa
127 0x04, // Metadata size
128 0x03, 0x01, 0x03, 0x00 // Metadata
129 };
130
131 const std::vector<uint8_t> invalidSourcePackNumOfPacs = {
132 0x00, // Magic
133 0x04, // Num of PACs
134 0x08, 0x12, // handle
135 0x09, 0x12, // cc handle
136 0x01, // Number of records in PAC
137 0x1e, // PAC entry size
138 0x06, 0x00, 0x00, 0x00, 0x00, // Codec Id
139 0x13, // Codec specific cap. size
140 0x03, 0x01, 0x04, 0x00, 0x02, 0x02, 0x01, 0x02, // Codec specific capa
141 0x03, 0x01, 0x05, 0x04, 0x1e, 0x00, 0x1e, 0x00, // Codec specific capa
142 0x02, 0x05, 0x01, // Codec specific capa
143 0x04, // Metadata size
144 0x03, 0x01, 0x03, 0x00, // Metadata
145 0x1e, // PAC entry size
146 0x06, 0x00, 0x00, 0x00, 0x00, // Codec Id
147 0x13, // Codec specific cap. size
148 0x03, 0x01, 0x20, 0x00, 0x02, 0x02, 0x01, 0x02, // Codec specific capa
149 0x03, 0x01, 0x05, 0x04, 0x3c, 0x00, 0x3c, 0x00, // Codec specific capa
150 0x02, 0x05, 0x01, // Codec specific capa
151 0x04, // Metadata size
152 0x03, 0x01, 0x03, 0x00 // Metadata
153 };
154
155 const std::vector<uint8_t> invalidSourcePackMagic = {
156 0x01, // Magic
157 0x01, // Num of PACs
158 0x08, 0x12, // handle
159 0x09, 0x12, // cc handle
160 0x02, // Number of records in PAC
161 0x1e, // PAC entry size
162 0x06, 0x00, 0x00, 0x00, 0x00, // Codec Id
163 0x13, // Codec specific cap. size
164 0x03, 0x01, 0x04, 0x00, 0x02, 0x02, 0x01, 0x02, // Codec specific capa
165 0x03, 0x01, 0x05, 0x04, 0x1e, 0x00, 0x1e, 0x00, // Codec specific capa
166 0x02, 0x05, 0x01, // Codec specific capa
167 0x04, // Metadata size
168 0x03, 0x01, 0x03, 0x00, // Metadata
169 0x1e, // PAC entry size
170 0x06, 0x00, 0x00, 0x00, 0x00, // Codec Id
171 0x13, // Codec specific cap. size
172 0x03, 0x01, 0x20, 0x00, 0x02, 0x02, 0x01, 0x02, // Codec specific capa
173 0x03, 0x01, 0x05, 0x04, 0x3c, 0x00, 0x3c, 0x00, // Codec specific capa
174 0x02, 0x05, 0x01, // Codec specific capa
175 0x04, // Metadata size
176 0x03, 0x01, 0x03, 0x00 // Metadata
177 };
178 // clang-format on
179
180 RawAddress test_address0 = GetTestAddress(0);
181 LeAudioDevice leAudioDevice(test_address0, DeviceConnectState::DISCONNECTED);
182 ASSERT_TRUE(DeserializeSourcePacs(&leAudioDevice, validSourcePack));
183 std::vector<uint8_t> serialize;
184 ASSERT_TRUE(SerializeSourcePacs(&leAudioDevice, serialize));
185 ASSERT_TRUE(serialize == validSourcePack);
186
187 ASSERT_FALSE(DeserializeSourcePacs(&leAudioDevice, invalidSourcePackMagic));
188 ASSERT_FALSE(DeserializeSourcePacs(&leAudioDevice, invalidSourcePackNumOfPacs));
189 }
190
TEST(StorageHelperTest,DeserializeAses)191 TEST(StorageHelperTest, DeserializeAses) {
192 // clang-format off
193 const std::vector<uint8_t> validAses {
194 0x00, // Magic
195 0x03, // Num of ASEs
196 0x05, 0x11, // handle
197 0x06, 0x11, // ccc handle
198 0x01, // ASE id
199 0x01, // direction
200 0x08, 0x11, // handle
201 0x09, 0x11, // ccc handle
202 0x02, // ASE id
203 0x01, // direction
204 0x0b, 0x11, // handle
205 0x0c, 0x11, // ccc handle
206 0x03, // ASE id
207 0x02 // direction
208 };
209 const std::vector<uint8_t> invalidAsesNumOfAses {
210 0x00, // Magic
211 0x05, // Num of ASEs
212 0x05, 0x11, // handle
213 0x06, 0x11, // ccc handle
214 0x01, // ASE id
215 0x01, // direction
216 0x08, 0x11, // handle
217 0x09, 0x11, // ccc handle
218 0x02, // ASE id
219 0x01, // direction
220 0x0b, 0x11, // handle
221 0x0c, 0x11, // ccc handle
222 0x03, // ASE id
223 0x02 // direction
224 };
225 const std::vector<uint8_t> invalidAsesMagic {
226 0x01, // Magic
227 0x03, // Num of ASEs
228 0x05, 0x11, // handle
229 0x06, 0x11, // ccc handle
230 0x01, // ASE id
231 0x01, // direction
232 0x08, 0x11, // handle
233 0x09, 0x11, // ccc handle
234 0x02, // ASE id
235 0x01, // direction
236 0x0b, 0x11, // handle
237 0x0c, 0x11, // ccc handle
238 0x03, // ASE id
239 0x02 // direction
240 };
241 // clang-format on
242 RawAddress test_address0 = GetTestAddress(0);
243 LeAudioDevice leAudioDevice(test_address0, DeviceConnectState::DISCONNECTED);
244 ASSERT_TRUE(DeserializeAses(&leAudioDevice, validAses));
245
246 std::vector<uint8_t> serialize;
247 ASSERT_TRUE(SerializeAses(&leAudioDevice, serialize));
248 ASSERT_TRUE(serialize == validAses);
249
250 ASSERT_FALSE(DeserializeAses(&leAudioDevice, invalidAsesNumOfAses));
251 ASSERT_FALSE(DeserializeAses(&leAudioDevice, invalidAsesMagic));
252 }
253
TEST(StorageHelperTest,DeserializeHandles)254 TEST(StorageHelperTest, DeserializeHandles) {
255 // clang-format off
256 const std::vector<uint8_t> validHandles {
257 0x00, // Magic
258 0x0e, 0x11, // Control point handle
259 0x0f, 0x11, // Control point ccc handle
260 0x05, 0x12, // Sink audio location handle
261 0x06, 0x12, // Sink audio location ccc handle
262 0x0b, 0x12, // Source audio location handle
263 0x0c, 0x12, // Source audio location ccc handle
264 0x11, 0x12, // Supported context types handle
265 0x12, 0x12, // Supported context types ccc handle
266 0x0e, 0x12, // Available context types handle
267 0x0f, 0x12, // Available context types ccc handle
268 0x03, 0xa3 // TMAP role handle
269 };
270 const std::vector<uint8_t> invalidHandlesMagic {
271 0x01, // Magic
272 0x0e, 0x11, // Control point handle
273 0x0f, 0x11, // Control point ccc handle
274 0x05, 0x12, // Sink audio location handle
275 0x06, 0x12, // Sink audio location ccc handle
276 0x0b, 0x12, // Source audio location handle
277 0x0c, 0x12, // Source audio location ccc handle
278 0x11, 0x12, // Supported context types handle
279 0x12, 0x12, // Supported context types ccc handle
280 0x0e, 0x12, // Available context types handle
281 0x0f, 0x12, // Available context types ccc handle
282 0x03, 0xa3 // TMAP role handle
283 };
284 const std::vector<uint8_t> invalidHandles {
285 0x00, // Magic
286 0x0e, 0x11, // Control point handle
287 0x0f, 0x11, // Control point ccc handle
288 0x05, 0x12, // Sink audio location handle
289 0x06, 0x12, // Sink audio location ccc handle
290 0x0b, 0x12, // Source audio location handle
291 0x0c, 0x12, // Source audio location ccc handle
292 0x11, 0x12, // Supported context types handle
293 0x12, 0x12, // Supported context types ccc handle
294 0x0e, 0x12, // Available context types handle
295 0x0f, 0x12, // Available context types ccc handle
296 0x03, 0xa3, // TMAP role handle
297 0x00, 0x00, // corrupted
298 };
299 // clang-format on
300 RawAddress test_address0 = GetTestAddress(0);
301 LeAudioDevice leAudioDevice(test_address0, DeviceConnectState::DISCONNECTED);
302 ASSERT_TRUE(DeserializeHandles(&leAudioDevice, validHandles));
303 std::vector<uint8_t> serialize;
304 ASSERT_TRUE(SerializeHandles(&leAudioDevice, serialize));
305 ASSERT_TRUE(serialize == validHandles);
306
307 ASSERT_FALSE(DeserializeHandles(&leAudioDevice, invalidHandlesMagic));
308 ASSERT_FALSE(DeserializeHandles(&leAudioDevice, invalidHandles));
309 }
310
TEST(StorageHelperTest,DeserializeGmapV1)311 TEST(StorageHelperTest, DeserializeGmapV1) {
312 // clang-format off
313 const std::vector<uint8_t> validHandles {
314 0x01, // V1 Layout Magic
315 0x0e, 0x11, // Role Handle
316 0x0f, 0x11, // Feature Handle
317 0x05, // Role value
318 0x06, // Feature value
319 };
320 const std::vector<uint8_t> invalidHandlesMagic {
321 0x00, // Unknown Layout Magic
322 0x0e, 0x11, // Role Handle
323 0x0f, 0x11, // Feature Handle
324 0x05, // Role value
325 0x06, // Feature value
326 };
327 const std::vector<uint8_t> invalidHandles {
328 0x01, // V1 Layout Magic
329 0x0e, 0x11, // Role Handle
330 0x0f, 0x11, // Feature Handle
331 0x05, // Role value
332 0x06, // Feature value
333 0x06, // corrupted
334 };
335
336 // clang-format on
337 RawAddress test_address0 = GetTestAddress(0);
338 GmapClient gmap(test_address0);
339 ASSERT_TRUE(DeserializeGmap(&gmap, validHandles));
340 std::vector<uint8_t> serialize;
341 ASSERT_TRUE(SerializeGmap(&gmap, serialize));
342 ASSERT_TRUE(serialize == validHandles);
343
344 ASSERT_FALSE(DeserializeGmap(&gmap, invalidHandlesMagic));
345 ASSERT_FALSE(DeserializeGmap(&gmap, invalidHandles));
346 }
347 } // namespace bluetooth::le_audio
348