xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/host/sdp/pdu_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 
2 // Copyright 2023 The Pigweed Authors
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 // use this file except in compliance with the License. You may obtain a copy of
6 // the License at
7 //
8 //     https://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, WITHOUT
12 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 // License for the specific language governing permissions and limitations under
14 // the License.
15 
16 #include "pw_bluetooth_sapphire/internal/host/sdp/pdu.h"
17 
18 #include <pw_bytes/endian.h>
19 
20 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
21 #include "pw_bluetooth_sapphire/internal/host/sdp/sdp.h"
22 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
23 #include "pw_unit_test/framework.h"
24 
25 namespace bt::sdp {
26 namespace {
27 
28 // The Default MTU in basic mode (Spec v5.1, Vol 3 Part A Section 5.1)
29 const uint16_t kDefaultMaxSize = 672;
30 // The smallest MTU allowed by the spec.
31 const uint16_t kMinMaxSize = 48;
32 
33 // Helper function to match one of two options, and print useful information on
34 // failure.
35 template <class Container1, class Container2, class Container3>
MatchesOneOf(const Container1 & one,const Container2 & two,const Container3 & actual)36 bool MatchesOneOf(const Container1& one,
37                   const Container2& two,
38                   const Container3& actual) {
39   bool opt_one =
40       std::equal(one.begin(), one.end(), actual.begin(), actual.end());
41   bool opt_two =
42       std::equal(two.begin(), two.end(), actual.begin(), actual.end());
43 
44   if (!(opt_one || opt_two)) {
45     std::cout << "Expected one of {";
46     PrintByteContainer(one.begin(), one.end());
47     std::cout << "}\n or {";
48     PrintByteContainer(two.begin(), two.end());
49     std::cout << "}\n   Found: { ";
50     PrintByteContainer(actual.begin(), actual.end());
51     std::cout << "}" << std::endl;
52   }
53   return opt_one || opt_two;
54 }
55 
TEST(PDUTest,ErrorResponse)56 TEST(PDUTest, ErrorResponse) {
57   ErrorResponse response;
58   EXPECT_FALSE(response.complete());
59   EXPECT_EQ(nullptr,
60             response.GetPDU(0xF00F /* ignored */,
61                             0xDEAD,
62                             kDefaultMaxSize /* ignored */,
63                             BufferView()));
64 
65   StaticByteBuffer kInvalidContState(
66       0x01,  // opcode: kErrorResponse
67       0xDE,
68       0xAD,  // transaction ID: 0xDEAD
69       0x00,
70       0x02,  // parameter length: 2 bytes
71       0x00,
72       0x05,  // ErrorCode: Invalid Continuation State
73       0xFF,
74       0x00  // extra bytes to cause an error
75   );
76 
77   fit::result<Error<>> status =
78       response.Parse(kInvalidContState.view(sizeof(Header)));
79   EXPECT_EQ(ToResult(HostError::kPacketMalformed), status);
80 
81   status = response.Parse(kInvalidContState.view(sizeof(Header), 2));
82   EXPECT_EQ(fit::ok(), status);
83   EXPECT_TRUE(response.complete());
84   EXPECT_EQ(ErrorCode::kInvalidContinuationState, response.error_code());
85 
86   response.set_error_code(ErrorCode::kInvalidContinuationState);
87   auto ptr = response.GetPDU(0xF00F /* ignored */,
88                              0xDEAD,
89                              kDefaultMaxSize /* ignored */,
90                              BufferView());
91 
92   ASSERT_TRUE(ptr);
93   EXPECT_TRUE(ContainersEqual(kInvalidContState.view(0, 7), *ptr));
94 }
95 
TEST(PDUTest,ServiceSearchRequestParse)96 TEST(PDUTest, ServiceSearchRequestParse) {
97   const StaticByteBuffer kL2capSearch(
98       // ServiceSearchPattern
99       0x35,
100       0x03,  // Sequence uint8 3 bytes
101       0x19,
102       0x01,
103       0x00,  // UUID: Protocol: L2CAP
104       0x00,
105       0x10,  // MaximumServiceRecordCount: 16
106       0x00   // Continuation State: none
107   );
108 
109   ServiceSearchRequest req(kL2capSearch);
110   EXPECT_TRUE(req.valid());
111   EXPECT_EQ(1u, req.service_search_pattern().size());
112   EXPECT_TRUE(req.service_search_pattern().count(protocol::kL2CAP));
113   EXPECT_EQ(16, req.max_service_record_count());
114 
115   const StaticByteBuffer kL2capSearchOne(
116       // ServiceSearchPattern
117       0x35,
118       0x06,  // Sequence uint8 6 bytes
119       0x19,
120       0x01,
121       0x00,  // UUID: Protocol: L2CAP
122       0x19,
123       0xED,
124       0xFE,  // UUID: 0xEDFE (unknown, doesn't need to be found)
125       0x00,
126       0x01,  // MaximumServiceRecordCount: 1
127       0x00   // Continuation State: none
128   );
129 
130   ServiceSearchRequest req_one(kL2capSearchOne);
131   EXPECT_TRUE(req_one.valid());
132   EXPECT_EQ(2u, req_one.service_search_pattern().size());
133   EXPECT_EQ(1, req_one.max_service_record_count());
134 
135   const StaticByteBuffer kInvalidNoItems(
136       // ServiceSearchPattern
137       0x35,
138       0x00,  // Sequence uint8 0 bytes
139       0xFF,
140       0xFF,  // MaximumServiceRecordCount: (none)
141       0x00   // Continuation State: none
142   );
143 
144   ServiceSearchRequest req2(kInvalidNoItems);
145   EXPECT_FALSE(req2.valid());
146 
147   const StaticByteBuffer kInvalidTooManyItems(
148       // ServiceSearchPattern
149       0x35,
150       0x27,  // Sequence uint8 27 bytes
151       0x19,
152       0x30,
153       0x01,  // 13 UUIDs in the search
154       0x19,
155       0x30,
156       0x02,
157       0x19,
158       0x30,
159       0x03,
160       0x19,
161       0x30,
162       0x04,
163       0x19,
164       0x30,
165       0x05,
166       0x19,
167       0x30,
168       0x06,
169       0x19,
170       0x30,
171       0x07,
172       0x19,
173       0x30,
174       0x08,
175       0x19,
176       0x30,
177       0x09,
178       0x19,
179       0x30,
180       0x10,
181       0x19,
182       0x30,
183       0x11,
184       0x19,
185       0x30,
186       0x12,
187       0x19,
188       0x30,
189       0x13,
190       0xFF,
191       0xFF,  // MaximumServiceRecordCount: (none)
192       0x00   // Continuation State: none
193   );
194 
195   ServiceSearchRequest req3(kInvalidTooManyItems);
196   EXPECT_FALSE(req3.valid());
197 
198   const StaticByteBuffer kInvalidMaxSizeZero(
199       // ServiceSearchPattern
200       0x35,
201       0x06,  // Sequence uint8 6 bytes
202       0x19,
203       0x01,
204       0x00,  // UUID: Protocol: L2CAP
205       0x19,
206       0xED,
207       0xFE,  // UUID: 0xEDFE (unknown, doesn't need to be found)
208       0x00,
209       0x00,  // MaximumServiceRecordCount: 0
210       0x00   // Continuation State: none
211   );
212 
213   ServiceSearchRequest req4(kInvalidMaxSizeZero);
214   EXPECT_FALSE(req4.valid());
215 }
216 
TEST(PDUTest,ServiceSearchRequestGetPDU)217 TEST(PDUTest, ServiceSearchRequestGetPDU) {
218   ServiceSearchRequest req;
219 
220   req.set_search_pattern({protocol::kATT, protocol::kL2CAP});
221   req.set_max_service_record_count(64);
222 
223   // Order is not specified, so there are two valid PDUs representing this.
224   const StaticByteBuffer kExpected(kServiceSearchRequest,
225                                    0x12,
226                                    0x34,  // Transaction ID
227                                    0x00,
228                                    0x0B,  // Parameter length (11 bytes)
229                                    // ServiceSearchPattern
230                                    0x35,
231                                    0x06,  // Sequence uint8 6 bytes
232                                    0x19,
233                                    0x00,
234                                    0x07,  // UUID (ATT)
235                                    0x19,
236                                    0x01,
237                                    0x00,  // UUID (L2CAP)
238                                    0x00,
239                                    0x40,  // MaximumServiceRecordCount: 64
240                                    0x00   // No continuation state
241   );
242   const auto kExpected2 =
243       StaticByteBuffer(kServiceSearchRequest,
244                        0x12,
245                        0x34,  // Transaction ID
246                        0x00,
247                        0x0B,  // Parameter length (11 bytes)
248                        // ServiceSearchPattern
249                        0x35,
250                        0x06,  // Sequence uint8 6 bytes
251                        0x19,
252                        0x01,
253                        0x00,  // UUID (L2CAP)
254                        0x19,
255                        0x00,
256                        0x07,  // UUID (ATT)
257                        0x00,
258                        0x40,  // MaximumServiceRecordCount: 64
259                        0x00   // No continuation state
260       );
261 
262   auto pdu = req.GetPDU(0x1234);
263   EXPECT_TRUE(MatchesOneOf(kExpected, kExpected2, *pdu));
264 }
265 
TEST(PDUTest,ServiceSearchResponseParse)266 TEST(PDUTest, ServiceSearchResponseParse) {
267   const StaticByteBuffer kValidResponse(
268       0x00,
269       0x02,  // Total service record count: 2
270       0x00,
271       0x02,  // Current service record count: 2
272       0x00,
273       0x00,
274       0x00,
275       0x01,  // Service Handle 1
276       0x00,
277       0x00,
278       0x00,
279       0x02,  // Service Handle 2
280       0x00   // No continuation state
281   );
282 
283   ServiceSearchResponse resp;
284   auto status = resp.Parse(kValidResponse);
285   EXPECT_EQ(fit::ok(), status);
286 
287   // Can't parse into an already complete record.
288   status = resp.Parse(kValidResponse);
289   EXPECT_TRUE(status.is_error());
290 
291   const auto kNotEnoughRecords =
292       StaticByteBuffer(0x00,
293                        0x02,  // Total service record count: 2
294                        0x00,
295                        0x02,  // Current service record count: 2
296                        0x00,
297                        0x00,
298                        0x00,
299                        0x01,  // Service Handle 1
300                        0x00   // No continuation state
301       );
302   // Doesn't contain the right # of records.
303   ServiceSearchResponse resp2;
304   status = resp2.Parse(kNotEnoughRecords);
305   EXPECT_TRUE(status.is_error());
306 
307   // A Truncated packet doesn't parse either.
308   const StaticByteBuffer kTruncated(0x00,
309                                     0x02,  // Total service record count: 2
310                                     0x00,
311                                     0x02  // Current service record count: 2
312   );
313   ServiceSearchResponse resp3;
314   status = resp3.Parse(kTruncated);
315   EXPECT_TRUE(status.is_error());
316 
317   // Too many bytes for the number of records is also not allowed (with or
318   // without a continuation state)
319   const StaticByteBuffer kTooLong(0x00,
320                                   0x01,  // Total service record count: 1
321                                   0x00,
322                                   0x01,  // Current service record count: 1
323                                   0x00,
324                                   0x00,
325                                   0x00,
326                                   0x01,  // Service Handle 1
327                                   0x00,
328                                   0x00,
329                                   0x00,
330                                   0x02,  // Service Handle 2
331                                   0x00   // No continuation state
332   );
333   ServiceSearchResponse resp4;
334   status = resp4.Parse(kTooLong);
335   EXPECT_TRUE(status.is_error());
336 
337   const auto kTooLongWithContinuation =
338       StaticByteBuffer(0x00,
339                        0x04,  // Total service record count: 1
340                        0x00,
341                        0x01,  // Current service record count: 1
342                        0x00,
343                        0x00,
344                        0x00,
345                        0x01,  // Service Handle 1
346                        0x00,
347                        0x00,
348                        0x00,
349                        0x02,  // Service Handle 2
350                        0x04,  // Continuation state (len: 4)
351                        0xF0,
352                        0x9F,
353                        0x92,
354                        0x96  // Continuation state
355       );
356   ServiceSearchResponse resp5;
357   status = resp5.Parse(kTooLongWithContinuation);
358   EXPECT_TRUE(status.is_error());
359 }
360 
TEST(PDUTest,ServiceSearchResponsePDU)361 TEST(PDUTest, ServiceSearchResponsePDU) {
362   std::vector<ServiceHandle> results{1, 2};
363   ServiceSearchResponse resp;
364 
365   // Empty results
366   const StaticByteBuffer kExpectedEmpty(
367       0x03,  // ServiceSearch Response PDU ID
368       0x01,
369       0x10,  // Transaction ID (0x0110)
370       0x00,
371       0x05,  // Parameter length: 5 bytes
372       0x00,
373       0x00,  // Total service record count: 0
374       0x00,
375       0x00,  // Current service record count: 0
376       0x00   // No continuation state
377   );
378 
379   auto pdu = resp.GetPDU(0xFFFF, 0x0110, kDefaultMaxSize, BufferView());
380   EXPECT_TRUE(ContainersEqual(kExpectedEmpty, *pdu));
381 
382   resp.set_service_record_handle_list(results);
383 
384   const StaticByteBuffer kExpected(0x03,  // ServiceSearch Response PDU ID
385                                    0x01,
386                                    0x10,  // Transaction ID (0x0110)
387                                    0x00,
388                                    0x0d,  // Parameter length: 13 bytes
389                                    0x00,
390                                    0x02,  // Total service record count: 2
391                                    0x00,
392                                    0x02,  // Current service record count: 2
393                                    0x00,
394                                    0x00,
395                                    0x00,
396                                    0x01,  // Service record 1
397                                    0x00,
398                                    0x00,
399                                    0x00,
400                                    0x02,  // Service record 2
401                                    0x00   // No continuation state
402   );
403 
404   pdu = resp.GetPDU(0xFFFF, 0x0110, kDefaultMaxSize, BufferView());
405   EXPECT_TRUE(ContainersEqual(kExpected, *pdu));
406 
407   const auto kExpectedLimited =
408       StaticByteBuffer(0x03,  // ServiceSearchResponse PDU ID
409                        0x01,
410                        0x10,  // Transaction ID (0x0110)
411                        0x00,
412                        0x09,  // Parameter length: 9
413                        0x00,
414                        0x01,  // Total service record count: 1
415                        0x00,
416                        0x01,  // Current service record count: 1
417                        0x00,
418                        0x00,
419                        0x00,
420                        0x01,  // Service record 1
421                        0x00   // No continuation state
422       );
423 
424   pdu = resp.GetPDU(1, 0x0110, kDefaultMaxSize, BufferView());
425   EXPECT_TRUE(ContainersEqual(kExpectedLimited, *pdu));
426 
427   resp.set_service_record_handle_list({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
428   const auto kExpectedLarge =
429       StaticByteBuffer(0x03,  // ServiceSearchResponse PDU ID
430                        0x01,
431                        0x10,  // Transaction ID (0x0110)
432                        0x00,
433                        0x31,  // Parameter length: 49
434                        0x00,
435                        0x0B,  // Total service record count: 11
436                        0x00,
437                        0x0B,  // Current service record count: 11
438                        0x00,
439                        0x00,
440                        0x00,
441                        0x01,  // Service record 1
442                        0x00,
443                        0x00,
444                        0x00,
445                        0x02,  // Service record 2
446                        0x00,
447                        0x00,
448                        0x00,
449                        0x03,  // Service record 3
450                        0x00,
451                        0x00,
452                        0x00,
453                        0x04,  // Service record 4
454                        0x00,
455                        0x00,
456                        0x00,
457                        0x05,  // Service record 5
458                        0x00,
459                        0x00,
460                        0x00,
461                        0x06,  // Service record 6
462                        0x00,
463                        0x00,
464                        0x00,
465                        0x07,  // Service record 7
466                        0x00,
467                        0x00,
468                        0x00,
469                        0x08,  // Service record 8
470                        0x00,
471                        0x00,
472                        0x00,
473                        0x09,  // Service record 9
474                        0x00,
475                        0x00,
476                        0x00,
477                        0x0A,  // Service record 10
478                        0x00,
479                        0x00,
480                        0x00,
481                        0x0B,  // Service record 11
482                        0x00   // No continuation state.
483       );
484 
485   pdu = resp.GetPDU(0x00FF, 0x0110, kDefaultMaxSize, BufferView());
486   EXPECT_TRUE(ContainersEqual(kExpectedLarge, *pdu));
487 }
488 
TEST(PDUTest,ServiceSearchResponsePDU_MaxSize)489 TEST(PDUTest, ServiceSearchResponsePDU_MaxSize) {
490   std::vector<ServiceHandle> results{1, 2};
491   ServiceSearchResponse resp;
492 
493   // Empty results
494   const StaticByteBuffer kExpectedEmpty(
495       0x03,  // ServiceSearch Response PDU ID
496       0x01,
497       0x10,  // Transaction ID (0x0110)
498       0x00,
499       0x05,  // Parameter length: 5 bytes
500       0x00,
501       0x00,  // Total service record count: 0
502       0x00,
503       0x00,  // Current service record count: 0
504       0x00   // No continuation state
505   );
506 
507   auto pdu = resp.GetPDU(0xFFFF, 0x0110, kMinMaxSize, BufferView());
508   EXPECT_TRUE(ContainersEqual(kExpectedEmpty, *pdu));
509 
510   resp.set_service_record_handle_list(results);
511 
512   const StaticByteBuffer kExpected(0x03,  // ServiceSearch Response PDU ID
513                                    0x01,
514                                    0x10,  // Transaction ID (0x0110)
515                                    0x00,
516                                    0x0d,  // Parameter length: 13 bytes
517                                    0x00,
518                                    0x02,  // Total service record count: 2
519                                    0x00,
520                                    0x02,  // Current service record count: 2
521                                    0x00,
522                                    0x00,
523                                    0x00,
524                                    0x01,  // Service record 1
525                                    0x00,
526                                    0x00,
527                                    0x00,
528                                    0x02,  // Service record 2
529                                    0x00   // No continuation state
530   );
531 
532   pdu = resp.GetPDU(0xFFFF, 0x0110, kMinMaxSize, BufferView());
533   EXPECT_TRUE(ContainersEqual(kExpected, *pdu));
534 
535   const auto kExpectedLimited =
536       StaticByteBuffer(0x03,  // ServiceSearchResponse PDU ID
537                        0x01,
538                        0x10,  // Transaction ID (0x0110)
539                        0x00,
540                        0x09,  // Parameter length: 9
541                        0x00,
542                        0x01,  // Total service record count: 1
543                        0x00,
544                        0x01,  // Current service record count: 1
545                        0x00,
546                        0x00,
547                        0x00,
548                        0x01,  // Service record 1
549                        0x00   // No continuation state
550       );
551 
552   pdu = resp.GetPDU(1, 0x0110, kMinMaxSize, BufferView());
553   EXPECT_TRUE(ContainersEqual(kExpectedLimited, *pdu));
554 
555   resp.set_service_record_handle_list({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
556   const auto kExpectedContinuation =
557       StaticByteBuffer(0x03,  // ServiceSearchResponse PDU ID
558                        0x01,
559                        0x10,  // Transaction ID (0x0110)
560                        0x00,
561                        0x2B,  // Parameter length: 42
562                        0x00,
563                        0x0B,  // Total service record count: 11
564                        0x00,
565                        0x09,  // Current service record count: 9
566                        0x00,
567                        0x00,
568                        0x00,
569                        0x01,  // Service record 1
570                        0x00,
571                        0x00,
572                        0x00,
573                        0x02,  // Service record 2
574                        0x00,
575                        0x00,
576                        0x00,
577                        0x03,  // Service record 3
578                        0x00,
579                        0x00,
580                        0x00,
581                        0x04,  // Service record 4
582                        0x00,
583                        0x00,
584                        0x00,
585                        0x05,  // Service record 5
586                        0x00,
587                        0x00,
588                        0x00,
589                        0x06,  // Service record 6
590                        0x00,
591                        0x00,
592                        0x00,
593                        0x07,  // Service record 7
594                        0x00,
595                        0x00,
596                        0x00,
597                        0x08,  // Service record 8
598                        0x00,
599                        0x00,
600                        0x00,
601                        0x09,  // Service record 9
602                        0x02,
603                        0x00,
604                        0x09  // Continuation state.
605       );
606 
607   // The MTU size here should limit the number of service records returned to 9.
608   pdu = resp.GetPDU(0x00FF, 0x0110, kMinMaxSize, BufferView());
609   EXPECT_TRUE(ContainersEqual(kExpectedContinuation, *pdu));
610 
611   const StaticByteBuffer kExpectedRest(0x03,  // ServiceSearchResponse PDU ID
612                                        0x01,
613                                        0x10,  // Transaction ID (0x0110)
614                                        0x00,
615                                        0x0D,  // Parameter length: 13
616                                        0x00,
617                                        0x0B,  // Total service record count: 11
618                                        0x00,
619                                        0x02,  // Current service record count: 2
620                                        0x00,
621                                        0x00,
622                                        0x00,
623                                        0x0A,  // Service record 10
624                                        0x00,
625                                        0x00,
626                                        0x00,
627                                        0x0B,  // Service record 11
628                                        0x00   // No continuation state.
629   );
630 
631   pdu = resp.GetPDU(0x00FF, 0x0110, kMinMaxSize, StaticByteBuffer(0x00, 0x09));
632   EXPECT_TRUE(ContainersEqual(kExpectedRest, *pdu));
633 }
634 
TEST(PDUTest,ServiceAttributeRequestValidity)635 TEST(PDUTest, ServiceAttributeRequestValidity) {
636   ServiceAttributeRequest req;
637 
638   // No attributes requested, so it begins invalid
639   EXPECT_FALSE(req.valid());
640 
641   // Adding an attribute makes it valid, and adds a range.
642   req.AddAttribute(kServiceClassIdList);
643 
644   EXPECT_TRUE(req.valid());
645   EXPECT_EQ(1u, req.attribute_ranges().size());
646   EXPECT_EQ(kServiceClassIdList, req.attribute_ranges().front().start);
647 
648   // Adding an attribute adjacent just adds to the range (on either end)
649   req.AddAttribute(kServiceClassIdList - 1);  // kServiceRecordHandle
650   req.AddAttribute(kServiceClassIdList + 1);
651   req.AddAttribute(kServiceClassIdList + 2);
652 
653   EXPECT_TRUE(req.valid());
654   EXPECT_EQ(1u, req.attribute_ranges().size());
655   EXPECT_EQ(kServiceClassIdList - 1, req.attribute_ranges().front().start);
656   EXPECT_EQ(kServiceClassIdList + 2, req.attribute_ranges().front().end);
657 
658   // Adding a disjoint range makes it two ranges, and they're in the right
659   // order.
660   req.AddAttribute(kServiceClassIdList + 4);
661 
662   EXPECT_TRUE(req.valid());
663   EXPECT_EQ(2u, req.attribute_ranges().size());
664   EXPECT_EQ(kServiceClassIdList - 1, req.attribute_ranges().front().start);
665   EXPECT_EQ(kServiceClassIdList + 2, req.attribute_ranges().front().end);
666   EXPECT_EQ(kServiceClassIdList + 4, req.attribute_ranges().back().start);
667   EXPECT_EQ(kServiceClassIdList + 4, req.attribute_ranges().back().end);
668 
669   // Adding one that makes it contiguous collapses them to a single range.
670   req.AddAttribute(kServiceClassIdList + 3);
671 
672   EXPECT_EQ(1u, req.attribute_ranges().size());
673   EXPECT_EQ(kServiceClassIdList - 1, req.attribute_ranges().front().start);
674   EXPECT_EQ(kServiceClassIdList + 4, req.attribute_ranges().front().end);
675 
676   EXPECT_TRUE(req.valid());
677 }
678 
TEST(PDUTest,ServiceAttributeRequestAddRange)679 TEST(PDUTest, ServiceAttributeRequestAddRange) {
680   ServiceAttributeRequest req;
681 
682   req.AddAttributeRange(0x0010, 0xFFF0);
683 
684   EXPECT_EQ(1u, req.attribute_ranges().size());
685   EXPECT_EQ(0x0010, req.attribute_ranges().front().start);
686   EXPECT_EQ(0xFFF0, req.attribute_ranges().front().end);
687 
688   req.AddAttributeRange(0x0100, 0xFF00);
689 
690   EXPECT_EQ(1u, req.attribute_ranges().size());
691   EXPECT_EQ(0x0010, req.attribute_ranges().front().start);
692   EXPECT_EQ(0xFFF0, req.attribute_ranges().front().end);
693 
694   req.AddAttributeRange(0x0000, 0x0002);
695 
696   EXPECT_EQ(2u, req.attribute_ranges().size());
697   EXPECT_EQ(0x0000, req.attribute_ranges().front().start);
698   EXPECT_EQ(0x0002, req.attribute_ranges().front().end);
699 
700   req.AddAttributeRange(0x0003, 0x000F);
701 
702   EXPECT_EQ(1u, req.attribute_ranges().size());
703   EXPECT_EQ(0x0000, req.attribute_ranges().front().start);
704   EXPECT_EQ(0xFFF0, req.attribute_ranges().front().end);
705 
706   req.AddAttributeRange(0xFFF2, 0xFFF3);
707   req.AddAttributeRange(0xFFF5, 0xFFF6);
708   req.AddAttributeRange(0xFFF8, 0xFFF9);
709   req.AddAttributeRange(0xFFFB, 0xFFFC);
710 
711   EXPECT_EQ(5u, req.attribute_ranges().size());
712 
713   // merges 0x0000-0xFFF0 with 0xFFF2-0xFFF3 and new range leaving
714   // 0x0000-0xFFF3, 0xFFF5-0xFFF6, 0xFFF8-0xFFF9 and 0xFFFB-0xFFFC
715   req.AddAttributeRange(0xFFF1, 0xFFF1);
716 
717   EXPECT_EQ(4u, req.attribute_ranges().size());
718 
719   // merges everything except 0xFFFB-0xFFFC
720   req.AddAttributeRange(0xFFF1, 0xFFF9);
721 
722   EXPECT_EQ(2u, req.attribute_ranges().size());
723 
724   req.AddAttributeRange(0xFFFA, 0xFFFF);
725 
726   EXPECT_EQ(1u, req.attribute_ranges().size());
727   EXPECT_EQ(0x0000, req.attribute_ranges().front().start);
728   EXPECT_EQ(0xFFFF, req.attribute_ranges().front().end);
729 }
730 
TEST(PDUTest,ServiceAttributeRequestParse)731 TEST(PDUTest, ServiceAttributeRequestParse) {
732   const StaticByteBuffer kSDPAllAttributes(
733       0x00,
734       0x00,
735       0x00,
736       0x00,  // ServiceRecordHandle: 0
737       0xF0,
738       0x0F,  // Maximum attribute byte count: (max = 61455)
739       // Attribute ID List
740       0x35,
741       0x05,  // Sequence uint8 5 bytes
742       0x0A,  // uint32_t
743       0x00,
744       0x00,
745       0xFF,
746       0xFF,  // Attribute range: 0x000 - 0xFFFF (All of them)
747       0x00   // No continuation state
748   );
749 
750   ServiceAttributeRequest req(kSDPAllAttributes);
751 
752   EXPECT_TRUE(req.valid());
753   EXPECT_EQ(1u, req.attribute_ranges().size());
754   EXPECT_EQ(0x0000, req.attribute_ranges().front().start);
755   EXPECT_EQ(0xFFFF, req.attribute_ranges().front().end);
756   EXPECT_EQ(61455, req.max_attribute_byte_count());
757 
758   const auto kContinued =
759       StaticByteBuffer(0x00,
760                        0x00,
761                        0x00,
762                        0x00,  // ServiceRecordHandle: 0
763                        0x00,
764                        0x0F,  // Maximum attribute byte count: (max = 15)
765                        // Attribute ID List
766                        0x35,
767                        0x06,  // Sequence uint8 3 bytes
768                        0x09,  // uint16_t
769                        0x00,
770                        0x01,  // Attribute ID: 1
771                        0x09,  // uint16_t
772                        0x00,
773                        0x02,  // Attribute ID: 2
774                        0x03,
775                        0x12,
776                        0x34,
777                        0x56  // Continuation state
778       );
779 
780   ServiceAttributeRequest req_cont_state(kContinued);
781 
782   EXPECT_TRUE(req_cont_state.valid());
783   EXPECT_EQ(2u, req_cont_state.attribute_ranges().size());
784   EXPECT_EQ(0x0001, req_cont_state.attribute_ranges().front().start);
785   EXPECT_EQ(0x0001, req_cont_state.attribute_ranges().front().end);
786   EXPECT_EQ(0x0002, req_cont_state.attribute_ranges().back().start);
787   EXPECT_EQ(0x0002, req_cont_state.attribute_ranges().back().end);
788   EXPECT_EQ(15, req_cont_state.max_attribute_byte_count());
789 
790   // Too short request.
791   ServiceAttributeRequest req_short((BufferView()));
792 
793   EXPECT_FALSE(req_short.valid());
794 
795   const auto kInvalidMaxBytes =
796       StaticByteBuffer(0x00,
797                        0x00,
798                        0x00,
799                        0x00,  // ServiceRecordHandle: 0
800                        0x00,
801                        0x04,  // Maximum attribute byte count (4)
802                        // Attribute ID List
803                        0x35,
804                        0x03,  // Sequence uint8 3 bytes
805                        0x09,
806                        0x00,
807                        0x02,  // uint16_t (2)
808                        0x00   // No continuation state
809       );
810 
811   ServiceAttributeRequest req_minmax(kInvalidMaxBytes);
812 
813   EXPECT_FALSE(req_minmax.valid());
814 
815   // Invalid order of the attributes.
816   const auto kInvalidAttributeListOrder =
817       StaticByteBuffer(0x00,
818                        0x00,
819                        0x00,
820                        0x00,  // ServiceRecordHandle: 0
821                        0xFF,
822                        0xFF,  // Maximum attribute byte count: (max = 65535)
823                        // Attribute ID List
824                        0x35,
825                        0x06,  // Sequence uint8 6 bytes
826                        0x09,
827                        0x00,
828                        0x02,  // uint16_t (2)
829                        0x09,
830                        0x00,
831                        0x01,  // uint16_t (1)
832                        0x00   // No continuation state
833       );
834 
835   ServiceAttributeRequest req_order(kInvalidAttributeListOrder);
836 
837   EXPECT_FALSE(req_short.valid());
838 
839   // AttributeID List has invalid items
840   const auto kInvalidAttributeList =
841       StaticByteBuffer(0x00,
842                        0x00,
843                        0x00,
844                        0x00,  // ServiceRecordHandle: 0
845                        0xFF,
846                        0xFF,  // Maximum attribute byte count: (max = 65535)
847                        // Attribute ID List
848                        0x35,
849                        0x06,  // Sequence uint8 5 bytes
850                        0x09,
851                        0x00,
852                        0x02,  // uint16_t (2)
853                        0x19,
854                        0x00,
855                        0x01,  // UUID (0x0001)
856                        0x00   // No continuation state
857       );
858 
859   ServiceAttributeRequest req_baditems(kInvalidAttributeList);
860 
861   EXPECT_FALSE(req_baditems.valid());
862 
863   // AttributeID list is empty
864   const auto kInvalidNoItems =
865       StaticByteBuffer(0x00,
866                        0x00,
867                        0x00,
868                        0x00,  // ServiceRecordHandle: 0
869                        0xFF,
870                        0xFF,  // Maximum attribute byte count: max
871                        0x35,
872                        0x00,  // Sequence uint8 no bytes
873                        0x00   // No continuation state
874       );
875 
876   ServiceAttributeRequest req_noitems(kInvalidNoItems);
877   EXPECT_FALSE(req_noitems.valid());
878 }
879 
TEST(PDUTest,ServiceAttributeRequestGetPDU)880 TEST(PDUTest, ServiceAttributeRequestGetPDU) {
881   ServiceAttributeRequest req;
882   req.AddAttribute(0xF00F);
883   req.AddAttributeRange(0x0001, 0xBECA);
884 
885   req.set_service_record_handle(0xEFFECACE);
886   req.set_max_attribute_byte_count(32);
887 
888   const auto kExpected =
889       StaticByteBuffer(kServiceAttributeRequest,
890                        0x12,
891                        0x34,  // transaction id
892                        0x00,
893                        0x11,  // Parameter Length (17 bytes)
894                        0xEF,
895                        0xFE,
896                        0xCA,
897                        0xCE,  // ServiceRecordHandle (0xEFFECACE)
898                        0x00,
899                        0x20,  // MaxAttributeByteCount (32)
900                        // Attribute ID list
901                        0x35,
902                        0x08,  // Sequence uint8 8 bytes
903                        0x0A,
904                        0x00,
905                        0x01,
906                        0xBE,
907                        0xCA,  // uint32_t (0x0001BECA)
908                        0x09,
909                        0xF0,
910                        0x0F,  // uint16_t (0xF00F)
911                        0x00   // No continuation state
912       );
913 
914   auto pdu = req.GetPDU(0x1234);
915   EXPECT_TRUE(ContainersEqual(kExpected, *pdu));
916 }
917 
TEST(PDUTest,ServiceAttributeRequestGetPDUFailsTooManyAttributes)918 TEST(PDUTest, ServiceAttributeRequestGetPDUFailsTooManyAttributes) {
919   ServiceAttributeRequest req;
920   // Skip attributes to prevent them from being combined into a range.
921   for (AttributeId attr = 0x0000; attr <= kMaxAttributeRangesInRequest * 2;
922        attr += 2) {
923     req.AddAttribute(attr);
924   }
925 
926   req.set_service_record_handle(0xEFFECACE);
927   req.set_max_attribute_byte_count(32);
928 
929   EXPECT_EQ(req.GetPDU(0x1234), nullptr);
930 }
931 
TEST(PDUTest,ServiceAttributeResponseParse)932 TEST(PDUTest, ServiceAttributeResponseParse) {
933   const StaticByteBuffer kValidResponseEmpty(0x00,
934                                              0x02,  // AttributeListByteCount (2
935                                                     // bytes) Attribute List
936                                              0x35,
937                                              0x00,  // Sequence uint8 0 bytes
938                                              0x00   // No continuation state
939   );
940 
941   ServiceAttributeResponse resp;
942   auto status = resp.Parse(kValidResponseEmpty);
943 
944   EXPECT_EQ(fit::ok(), status);
945 
946   const StaticByteBuffer kValidResponseItems(
947       0x00,
948       0x12,  // AttributeListByteCount (18 bytes)
949       // Attribute List
950       0x35,
951       0x10,  // Sequence uint8 16 bytes
952       0x09,
953       0x00,
954       0x00,  // Handle: uint16_t (0 = kServiceRecordHandle)
955       0x0A,
956       0xFE,
957       0xED,
958       0xBE,
959       0xEF,  // Element: uint32_t (0xFEEDBEEF)
960       0x09,
961       0x00,
962       0x01,  // Handle: uint16_t (1 = kServiceClassIdList)
963       0x35,
964       0x03,
965       0x19,
966       0x11,
967       0x01,  // Element: Sequence (3) { UUID(0x1101) }
968       0x00   // No continuation state
969   );
970 
971   ServiceAttributeResponse resp2;
972   status = resp2.Parse(kValidResponseItems);
973 
974   EXPECT_EQ(fit::ok(), status);
975   EXPECT_EQ(2u, resp2.attributes().size());
976   auto it = resp2.attributes().find(0x00);
977   EXPECT_NE(resp2.attributes().end(), it);
978   EXPECT_EQ(DataElement::Type::kUnsignedInt, it->second.type());
979 
980   it = resp2.attributes().find(0x01);
981   EXPECT_NE(resp2.attributes().end(), it);
982   EXPECT_EQ(DataElement::Type::kSequence, it->second.type());
983 
984   const StaticByteBuffer kInvalidItemsWrongOrder(
985       0x00,
986       0x12,  // AttributeListByteCount (18 bytes)
987       // Attribute List
988       0x35,
989       0x10,  // Sequence uint8 16 bytes
990       0x09,
991       0x00,
992       0x01,  // Handle: uint16_t (1 = kServiceClassIdList)
993       0x35,
994       0x03,
995       0x19,
996       0x11,
997       0x01,  // Element: Sequence (3) { UUID(0x1101) }
998       0x09,
999       0x00,
1000       0x00,  // Handle: uint16_t (0 = kServiceRecordHandle)
1001       0x0A,
1002       0xFE,
1003       0xED,
1004       0xBE,
1005       0xEF,  // Element: uint32_t (0xFEEDBEEF)
1006       0x00   // No continuation state
1007   );
1008 
1009   ServiceAttributeResponse resp3;
1010   status = resp3.Parse(kInvalidItemsWrongOrder);
1011 
1012   EXPECT_TRUE(status.is_error());
1013 
1014   const StaticByteBuffer kInvalidHandleWrongType(
1015       0x00,
1016       0x11,  // AttributeListByteCount (17 bytes)
1017       // Attribute List
1018       0x35,
1019       0x0F,  // Sequence uint8 15 bytes
1020       0x09,
1021       0x00,
1022       0x00,  // Handle: uint16_t (0 = kServiceRecordHandle)
1023       0x0A,
1024       0xFE,
1025       0xED,
1026       0xBE,
1027       0xEF,  // Element: uint32_t (0xFEEDBEEF)
1028       0x08,
1029       0x01,  // Handle: uint8_t (!) (1 = kServiceClassIdList)
1030       0x35,
1031       0x03,
1032       0x19,
1033       0x11,
1034       0x01,  // Element: Sequence (3) { UUID(0x1101) }
1035       0x00   // No continuation state
1036   );
1037 
1038   ServiceAttributeResponse resp_wrongtype;
1039   status = resp_wrongtype.Parse(kInvalidHandleWrongType);
1040 
1041   EXPECT_TRUE(status.is_error());
1042 
1043   const StaticByteBuffer kInvalidByteCount(
1044       0x00,
1045       0x12,  // AttributeListByteCount (18 bytes)
1046              // Attribute List (only 17 bytes long)
1047       0x35,
1048       0x0F,  // Sequence uint8 15 bytes
1049       0x09,
1050       0x00,
1051       0x01,  // Handle: uint16_t (1)
1052       0x35,
1053       0x03,
1054       0x19,
1055       0x11,
1056       0x01,  // Element: Sequence (3) { UUID(0x1101) }
1057       0x09,
1058       0x00,
1059       0x00,  // Handle: uint16_t (0)
1060       0x25,
1061       0x02,
1062       'h',
1063       'i',  // Element: String ('hi')
1064       0x00  // No continuation state
1065   );
1066 
1067   ServiceAttributeResponse resp4;
1068   status = resp4.Parse(kInvalidByteCount);
1069   EXPECT_EQ(ToResult(HostError::kPacketMalformed), status);
1070 
1071   // Sending too much data eventually fails.
1072   auto kContinuationPacket = DynamicByteBuffer(4096);
1073   // Put the correct byte count at the front: 4096 - 2 (byte count) - 5
1074   // (continuation size)
1075   const StaticByteBuffer kAttributeListByteCount(0x0F, 0xF9);
1076   kContinuationPacket.Write(kAttributeListByteCount, 0);
1077   // Put the correct continuation at the end.
1078   const StaticByteBuffer kContinuation(0x04, 0xF0, 0x9F, 0x92, 0x96);
1079   kContinuationPacket.Write(kContinuation, kContinuationPacket.size() - 5);
1080 
1081   ServiceAttributeResponse resp5;
1082   status = resp5.Parse(kContinuationPacket);
1083   EXPECT_EQ(ToResult(HostError::kInProgress), status);
1084   while (status == ToResult(HostError::kInProgress)) {
1085     status = resp5.Parse(kContinuationPacket);
1086   }
1087   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
1088 }
1089 
TEST(PDUTest,ServiceAttributeResponseGetPDU_MaxSize)1090 TEST(PDUTest, ServiceAttributeResponseGetPDU_MaxSize) {
1091   ServiceAttributeResponse resp;
1092 
1093   // Even if set in the wrong order, attributes should be sorted in the PDU.
1094   resp.set_attribute(0x4000, DataElement(uint16_t{0xfeed}));
1095   resp.set_attribute(0x4001, DataElement(protocol::kSDP));
1096   resp.set_attribute(0x4002, DataElement(uint32_t{0xc0decade}));
1097   DataElement str;
1098   str.Set(std::string("��"));
1099   resp.set_attribute(0x4003, std::move(str));
1100   resp.set_attribute(0x4005, DataElement(uint32_t{0xC0DEB4BE}));
1101   resp.set_attribute(kServiceRecordHandle, DataElement(uint32_t{0}));
1102 
1103   const uint16_t kTransactionID = 0xfeed;
1104 
1105   const StaticByteBuffer kExpectedContinuation(
1106       0x05,  // ServiceAttributeResponse
1107       UpperBits(kTransactionID),
1108       LowerBits(kTransactionID),  // Transaction ID
1109       0x00,
1110       0x2B,  // Param Length (43 bytes)
1111       0x00,
1112       0x24,  // AttributeListsByteCount (36 bytes)
1113       // AttributeLists
1114       0x35,
1115       0x2d,  // Sequence uint8 46 bytes
1116       0x09,
1117       0x00,
1118       0x00,  // uint16_t (handle) = kServiceRecordHandle
1119       0x0A,
1120       0x00,
1121       0x00,
1122       0x00,
1123       0x00,  // uint32_t, 0
1124       0x09,
1125       0x40,
1126       0x00,  // uint16_t (handle) = 0x4000
1127       0x09,
1128       0xfe,
1129       0xed,  // uint16_t (0xfeed)
1130       0x09,
1131       0x40,
1132       0x01,  // uint16_t (handle) = 0x4001
1133       0x19,
1134       0x00,
1135       0x01,  // UUID (kSDP)
1136       0x09,
1137       0x40,
1138       0x02,  // uint32_t (handle) = 0x4002
1139       0x0A,
1140       0xc0,
1141       0xde,
1142       0xca,
1143       0xde,  // uint32_t = 0xc0decade
1144       0x09,
1145       0x40,
1146       0x03,  // uint32_t (handle) = 0x4003
1147       0x25,
1148       0x04,
1149       0xf0,  // Partial String: '��' (type, length, first char)
1150       0x04,
1151       0x00,
1152       0x00,
1153       0x00,
1154       0x24  // Continuation state (4 bytes: 36 bytes offset)
1155   );
1156 
1157   auto pdu = resp.GetPDU(
1158       0xFFFF /* no max */, kTransactionID, kMinMaxSize, BufferView());
1159   EXPECT_TRUE(ContainersEqual(kExpectedContinuation, *pdu));
1160 
1161   const StaticByteBuffer kExpectedRemaining(
1162       0x05,  // ServiceSearchAttributeResponse
1163       UpperBits(kTransactionID),
1164       LowerBits(kTransactionID),  // Transaction ID
1165       0x00,
1166       0x0e,  // Param Length (14 bytes)
1167       0x00,
1168       0x0b,  // AttributeListsByteCount (12 bytes)
1169       // AttributeLists (continued)
1170       0x9f,
1171       0x92,
1172       0x96,  // Remaining 3 bytes of String: '��'
1173       0x09,
1174       0x40,
1175       0x05,  // uint16_t (handle) = 0x4005
1176       0x0A,
1177       0xc0,
1178       0xde,
1179       0xb4,
1180       0xbe,  // value: uint32_t (0xC0DEB4BE)
1181       0x00   // Continuation state (none)
1182   );
1183 
1184   pdu = resp.GetPDU(0xFFFF /* no max */,
1185                     kTransactionID,
1186                     kMinMaxSize,
1187                     StaticByteBuffer(0x00, 0x00, 0x00, 0x24));
1188   EXPECT_TRUE(ContainersEqual(kExpectedRemaining, *pdu));
1189 }
1190 
TEST(PDUTest,ServiceSearchAttributeRequestParse)1191 TEST(PDUTest, ServiceSearchAttributeRequestParse) {
1192   const StaticByteBuffer kSDPL2CAPAllAttributes(
1193       // Service search pattern
1194       0x35,
1195       0x03,  // Sequence uint8 3 bytes
1196       0x19,
1197       0x01,
1198       0x00,  // UUID: Protocol: L2CAP
1199       0xF0,
1200       0x0F,  // Maximum attribute byte count: (max = 61455)
1201       // Attribute ID List
1202       0x35,
1203       0x05,  // Sequence uint8 5 bytes
1204       0x0A,  // uint32_t
1205       0x00,
1206       0x00,
1207       0xFF,
1208       0xFF,  // Attribute range: 0x000 - 0xFFFF (All of them)
1209       0x00   // No continuation state
1210   );
1211 
1212   ServiceSearchAttributeRequest req(kSDPL2CAPAllAttributes);
1213 
1214   EXPECT_TRUE(req.valid());
1215   EXPECT_EQ(1u, req.service_search_pattern().size());
1216   EXPECT_EQ(1u, req.service_search_pattern().count(protocol::kL2CAP));
1217   EXPECT_EQ(1u, req.attribute_ranges().size());
1218   EXPECT_EQ(0x0000, req.attribute_ranges().front().start);
1219   EXPECT_EQ(0xFFFF, req.attribute_ranges().front().end);
1220   EXPECT_EQ(61455, req.max_attribute_byte_count());
1221 
1222   const auto kContinued =
1223       StaticByteBuffer(0x35,
1224                        0x03,  // Sequence uint8 3 bytes
1225                        0x19,
1226                        0x01,
1227                        0x00,  // UUID: Protocol: L2CAP
1228                        0x00,
1229                        0x0F,  // Maximum attribute byte count: (max = 15)
1230                        // Attribute ID List
1231                        0x35,
1232                        0x06,  // Sequence uint8 6 bytes
1233                        0x09,  // uint16_t
1234                        0x00,
1235                        0x01,  // Attribute ID: 1
1236                        0x09,  // uint16_t
1237                        0x00,
1238                        0x02,  // Attribute ID: 2
1239                        0x03,
1240                        0x12,
1241                        0x34,
1242                        0x56  // Continuation state
1243       );
1244 
1245   ServiceSearchAttributeRequest req_cont_state(kContinued);
1246 
1247   EXPECT_TRUE(req_cont_state.valid());
1248   EXPECT_EQ(1u, req.service_search_pattern().size());
1249   EXPECT_EQ(1u, req.service_search_pattern().count(protocol::kL2CAP));
1250   EXPECT_EQ(2u, req_cont_state.attribute_ranges().size());
1251   EXPECT_EQ(0x0001, req_cont_state.attribute_ranges().front().start);
1252   EXPECT_EQ(0x0001, req_cont_state.attribute_ranges().front().end);
1253   EXPECT_EQ(0x0002, req_cont_state.attribute_ranges().back().start);
1254   EXPECT_EQ(0x0002, req_cont_state.attribute_ranges().back().end);
1255   EXPECT_EQ(15, req_cont_state.max_attribute_byte_count());
1256 
1257   // Too short request.
1258   ServiceSearchAttributeRequest req_short((BufferView()));
1259 
1260   EXPECT_FALSE(req_short.valid());
1261 
1262   const auto kInvalidMaxBytes =
1263       StaticByteBuffer(0x35,
1264                        0x03,  // Sequence uint8 3 bytes
1265                        0x19,
1266                        0x01,
1267                        0x00,  // UUID: Protocol: L2CAP
1268                        0x00,
1269                        0x04,  // Maximum attribute byte count (4)
1270                        // Attribute ID List
1271                        0x35,
1272                        0x03,  // Sequence uint8 3 bytes
1273                        0x09,
1274                        0x00,
1275                        0x02,  // uint16_t (2)
1276                        0x00   // No continuation state
1277       );
1278 
1279   ServiceSearchAttributeRequest req_minmax(kInvalidMaxBytes);
1280 
1281   EXPECT_FALSE(req_minmax.valid());
1282 
1283   // Invalid order of the attributes.
1284   const auto kInvalidAttributeListOrder =
1285       StaticByteBuffer(0x35,
1286                        0x03,  // Sequence uint8 3 bytes
1287                        0x19,
1288                        0x01,
1289                        0x00,  // UUID: Protocol: L2CAP
1290                        0xFF,
1291                        0xFF,  // Maximum attribute byte count: (max = 65535)
1292                        // Attribute ID List
1293                        0x35,
1294                        0x06,  // Sequence uint8 6 bytes
1295                        0x09,
1296                        0x00,
1297                        0x02,  // uint16_t (2)
1298                        0x09,
1299                        0x00,
1300                        0x01,  // uint16_t (1)
1301                        0x00   // No continuation state
1302       );
1303 
1304   ServiceSearchAttributeRequest req_order(kInvalidAttributeListOrder);
1305 
1306   EXPECT_FALSE(req_short.valid());
1307 
1308   // AttributeID List has invalid items
1309   const auto kInvalidAttributeList =
1310       StaticByteBuffer(0x35,
1311                        0x03,  // Sequence uint8 3 bytes
1312                        0x19,
1313                        0x01,
1314                        0x00,  // UUID: Protocol: L2CAP
1315                        0xFF,
1316                        0xFF,  // Maximum attribute byte count: (max = 65535)
1317                        // Attribute ID List
1318                        0x35,
1319                        0x06,  // Sequence uint8 6 bytes
1320                        0x09,
1321                        0x00,
1322                        0x02,  // uint16_t (2)
1323                        0x19,
1324                        0x00,
1325                        0x01,  // UUID (0x0001)
1326                        0x00   // No continuation state
1327       );
1328 
1329   ServiceSearchAttributeRequest req_baditems(kInvalidAttributeList);
1330 
1331   EXPECT_FALSE(req_baditems.valid());
1332 
1333   const auto kInvalidNoItems =
1334       StaticByteBuffer(0x35,
1335                        0x00,  // Sequence uint8 0 bytes
1336                        0xF0,
1337                        0x0F,  // Maximum attribute byte count (61455)
1338                        // Attribute ID List
1339                        0x35,
1340                        0x03,  // Sequence uint8 3 bytes
1341                        0x09,
1342                        0x00,
1343                        0x02,  // uint16_t (2)
1344                        0x00   // No continuation state
1345       );
1346 
1347   ServiceSearchAttributeRequest req_noitems(kInvalidNoItems);
1348   EXPECT_FALSE(req_noitems.valid());
1349 
1350   const auto kInvalidNoAttributes =
1351       StaticByteBuffer(0x35,
1352                        0x03,  // Sequence uint8 3 bytes
1353                        0x19,
1354                        0x01,
1355                        0x00,  // UUID: Protocol: L2CAP
1356                        0xF0,
1357                        0x0F,  // Maximum attribute byte count (61455)
1358                        // Attribute ID List
1359                        0x35,
1360                        0x00,  // Sequence uint8 0 bytes
1361                        0x00   // No continuation state
1362       );
1363 
1364   ServiceSearchAttributeRequest req_noattributes(kInvalidNoAttributes);
1365   EXPECT_FALSE(req_noattributes.valid());
1366 
1367   const StaticByteBuffer kInvalidTooManyItems(
1368       // ServiceSearchPattern
1369       0x35,
1370       0x27,  // Sequence uint8 27 bytes
1371       0x19,
1372       0x30,
1373       0x01,  // 13 UUIDs in the search
1374       0x19,
1375       0x30,
1376       0x02,
1377       0x19,
1378       0x30,
1379       0x03,
1380       0x19,
1381       0x30,
1382       0x04,
1383       0x19,
1384       0x30,
1385       0x05,
1386       0x19,
1387       0x30,
1388       0x06,
1389       0x19,
1390       0x30,
1391       0x07,
1392       0x19,
1393       0x30,
1394       0x08,
1395       0x19,
1396       0x30,
1397       0x09,
1398       0x19,
1399       0x30,
1400       0x10,
1401       0x19,
1402       0x30,
1403       0x11,
1404       0x19,
1405       0x30,
1406       0x12,
1407       0x19,
1408       0x30,
1409       0x13,
1410       0xF0,
1411       0x0F,  // Maximum attribute byte count (61455)
1412       0x35,
1413       0x03,  // Sequence uint8 3 bytes
1414       0x09,
1415       0x00,
1416       0x02,  // uint16_t (2)
1417       0x00   // No continuation state
1418   );
1419 
1420   ServiceSearchAttributeRequest req_toomany(kInvalidTooManyItems);
1421   EXPECT_FALSE(req_toomany.valid());
1422 }
1423 
TEST(PDUTest,ServiceSearchAttributeRequestGetPDU)1424 TEST(PDUTest, ServiceSearchAttributeRequestGetPDU) {
1425   ServiceSearchAttributeRequest req;
1426   req.AddAttribute(0xF00F);
1427   req.AddAttributeRange(0x0001, 0xBECA);
1428 
1429   req.set_search_pattern({protocol::kATT, protocol::kL2CAP});
1430   req.set_max_attribute_byte_count(32);
1431 
1432   const auto kExpected = StaticByteBuffer(kServiceSearchAttributeRequest,
1433                                           0x12,
1434                                           0x34,  // transaction id
1435                                           0x00,
1436                                           0x15,  // Parameter Length (21 bytes)
1437                                           // ServiceSearchPattern
1438                                           0x35,
1439                                           0x06,  // Sequence uint8 6 bytes
1440                                           0x19,
1441                                           0x00,
1442                                           0x07,  // UUID (ATT)
1443                                           0x19,
1444                                           0x01,
1445                                           0x00,  // UUID (L2CAP)
1446                                           0x00,
1447                                           0x20,  // MaxAttributeByteCount (32)
1448                                           // Attribute ID list
1449                                           0x35,
1450                                           0x08,  // Sequence uint8 8 bytes
1451                                           0x0A,
1452                                           0x00,
1453                                           0x01,
1454                                           0xBE,
1455                                           0xCA,  // uint32_t (0x0001BECA)
1456                                           0x09,
1457                                           0xF0,
1458                                           0x0F,  // uint16_t (0xF00F)
1459                                           0x00   // No continuation state
1460   );
1461 
1462   const auto kExpected2 = StaticByteBuffer(kServiceSearchAttributeRequest,
1463                                            0x12,
1464                                            0x34,  // transaction id
1465                                            0x00,
1466                                            0x15,  // Parameter Length (21 bytes)
1467                                            // ServiceSearchPattern
1468                                            0x35,
1469                                            0x06,  // Sequence uint8 6 bytes
1470                                            0x19,
1471                                            0x01,
1472                                            0x00,  // UUID (L2CAP)
1473                                            0x19,
1474                                            0x00,
1475                                            0x07,  // UUID (ATT)
1476                                            0x00,
1477                                            0x20,  // MaxAttributeByteCount (32)
1478                                            // Attribute ID list
1479                                            0x35,
1480                                            0x08,  // Sequence uint8 8 bytes
1481                                            0x0A,
1482                                            0x00,
1483                                            0x01,
1484                                            0xBE,
1485                                            0xCA,  // uint32_t (0x0001BECA)
1486                                            0x09,
1487                                            0xF0,
1488                                            0x0F,  // uint16_t (0xF00F)
1489                                            0x00   // No continuation state
1490   );
1491 
1492   auto pdu = req.GetPDU(0x1234);
1493   EXPECT_TRUE(MatchesOneOf(kExpected, kExpected2, *pdu));
1494 }
1495 
TEST(PDUTest,ServiceSearchAttributeRequestGetPDUTooManyAttributes)1496 TEST(PDUTest, ServiceSearchAttributeRequestGetPDUTooManyAttributes) {
1497   ServiceSearchAttributeRequest req;
1498   // Skip attributes to prevent them from being combined into a range.
1499   for (AttributeId attr = 0x0000; attr <= kMaxAttributeRangesInRequest * 2;
1500        attr += 2) {
1501     req.AddAttribute(attr);
1502   }
1503 
1504   req.set_search_pattern({protocol::kATT, protocol::kL2CAP});
1505   req.set_max_attribute_byte_count(32);
1506 
1507   EXPECT_EQ(req.GetPDU(0x1234), nullptr);
1508 }
1509 
TEST(PDUTest,ServiceSearchAttributeResponseParse)1510 TEST(PDUTest, ServiceSearchAttributeResponseParse) {
1511   const StaticByteBuffer kValidResponseEmpty(0x00,
1512                                              0x02,  // AttributeListsByteCount
1513                                                     // (2 bytes) Attribute List
1514                                              0x35,
1515                                              0x00,  // Sequence uint8 0 bytes
1516                                              0x00   // No continuation state
1517   );
1518 
1519   ServiceSearchAttributeResponse resp;
1520   auto status = resp.Parse(kValidResponseEmpty);
1521 
1522   EXPECT_EQ(fit::ok(), status);
1523   EXPECT_TRUE(resp.complete());
1524   EXPECT_EQ(0u, resp.num_attribute_lists());
1525 
1526   const StaticByteBuffer kValidResponseItems(
1527       0x00,
1528       0x14,  // AttributeListsByteCount (20 bytes)
1529       // Wrapping Attribute List
1530       0x35,
1531       0x12,  // Sequence uint8 18 bytes
1532       // Attribute List
1533       0x35,
1534       0x10,  // Sequence uint8 16 bytes
1535       0x09,
1536       0x00,
1537       0x00,  // Handle: uint16_t (0 = kServiceRecordHandle)
1538       0x0A,
1539       0xFE,
1540       0xED,
1541       0xBE,
1542       0xEF,  // Element: uint32_t (0xFEEDBEEF)
1543       0x09,
1544       0x00,
1545       0x01,  // Handle: uint16_t (1 = kServiceClassIdList)
1546       0x35,
1547       0x03,
1548       0x19,
1549       0x11,
1550       0x01,  // Element: Sequence (3) { UUID(0x1101) }
1551       0x00   // No continuation state
1552   );
1553 
1554   status = resp.Parse(kValidResponseItems);
1555 
1556   EXPECT_EQ(fit::ok(), status);
1557   EXPECT_TRUE(resp.complete());
1558   EXPECT_EQ(1u, resp.num_attribute_lists());
1559   EXPECT_EQ(2u, resp.attributes(0).size());
1560   auto it = resp.attributes(0).find(0x0000);
1561   EXPECT_NE(resp.attributes(0).end(), it);
1562   EXPECT_EQ(DataElement::Type::kUnsignedInt, it->second.type());
1563 
1564   it = resp.attributes(0).find(0x0001);
1565   EXPECT_NE(resp.attributes(0).end(), it);
1566   EXPECT_EQ(DataElement::Type::kSequence, it->second.type());
1567 
1568   const StaticByteBuffer kValidResponseTwoLists(
1569       0x00,
1570       0x1E,  // AttributeListsByteCount (30 bytes)
1571       // Wrapping Attribute List
1572       0x35,
1573       0x1C,  // Sequence uint8 28 bytes
1574       // Attribute List 0 (first service)
1575       0x35,
1576       0x08,  // Sequence uint8 8 bytes
1577       0x09,
1578       0x00,
1579       0x00,  // Handle: uint16_t (0 = kServiceRecordHandle)
1580       0x0A,
1581       0xFE,
1582       0xED,
1583       0xBE,
1584       0xEF,  // Element: uint32_t (0xFEEDBEEF)
1585       // Attribute List 1 (second service)
1586       0x35,
1587       0x10,  // Sequence uint8 16 bytes
1588       0x09,
1589       0x00,
1590       0x00,  // Handle: uint16_t (0 = kServiceRecordHandle)
1591       0x0A,
1592       0xFE,
1593       0xDB,
1594       0xAC,
1595       0x01,  // Element: uint32_t (0xFEDBAC01)
1596       0x09,
1597       0x00,
1598       0x01,  // Handle: uint16_t (1 = kServiceClassIdList)
1599       0x35,
1600       0x03,
1601       0x19,
1602       0x11,
1603       0x01,  // Element: Sequence (3) { UUID(0x1101) }
1604       0x00   // No continuation state
1605   );
1606 
1607   ServiceSearchAttributeResponse resp2;
1608   status = resp2.Parse(kValidResponseTwoLists);
1609 
1610   EXPECT_EQ(fit::ok(), status);
1611   EXPECT_TRUE(resp2.complete());
1612   EXPECT_EQ(2u, resp2.num_attribute_lists());
1613 
1614   EXPECT_EQ(1u, resp2.attributes(0).size());
1615   it = resp2.attributes(0).find(0x0000);
1616   EXPECT_NE(resp2.attributes(0).end(), it);
1617   EXPECT_EQ(DataElement::Type::kUnsignedInt, it->second.type());
1618 
1619   EXPECT_EQ(2u, resp2.attributes(1).size());
1620   it = resp2.attributes(1).find(0x0000);
1621   EXPECT_NE(resp2.attributes(1).end(), it);
1622   EXPECT_EQ(DataElement::Type::kUnsignedInt, it->second.type());
1623 
1624   // Note: see test below, some peers will send in the wrong order.
1625   // We still will fail if the peer sends us two of the same type.
1626   const StaticByteBuffer kInvalidItemsDuplicateAttribute(
1627       0x00,
1628       0x14,  // AttributeListByteCount (20 bytes)
1629       // Wrapping Attribute List
1630       0x35,
1631       0x12,  // Sequence uint8 18 bytes
1632       // Attribute List
1633       0x35,
1634       0x10,  // Sequence uint8 16 bytes
1635       0x09,
1636       0x00,
1637       0x00,  // Handle: uint16_t (0 = kServiceRecordHandle)
1638       0x0A,
1639       0xB0,
1640       0xBA,
1641       0xCA,
1642       0xFE,  // Element: uint32_t (0xB0BACAFE)
1643       0x09,
1644       0x00,
1645       0x00,  // Handle: uint16_t (0 = kServiceRecordHandle)
1646       0x0A,
1647       0xFE,
1648       0xED,
1649       0xBE,
1650       0xEF,  // Element: uint32_t (0xFEEDBEEF)
1651       0x00   // No continuation state
1652   );
1653 
1654   ServiceSearchAttributeResponse resp3;
1655   status = resp3.Parse(kInvalidItemsDuplicateAttribute);
1656 
1657   EXPECT_TRUE(status.is_error());
1658   EXPECT_EQ(0u, resp3.num_attribute_lists());
1659 
1660   const StaticByteBuffer kInvalidHandleWrongType(
1661       0x00,
1662       0x13,  // AttributeListByteCount (19 bytes)
1663       // Wrapping Attribute List
1664       0x35,
1665       0x11,  // Sequence uint8 17 bytes
1666       // Attribute List
1667       0x35,
1668       0x0F,  // Sequence uint8 15 bytes
1669       0x09,
1670       0x00,
1671       0x00,  // Handle: uint16_t (0 = kServiceRecordHandle)
1672       0x0A,
1673       0xFE,
1674       0xED,
1675       0xBE,
1676       0xEF,  // Element: uint32_t (0xFEEDBEEF)
1677       0x08,
1678       0x01,  // Handle: uint8_t (!) (1 = kServiceClassIdList)
1679       0x35,
1680       0x03,
1681       0x19,
1682       0x11,
1683       0x01,  // Element: Sequence (3) { UUID(0x1101) }
1684       0x00   // No continuation state
1685   );
1686 
1687   ServiceAttributeResponse resp_wrongtype;
1688   status = resp_wrongtype.Parse(kInvalidHandleWrongType);
1689 
1690   EXPECT_TRUE(status.is_error());
1691 
1692   const StaticByteBuffer kInvalidByteCount(
1693       0x00,
1694       0x12,  // AttributeListsByteCount (18 bytes)
1695       0x35,
1696       0x11,  // Sequence uint8 17 bytes
1697       // Attribute List
1698       0x35,
1699       0x0F,  // Sequence uint8 15 bytes
1700       0x09,
1701       0x00,
1702       0x01,  // Handle: uint16_t (1)
1703       0x35,
1704       0x03,
1705       0x19,
1706       0x11,
1707       0x01,  // Element: Sequence (3) { UUID(0x1101) }
1708       0x09,
1709       0x00,
1710       0x00,  // Handle: uint16_t (0)
1711       0x25,
1712       0x02,
1713       'h',
1714       'i',  // Element: String ('hi')
1715       0x00  // No continuation state
1716   );
1717 
1718   status = resp3.Parse(kInvalidByteCount);
1719 
1720   EXPECT_TRUE(status.is_error());
1721 
1722   // Sending too much data eventually fails.
1723   auto kContinuationPacket = DynamicByteBuffer(4096);
1724   // Put the correct byte count at the front: 4096 - 2 (byte count) - 5
1725   // (continuation size)
1726   const StaticByteBuffer kAttributeListByteCount(0x0F, 0xF9);
1727   kContinuationPacket.Write(kAttributeListByteCount, 0);
1728   // Put the correct continuation at the end.
1729   const StaticByteBuffer kContinuation(0x04, 0xF0, 0x9F, 0x92, 0x96);
1730   kContinuationPacket.Write(kContinuation, kContinuationPacket.size() - 5);
1731 
1732   ServiceSearchAttributeResponse resp4;
1733   status = resp4.Parse(kContinuationPacket);
1734   EXPECT_EQ(ToResult(HostError::kInProgress), status);
1735   while (status == ToResult(HostError::kInProgress)) {
1736     status = resp4.Parse(kContinuationPacket);
1737   }
1738   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
1739 }
1740 
1741 // Some peers will send the attributes in the wrong order.
1742 // As long as they are not duplicate attributes, we are flexible to this.
TEST(PDUTest,ServiceSearchAttributeResponseParseContinuationWrongOrder)1743 TEST(PDUTest, ServiceSearchAttributeResponseParseContinuationWrongOrder) {
1744   // Attributes can come in the wrong order.
1745   const StaticByteBuffer kItemsWrongOrder(
1746       0x00,
1747       0x14,  // AttributeListByteCount (20 bytes)
1748       // Wrapping Attribute List
1749       0x35,
1750       0x12,  // Sequence uint8 18 bytes
1751       // Attribute List
1752       0x35,
1753       0x10,  // Sequence uint8 16 bytes
1754       0x09,
1755       0x00,
1756       0x01,  // Handle: uint16_t (1 = kServiceClassIdList)
1757       0x35,
1758       0x03,
1759       0x19,
1760       0x11,
1761       0x01,  // Element: Sequence (3) { UUID(0x1101) }
1762       0x09,
1763       0x00,
1764       0x00,  // Handle: uint16_t (0 = kServiceRecordHandle)
1765       0x0A,
1766       0xFE,
1767       0xED,
1768       0xBE,
1769       0xEF,  // Element: uint32_t (0xFEEDBEEF)
1770       0x00   // No continuation state
1771   );
1772 
1773   ServiceSearchAttributeResponse resp_simple;
1774   auto status = resp_simple.Parse(kItemsWrongOrder);
1775 
1776   EXPECT_EQ(fit::ok(), status);
1777 
1778   // Packets seen in real-world testing, a more complicated example.
1779   const StaticByteBuffer kFirstPacket(
1780       0x00,
1781       0x77,  // AttributeListsByteCount (119 bytes (in this packet))
1782       0x35,
1783       0x7e,  // Wrapping attribute list sequence: 126 bytes
1784       0x35,
1785       0x33,  // Begin attribute list 1 (51 bytes)
1786       0x09,
1787       0x00,
1788       0x01,  // Attribute 0x01
1789       0x35,
1790       0x06,
1791       0x19,
1792       0x11,
1793       0x0e,
1794       0x19,
1795       0x11,
1796       0x0f,  // Attribute 0x01 data: 2 UUIDs list
1797       0x09,
1798       0x00,
1799       0x04,  // Attribute 0x04
1800       0x35,
1801       0x10,
1802       0x35,
1803       0x06,
1804       0x19,
1805       0x01,
1806       0x00,
1807       0x09,
1808       0x00,
1809       0x17,
1810       0x35,
1811       0x06,
1812       0x19,
1813       0x00,
1814       0x17,
1815       0x09,
1816       0x01,
1817       0x04,  // Attribute 0x04 data
1818       0x09,
1819       0x00,
1820       0x09,  // Attribute 0x09
1821       0x35,
1822       0x08,
1823       0x35,
1824       0x06,
1825       0x19,
1826       0x11,
1827       0x0e,
1828       0x09,
1829       0x01,
1830       0x05,  // Attribute 0x09 data
1831       0x09,
1832       0x03,
1833       0x11,  // Attribute 0x311
1834       0x09,
1835       0x00,
1836       0x01,  // Attribute 0x311 data: uint16 (0x01)
1837       0x35,
1838       0x47,  // Begin attribute list 2 (71 bytes)
1839       0x09,
1840       0x00,
1841       0x01,  // Attribute 0x01
1842       0x35,
1843       0x03,
1844       0x19,
1845       0x11,
1846       0x0c,  // Attribute 0x01 data, Sequence of 1 UUID
1847       0x09,
1848       0x00,
1849       0x04,  // Attribute 0x04
1850       0x35,
1851       0x10,
1852       0x35,
1853       0x06,
1854       0x19,
1855       0x01,
1856       0x00,
1857       0x09,
1858       0x00,
1859       0x17,
1860       0x35,
1861       0x06,
1862       0x19,
1863       0x00,
1864       0x17,
1865       0x09,
1866       0x01,
1867       0x04,  // Attribute 0x04 data
1868       0x09,
1869       0x00,
1870       0x0d,  // Attribute 0x0d
1871       0x35,
1872       0x12,
1873       0x35,
1874       0x10,
1875       0x35,
1876       0x06,
1877       0x19,
1878       0x01,
1879       0x00,
1880       0x09,
1881       0x00,
1882       0x1b,
1883       0x35,
1884       0x06,
1885       0x19,
1886       0x00,
1887       0x17,
1888       0x09,
1889       0x01,
1890       0x04,  // Attribute 0x0d data
1891       0x09,
1892       0x00,
1893       0x09,  // Attribute 0x09
1894       0x35,
1895       0x08,
1896       0x35,
1897       0x06,
1898       0x19,
1899       0x11,
1900       0x0e,
1901       0x01,  // Start of Attribute 0x09 data
1902              // (continued in next packet)
1903       0x01   // Continuation state (yes, one byte, 0x01)
1904   );
1905 
1906   ServiceSearchAttributeResponse resp;
1907   status = resp.Parse(kFirstPacket);
1908   EXPECT_EQ(ToResult(HostError::kInProgress), status);
1909 
1910   const StaticByteBuffer kSecondPacket(
1911       0x00,
1912       0x09,  // AttributeListsByteCount (9 bytes)
1913              // 9 bytes continuing the previous response
1914       0x09,
1915       0x01,
1916       0x05,  // Continuation of previous 0x09 attribute
1917       0x09,
1918       0x03,
1919       0x11,  // Attribute 0x311
1920       0x09,
1921       0x00,
1922       0x02,  // Attribute 0x0311 data: uint16(0x02)
1923       0x00   // No continuation state.
1924   );
1925 
1926   status = resp.Parse(kSecondPacket);
1927   EXPECT_EQ(fit::ok(), status);
1928 }
1929 
TEST(PDUTest,ServiceSearchAttributeResponseGetPDU)1930 TEST(PDUTest, ServiceSearchAttributeResponseGetPDU) {
1931   ServiceSearchAttributeResponse resp;
1932 
1933   // Even if set in the wrong order, attributes should be sorted in the PDU.
1934   resp.SetAttribute(0, 0x4000, DataElement(uint16_t{0xfeed}));
1935   resp.SetAttribute(0, 0x4001, DataElement(protocol::kSDP));
1936   resp.SetAttribute(0, kServiceRecordHandle, DataElement(uint32_t{0}));
1937 
1938   // Attributes do not need to be continuous
1939   resp.SetAttribute(5, kServiceRecordHandle, DataElement(uint32_t{0x10002000}));
1940 
1941   const uint16_t kTransactionID = 0xfeed;
1942 
1943   const StaticByteBuffer kExpected(
1944       0x07,  // ServiceSearchAttributeResponse
1945       UpperBits(kTransactionID),
1946       LowerBits(kTransactionID),  // Transaction ID
1947       0x00,
1948       0x25,  // Param Length (37 bytes)
1949       0x00,
1950       0x22,  // AttributeListsByteCount (34 bytes)
1951       // AttributeLists
1952       0x35,
1953       0x20,  // Sequence uint8 32 bytes
1954       0x35,
1955       0x14,  // Sequence uint8 20 bytes
1956       0x09,
1957       0x00,
1958       0x00,  // uint16_t (handle) = kServiceRecordHandle
1959       0x0A,
1960       0x00,
1961       0x00,
1962       0x00,
1963       0x00,  // uint32_t, 0
1964       0x09,
1965       0x40,
1966       0x00,  // uint16_t (handle) = 0x4000
1967       0x09,
1968       0xfe,
1969       0xed,  // uint16_t (0xfeed)
1970       0x09,
1971       0x40,
1972       0x01,  // uint16_t (handle) = 0x4001
1973       0x19,
1974       0x00,
1975       0x01,  // UUID (kSDP)
1976       0x35,
1977       0x08,  // Sequence uint8 8 bytes
1978       0x09,
1979       0x00,
1980       0x00,  // uint16_t (handle) = kServiceRecordHandle
1981       0x0A,
1982       0x10,
1983       0x00,
1984       0x20,
1985       0x00,  // value: uint32_t (0x10002000)
1986       0x00   // Continuation state (none)
1987   );
1988 
1989   auto pdu = resp.GetPDU(
1990       0xFFFF /* no max */, kTransactionID, kDefaultMaxSize, BufferView());
1991 
1992   EXPECT_TRUE(ContainersEqual(kExpected, *pdu));
1993 }
1994 
TEST(PDUTest,ServiceSearchAttributeResponseGetPDU_MaxSize)1995 TEST(PDUTest, ServiceSearchAttributeResponseGetPDU_MaxSize) {
1996   ServiceSearchAttributeResponse resp;
1997 
1998   // Even if set in the wrong order, attributes should be sorted in the PDU.
1999   resp.SetAttribute(0, 0x4000, DataElement(uint16_t{0xfeed}));
2000   resp.SetAttribute(0, 0x4001, DataElement(protocol::kSDP));
2001   resp.SetAttribute(0, 0x4002, DataElement(uint32_t{0xc0decade}));
2002   DataElement str;
2003   str.Set(std::string("��"));
2004   resp.SetAttribute(0, 0x4003, std::move(str));
2005   resp.SetAttribute(0, kServiceRecordHandle, DataElement(uint32_t{0}));
2006 
2007   // Attributes do not need to be continuous
2008   resp.SetAttribute(5, kServiceRecordHandle, DataElement(uint32_t{0x10002000}));
2009 
2010   const uint16_t kTransactionID = 0xfeed;
2011 
2012   const StaticByteBuffer kExpectedContinuation(
2013       0x07,  // ServiceSearchAttributeResponse
2014       UpperBits(kTransactionID),
2015       LowerBits(kTransactionID),  // Transaction ID
2016       0x00,
2017       0x2B,  // Param Length (43 bytes)
2018       0x00,
2019       0x24,  // AttributeListsByteCount (36 bytes)
2020       // AttributeLists
2021       0x35,
2022       0x31,  // Sequence uint8 49 bytes = 37 + 2 + 8 + 2
2023       0x35,
2024       0x25,  // Sequence uint8 37 bytes
2025       0x09,
2026       0x00,
2027       0x00,  // uint16_t (handle) = kServiceRecordHandle
2028       0x0A,
2029       0x00,
2030       0x00,
2031       0x00,
2032       0x00,  // uint32_t, 0
2033       0x09,
2034       0x40,
2035       0x00,  // uint16_t (handle) = 0x4000
2036       0x09,
2037       0xfe,
2038       0xed,  // uint16_t (0xfeed)
2039       0x09,
2040       0x40,
2041       0x01,  // uint16_t (handle) = 0x4001
2042       0x19,
2043       0x00,
2044       0x01,  // UUID (kSDP)
2045       0x09,
2046       0x40,
2047       0x02,  // uint32_t (handle) = 0x4002
2048       0x0A,
2049       0xc0,
2050       0xde,
2051       0xca,
2052       0xde,  // uint32_t = 0xc0decade
2053       0x09,
2054       0x40,
2055       0x03,  // uint32_t (handle) = 0x4003
2056       0x25,  // Partial String: '��' (just the type)
2057       0x04,
2058       0x00,
2059       0x00,
2060       0x00,
2061       0x24  // Continuation state (4 bytes: 36 bytes offset)
2062   );
2063 
2064   auto pdu = resp.GetPDU(
2065       0xFFFF /* no max */, kTransactionID, kMinMaxSize, BufferView());
2066   EXPECT_TRUE(ContainersEqual(kExpectedContinuation, *pdu));
2067 
2068   const StaticByteBuffer kExpectedRemaining(
2069       0x07,  // ServiceSearchAttributeResponse
2070       UpperBits(kTransactionID),
2071       LowerBits(kTransactionID),  // Transaction ID
2072       0x00,
2073       0x12,  // Param Length (18 bytes)
2074       0x00,
2075       0x0F,  // AttributeListsByteCount (14 bytes)
2076       // AttributeLists (continued)
2077       0x04,
2078       0xf0,
2079       0x9f,
2080       0x92,
2081       0x96,  // Remaining 5 bytes of String: '��'
2082       0x35,
2083       0x08,  // Sequence uint8 8 bytes
2084       0x09,
2085       0x00,
2086       0x00,  // uint16_t (handle) = kServiceRecordHandle
2087       0x0A,
2088       0x10,
2089       0x00,
2090       0x20,
2091       0x00,  // value: uint32_t (0x10002000)
2092       0x00   // Continuation state (none)
2093   );
2094 
2095   pdu = resp.GetPDU(0xFFFF /* no max */,
2096                     kTransactionID,
2097                     kMinMaxSize,
2098                     StaticByteBuffer(0x00, 0x00, 0x00, 0x24));
2099   EXPECT_TRUE(ContainersEqual(kExpectedRemaining, *pdu));
2100 }
2101 
TEST(PDUTest,ResponseOutOfRangeContinuation)2102 TEST(PDUTest, ResponseOutOfRangeContinuation) {
2103   ServiceSearchResponse rsp_search;
2104   rsp_search.set_service_record_handle_list({1, 2, 3, 4});
2105   auto buf = rsp_search.GetPDU(0xFFFF, 0x0110, kDefaultMaxSize, BufferView());
2106   EXPECT_TRUE(buf);
2107   // Out of Range (continuation is zero-indexed)
2108   uint16_t handle_count = pw::bytes::ConvertOrderTo(
2109       cpp20::endian::big,
2110       static_cast<uint16_t>(rsp_search.service_record_handle_list().size()));
2111   auto service_search_cont = DynamicByteBuffer(sizeof(uint16_t));
2112   service_search_cont.WriteObj(handle_count, 0);
2113   buf = rsp_search.GetPDU(0xFFFF, 0x0110, kDefaultMaxSize, service_search_cont);
2114   EXPECT_FALSE(buf);
2115   // Wrong size continuation state
2116   buf = rsp_search.GetPDU(
2117       0xFFFF, 0x0110, kDefaultMaxSize, StaticByteBuffer(0x01, 0xFF, 0xFF));
2118   EXPECT_FALSE(buf);
2119 
2120   ServiceAttributeResponse rsp_attr;
2121   rsp_attr.set_attribute(1, DataElement(uint32_t{45}));
2122 
2123   buf = rsp_attr.GetPDU(0xFFFF, 0x0110, kDefaultMaxSize, BufferView());
2124   EXPECT_TRUE(buf);
2125 
2126   uint32_t rsp_size = pw::bytes::ConvertOrderTo(
2127       cpp20::endian::big, static_cast<uint32_t>(buf->size()) + 5);
2128   auto too_large_cont = DynamicByteBuffer(sizeof(uint32_t));
2129   too_large_cont.WriteObj(rsp_size, 0);
2130   buf = rsp_attr.GetPDU(0xFFFF, 0x0110, kDefaultMaxSize, too_large_cont);
2131 
2132   EXPECT_FALSE(buf);
2133 
2134   ServiceSearchAttributeResponse rsp_search_attr;
2135 
2136   rsp_search_attr.SetAttribute(0, 0x4000, DataElement(uint16_t{0xfeed}));
2137   rsp_search_attr.SetAttribute(0, 0x4001, DataElement(protocol::kSDP));
2138   rsp_search_attr.SetAttribute(
2139       0, kServiceRecordHandle, DataElement(uint32_t{0}));
2140   rsp_search_attr.SetAttribute(
2141       5, kServiceRecordHandle, DataElement(uint32_t{0x10002000}));
2142 
2143   buf = rsp_search_attr.GetPDU(0xFFFF, 0x0110, kDefaultMaxSize, BufferView());
2144 
2145   EXPECT_TRUE(buf);
2146 
2147   rsp_size = pw::bytes::ConvertOrderTo(cpp20::endian::big,
2148                                        static_cast<uint32_t>(buf->size()) + 5);
2149   too_large_cont.WriteObj(rsp_size, 0);
2150   buf = rsp_attr.GetPDU(0xFFFF, 0x0110, kDefaultMaxSize, too_large_cont);
2151 
2152   EXPECT_FALSE(buf);
2153 }
2154 
2155 }  // namespace
2156 }  // namespace bt::sdp
2157