1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_bluetooth_sapphire/internal/host/gap/discovery_filter.h"
16
17 #include "pw_bluetooth_sapphire/internal/host/common/advertising_data.h"
18 #include "pw_bluetooth_sapphire/internal/host/common/supplement_data.h"
19 #include "pw_bluetooth_sapphire/internal/host/common/uint128.h"
20 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_scanner.h"
21 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
22 #include "pw_unit_test/framework.h"
23
24 namespace bt::gap {
25 namespace {
26
27 constexpr uint16_t kUuid0 = 0x180d;
28
TEST(DiscoveryFilterTest,Flags)29 TEST(DiscoveryFilterTest, Flags) {
30 const StaticByteBuffer kNoFlagsData(0x02, 0x09, 'a');
31 const StaticByteBuffer kValidFlagsData(0x02, 0x01, 0b101);
32
33 auto no_flags_data = AdvertisingData::FromBytes(kNoFlagsData).value();
34 auto valid_flags_data = AdvertisingData::FromBytes(kValidFlagsData).value();
35
36 DiscoveryFilter filter;
37
38 // Empty filter should match everything.
39 EXPECT_TRUE(
40 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
41 EXPECT_TRUE(filter.MatchLowEnergyResult(
42 no_flags_data, false, hci_spec::kRSSIInvalid));
43 EXPECT_TRUE(filter.MatchLowEnergyResult(
44 valid_flags_data, false, hci_spec::kRSSIInvalid));
45
46 filter.set_flags(0b100);
47 EXPECT_FALSE(
48 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
49 EXPECT_FALSE(filter.MatchLowEnergyResult(
50 no_flags_data, false, hci_spec::kRSSIInvalid));
51 EXPECT_TRUE(filter.MatchLowEnergyResult(
52 valid_flags_data, false, hci_spec::kRSSIInvalid));
53
54 filter.set_flags(0b001);
55 EXPECT_FALSE(
56 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
57 EXPECT_FALSE(filter.MatchLowEnergyResult(
58 no_flags_data, false, hci_spec::kRSSIInvalid));
59 EXPECT_TRUE(filter.MatchLowEnergyResult(
60 valid_flags_data, false, hci_spec::kRSSIInvalid));
61
62 // The following filters set multiple bits. As long as one of them is set, the
63 // filter should match.
64 filter.set_flags(0b101);
65 EXPECT_FALSE(
66 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
67 EXPECT_FALSE(filter.MatchLowEnergyResult(
68 no_flags_data, false, hci_spec::kRSSIInvalid));
69 EXPECT_TRUE(filter.MatchLowEnergyResult(
70 valid_flags_data, false, hci_spec::kRSSIInvalid));
71
72 filter.set_flags(0b111);
73 EXPECT_FALSE(
74 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
75 EXPECT_FALSE(filter.MatchLowEnergyResult(
76 no_flags_data, false, hci_spec::kRSSIInvalid));
77 EXPECT_TRUE(filter.MatchLowEnergyResult(
78 valid_flags_data, false, hci_spec::kRSSIInvalid));
79
80 filter.set_flags(0b011);
81 EXPECT_FALSE(
82 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
83 EXPECT_FALSE(filter.MatchLowEnergyResult(
84 no_flags_data, false, hci_spec::kRSSIInvalid));
85 EXPECT_TRUE(filter.MatchLowEnergyResult(
86 valid_flags_data, false, hci_spec::kRSSIInvalid));
87
88 filter.set_flags(0b010);
89 EXPECT_FALSE(
90 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
91 EXPECT_FALSE(filter.MatchLowEnergyResult(
92 no_flags_data, false, hci_spec::kRSSIInvalid));
93 EXPECT_FALSE(filter.MatchLowEnergyResult(
94 valid_flags_data, false, hci_spec::kRSSIInvalid));
95
96 // The following filters requre that *all* bits be present in the advertising
97 // data.
98 filter.set_flags(0b101, /*require_all=*/true);
99 EXPECT_FALSE(
100 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
101 EXPECT_FALSE(filter.MatchLowEnergyResult(
102 no_flags_data, false, hci_spec::kRSSIInvalid));
103 EXPECT_TRUE(filter.MatchLowEnergyResult(
104 valid_flags_data, false, hci_spec::kRSSIInvalid));
105
106 filter.set_flags(0b111, /*require_all=*/true);
107 EXPECT_FALSE(
108 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
109 EXPECT_FALSE(filter.MatchLowEnergyResult(
110 no_flags_data, false, hci_spec::kRSSIInvalid));
111 EXPECT_FALSE(filter.MatchLowEnergyResult(
112 valid_flags_data, false, hci_spec::kRSSIInvalid));
113
114 filter.set_flags(0b011, /*require_all=*/true);
115 EXPECT_FALSE(
116 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
117 EXPECT_FALSE(filter.MatchLowEnergyResult(
118 no_flags_data, false, hci_spec::kRSSIInvalid));
119 EXPECT_FALSE(filter.MatchLowEnergyResult(
120 valid_flags_data, false, hci_spec::kRSSIInvalid));
121
122 filter.set_flags(0b010, /*require_all=*/true);
123 EXPECT_FALSE(
124 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
125 EXPECT_FALSE(filter.MatchLowEnergyResult(
126 no_flags_data, false, hci_spec::kRSSIInvalid));
127 EXPECT_FALSE(filter.MatchLowEnergyResult(
128 valid_flags_data, false, hci_spec::kRSSIInvalid));
129 }
130
TEST(DiscoveryFilterTest,Connectable)131 TEST(DiscoveryFilterTest, Connectable) {
132 DiscoveryFilter filter;
133
134 // Empty filter should match both.
135 EXPECT_TRUE(
136 filter.MatchLowEnergyResult(std::nullopt, true, hci_spec::kRSSIInvalid));
137 EXPECT_TRUE(
138 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
139
140 // Filter connectable.
141 filter.set_connectable(true);
142 EXPECT_TRUE(filter.connectable());
143 EXPECT_TRUE(
144 filter.MatchLowEnergyResult(std::nullopt, true, hci_spec::kRSSIInvalid));
145 EXPECT_FALSE(
146 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
147
148 // Filter not connectable.
149 filter.set_connectable(false);
150 EXPECT_TRUE(filter.connectable());
151 EXPECT_FALSE(
152 filter.MatchLowEnergyResult(std::nullopt, true, hci_spec::kRSSIInvalid));
153 EXPECT_TRUE(
154 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
155
156 filter.Reset();
157 EXPECT_FALSE(filter.connectable());
158 }
159
160 TEST(DiscoveryFilterTest, 16BitServiceUuids) {
161 constexpr uint16_t kUuid1 = 0x1800;
162
163 // Below, "Incomplete" refers to the "Incomplete Service UUIDs" field while
164 // "Complete" refers to "Complete Service UUIDs".
165
166 const auto kIncompleteEmpty(
167 AdvertisingData::FromBytes(
168 StaticByteBuffer(0x01, DataType::kIncomplete16BitServiceUuids))
169 .value());
170 const auto kIncompleteNoMatch(
171 AdvertisingData::FromBytes(
172 StaticByteBuffer(0x05,
173 DataType::kIncomplete16BitServiceUuids,
174 0x01,
175 0x02,
176 0x03,
177 0x04))
178 .value());
179 const auto kIncompleteMatch0(
180 AdvertisingData::FromBytes(
181 StaticByteBuffer(0x05,
182 DataType::kIncomplete16BitServiceUuids,
183 0x01,
184 0x02,
185 LowerBits(kUuid0),
186 UpperBits(kUuid0)))
187 .value());
188 const auto kIncompleteMatch1(
189 AdvertisingData::FromBytes(
190 StaticByteBuffer(0x05,
191 DataType::kIncomplete16BitServiceUuids,
192 LowerBits(kUuid1),
193 UpperBits(kUuid1),
194 0x03,
195 0x04))
196 .value());
197 const auto kCompleteEmpty(
198 AdvertisingData::FromBytes(
199 StaticByteBuffer(0x01, DataType::kComplete16BitServiceUuids))
200 .value());
201 const auto kCompleteNoMatch(
202 AdvertisingData::FromBytes(
203 StaticByteBuffer(0x05,
204 DataType::kComplete16BitServiceUuids,
205 0x01,
206 0x02,
207 0x03,
208 0x04))
209 .value());
210 const auto kCompleteMatch0(
211 AdvertisingData::FromBytes(
212 StaticByteBuffer(0x05,
213 DataType::kComplete16BitServiceUuids,
214 0x01,
215 0x02,
216 LowerBits(kUuid0),
217 UpperBits(kUuid0)))
218 .value());
219 const auto kCompleteMatch1(
220 AdvertisingData::FromBytes(
221 StaticByteBuffer(0x05,
222 DataType::kComplete16BitServiceUuids,
223 LowerBits(kUuid1),
224 UpperBits(kUuid1),
225 0x03,
226 0x04))
227 .value());
228
229 DiscoveryFilter filter;
230
231 // An empty filter should match all payloads.
232 EXPECT_TRUE(
233 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
234 EXPECT_TRUE(filter.MatchLowEnergyResult(
235 kIncompleteEmpty, false, hci_spec::kRSSIInvalid));
236 EXPECT_TRUE(filter.MatchLowEnergyResult(
237 kIncompleteNoMatch, false, hci_spec::kRSSIInvalid));
238 EXPECT_TRUE(filter.MatchLowEnergyResult(
239 kIncompleteMatch0, false, hci_spec::kRSSIInvalid));
240 EXPECT_TRUE(filter.MatchLowEnergyResult(
241 kIncompleteMatch1, false, hci_spec::kRSSIInvalid));
242 EXPECT_TRUE(filter.MatchLowEnergyResult(
243 kCompleteEmpty, false, hci_spec::kRSSIInvalid));
244 EXPECT_TRUE(filter.MatchLowEnergyResult(
245 kCompleteNoMatch, false, hci_spec::kRSSIInvalid));
246 EXPECT_TRUE(filter.MatchLowEnergyResult(
247 kCompleteMatch0, false, hci_spec::kRSSIInvalid));
248 EXPECT_TRUE(filter.MatchLowEnergyResult(
249 kCompleteMatch1, false, hci_spec::kRSSIInvalid));
250
251 // Filter for kUuid0 and kUuid1.
252 filter.set_service_uuids(std::vector<UUID>{UUID(kUuid0), UUID(kUuid1)});
253 EXPECT_FALSE(filter.service_uuids().empty());
254 EXPECT_FALSE(
255 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
256 EXPECT_FALSE(filter.MatchLowEnergyResult(
257 kIncompleteEmpty, false, hci_spec::kRSSIInvalid));
258 EXPECT_FALSE(filter.MatchLowEnergyResult(
259 kIncompleteNoMatch, false, hci_spec::kRSSIInvalid));
260 EXPECT_TRUE(filter.MatchLowEnergyResult(
261 kIncompleteMatch0, false, hci_spec::kRSSIInvalid));
262 EXPECT_TRUE(filter.MatchLowEnergyResult(
263 kIncompleteMatch1, false, hci_spec::kRSSIInvalid));
264 EXPECT_FALSE(filter.MatchLowEnergyResult(
265 kCompleteEmpty, false, hci_spec::kRSSIInvalid));
266 EXPECT_FALSE(filter.MatchLowEnergyResult(
267 kCompleteNoMatch, false, hci_spec::kRSSIInvalid));
268 EXPECT_TRUE(filter.MatchLowEnergyResult(
269 kCompleteMatch0, false, hci_spec::kRSSIInvalid));
270 EXPECT_TRUE(filter.MatchLowEnergyResult(
271 kCompleteMatch1, false, hci_spec::kRSSIInvalid));
272
273 filter.Reset();
274 EXPECT_TRUE(filter.service_uuids().empty());
275 }
276
277 TEST(DiscoveryFilterTest, 32BitServiceUuids) {
278 constexpr uint32_t kUuid1 = 0xabcd1800;
279
280 // Below, "Incomplete" refers to the "Incomplete Service UUIDs" field while
281 // "Complete" refers to "Complete Service UUIDs".
282
283 const auto kIncompleteEmpty(
284 AdvertisingData::FromBytes(StaticByteBuffer(0x01, 0x04)).value());
285 const auto kIncompleteNoMatch(
286 AdvertisingData::FromBytes(
287 StaticByteBuffer(0x09,
288 DataType::kIncomplete32BitServiceUuids,
289 // First UUID
290 0x01,
291 0x02,
292 0x03,
293 0x04,
294 // Second UUID
295 0x05,
296 0x06,
297 0x07,
298 0x08))
299 .value());
300 const auto kIncompleteMatch0(
301 AdvertisingData::FromBytes(
302 StaticByteBuffer(0x09,
303 DataType::kIncomplete32BitServiceUuids,
304 // First UUID
305 0x01,
306 0x02,
307 0x03,
308 0x04,
309 // kUuid0
310 LowerBits(kUuid0),
311 UpperBits(kUuid0),
312 0x00,
313 0x00))
314 .value());
315 const auto kIncompleteMatch1(
316 AdvertisingData::FromBytes(
317 StaticByteBuffer(0x09,
318 DataType::kIncomplete32BitServiceUuids,
319 // kUuid1
320 0x00,
321 0x18,
322 0xcd,
323 0xab,
324 // Second UUID
325 0x01,
326 0x02,
327 0x03,
328 0x04))
329 .value());
330 const auto kCompleteEmpty(
331 AdvertisingData::FromBytes(
332 StaticByteBuffer(0x01, DataType::kComplete32BitServiceUuids))
333 .value());
334 const auto kCompleteNoMatch(
335 AdvertisingData::FromBytes(
336 StaticByteBuffer(0x09,
337 DataType::kComplete32BitServiceUuids,
338 // First UUID
339 0x01,
340 0x02,
341 0x03,
342 0x04,
343 // Second UUID
344 0x05,
345 0x06,
346 0x07,
347 0x08))
348 .value());
349 const auto kCompleteMatch0(
350 AdvertisingData::FromBytes(
351 StaticByteBuffer(0x09,
352 DataType::kComplete32BitServiceUuids,
353 // First UUID
354 0x01,
355 0x02,
356 0x03,
357 0x04,
358 // kUuid0
359 LowerBits(kUuid0),
360 UpperBits(kUuid0),
361 0x00,
362 0x00))
363 .value());
364 const auto kCompleteMatch1(
365 AdvertisingData::FromBytes(
366 StaticByteBuffer(0x09,
367 DataType::kComplete32BitServiceUuids,
368 // kUuid1
369 0x00,
370 0x18,
371 0xcd,
372 0xab,
373 // Second UUID
374 0x01,
375 0x02,
376 0x03,
377 0x04))
378 .value());
379
380 DiscoveryFilter filter;
381
382 // An empty filter should match all payloads.
383 EXPECT_TRUE(
384 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
385 EXPECT_TRUE(filter.MatchLowEnergyResult(
386 kIncompleteEmpty, false, hci_spec::kRSSIInvalid));
387 EXPECT_TRUE(filter.MatchLowEnergyResult(
388 kIncompleteNoMatch, false, hci_spec::kRSSIInvalid));
389 EXPECT_TRUE(filter.MatchLowEnergyResult(
390 kIncompleteMatch0, false, hci_spec::kRSSIInvalid));
391 EXPECT_TRUE(filter.MatchLowEnergyResult(
392 kIncompleteMatch1, false, hci_spec::kRSSIInvalid));
393 EXPECT_TRUE(filter.MatchLowEnergyResult(
394 kCompleteEmpty, false, hci_spec::kRSSIInvalid));
395 EXPECT_TRUE(filter.MatchLowEnergyResult(
396 kCompleteNoMatch, false, hci_spec::kRSSIInvalid));
397 EXPECT_TRUE(filter.MatchLowEnergyResult(
398 kCompleteMatch0, false, hci_spec::kRSSIInvalid));
399 EXPECT_TRUE(filter.MatchLowEnergyResult(
400 kCompleteMatch1, false, hci_spec::kRSSIInvalid));
401
402 // Filter for kUuid0 and kUuid1.
403 filter.set_service_uuids(std::vector<UUID>{UUID(kUuid0), UUID(kUuid1)});
404 EXPECT_FALSE(filter.service_uuids().empty());
405 EXPECT_FALSE(
406 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
407 EXPECT_FALSE(filter.MatchLowEnergyResult(
408 kIncompleteEmpty, false, hci_spec::kRSSIInvalid));
409 EXPECT_FALSE(filter.MatchLowEnergyResult(
410 kIncompleteNoMatch, false, hci_spec::kRSSIInvalid));
411 EXPECT_TRUE(filter.MatchLowEnergyResult(
412 kIncompleteMatch0, false, hci_spec::kRSSIInvalid));
413 EXPECT_TRUE(filter.MatchLowEnergyResult(
414 kIncompleteMatch1, false, hci_spec::kRSSIInvalid));
415 EXPECT_FALSE(filter.MatchLowEnergyResult(
416 kCompleteEmpty, false, hci_spec::kRSSIInvalid));
417 EXPECT_FALSE(filter.MatchLowEnergyResult(
418 kCompleteNoMatch, false, hci_spec::kRSSIInvalid));
419 EXPECT_TRUE(filter.MatchLowEnergyResult(
420 kCompleteMatch0, false, hci_spec::kRSSIInvalid));
421 EXPECT_TRUE(filter.MatchLowEnergyResult(
422 kCompleteMatch1, false, hci_spec::kRSSIInvalid));
423
424 filter.Reset();
425 EXPECT_TRUE(filter.service_uuids().empty());
426 }
427
428 TEST(DiscoveryFilterTest, 128BitServiceUuids) {
429 constexpr UInt128 kUuid1 = {0xDE,
430 0xAD,
431 0xBE,
432 0xEF,
433 0xDE,
434 0xAD,
435 0xBE,
436 0xEF,
437 0xDE,
438 0xAD,
439 0xBE,
440 0xEF,
441 0x00,
442 0x18,
443 0xcd,
444 0xab};
445
446 // Below, "Incomplete" refers to the "Incomplete Service UUIDs" field while
447 // "Complete" refers to "Complete Service UUIDs".
448
449 const auto kIncompleteEmpty(
450 AdvertisingData::FromBytes(
451 StaticByteBuffer(0x01, DataType::kIncomplete128BitServiceUuids))
452 .value());
453 const auto kIncompleteNoMatch(
454 AdvertisingData::FromBytes(
455 StaticByteBuffer(0x11,
456 DataType::kIncomplete128BitServiceUuids,
457
458 // UUID
459 0x00,
460 0x01,
461 0x02,
462 0x03,
463 0x04,
464 0x05,
465 0x06,
466 0x07,
467 0x08,
468 0x09,
469 0x0A,
470 0x0B,
471 0x0C,
472 0x0D,
473 0x0E,
474 0x0F))
475 .value());
476 const auto kIncompleteMatch0(
477 AdvertisingData::FromBytes(
478 StaticByteBuffer(0x21,
479 DataType::kIncomplete128BitServiceUuids,
480 // First UUID
481 0x00,
482 0x01,
483 0x02,
484 0x03,
485 0x04,
486 0x05,
487 0x06,
488 0x07,
489 0x08,
490 0x09,
491 0x0A,
492 0x0B,
493 0x0C,
494 0x0D,
495 0x0E,
496 0x0F,
497
498 // kUuid0 - padded with the BT SIG Base UUID.
499 // See Core Spec v5.0, Vol 3, Part B, Section 2.5.1.
500 0xFB,
501 0x34,
502 0x9B,
503 0x5F,
504 0x80,
505 0x00,
506 0x00,
507 0x80,
508 0x00,
509 0x10,
510 0x00,
511 0x00,
512 LowerBits(kUuid0),
513 UpperBits(kUuid0),
514 0x00,
515 0x00))
516 .value());
517 const auto kIncompleteMatch1(
518 AdvertisingData::FromBytes(
519 StaticByteBuffer(0x21,
520 DataType::kIncomplete128BitServiceUuids,
521
522 // kUuid1
523 kUuid1[0],
524 kUuid1[1],
525 kUuid1[2],
526 kUuid1[3],
527 kUuid1[4],
528 kUuid1[5],
529 kUuid1[6],
530 kUuid1[7],
531 kUuid1[8],
532 kUuid1[9],
533 kUuid1[10],
534 kUuid1[11],
535 kUuid1[12],
536 kUuid1[13],
537 kUuid1[14],
538 kUuid1[15],
539
540 // Second UUID
541 0x00,
542 0x01,
543 0x02,
544 0x03,
545 0x04,
546 0x05,
547 0x06,
548 0x07,
549 0x08,
550 0x09,
551 0x0A,
552 0x0B,
553 0x0C,
554 0x0D,
555 0x0E,
556 0x0F))
557 .value());
558 const auto kCompleteEmpty(
559 AdvertisingData::FromBytes(
560 StaticByteBuffer(0x01, DataType::kComplete128BitServiceUuids))
561 .value());
562 const auto kCompleteNoMatch(
563 AdvertisingData::FromBytes(
564 StaticByteBuffer(0x11,
565 DataType::kComplete128BitServiceUuids,
566
567 // UUID
568 0x00,
569 0x01,
570 0x02,
571 0x03,
572 0x04,
573 0x05,
574 0x06,
575 0x07,
576 0x08,
577 0x09,
578 0x0A,
579 0x0B,
580 0x0C,
581 0x0D,
582 0x0E,
583 0x0F))
584 .value());
585 const auto kCompleteMatch0(
586 AdvertisingData::FromBytes(
587 StaticByteBuffer(0x21,
588 DataType::kComplete128BitServiceUuids,
589
590 // First UUID
591 0x00,
592 0x01,
593 0x02,
594 0x03,
595 0x04,
596 0x05,
597 0x06,
598 0x07,
599 0x08,
600 0x09,
601 0x0A,
602 0x0B,
603 0x0C,
604 0x0D,
605 0x0E,
606 0x0F,
607
608 // kUuid0 - padded with the BT SIG Base UUID.
609 // See Core Spec v5.0, Vol 3, Part B, Section 2.5.1.
610 0xFB,
611 0x34,
612 0x9B,
613 0x5F,
614 0x80,
615 0x00,
616 0x00,
617 0x80,
618 0x00,
619 0x10,
620 0x00,
621 0x00,
622 LowerBits(kUuid0),
623 UpperBits(kUuid0),
624 0x00,
625 0x00))
626 .value());
627 const auto kCompleteMatch1(
628 AdvertisingData::FromBytes(
629 StaticByteBuffer(0x21,
630 DataType::kComplete128BitServiceUuids,
631
632 // kUuid1
633 kUuid1[0],
634 kUuid1[1],
635 kUuid1[2],
636 kUuid1[3],
637 kUuid1[4],
638 kUuid1[5],
639 kUuid1[6],
640 kUuid1[7],
641 kUuid1[8],
642 kUuid1[9],
643 kUuid1[10],
644 kUuid1[11],
645 kUuid1[12],
646 kUuid1[13],
647 kUuid1[14],
648 kUuid1[15],
649
650 // Second UUID
651 0x00,
652 0x01,
653 0x02,
654 0x03,
655 0x04,
656 0x05,
657 0x06,
658 0x07,
659 0x08,
660 0x09,
661 0x0A,
662 0x0B,
663 0x0C,
664 0x0D,
665 0x0E,
666 0x0F))
667 .value());
668
669 DiscoveryFilter filter;
670
671 // An empty filter should match all payloads.
672 EXPECT_TRUE(
673 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
674 EXPECT_TRUE(filter.MatchLowEnergyResult(
675 kIncompleteEmpty, false, hci_spec::kRSSIInvalid));
676 EXPECT_TRUE(filter.MatchLowEnergyResult(
677 kIncompleteNoMatch, false, hci_spec::kRSSIInvalid));
678 EXPECT_TRUE(filter.MatchLowEnergyResult(
679 kIncompleteMatch0, false, hci_spec::kRSSIInvalid));
680 EXPECT_TRUE(filter.MatchLowEnergyResult(
681 kIncompleteMatch1, false, hci_spec::kRSSIInvalid));
682 EXPECT_TRUE(filter.MatchLowEnergyResult(
683 kCompleteEmpty, false, hci_spec::kRSSIInvalid));
684 EXPECT_TRUE(filter.MatchLowEnergyResult(
685 kCompleteNoMatch, false, hci_spec::kRSSIInvalid));
686 EXPECT_TRUE(filter.MatchLowEnergyResult(
687 kCompleteMatch0, false, hci_spec::kRSSIInvalid));
688 EXPECT_TRUE(filter.MatchLowEnergyResult(
689 kCompleteMatch1, false, hci_spec::kRSSIInvalid));
690
691 // Filter for kUuid0 and kUuid1.
692 filter.set_service_uuids(std::vector<UUID>{UUID(kUuid0), UUID(kUuid1)});
693 EXPECT_FALSE(filter.service_uuids().empty());
694 EXPECT_FALSE(
695 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
696 EXPECT_FALSE(filter.MatchLowEnergyResult(
697 kIncompleteEmpty, false, hci_spec::kRSSIInvalid));
698 EXPECT_FALSE(filter.MatchLowEnergyResult(
699 kIncompleteNoMatch, false, hci_spec::kRSSIInvalid));
700 EXPECT_TRUE(filter.MatchLowEnergyResult(
701 kIncompleteMatch0, false, hci_spec::kRSSIInvalid));
702 EXPECT_TRUE(filter.MatchLowEnergyResult(
703 kIncompleteMatch1, false, hci_spec::kRSSIInvalid));
704 EXPECT_FALSE(filter.MatchLowEnergyResult(
705 kCompleteEmpty, false, hci_spec::kRSSIInvalid));
706 EXPECT_FALSE(filter.MatchLowEnergyResult(
707 kCompleteNoMatch, false, hci_spec::kRSSIInvalid));
708 EXPECT_TRUE(filter.MatchLowEnergyResult(
709 kCompleteMatch0, false, hci_spec::kRSSIInvalid));
710 EXPECT_TRUE(filter.MatchLowEnergyResult(
711 kCompleteMatch1, false, hci_spec::kRSSIInvalid));
712
713 filter.Reset();
714 EXPECT_TRUE(filter.service_uuids().empty());
715 }
716
717 TEST(DiscoveryFilterTest, 16BitServiceDataUuids) {
718 constexpr uint16_t kUuid1 = 0x1800;
719
720 const auto kNoMatch(
721 AdvertisingData::FromBytes(
722 StaticByteBuffer(
723 0x05, DataType::kServiceData16Bit, 0x01, 0x02, 0x03, 0x04))
724 .value());
725 const auto kMatch0(
726 AdvertisingData::FromBytes(StaticByteBuffer(0x05,
727 DataType::kServiceData16Bit,
728 LowerBits(kUuid0),
729 UpperBits(kUuid0),
730 0x01,
731 0x02))
732 .value());
733 const auto kMatch1(
734 AdvertisingData::FromBytes(StaticByteBuffer(0x05,
735 DataType::kServiceData16Bit,
736 LowerBits(kUuid1),
737 UpperBits(kUuid1),
738 0x03,
739 0x04))
740 .value());
741
742 DiscoveryFilter filter;
743
744 // An empty filter should match all payloads.
745 EXPECT_TRUE(
746 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
747 EXPECT_TRUE(
748 filter.MatchLowEnergyResult(kNoMatch, false, hci_spec::kRSSIInvalid));
749 EXPECT_TRUE(
750 filter.MatchLowEnergyResult(kMatch0, false, hci_spec::kRSSIInvalid));
751 EXPECT_TRUE(
752 filter.MatchLowEnergyResult(kMatch1, false, hci_spec::kRSSIInvalid));
753
754 // Filter for kUuid0 and kUuid1.
755 filter.set_service_data_uuids(std::vector<UUID>{UUID(kUuid0), UUID(kUuid1)});
756 EXPECT_FALSE(filter.service_data_uuids().empty());
757 EXPECT_FALSE(
758 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
759 EXPECT_FALSE(
760 filter.MatchLowEnergyResult(kNoMatch, false, hci_spec::kRSSIInvalid));
761 EXPECT_TRUE(
762 filter.MatchLowEnergyResult(kMatch0, false, hci_spec::kRSSIInvalid));
763 EXPECT_TRUE(
764 filter.MatchLowEnergyResult(kMatch1, false, hci_spec::kRSSIInvalid));
765
766 filter.Reset();
767 EXPECT_TRUE(filter.service_data_uuids().empty());
768 }
769
770 TEST(DiscoveryFilterTest, 32BitServiceDataUuids) {
771 constexpr uint32_t kUuid1 = 0xabcd1800;
772
773 const auto kNoMatch(
774 AdvertisingData::FromBytes(StaticByteBuffer(0x09,
775 DataType::kServiceData32Bit,
776 // Random UUID
777 0x01,
778 0x02,
779 0x03,
780 0x04,
781 // Random UUID
782 0x05,
783 0x06,
784 0x07,
785 0x08))
786 .value());
787 const auto kMatch0(
788 AdvertisingData::FromBytes(StaticByteBuffer(0x09,
789 DataType::kServiceData32Bit,
790 // kUuid0
791 LowerBits(kUuid0),
792 UpperBits(kUuid0),
793 0x00,
794 0x00,
795 // Data
796 0x01,
797 0x02,
798 0x03,
799 0x04))
800 .value());
801 const auto kMatch1(
802 AdvertisingData::FromBytes(StaticByteBuffer(0x09,
803 DataType::kServiceData32Bit,
804 // kUuid1
805 0x00,
806 0x18,
807 0xcd,
808 0xab,
809 // Random UUID
810 0x01,
811 0x02,
812 0x03,
813 0x04))
814 .value());
815
816 DiscoveryFilter filter;
817
818 // An empty filter should match all payloads.
819 EXPECT_TRUE(
820 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
821 EXPECT_TRUE(
822 filter.MatchLowEnergyResult(kNoMatch, false, hci_spec::kRSSIInvalid));
823 EXPECT_TRUE(
824 filter.MatchLowEnergyResult(kMatch0, false, hci_spec::kRSSIInvalid));
825 EXPECT_TRUE(
826 filter.MatchLowEnergyResult(kMatch1, false, hci_spec::kRSSIInvalid));
827
828 // Filter for kUuid0 and kUuid1.
829 filter.set_service_data_uuids(std::vector<UUID>{UUID(kUuid0), UUID(kUuid1)});
830 EXPECT_FALSE(filter.service_data_uuids().empty());
831 EXPECT_FALSE(
832 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
833 EXPECT_FALSE(
834 filter.MatchLowEnergyResult(kNoMatch, false, hci_spec::kRSSIInvalid));
835 EXPECT_TRUE(
836 filter.MatchLowEnergyResult(kMatch0, false, hci_spec::kRSSIInvalid));
837 EXPECT_TRUE(
838 filter.MatchLowEnergyResult(kMatch1, false, hci_spec::kRSSIInvalid));
839
840 filter.Reset();
841 EXPECT_TRUE(filter.service_data_uuids().empty());
842 }
843
844 TEST(DiscoveryFilterTest, 128BitServiceDataUuids) {
845 constexpr UInt128 kUuid1 = {0xDE,
846 0xAD,
847 0xBE,
848 0xEF,
849 0xDE,
850 0xAD,
851 0xBE,
852 0xEF,
853 0xDE,
854 0xAD,
855 0xBE,
856 0xEF,
857 0x00,
858 0x18,
859 0xcd,
860 0xab};
861
862 const auto kNoMatch(
863 AdvertisingData::FromBytes(StaticByteBuffer(0x11,
864 DataType::kServiceData128Bit,
865
866 // Random UUID
867 0x00,
868 0x01,
869 0x02,
870 0x03,
871 0x04,
872 0x05,
873 0x06,
874 0x07,
875 0x08,
876 0x09,
877 0x0A,
878 0x0B,
879 0x0C,
880 0x0D,
881 0x0E,
882 0x0F))
883 .value());
884 const auto kMatch0(
885 AdvertisingData::FromBytes(
886 StaticByteBuffer(0x21,
887 DataType::kServiceData128Bit,
888 // kUuid0 - padded with the BT SIG Base UUID. See
889 // Core Spec v5.0, Vol 3, Part B, Section 2.5.1.
890 0xFB,
891 0x34,
892 0x9B,
893 0x5F,
894 0x80,
895 0x00,
896 0x00,
897 0x80,
898 0x00,
899 0x10,
900 0x00,
901 0x00,
902 LowerBits(kUuid0),
903 UpperBits(kUuid0),
904 0x00,
905 0x00,
906 // Random Data
907 0x00,
908 0x01,
909 0x02,
910 0x03,
911 0x04,
912 0x05,
913 0x06,
914 0x07,
915 0x08,
916 0x09,
917 0x0A,
918 0x0B,
919 0x0C,
920 0x0D,
921 0x0E,
922 0x0F))
923 .value());
924 const auto kMatch1(
925 AdvertisingData::FromBytes(StaticByteBuffer(0x21,
926 DataType::kServiceData128Bit,
927
928 // kUuid1
929 kUuid1[0],
930 kUuid1[1],
931 kUuid1[2],
932 kUuid1[3],
933 kUuid1[4],
934 kUuid1[5],
935 kUuid1[6],
936 kUuid1[7],
937 kUuid1[8],
938 kUuid1[9],
939 kUuid1[10],
940 kUuid1[11],
941 kUuid1[12],
942 kUuid1[13],
943 kUuid1[14],
944 kUuid1[15],
945
946 // Random UUID
947 0x00,
948 0x01,
949 0x02,
950 0x03,
951 0x04,
952 0x05,
953 0x06,
954 0x07,
955 0x08,
956 0x09,
957 0x0A,
958 0x0B,
959 0x0C,
960 0x0D,
961 0x0E,
962 0x0F))
963 .value());
964
965 DiscoveryFilter filter;
966
967 // An empty filter should match all payloads.
968 EXPECT_TRUE(
969 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
970 EXPECT_TRUE(
971 filter.MatchLowEnergyResult(kNoMatch, false, hci_spec::kRSSIInvalid));
972 EXPECT_TRUE(
973 filter.MatchLowEnergyResult(kMatch0, false, hci_spec::kRSSIInvalid));
974 EXPECT_TRUE(
975 filter.MatchLowEnergyResult(kMatch1, false, hci_spec::kRSSIInvalid));
976
977 // Filter for kUuid0 and kUuid1.
978 filter.set_service_data_uuids(std::vector<UUID>{UUID(kUuid0), UUID(kUuid1)});
979 EXPECT_FALSE(filter.service_data_uuids().empty());
980 EXPECT_FALSE(
981 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
982 EXPECT_FALSE(
983 filter.MatchLowEnergyResult(kNoMatch, false, hci_spec::kRSSIInvalid));
984 EXPECT_TRUE(
985 filter.MatchLowEnergyResult(kMatch0, false, hci_spec::kRSSIInvalid));
986 EXPECT_TRUE(
987 filter.MatchLowEnergyResult(kMatch1, false, hci_spec::kRSSIInvalid));
988
989 filter.Reset();
990 EXPECT_TRUE(filter.service_data_uuids().empty());
991 }
992
TEST(DiscoveryFilterTest,NameSubstring)993 TEST(DiscoveryFilterTest, NameSubstring) {
994 const auto kShortenedName(
995 AdvertisingData::FromBytes(
996 StaticByteBuffer(0x05, 0x08, 'T', 'e', 's', 't'))
997 .value());
998 const auto kCompleteName(AdvertisingData::FromBytes(StaticByteBuffer(0x0E,
999 0x09,
1000 'T',
1001 'e',
1002 's',
1003 't',
1004 ' ',
1005 'C',
1006 'o',
1007 'm',
1008 'p',
1009 'l',
1010 'e',
1011 't',
1012 'e'))
1013 .value());
1014
1015 DiscoveryFilter filter;
1016
1017 // An empty filter should match all payloads.
1018 EXPECT_TRUE(
1019 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
1020 EXPECT_TRUE(filter.MatchLowEnergyResult(
1021 kShortenedName, false, hci_spec::kRSSIInvalid));
1022 EXPECT_TRUE(filter.MatchLowEnergyResult(
1023 kCompleteName, false, hci_spec::kRSSIInvalid));
1024
1025 // Assigning an empty string for the name filter should have the same effect
1026 // as an empty filter.
1027 filter.set_name_substring("");
1028 EXPECT_TRUE(
1029 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
1030 EXPECT_TRUE(filter.MatchLowEnergyResult(
1031 kShortenedName, false, hci_spec::kRSSIInvalid));
1032 EXPECT_TRUE(filter.MatchLowEnergyResult(
1033 kCompleteName, false, hci_spec::kRSSIInvalid));
1034
1035 filter.set_name_substring("foo");
1036 EXPECT_FALSE(
1037 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
1038 EXPECT_FALSE(filter.MatchLowEnergyResult(
1039 kShortenedName, false, hci_spec::kRSSIInvalid));
1040 EXPECT_FALSE(filter.MatchLowEnergyResult(
1041 kCompleteName, false, hci_spec::kRSSIInvalid));
1042
1043 filter.set_name_substring("est");
1044 EXPECT_FALSE(
1045 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
1046 EXPECT_TRUE(filter.MatchLowEnergyResult(
1047 kShortenedName, false, hci_spec::kRSSIInvalid));
1048 EXPECT_TRUE(filter.MatchLowEnergyResult(
1049 kCompleteName, false, hci_spec::kRSSIInvalid));
1050
1051 filter.set_name_substring("Compl");
1052 EXPECT_FALSE(filter.name_substring().empty());
1053 EXPECT_FALSE(
1054 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
1055 EXPECT_FALSE(filter.MatchLowEnergyResult(
1056 kShortenedName, false, hci_spec::kRSSIInvalid));
1057 EXPECT_TRUE(filter.MatchLowEnergyResult(
1058 kCompleteName, false, hci_spec::kRSSIInvalid));
1059
1060 filter.Reset();
1061 EXPECT_TRUE(filter.name_substring().empty());
1062 }
1063
TEST(DiscoveryFilterTest,RSSI)1064 TEST(DiscoveryFilterTest, RSSI) {
1065 constexpr int8_t kRSSIThreshold = 60;
1066 DiscoveryFilter filter;
1067 filter.set_rssi(hci_spec::kRSSIInvalid);
1068
1069 // |result| reports an invalid RSSI. This should fail to match even though the
1070 // value numerically satisfies the filter.
1071 EXPECT_FALSE(
1072 filter.MatchLowEnergyResult(std::nullopt, true, hci_spec::kRSSIInvalid));
1073
1074 filter.set_rssi(kRSSIThreshold);
1075 EXPECT_FALSE(
1076 filter.MatchLowEnergyResult(std::nullopt, true, hci_spec::kRSSIInvalid));
1077
1078 EXPECT_TRUE(filter.MatchLowEnergyResult(std::nullopt, true, kRSSIThreshold));
1079
1080 EXPECT_TRUE(
1081 filter.MatchLowEnergyResult(std::nullopt, true, kRSSIThreshold + 1));
1082
1083 // When a pathloss filter value is set and the scan result does not satisfy it
1084 // because it didn't include the transmission power level, the filter should
1085 // match since an RSSI value has been set which was used as a fallback.
1086 filter.set_pathloss(5);
1087 EXPECT_TRUE(
1088 filter.MatchLowEnergyResult(std::nullopt, true, kRSSIThreshold + 1));
1089
1090 // Finally, an empty filter should always succeed.
1091 filter.Reset();
1092 EXPECT_TRUE(
1093 filter.MatchLowEnergyResult(std::nullopt, true, kRSSIThreshold + 1));
1094 }
1095
TEST(DiscoveryFilterTest,Pathloss)1096 TEST(DiscoveryFilterTest, Pathloss) {
1097 constexpr int8_t kPathlossThreshold = 70;
1098 constexpr int8_t kTxPower = 5;
1099 constexpr int8_t kMatchingRSSI = -65;
1100 constexpr int8_t kNotMatchingRSSI = -66;
1101 constexpr int8_t kTooLargeRSSI = 71;
1102
1103 const auto kDataWithTxPower(
1104 AdvertisingData::FromBytes(StaticByteBuffer(0x02, 0x0A, kTxPower))
1105 .value());
1106
1107 DiscoveryFilter filter;
1108 filter.set_pathloss(kPathlossThreshold);
1109
1110 // No Tx Power and no RSSI. Filter should not match.
1111 EXPECT_FALSE(
1112 filter.MatchLowEnergyResult(std::nullopt, true, hci_spec::kRSSIInvalid));
1113
1114 // Tx Power is reported but RSSI is unknown. Filter should not match.
1115 EXPECT_FALSE(filter.MatchLowEnergyResult(
1116 kDataWithTxPower, true, hci_spec::kRSSIInvalid));
1117
1118 // RSSI is known but Tx Power is not reported.
1119 EXPECT_FALSE(filter.MatchLowEnergyResult(std::nullopt, true, kMatchingRSSI));
1120
1121 // RSSI and Tx Power are present and pathloss is within threshold.
1122 EXPECT_TRUE(
1123 filter.MatchLowEnergyResult(kDataWithTxPower, true, kMatchingRSSI));
1124
1125 // RSSI and Tx Power are present but RSSI is larger than Tx Power.
1126 EXPECT_FALSE(
1127 filter.MatchLowEnergyResult(kDataWithTxPower, true, kTooLargeRSSI));
1128
1129 // RSSI and Tx Power are present but pathloss is above threshold.
1130 EXPECT_FALSE(
1131 filter.MatchLowEnergyResult(kDataWithTxPower, true, kNotMatchingRSSI));
1132
1133 // Assign a RSSI filter. Even though this field alone WOULD satisfy the
1134 // filter, the match function should not fall back to it when Tx Power is
1135 // present and the pathloss filter is unsatisfied.
1136 filter.set_rssi(kNotMatchingRSSI);
1137 EXPECT_TRUE(filter.pathloss());
1138 EXPECT_FALSE(
1139 filter.MatchLowEnergyResult(kDataWithTxPower, true, kNotMatchingRSSI));
1140 EXPECT_TRUE(
1141 filter.MatchLowEnergyResult(std::nullopt, true, kNotMatchingRSSI));
1142
1143 // Finally, an empty filter should always succeed.
1144 filter.Reset();
1145 EXPECT_FALSE(filter.pathloss());
1146 EXPECT_TRUE(
1147 filter.MatchLowEnergyResult(kDataWithTxPower, true, kNotMatchingRSSI));
1148 }
1149
TEST(DiscoveryFilterTest,ManufacturerCode)1150 TEST(DiscoveryFilterTest, ManufacturerCode) {
1151 const auto kValidData0(
1152 AdvertisingData::FromBytes(StaticByteBuffer(0x03, 0xFF, 0xE0, 0x00))
1153 .value());
1154 const auto kValidData1(
1155 AdvertisingData::FromBytes(
1156 StaticByteBuffer(0x06, 0xFF, 0xE0, 0x00, 0x01, 0x02, 0x03))
1157 .value());
1158 const auto kInvalidData1(
1159 AdvertisingData::FromBytes(StaticByteBuffer(0x03, 0xFF, 0x4C, 0x00))
1160 .value());
1161
1162 DiscoveryFilter filter;
1163
1164 // Empty filter should match everything.
1165 EXPECT_TRUE(
1166 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
1167 EXPECT_TRUE(
1168 filter.MatchLowEnergyResult(kValidData0, false, hci_spec::kRSSIInvalid));
1169 EXPECT_TRUE(
1170 filter.MatchLowEnergyResult(kValidData1, false, hci_spec::kRSSIInvalid));
1171 EXPECT_TRUE(filter.MatchLowEnergyResult(
1172 kInvalidData1, false, hci_spec::kRSSIInvalid));
1173
1174 filter.set_manufacturer_code(0x00E0);
1175 EXPECT_TRUE(filter.manufacturer_code());
1176 EXPECT_FALSE(
1177 filter.MatchLowEnergyResult(std::nullopt, false, hci_spec::kRSSIInvalid));
1178 EXPECT_TRUE(
1179 filter.MatchLowEnergyResult(kValidData0, false, hci_spec::kRSSIInvalid));
1180 EXPECT_TRUE(
1181 filter.MatchLowEnergyResult(kValidData1, false, hci_spec::kRSSIInvalid));
1182 EXPECT_FALSE(filter.MatchLowEnergyResult(
1183 kInvalidData1, false, hci_spec::kRSSIInvalid));
1184
1185 filter.Reset();
1186 EXPECT_FALSE(filter.manufacturer_code());
1187 }
1188
TEST(DiscoveryFilterTest,Combined)1189 TEST(DiscoveryFilterTest, Combined) {
1190 constexpr int8_t kMatchingPathlossThreshold = 70;
1191 constexpr int8_t kNotMatchingPathlossThreshold = 69;
1192 constexpr int8_t kTxPower = 5;
1193 constexpr int8_t kRSSI = -65;
1194
1195 constexpr uint16_t kMatchingUuid = 0x180d;
1196 constexpr uint16_t kNotMatchingUuid = 0x1800;
1197 constexpr uint16_t kMatchingServiceDataUuid = 0x1234;
1198 constexpr uint16_t kNotMatchingServiceDataUuid = 0x5678;
1199
1200 constexpr char kMatchingName[] = "test";
1201 constexpr char kNotMatchingName[] = "foo";
1202
1203 const auto kAdvertisingData(
1204 AdvertisingData::FromBytes(StaticByteBuffer(
1205 // Flags
1206 0x02,
1207 0x01,
1208 0x01,
1209
1210 // 16 Bit Service UUIDs
1211 0x03,
1212 0x02,
1213 0x0d,
1214 0x18,
1215
1216 // 16 Bit Service Data UUIDs
1217 0x03,
1218 DataType::kServiceData16Bit,
1219 0x34,
1220 0x12,
1221
1222 // Complete name
1223 0x05,
1224 0x09,
1225 't',
1226 'e',
1227 's',
1228 't',
1229
1230 // Tx Power Level
1231 0x02,
1232 0x0A,
1233 kTxPower,
1234
1235 // Manufacturer specific data
1236 0x05,
1237 0xFF,
1238 0xE0,
1239 0x00,
1240 0x01,
1241 0x02))
1242 .value());
1243
1244 DiscoveryFilter filter;
1245
1246 // Empty filter should match.
1247 EXPECT_TRUE(filter.MatchLowEnergyResult(kAdvertisingData, true, kRSSI));
1248
1249 // Assign all fields and make them match.
1250 filter.set_flags(0x01);
1251 filter.set_connectable(true);
1252 filter.set_service_uuids(std::vector<UUID>{UUID(kMatchingUuid)});
1253 filter.set_service_data_uuids(
1254 std::vector<UUID>{UUID(kMatchingServiceDataUuid)});
1255 filter.set_name_substring(kMatchingName);
1256 filter.set_pathloss(kMatchingPathlossThreshold);
1257 filter.set_manufacturer_code(0x00E0);
1258 EXPECT_TRUE(filter.MatchLowEnergyResult(kAdvertisingData, true, kRSSI));
1259
1260 // Toggle each field one by one to test that a single mismatch causes the
1261 // filter to fail.
1262 filter.set_flags(0x03, /*require_all=*/true);
1263 EXPECT_FALSE(filter.MatchLowEnergyResult(kAdvertisingData, true, kRSSI));
1264 filter.set_flags(0x01);
1265
1266 filter.set_connectable(false);
1267 EXPECT_FALSE(filter.MatchLowEnergyResult(kAdvertisingData, true, kRSSI));
1268 filter.set_connectable(true);
1269
1270 filter.set_service_uuids(std::vector<UUID>{UUID(kNotMatchingUuid)});
1271 EXPECT_FALSE(filter.MatchLowEnergyResult(kAdvertisingData, true, kRSSI));
1272 filter.set_service_uuids(std::vector<UUID>{UUID(kMatchingUuid)});
1273
1274 filter.set_service_data_uuids(
1275 std::vector<UUID>{UUID(kNotMatchingServiceDataUuid)});
1276 EXPECT_FALSE(filter.MatchLowEnergyResult(kAdvertisingData, true, kRSSI));
1277 filter.set_service_data_uuids(
1278 std::vector<UUID>{UUID(kMatchingServiceDataUuid)});
1279
1280 filter.set_name_substring(kNotMatchingName);
1281 EXPECT_FALSE(filter.MatchLowEnergyResult(kAdvertisingData, true, kRSSI));
1282 filter.set_name_substring(kMatchingName);
1283
1284 filter.set_pathloss(kNotMatchingPathlossThreshold);
1285 EXPECT_FALSE(filter.MatchLowEnergyResult(kAdvertisingData, true, kRSSI));
1286 filter.set_pathloss(kMatchingPathlossThreshold);
1287
1288 filter.set_manufacturer_code(0x004C);
1289 EXPECT_FALSE(filter.MatchLowEnergyResult(kAdvertisingData, true, kRSSI));
1290 filter.set_manufacturer_code(0x00E0);
1291
1292 EXPECT_TRUE(filter.MatchLowEnergyResult(kAdvertisingData, true, kRSSI));
1293 }
1294
TEST(DiscoveryFilterTest,GeneralDiscoveryFlags)1295 TEST(DiscoveryFilterTest, GeneralDiscoveryFlags) {
1296 const auto kLimitedDiscoverableData(
1297 AdvertisingData::FromBytes(StaticByteBuffer(
1298 // Flags
1299 0x02,
1300 0x01,
1301 0x01))
1302 .value());
1303 const auto kGeneralDiscoverableData(
1304 AdvertisingData::FromBytes(StaticByteBuffer(
1305 // Flags
1306 0x02,
1307 0x01,
1308 0x02))
1309 .value());
1310 const auto kNonDiscoverableData(
1311 AdvertisingData::FromBytes(
1312 StaticByteBuffer(
1313 // Flags (all flags are set except for discoverability).
1314 0x02,
1315 0x01,
1316 0xFC))
1317 .value());
1318
1319 DiscoveryFilter filter;
1320 filter.SetGeneralDiscoveryFlags();
1321
1322 EXPECT_TRUE(filter.MatchLowEnergyResult(kLimitedDiscoverableData, true, 0));
1323 EXPECT_TRUE(filter.MatchLowEnergyResult(kGeneralDiscoverableData, true, 0));
1324 EXPECT_FALSE(filter.MatchLowEnergyResult(kNonDiscoverableData, true, 0));
1325 }
1326
1327 } // namespace
1328 } // namespace bt::gap
1329