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