1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_bluetooth_sapphire/internal/host/sdp/server.h"
16
17 #include "pw_bluetooth_sapphire/internal/host/l2cap/fake_channel.h"
18 #include "pw_bluetooth_sapphire/internal/host/l2cap/fake_channel_test.h"
19 #include "pw_bluetooth_sapphire/internal/host/l2cap/fake_l2cap.h"
20 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
21 #include "pw_bluetooth_sapphire/internal/host/sdp/data_element.h"
22 #include "pw_bluetooth_sapphire/internal/host/sdp/pdu.h"
23 #include "pw_bluetooth_sapphire/internal/host/sdp/sdp.h"
24 #include "pw_bluetooth_sapphire/internal/host/testing/fake_controller.h"
25 #include "pw_bluetooth_sapphire/internal/host/testing/inspect.h"
26 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
27 #include "pw_unit_test/framework.h"
28
29 namespace bt::sdp {
30
31 using RegistrationHandle = Server::RegistrationHandle;
32
33 namespace {
34
35 using namespace inspect::testing;
36
37 using TestingBase = l2cap::testing::FakeChannelTest;
38
39 constexpr hci_spec::ConnectionHandle kTestHandle1 = 1;
40 constexpr hci_spec::ConnectionHandle kTestHandle2 = 2;
41
NopConnectCallback(l2cap::Channel::WeakPtr,const DataElement &)42 void NopConnectCallback(l2cap::Channel::WeakPtr, const DataElement&) {}
43
44 constexpr l2cap::ChannelParameters kChannelParams;
45
46 class ServerTest : public TestingBase {
47 public:
48 ServerTest() = default;
49 ~ServerTest() = default;
50
51 protected:
SetUp()52 void SetUp() override {
53 l2cap_ = std::make_unique<l2cap::testing::FakeL2cap>(dispatcher());
54 l2cap_->set_channel_callback([this](auto fake_chan) {
55 channel_ = std::move(fake_chan);
56 set_fake_chan(channel_);
57 });
58 l2cap_->AddACLConnection(kTestHandle1,
59 pw::bluetooth::emboss::ConnectionRole::PERIPHERAL,
60 nullptr,
61 nullptr);
62 l2cap_->AddACLConnection(kTestHandle2,
63 pw::bluetooth::emboss::ConnectionRole::PERIPHERAL,
64 nullptr,
65 nullptr);
66 server_ = std::make_unique<Server>(l2cap_.get());
67 }
68
TearDown()69 void TearDown() override {
70 channel_.reset();
71 server_ = nullptr;
72 l2cap_ = nullptr;
73 }
74
server() const75 Server* server() const { return server_.get(); }
76
l2cap() const77 l2cap::testing::FakeL2cap* l2cap() const { return l2cap_.get(); }
78
AddSPP(sdp::Server::ConnectCallback cb=NopConnectCallback)79 RegistrationHandle AddSPP(
80 sdp::Server::ConnectCallback cb = NopConnectCallback) {
81 ServiceRecord record;
82
83 record.SetServiceClassUUIDs({profile::kSerialPort});
84 record.AddProtocolDescriptor(
85 ServiceRecord::kPrimaryProtocolList, protocol::kL2CAP, DataElement());
86 record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
87 protocol::kRFCOMM,
88 DataElement(uint8_t{0}));
89 record.AddProfile(profile::kSerialPort, 1, 2);
90 record.AddInfo("en", "FAKE", "", "");
91 std::vector<ServiceRecord> records;
92 records.emplace_back(std::move(record));
93 RegistrationHandle handle = server()->RegisterService(
94 std::move(records), kChannelParams, std::move(cb));
95 EXPECT_TRUE(handle);
96 return handle;
97 }
98
AddA2DPSink(sdp::Server::ConnectCallback cb=NopConnectCallback)99 RegistrationHandle AddA2DPSink(
100 sdp::Server::ConnectCallback cb = NopConnectCallback) {
101 ServiceRecord record;
102 record.SetServiceClassUUIDs({profile::kAudioSink});
103 record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
104 protocol::kL2CAP,
105 DataElement(l2cap::kAVDTP));
106 record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
107 protocol::kAVDTP,
108 DataElement(uint16_t{0x0103})); // Version
109 record.AddProfile(profile::kAdvancedAudioDistribution, 1, 3);
110 record.SetAttribute(kA2DP_SupportedFeatures,
111 DataElement(uint16_t{0x0001})); // Headphones
112 std::vector<ServiceRecord> records;
113 records.emplace_back(std::move(record));
114 RegistrationHandle handle = server()->RegisterService(
115 std::move(records), kChannelParams, std::move(cb));
116 EXPECT_TRUE(handle);
117 return handle;
118 }
119
AddL2capService(l2cap::Psm channel,l2cap::ChannelParameters chan_params=kChannelParams,sdp::Server::ConnectCallback cb=NopConnectCallback)120 RegistrationHandle AddL2capService(
121 l2cap::Psm channel,
122 l2cap::ChannelParameters chan_params = kChannelParams,
123 sdp::Server::ConnectCallback cb = NopConnectCallback) {
124 ServiceRecord record;
125 record.SetServiceClassUUIDs({profile::kAudioSink});
126 record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
127 protocol::kL2CAP,
128 DataElement(channel));
129 record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
130 protocol::kAVDTP,
131 DataElement(uint16_t{0x0103})); // Version
132 record.AddProfile(profile::kAdvancedAudioDistribution, 1, 3);
133 record.SetAttribute(kA2DP_SupportedFeatures,
134 DataElement(uint16_t{0x0001})); // Headphones
135 std::vector<ServiceRecord> records;
136 records.emplace_back(std::move(record));
137 RegistrationHandle handle = server()->RegisterService(
138 std::move(records), chan_params, std::move(cb));
139 EXPECT_TRUE(handle);
140 return handle;
141 }
142
TriggerInboundL2capChannelsForAllocated(size_t expected_psm_count)143 void TriggerInboundL2capChannelsForAllocated(size_t expected_psm_count) {
144 auto allocated = server()->AllocatedPsmsForTest();
145 // The SDP PSM is special and will always exist. Not connectable.
146 EXPECT_TRUE(allocated.erase(l2cap::kSDP));
147 EXPECT_EQ(expected_psm_count, allocated.size());
148
149 // Trigger inbound L2CAP channels for the remaining. |id|, |remote_id|
150 // aren't important.
151 auto id = 0x40;
152 for (auto it = allocated.begin(); it != allocated.end(); it++) {
153 EXPECT_TRUE(
154 l2cap()->TriggerInboundL2capChannel(kTestHandle1, *it, id, id));
155 id++;
156 }
157
158 RunUntilIdle();
159 }
160
161 private:
162 l2cap::testing::FakeChannel::WeakPtr channel_;
163 std::unique_ptr<l2cap::testing::FakeL2cap> l2cap_;
164 std::unique_ptr<Server> server_;
165 };
166
167 constexpr l2cap::ChannelId kSdpChannel = 0x0041;
168
169 #define SDP_ERROR_RSP(t_id, code) \
170 StaticByteBuffer(0x01, \
171 UpperBits(t_id), \
172 LowerBits(t_id), \
173 0x00, \
174 0x02, \
175 UpperBits(uint16_t(code)), \
176 LowerBits(uint16_t(code)));
177
178 #define UINT32_AS_BE_BYTES(x) \
179 UpperBits(x >> 16), LowerBits(x >> 16), UpperBits(x & 0xFFFF), \
180 LowerBits(x & 0xFFFF)
181
182 // Test:
183 // - Accepts channels and holds channel open correctly.
184 // - More than one channel from the same peer can be open at once.
185 // - Packets that are the wrong length are responded to with kInvalidSize
186 // - Answers with the same TransactionID as sent
TEST_F(ServerTest,BasicError)187 TEST_F(ServerTest, BasicError) {
188 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
189 kTestHandle1, l2cap::kSDP, kSdpChannel, 0x0bad));
190 RunUntilIdle();
191 ASSERT_TRUE(fake_chan().is_alive());
192 EXPECT_TRUE(fake_chan()->activated());
193
194 const auto kRspErrSize = SDP_ERROR_RSP(0x1001, ErrorCode::kInvalidSize);
195
196 const StaticByteBuffer kTooSmall(0x01, // SDP_ServiceSearchRequest
197 0x10,
198 0x01, // Transaction ID (0x1001)
199 0x00,
200 0x09 // Parameter length (9 bytes)
201 );
202
203 const auto kRspTooSmall = SDP_ERROR_RSP(0x1001, ErrorCode::kInvalidSize);
204
205 const StaticByteBuffer kTooBig(0x01, // SDP_ServiceSearchRequest
206 0x20,
207 0x10, // Transaction ID (0x2010)
208 0x00,
209 0x02, // Parameter length (2 bytes)
210 0x01,
211 0x02,
212 0x03 // 3 bytes of parameters
213 );
214
215 const auto kRspTooBig = SDP_ERROR_RSP(0x2010, ErrorCode::kInvalidSize);
216
217 EXPECT_TRUE(ReceiveAndExpect(kTooSmall, kRspTooSmall));
218 EXPECT_TRUE(ReceiveAndExpect(kTooBig, kRspTooBig));
219
220 const auto kRspInvalidSyntax =
221 SDP_ERROR_RSP(0x2010, ErrorCode::kInvalidRequestSyntax);
222
223 // Responses aren't valid requests
224 EXPECT_TRUE(ReceiveAndExpect(kRspTooBig, kRspInvalidSyntax));
225
226 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
227 kTestHandle1, l2cap::kSDP, kSdpChannel + 1, 0x0bad));
228 RunUntilIdle();
229 ASSERT_TRUE(fake_chan().is_alive());
230 EXPECT_TRUE(fake_chan()->activated());
231
232 EXPECT_TRUE(ReceiveAndExpect(kTooSmall, kRspTooSmall));
233 }
234
235 // Test:
236 // - Passes an initialized ServiceRecord that has a matching ServiceHandle
237 // - Doesn't add a service that doesn't contain a ServiceClassIDList
238 // - Adds a service that is valid.
239 // - Services can be Unregistered.
TEST_F(ServerTest,RegisterService)240 TEST_F(ServerTest, RegisterService) {
241 std::vector<ServiceRecord> records;
242 EXPECT_FALSE(
243 server()->RegisterService(std::move(records), kChannelParams, {}));
244
245 ServiceRecord record = ServiceRecord();
246 std::vector<ServiceRecord> records0;
247 records0.emplace_back(std::move(record));
248 EXPECT_FALSE(
249 server()->RegisterService(std::move(records0), kChannelParams, {}));
250
251 ServiceRecord record1;
252 record1.SetAttribute(kServiceClassIdList, DataElement(uint16_t{42}));
253 std::vector<ServiceRecord> records1;
254 records1.emplace_back(std::move(record1));
255 EXPECT_FALSE(
256 server()->RegisterService(std::move(records1), kChannelParams, {}));
257
258 ServiceRecord has_handle;
259 has_handle.SetHandle(42);
260 std::vector<ServiceRecord> records2;
261 records2.emplace_back(std::move(has_handle));
262 EXPECT_FALSE(
263 server()->RegisterService(std::move(records2), kChannelParams, {}));
264
265 ServiceRecord valid;
266 valid.SetServiceClassUUIDs({profile::kAVRemoteControl});
267 std::vector<ServiceRecord> records3;
268 records3.emplace_back(std::move(valid));
269 RegistrationHandle handle =
270 server()->RegisterService(std::move(records3), kChannelParams, {});
271
272 EXPECT_TRUE(handle);
273
274 EXPECT_TRUE(server()->UnregisterService(handle));
275 EXPECT_FALSE(server()->UnregisterService(handle));
276 }
277
278 // Test:
279 // - Adds a protocol-only service to the server.
280 // - Tests registration of the PSM is successful.
281 // - Tests callback correctness when inbound l2cap channels are connected.
TEST_F(ServerTest,RegisterProtocolOnlyService)282 TEST_F(ServerTest, RegisterProtocolOnlyService) {
283 ServiceRecord protocol_only;
284 l2cap::Psm test_psm = 500;
285 protocol_only.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
286 protocol::kL2CAP,
287 DataElement(uint16_t{test_psm}));
288
289 std::vector<uint16_t> protocols_discovered;
290 auto service_connect_cb = [&](auto /*channel*/,
291 const DataElement& protocol_list) {
292 EXPECT_EQ(DataElement::Type::kSequence, protocol_list.type());
293 auto* psm = protocol_list.At(0);
294 EXPECT_EQ(DataElement::Type::kSequence, psm->type());
295 psm = psm->At(1);
296 EXPECT_EQ(DataElement::Type::kUnsignedInt, psm->type());
297 protocols_discovered.emplace_back(*psm->template Get<uint16_t>());
298 };
299
300 std::vector<ServiceRecord> records;
301 records.emplace_back(std::move(protocol_only));
302 auto handle = server()->RegisterService(
303 std::move(records), kChannelParams, std::move(service_connect_cb));
304
305 EXPECT_TRUE(handle);
306
307 EXPECT_TRUE(
308 l2cap()->TriggerInboundL2capChannel(kTestHandle1, test_psm, 0x40, 0x41));
309 RunUntilIdle();
310
311 ASSERT_EQ(1u, protocols_discovered.size());
312 // There should be one connection (and therefore protocol_list) per psm
313 // registered.
314 ASSERT_EQ(test_psm, protocols_discovered[0]);
315
316 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
317 kTestHandle1, l2cap::kSDP, kSdpChannel, 0x0bad));
318 RunUntilIdle();
319
320 // Searching for the service record doesn't work
321 //
322 // By asking for everything L2CAP
323 const StaticByteBuffer kL2capSearch(
324 0x02, // SDP_ServiceSearchRequest
325 0x10,
326 0x01, // Transaction ID (0x1001)
327 0x00,
328 0x08, // Parameter length (8 bytes)
329 // ServiceSearchPattern
330 0x35,
331 0x03, // Sequence uint8 3 bytes
332 0x19,
333 0x01,
334 0x00, // UUID: Protocol: L2CAP
335 0xFF,
336 0xFF, // MaximumServiceRecordCount: (none)
337 0x00 // Continuation State: none
338 );
339 bool responded = false;
340 auto service_search_cb = [&responded](auto cb_packet) {
341 EXPECT_LE(sizeof(Header), cb_packet->size());
342 PacketView<Header> packet(cb_packet.get());
343 EXPECT_EQ(kServiceSearchResponse, packet.header().pdu_id);
344 uint16_t len = be16toh(packet.header().param_length);
345 packet.Resize(len);
346 ServiceSearchResponse resp;
347 fit::result<Error<>> result = resp.Parse(packet.payload_data());
348 EXPECT_EQ(fit::ok(), result);
349 EXPECT_EQ(0u, resp.service_record_handle_list().size());
350 responded = true;
351 };
352
353 fake_chan()->SetSendCallback(service_search_cb, dispatcher());
354 fake_chan()->Receive(kL2capSearch);
355 RunUntilIdle();
356 EXPECT_TRUE(responded);
357
358 // By asking for everything L2CAP with all attributes
359 const auto kServiceSearchAttributeRequest =
360 StaticByteBuffer(0x06, // SDP_ServiceAttributeRequest
361 0x10,
362 0x01, // Transaction ID (0x1001)
363 0x00,
364 0x12, // Parameter length (18 bytes)
365 // ServiceSearchPattern
366 0x35,
367 0x03, // Sequence uint8 3 bytes
368 0x19,
369 0x01,
370 0x00, // UUID: Protocol: L2CAP
371 0xFF,
372 0xFF, // MaximumAttributeByteCount (no max)
373 // AttributeIDList
374 0x35,
375 0x08, // Sequence uint8 8 bytes
376 0x09, // uint16_t, single attribute
377 0x00,
378 0x00, // ServiceRecordHandle
379 0x0A, // uint32_t, which is a range (0x3000 - 0xf000)
380 0x00,
381 0x00, // low end of range
382 0xff,
383 0xff, // high end of range
384 0x00 // Continuation State: none
385 );
386
387 responded = false;
388 auto service_search_attribute_cb = [&responded](auto cb_packet) {
389 EXPECT_LE(sizeof(Header), cb_packet->size());
390 PacketView<sdp::Header> packet(cb_packet.get());
391 ASSERT_EQ(kServiceSearchAttributeResponse, packet.header().pdu_id);
392 uint16_t len = be16toh(packet.header().param_length);
393 packet.Resize(len);
394 ServiceSearchAttributeResponse rsp;
395 fit::result<Error<>> result = rsp.Parse(packet.payload_data());
396 EXPECT_EQ(fit::ok(), result);
397 EXPECT_EQ(0u, rsp.num_attribute_lists());
398 responded = true;
399 };
400
401 fake_chan()->SetSendCallback(service_search_attribute_cb, dispatcher());
402 fake_chan()->Receive(kServiceSearchAttributeRequest);
403 RunUntilIdle();
404 EXPECT_TRUE(responded);
405
406 // Asking for the service handle directly will also not work, and gives an
407 // InvalidRecordHandle
408 const auto kServiceAttributeRequest =
409 StaticByteBuffer(0x04, // SDP_ServiceAttributeRequest
410 0x10,
411 0x01, // Transaction ID (0x1001)
412 0x00,
413 0x11, // Parameter length (17 bytes)
414 UINT32_AS_BE_BYTES(handle), // ServiceRecordHandle
415 0xFF,
416 0xFF, // MaximumAttributeByteCount (10 bytes max)
417 // AttributeIDList
418 0x35,
419 0x08, // Sequence uint8 8 bytes
420 0x09, // uint16_t, single attribute
421 0x00,
422 0x01, // ServiceClassIDList
423 0x0A, // uint32_t, which is a range (0x3000 - 0xf000)
424 0x30,
425 0x00, // low end of range
426 0xf0,
427 0x00, // high end of range
428 0x00 // Continuation State: none
429 );
430
431 responded = false;
432 auto service_attribute_cb = [&responded](auto cb_packet) {
433 EXPECT_LE(sizeof(Header), cb_packet->size());
434 PacketView<sdp::Header> packet(cb_packet.get());
435 ASSERT_EQ(0x01, packet.header().pdu_id);
436 uint16_t len = be16toh(packet.header().param_length);
437 ASSERT_GE(sizeof(Header) + len, cb_packet->size());
438 packet.Resize(len);
439 ErrorResponse rsp;
440 fit::result<Error<>> result = rsp.Parse(packet.payload_data());
441 EXPECT_FALSE(result.is_error());
442 EXPECT_EQ(rsp.error_code(), ErrorCode::kInvalidRecordHandle);
443 responded = true;
444 };
445
446 fake_chan()->SetSendCallback(service_attribute_cb, dispatcher());
447 fake_chan()->Receive(kServiceAttributeRequest);
448 RunUntilIdle();
449
450 EXPECT_TRUE(responded);
451
452 // Should still be able to unregister it by the handle.
453 EXPECT_TRUE(server()->UnregisterService(handle));
454 }
455
456 // Test:
457 // - Adds a primary protocol to the service definition.
458 // - Adds multiple additional protocols to the service definition.
459 // - Tests registration and removal are successful.
460 // - Tests callback correctness when inbound l2cap channels are connected.
TEST_F(ServerTest,RegisterServiceWithAdditionalProtocol)461 TEST_F(ServerTest, RegisterServiceWithAdditionalProtocol) {
462 std::vector<l2cap::Psm> psms{500, 27, 29};
463
464 ServiceRecord psm_additional;
465 psm_additional.SetServiceClassUUIDs({profile::kAVRemoteControl});
466 psm_additional.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
467 protocol::kL2CAP,
468 DataElement(uint16_t{psms[0]}));
469 psm_additional.AddProtocolDescriptor(
470 1, protocol::kL2CAP, DataElement(uint16_t{psms[1]}));
471 psm_additional.AddProtocolDescriptor(
472 2, protocol::kL2CAP, DataElement(uint16_t{psms[2]}));
473
474 std::vector<uint16_t> protocols_discovered;
475 auto cb = [&](auto /*channel*/, const DataElement& protocol_list) {
476 EXPECT_EQ(DataElement::Type::kSequence, protocol_list.type());
477 auto* psm = protocol_list.At(0);
478 EXPECT_EQ(DataElement::Type::kSequence, psm->type());
479 psm = psm->At(1);
480 EXPECT_EQ(DataElement::Type::kUnsignedInt, psm->type());
481 protocols_discovered.emplace_back(*psm->template Get<uint16_t>());
482 };
483
484 std::vector<ServiceRecord> records;
485 records.emplace_back(std::move(psm_additional));
486 auto handle = server()->RegisterService(
487 std::move(records), kChannelParams, std::move(cb));
488
489 EXPECT_TRUE(handle);
490
491 EXPECT_TRUE(
492 l2cap()->TriggerInboundL2capChannel(kTestHandle1, psms[0], 0x40, 0x41));
493 EXPECT_TRUE(
494 l2cap()->TriggerInboundL2capChannel(kTestHandle1, psms[1], 0x42, 0x43));
495 EXPECT_TRUE(
496 l2cap()->TriggerInboundL2capChannel(kTestHandle1, psms[2], 0x44, 0x44));
497 RunUntilIdle();
498
499 ASSERT_EQ(3u, protocols_discovered.size());
500 // There should be one connection (and therefore protocol_list) per psm
501 // registered.
502 for (auto& psm : psms) {
503 ASSERT_EQ(
504 1u,
505 std::count(
506 protocols_discovered.begin(), protocols_discovered.end(), psm));
507 }
508
509 EXPECT_TRUE(server()->UnregisterService(handle));
510 }
511
512 // Test:
513 // - Adds a primary protocol to the service definition.
514 // - Adds an additional protocol to the service definition.
515 // - Adds an additional protocol with missing information.
516 // - Tests that none of protocols are registered.
TEST_F(ServerTest,RegisterServiceWithIncompleteAdditionalProtocol)517 TEST_F(ServerTest, RegisterServiceWithIncompleteAdditionalProtocol) {
518 ServiceRecord psm_additional;
519 psm_additional.SetServiceClassUUIDs({profile::kAVRemoteControl});
520 psm_additional.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
521 protocol::kL2CAP,
522 DataElement(uint16_t{500}));
523 psm_additional.AddProtocolDescriptor(
524 1, protocol::kL2CAP, DataElement(uint16_t{27}));
525 psm_additional.AddProtocolDescriptor(2, protocol::kL2CAP, DataElement());
526
527 size_t cb_count = 0;
528 auto cb = [&](auto /*channel*/, auto& /* protocol_list */) { cb_count++; };
529
530 std::vector<ServiceRecord> records;
531 records.emplace_back(std::move(psm_additional));
532 RegistrationHandle handle = server()->RegisterService(
533 std::move(records), kChannelParams, std::move(cb));
534
535 EXPECT_FALSE(handle);
536 EXPECT_FALSE(
537 l2cap()->TriggerInboundL2capChannel(kTestHandle1, 500, 0x40, 0x41));
538 RunUntilIdle();
539
540 // Despite an incoming L2CAP connection, the callback should never be
541 // triggered since no services should be registered.
542 EXPECT_EQ(0u, cb_count);
543
544 EXPECT_FALSE(server()->UnregisterService(handle));
545 }
546
TEST_F(ServerTest,PsmVerification)547 TEST_F(ServerTest, PsmVerification) {
548 ServiceRecord no_psm;
549 no_psm.SetServiceClassUUIDs({profile::kAVRemoteControl});
550 no_psm.AddProtocolDescriptor(
551 ServiceRecord::kPrimaryProtocolList, protocol::kL2CAP, DataElement());
552
553 std::vector<ServiceRecord> records;
554 records.emplace_back(std::move(no_psm));
555 EXPECT_FALSE(
556 server()->RegisterService(std::move(records), kChannelParams, {}));
557
558 ServiceRecord psm_wrong_argtype;
559 psm_wrong_argtype.SetServiceClassUUIDs({profile::kAVRemoteControl});
560 psm_wrong_argtype.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
561 protocol::kL2CAP,
562 DataElement(bool(true)));
563
564 std::vector<ServiceRecord> records2;
565 records2.emplace_back(std::move(psm_wrong_argtype));
566 EXPECT_FALSE(
567 server()->RegisterService(std::move(records2), kChannelParams, {}));
568
569 ServiceRecord psm_wrong_intsize;
570 psm_wrong_intsize.SetServiceClassUUIDs({profile::kAVRemoteControl});
571 psm_wrong_intsize.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
572 protocol::kL2CAP,
573 DataElement(uint8_t{5}));
574
575 std::vector<ServiceRecord> records_wrong_intsize;
576 records_wrong_intsize.emplace_back(std::move(psm_wrong_intsize));
577 EXPECT_FALSE(server()->RegisterService(
578 std::move(records_wrong_intsize), kChannelParams, {}));
579
580 ServiceRecord psm_rfcomm;
581 psm_rfcomm.SetServiceClassUUIDs({profile::kAVRemoteControl});
582 psm_rfcomm.AddProtocolDescriptor(
583 ServiceRecord::kPrimaryProtocolList, protocol::kL2CAP, DataElement());
584 psm_rfcomm.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
585 protocol::kRFCOMM,
586 DataElement(uint16_t{5}));
587
588 std::vector<ServiceRecord> records3;
589 records3.emplace_back(std::move(psm_rfcomm));
590 EXPECT_TRUE(server()->RegisterService(
591 std::move(records3), kChannelParams, NopConnectCallback));
592
593 // Another RFCOMM should fail, even with a different channel.
594 ServiceRecord psm_rfcomm2;
595 psm_rfcomm2.SetServiceClassUUIDs({profile::kAVRemoteControl});
596 psm_rfcomm2.AddProtocolDescriptor(
597 ServiceRecord::kPrimaryProtocolList, protocol::kL2CAP, DataElement());
598 psm_rfcomm2.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
599 protocol::kRFCOMM,
600 DataElement(uint16_t{7}));
601
602 std::vector<ServiceRecord> records4;
603 records4.emplace_back(std::move(psm_rfcomm2));
604 EXPECT_FALSE(server()->RegisterService(
605 std::move(records4), kChannelParams, NopConnectCallback));
606
607 ServiceRecord psm_ok;
608 psm_ok.SetServiceClassUUIDs({profile::kAVRemoteControl});
609 psm_ok.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
610 protocol::kL2CAP,
611 DataElement(uint16_t{500}));
612
613 std::vector<ServiceRecord> records5;
614 records5.emplace_back(std::move(psm_ok));
615 auto handle = server()->RegisterService(
616 std::move(records5), kChannelParams, NopConnectCallback);
617 EXPECT_TRUE(handle);
618
619 ServiceRecord psm_same;
620 psm_same.SetServiceClassUUIDs({profile::kAVRemoteControl});
621 psm_same.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
622 protocol::kL2CAP,
623 DataElement(uint16_t{500}));
624
625 std::vector<ServiceRecord> records6;
626 records6.emplace_back(std::move(psm_same));
627 EXPECT_FALSE(server()->RegisterService(
628 std::move(records6), kChannelParams, NopConnectCallback));
629
630 // Unregistering allows us to re-register with PSM.
631 server()->UnregisterService(handle);
632 ServiceRecord psm_readd;
633 psm_readd.SetServiceClassUUIDs({profile::kAVRemoteControl});
634 psm_readd.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
635 protocol::kL2CAP,
636 DataElement(uint16_t{500}));
637
638 std::vector<ServiceRecord> records7;
639 records7.emplace_back(std::move(psm_readd));
640 EXPECT_TRUE(server()->RegisterService(
641 std::move(records7), kChannelParams, NopConnectCallback));
642 }
643
644 // Test:
645 // - Registering multiple ServiceRecords from the same client is successful.
646 // - Inbound L2CAP connections on the registered PSMs trigger the callback.
TEST_F(ServerTest,RegisterServiceMultipleRecordsSuccess)647 TEST_F(ServerTest, RegisterServiceMultipleRecordsSuccess) {
648 ServiceRecord record1;
649 record1.SetServiceClassUUIDs({profile::kAVRemoteControl});
650 record1.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
651 protocol::kL2CAP,
652 DataElement(uint16_t{7}));
653 record1.AddProtocolDescriptor(1, protocol::kL2CAP, DataElement(uint16_t{8}));
654
655 ServiceRecord record2;
656 record2.SetServiceClassUUIDs({profile::kAudioSink});
657 record2.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
658 protocol::kL2CAP,
659 DataElement(uint16_t{9}));
660 record2.AddProtocolDescriptor(1, protocol::kL2CAP, DataElement(uint16_t{10}));
661
662 std::vector<ServiceRecord> records;
663 records.emplace_back(std::move(record1));
664 records.emplace_back(std::move(record2));
665
666 size_t cb_count = 0;
667 auto cb = [&](auto /*channel*/, auto& protocol_list) { cb_count++; };
668
669 auto handle = server()->RegisterService(
670 std::move(records), kChannelParams, std::move(cb));
671 EXPECT_TRUE(handle);
672
673 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(kTestHandle1, 7, 0x40, 0x41));
674 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(kTestHandle1, 8, 0x42, 0x43));
675 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(kTestHandle1, 9, 0x44, 0x44));
676 EXPECT_TRUE(
677 l2cap()->TriggerInboundL2capChannel(kTestHandle1, 10, 0x45, 0x46));
678 RunUntilIdle();
679
680 EXPECT_EQ(4u, cb_count);
681
682 EXPECT_TRUE(server()->UnregisterService(handle));
683 }
684
685 // Test:
686 // - Registering multiple ServiceRecords with the same PSM from the same client
687 // is successful.
688 // - Inbound L2CAP connections on the registered PSMs trigger the same callback.
689 // - Attempting to register a record with an already taken PSM will fail, and
690 // not register any of the other records in the set of records.
TEST_F(ServerTest,RegisterServiceMultipleRecordsSamePsm)691 TEST_F(ServerTest, RegisterServiceMultipleRecordsSamePsm) {
692 ServiceRecord target_browse_record;
693 target_browse_record.SetServiceClassUUIDs({profile::kAVRemoteControlTarget});
694 target_browse_record.AddProtocolDescriptor(
695 ServiceRecord::kPrimaryProtocolList,
696 protocol::kL2CAP,
697 DataElement(uint16_t{25}));
698 target_browse_record.AddProtocolDescriptor(
699 1, protocol::kL2CAP, DataElement(uint16_t{27}));
700
701 ServiceRecord controller_record;
702 controller_record.SetServiceClassUUIDs({profile::kAVRemoteControlController});
703 controller_record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
704 protocol::kL2CAP,
705 DataElement(uint16_t{25}));
706
707 std::vector<ServiceRecord> records;
708 records.emplace_back(std::move(target_browse_record));
709 records.emplace_back(std::move(controller_record));
710
711 std::vector<uint16_t> protocols_discovered;
712 auto cb = [&](auto /*channel*/, const DataElement& protocol_list) {
713 EXPECT_EQ(DataElement::Type::kSequence, protocol_list.type());
714 auto* psm = protocol_list.At(0);
715 EXPECT_EQ(DataElement::Type::kSequence, psm->type());
716 psm = psm->At(1);
717 EXPECT_EQ(DataElement::Type::kUnsignedInt, psm->type());
718 protocols_discovered.emplace_back(*psm->template Get<uint16_t>());
719 };
720
721 auto handle = server()->RegisterService(
722 std::move(records), kChannelParams, std::move(cb));
723 EXPECT_TRUE(handle);
724
725 EXPECT_TRUE(
726 l2cap()->TriggerInboundL2capChannel(kTestHandle1, 25, 0x40, 0x41));
727 EXPECT_TRUE(
728 l2cap()->TriggerInboundL2capChannel(kTestHandle1, 27, 0x44, 0x44));
729 EXPECT_TRUE(
730 l2cap()->TriggerInboundL2capChannel(kTestHandle1, 25, 0x42, 0x43));
731 RunUntilIdle();
732
733 // We expect two calls to the callback for psm=25, and one for psm=27.
734 ASSERT_EQ(
735 2u,
736 std::count(protocols_discovered.begin(), protocols_discovered.end(), 25));
737 ASSERT_EQ(
738 1u,
739 std::count(protocols_discovered.begin(), protocols_discovered.end(), 27));
740
741 // Attempt to register existing PSM.
742 ServiceRecord duplicate_psm;
743 duplicate_psm.SetServiceClassUUIDs({profile::kAVRemoteControlTarget});
744 duplicate_psm.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
745 protocol::kL2CAP,
746 DataElement(uint16_t{25}));
747
748 ServiceRecord valid_psm;
749 valid_psm.SetServiceClassUUIDs({profile::kAudioSource});
750 valid_psm.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
751 protocol::kL2CAP,
752 DataElement(uint16_t{31}));
753
754 std::vector<ServiceRecord> invalid_records;
755 invalid_records.emplace_back(std::move(duplicate_psm));
756 invalid_records.emplace_back(std::move(valid_psm));
757 EXPECT_FALSE(server()->RegisterService(
758 std::move(invalid_records), kChannelParams, NopConnectCallback));
759
760 EXPECT_TRUE(server()->UnregisterService(handle));
761 }
762
TEST_F(ServerTest,RegisterObexService)763 TEST_F(ServerTest, RegisterObexService) {
764 ServiceRecord record;
765 record.SetServiceClassUUIDs({profile::kAVRemoteControlTarget});
766 // The AVRCP Target primary protocol has format: L2CAP: uint16_t, AVCTP:
767 // uint16_t.
768 record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
769 protocol::kL2CAP,
770 DataElement(uint16_t{l2cap::kAVCTP}));
771 record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
772 protocol::kAVCTP,
773 DataElement(uint16_t{0x0104}));
774 // It also has additional L2CAP protocols for Browsing & OBEX.
775 record.AddProtocolDescriptor(
776 1, protocol::kL2CAP, DataElement(uint16_t{l2cap::kAVCTP_Browse}));
777 record.AddProtocolDescriptor(
778 1, protocol::kAVCTP, DataElement(uint16_t{0x0104}));
779 record.AddProtocolDescriptor(
780 2, protocol::kL2CAP, DataElement(uint16_t{Server::kDynamicPsm}));
781 record.AddProtocolDescriptor(2, protocol::kOBEX, DataElement());
782
783 std::vector<ServiceRecord> records;
784 records.emplace_back(std::move(record));
785
786 size_t cb_count = 0;
787 auto cb = [&](auto /*channel*/, auto& protocol_list) { cb_count++; };
788
789 auto handle = server()->RegisterService(
790 std::move(records), kChannelParams, std::move(cb));
791 EXPECT_TRUE(handle);
792
793 // We expect 3 PSMs to be allocated for this service.
794 // The dynamic PSM is generated randomly and is not known in advance -
795 // therefore we trigger L2CAP channels for all allocated PSMs.
796 TriggerInboundL2capChannelsForAllocated(/*expected_psm_count=*/3);
797
798 // Expect the 3 service-specific PSMs to be connectable.
799 EXPECT_EQ(3u, cb_count);
800 EXPECT_TRUE(server()->UnregisterService(handle));
801 }
802
TEST_F(ServerTest,RegisterObexServiceWithAttribute)803 TEST_F(ServerTest, RegisterObexServiceWithAttribute) {
804 ServiceRecord record;
805 record.SetServiceClassUUIDs({profile::kMessageNotificationServer});
806 // The MNS primary protocol has format: L2CAP, RFCOMM: uint8_t, OBEX
807 record.AddProtocolDescriptor(
808 ServiceRecord::kPrimaryProtocolList, protocol::kL2CAP, DataElement());
809 record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
810 protocol::kRFCOMM,
811 DataElement(uint8_t{8}));
812 record.AddProtocolDescriptor(
813 ServiceRecord::kPrimaryProtocolList, protocol::kOBEX, DataElement());
814 // The MNS protocol also specifies an L2CAP protocol in the attributes
815 // section.
816 record.SetAttribute(kGoepL2capPsm,
817 DataElement(uint16_t(Server::kDynamicPsm)));
818
819 std::vector<ServiceRecord> records;
820 records.emplace_back(std::move(record));
821
822 size_t cb_count = 0;
823 auto cb = [&](auto /*channel*/, auto& protocol_list) { cb_count++; };
824
825 auto handle = server()->RegisterService(
826 std::move(records), kChannelParams, std::move(cb));
827 EXPECT_TRUE(handle);
828
829 // We expect 2 PSMs to be allocated and connectable for this service (RFCOMM &
830 // Dynamic).
831 TriggerInboundL2capChannelsForAllocated(/*expected_psm_count=*/2);
832 EXPECT_EQ(2u, cb_count);
833 EXPECT_TRUE(server()->UnregisterService(handle));
834 }
835
TEST_F(ServerTest,RegisterServiceWithMultipleDynamicPsms)836 TEST_F(ServerTest, RegisterServiceWithMultipleDynamicPsms) {
837 // This service is not defined in any Bluetooth specification.
838 ServiceRecord record;
839 record.SetServiceClassUUIDs({profile::kMessageNotificationServer});
840 // Fictional MNS service with a primary protocol with dynamic PSM.
841 record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
842 protocol::kL2CAP,
843 DataElement(uint16_t{Server::kDynamicPsm}));
844 record.AddProtocolDescriptor(
845 ServiceRecord::kPrimaryProtocolList, protocol::kOBEX, DataElement());
846 // Fictional protocol also contains a dynamic PSM in the GoepL2capAttribute.
847 record.SetAttribute(kGoepL2capPsm,
848 DataElement(uint16_t(Server::kDynamicPsm)));
849 // Additional protocol has dynamic PSM as well.
850 record.AddProtocolDescriptor(
851 1, protocol::kL2CAP, DataElement(uint16_t{Server::kDynamicPsm}));
852 record.AddProtocolDescriptor(1, protocol::kOBEX, DataElement());
853
854 std::vector<ServiceRecord> records;
855 records.emplace_back(std::move(record));
856
857 size_t cb_count = 0;
858 auto cb = [&](auto /*channel*/, auto& protocol_list) { cb_count++; };
859
860 auto handle = server()->RegisterService(
861 std::move(records), kChannelParams, std::move(cb));
862 EXPECT_TRUE(handle);
863
864 // The dynamic PSMs should all be unique and allocated. Can connect.
865 TriggerInboundL2capChannelsForAllocated(/*expected_psm_count=*/3);
866 EXPECT_EQ(3u, cb_count);
867 EXPECT_TRUE(server()->UnregisterService(handle));
868 }
869
TEST_F(ServerTest,RegisterNonObexServiceWithAttributeIsIgnored)870 TEST_F(ServerTest, RegisterNonObexServiceWithAttributeIsIgnored) {
871 ServiceRecord record;
872 // The AVRCP Controller service does not require OBEX.
873 record.SetServiceClassUUIDs({profile::kAVRemoteControlController});
874 record.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
875 protocol::kL2CAP,
876 DataElement(uint16_t{l2cap::kAVCTP}));
877 // The OBEX attribute should be ignored during registration.
878 record.SetAttribute(kGoepL2capPsm, DataElement(uint16_t(55)));
879
880 std::vector<ServiceRecord> records;
881 records.emplace_back(std::move(record));
882
883 size_t cb_count = 0;
884 auto cb = [&](auto /*channel*/, auto& protocol_list) { cb_count++; };
885
886 auto handle = server()->RegisterService(
887 std::move(records), kChannelParams, std::move(cb));
888 EXPECT_TRUE(handle);
889
890 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
891 kTestHandle1, l2cap::kAVCTP, 0x40, 0x41));
892 EXPECT_FALSE(
893 l2cap()->TriggerInboundL2capChannel(kTestHandle1, 55, 0x42, 0x43));
894 RunUntilIdle();
895 EXPECT_EQ(1u, cb_count);
896 EXPECT_TRUE(server()->UnregisterService(handle));
897 }
898
899 // Test ServiceSearchRequest:
900 // - returns services with the UUID included
901 // - doesn't return services that don't have the UUID
902 // - fails when there are no items or too many items in the search
903 // - doesn't return more than the max requested
TEST_F(ServerTest,ServiceSearchRequest)904 TEST_F(ServerTest, ServiceSearchRequest) {
905 RegistrationHandle spp_handle = AddSPP();
906 RegistrationHandle a2dp_handle = AddA2DPSink();
907
908 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
909 kTestHandle1, l2cap::kSDP, kSdpChannel, 0x0bad));
910 RunUntilIdle();
911
912 const StaticByteBuffer kL2capSearch(
913 0x02, // SDP_ServiceSearchRequest
914 0x10,
915 0x01, // Transaction ID (0x1001)
916 0x00,
917 0x08, // Parameter length (8 bytes)
918 // ServiceSearchPattern
919 0x35,
920 0x03, // Sequence uint8 3 bytes
921 0x19,
922 0x01,
923 0x00, // UUID: Protocol: L2CAP
924 0xFF,
925 0xFF, // MaximumServiceRecordCount: (none)
926 0x00 // Continuation State: none
927 );
928
929 ServiceSearchRequest search_req;
930 EXPECT_FALSE(search_req.valid());
931 EXPECT_EQ(nullptr, search_req.GetPDU(0x1001));
932
933 search_req.set_search_pattern({protocol::kL2CAP});
934
935 auto pdu = search_req.GetPDU(0x1001);
936 EXPECT_NE(nullptr, pdu);
937
938 EXPECT_TRUE(ContainersEqual(kL2capSearch, *pdu));
939
940 const StaticByteBuffer kL2capSearchResponse(
941 0x03, // SDP_ServicesearchResponse
942 0x10,
943 0x01, // Transaction ID (0x1001)
944 0x00,
945 0x0D, // Parameter length (13 bytes)
946 0x00,
947 0x02, // Total service record count: 2
948 0x00,
949 0x02, // Current service record count: 2
950 UINT32_AS_BE_BYTES(spp_handle), // This list isn't specifically ordered
951 UINT32_AS_BE_BYTES(a2dp_handle),
952 0x00 // No continuation state
953 );
954
955 bool recv = false;
956 std::vector<ServiceHandle> handles;
957 TransactionId tid;
958 auto cb = [&recv, &handles, &tid](auto cb_packet) {
959 EXPECT_LE(sizeof(Header), cb_packet->size());
960 PacketView<Header> packet(cb_packet.get());
961 EXPECT_EQ(kServiceSearchResponse, packet.header().pdu_id);
962 tid = be16toh(packet.header().tid);
963 uint16_t len = be16toh(packet.header().param_length);
964 bt_log(TRACE, "unittest", "resize packet to %d", len);
965 packet.Resize(len);
966 ServiceSearchResponse resp;
967 auto status = resp.Parse(packet.payload_data());
968 EXPECT_EQ(fit::ok(), status);
969 handles = resp.service_record_handle_list();
970 recv = true;
971 };
972
973 fake_chan()->SetSendCallback(cb, dispatcher());
974 fake_chan()->Receive(kL2capSearch);
975 RunUntilIdle();
976
977 EXPECT_TRUE(recv);
978 EXPECT_EQ(0x1001, tid);
979 EXPECT_EQ(2u, handles.size());
980 EXPECT_NE(handles.end(),
981 std::find(handles.begin(), handles.end(), spp_handle));
982 EXPECT_NE(handles.end(),
983 std::find(handles.begin(), handles.end(), a2dp_handle));
984
985 const StaticByteBuffer kInvalidNoItems(
986 0x02, // SDP_ServiceSearchRequest
987 0x10,
988 0xA1, // Transaction ID (0x10A1)
989 0x00,
990 0x05, // Parameter length (5 bytes)
991 // ServiceSearchPattern
992 0x35,
993 0x00, // Sequence uint8 0 bytes
994 0xFF,
995 0xFF, // MaximumServiceRecordCount: (none)
996 0x00 // Continuation State: none
997 );
998
999 const auto kRspErrSyntax =
1000 SDP_ERROR_RSP(0x10A1, ErrorCode::kInvalidRequestSyntax);
1001
1002 EXPECT_TRUE(ReceiveAndExpect(kInvalidNoItems, kRspErrSyntax));
1003
1004 const StaticByteBuffer kInvalidTooManyItems(
1005 0x02, // SDP_ServiceSearchRequest
1006 0x10,
1007 0xA1, // Transaction ID (0x10B1)
1008 0x00,
1009 0x2C, // Parameter length (44 bytes)
1010 // ServiceSearchPattern
1011 0x35,
1012 0x27, // Sequence uint8 27 bytes
1013 0x19,
1014 0x30,
1015 0x01, // 13 UUIDs in the search
1016 0x19,
1017 0x30,
1018 0x02,
1019 0x19,
1020 0x30,
1021 0x03,
1022 0x19,
1023 0x30,
1024 0x04,
1025 0x19,
1026 0x30,
1027 0x05,
1028 0x19,
1029 0x30,
1030 0x06,
1031 0x19,
1032 0x30,
1033 0x07,
1034 0x19,
1035 0x30,
1036 0x08,
1037 0x19,
1038 0x30,
1039 0x09,
1040 0x19,
1041 0x30,
1042 0x10,
1043 0x19,
1044 0x30,
1045 0x11,
1046 0x19,
1047 0x30,
1048 0x12,
1049 0x19,
1050 0x30,
1051 0x13,
1052 0xFF,
1053 0xFF, // MaximumServiceRecordCount: (none)
1054 0x00 // Continuation State: none
1055 );
1056
1057 EXPECT_TRUE(ReceiveAndExpect(kInvalidTooManyItems, kRspErrSyntax));
1058 }
1059
1060 // Test ServiceSearchRequest:
1061 // - doesn't return more than the max requested
TEST_F(ServerTest,ServiceSearchRequestOneOfMany)1062 TEST_F(ServerTest, ServiceSearchRequestOneOfMany) {
1063 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
1064 kTestHandle1, l2cap::kSDP, kSdpChannel, 0x0bad));
1065 RunUntilIdle();
1066
1067 RegistrationHandle spp_handle = AddSPP();
1068 RegistrationHandle a2dp_handle = AddA2DPSink();
1069
1070 bool recv = false;
1071 std::vector<ServiceHandle> handles;
1072 TransactionId tid;
1073 auto cb = [&recv, &handles, &tid](auto cb_packet) {
1074 EXPECT_LE(sizeof(Header), cb_packet->size());
1075 PacketView<Header> packet(cb_packet.get());
1076 EXPECT_EQ(kServiceSearchResponse, packet.header().pdu_id);
1077 tid = be16toh(packet.header().tid);
1078 uint16_t len = be16toh(packet.header().param_length);
1079 bt_log(TRACE, "unittests", "resizing packet to %d", len);
1080 packet.Resize(len);
1081 ServiceSearchResponse resp;
1082 auto status = resp.Parse(packet.payload_data());
1083 EXPECT_EQ(fit::ok(), status);
1084 handles = resp.service_record_handle_list();
1085 recv = true;
1086 };
1087
1088 const StaticByteBuffer kL2capSearchOne(0x02, // SDP_ServiceSearchRequest
1089 0x10,
1090 0xC1, // Transaction ID (0x10C1)
1091 0x00,
1092 0x08, // Parameter length (8 bytes)
1093 // ServiceSearchPattern
1094 0x35,
1095 0x03, // Sequence uint8 3 bytes
1096 0x19,
1097 0x01,
1098 0x00, // UUID: Protocol: L2CAP
1099 0x00,
1100 0x01, // MaximumServiceRecordCount: 1
1101 0x00 // Continuation State: none
1102 );
1103
1104 handles.clear();
1105 recv = false;
1106
1107 fake_chan()->SetSendCallback(cb, dispatcher());
1108 fake_chan()->Receive(kL2capSearchOne);
1109 RunUntilIdle();
1110
1111 EXPECT_TRUE(recv);
1112 EXPECT_EQ(0x10C1, tid);
1113 EXPECT_EQ(1u, handles.size());
1114 bool found_spp =
1115 std::find(handles.begin(), handles.end(), spp_handle) != handles.end();
1116 bool found_a2dp =
1117 std::find(handles.begin(), handles.end(), a2dp_handle) != handles.end();
1118 EXPECT_TRUE(found_spp || found_a2dp);
1119 }
1120
1121 // Test ServiceSearchRequest:
1122 // - returns continuation state if too many services match
1123 // - continuation state in request works correctly
TEST_F(ServerTest,ServiceSearchContinuationState)1124 TEST_F(ServerTest, ServiceSearchContinuationState) {
1125 // Set the TX MTU to the lowest that's allowed (48)
1126 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
1127 kTestHandle1, l2cap::kSDP, kSdpChannel, 0x0bad, 48 /* tx_mtu */));
1128 RunUntilIdle();
1129
1130 // Add enough services to generate a continuation state.
1131 AddL2capService(0x1001);
1132 AddL2capService(0x1003);
1133 AddL2capService(0x1005);
1134 AddL2capService(0x1007);
1135 AddL2capService(0x1009);
1136 AddL2capService(0x100B);
1137 AddL2capService(0x100D);
1138 AddL2capService(0x100F);
1139 AddL2capService(0x1011);
1140 AddL2capService(0x1013);
1141 AddL2capService(0x1015);
1142
1143 size_t received = 0;
1144 ServiceSearchResponse rsp;
1145
1146 auto send_cb = [this, &rsp, &received](auto cb_packet) {
1147 EXPECT_LE(sizeof(Header), cb_packet->size());
1148 PacketView<sdp::Header> packet(cb_packet.get());
1149 ASSERT_EQ(0x03, packet.header().pdu_id);
1150 uint16_t len = be16toh(packet.header().param_length);
1151 EXPECT_LE(len,
1152 0x2F); // 10 records (4 * 10) + 2 (total count) + 2 (current
1153 // count) + 3 (cont state)
1154 packet.Resize(len);
1155 fit::result<Error<>> result = rsp.Parse(packet.payload_data());
1156 if (received == 0) {
1157 // Server should have split this into more than one response.
1158 EXPECT_EQ(ToResult(HostError::kInProgress), result);
1159 EXPECT_FALSE(rsp.complete());
1160 }
1161 received++;
1162 if (result.is_error() && !result.error_value().is(HostError::kInProgress)) {
1163 // This isn't a valid packet and we shouldn't try to get
1164 // a continuation.
1165 return;
1166 }
1167 if (!rsp.complete()) {
1168 // Repeat the request with the continuation state if it was returned.
1169 auto continuation = rsp.ContinuationState();
1170 uint8_t cont_size = continuation.size();
1171 EXPECT_NE(0u, cont_size);
1172 // Make another request with the continuation data.
1173 size_t param_size = 8 + cont_size;
1174 StaticByteBuffer kContinuedRequestStart(
1175 0x02, // SDP_ServiceSearchRequest
1176 0x10,
1177 0xC1, // Transaction ID (0x10C1)
1178 UpperBits(param_size),
1179 LowerBits(param_size), // Parameter length
1180 // ServiceSearchPattern
1181 0x35,
1182 0x03, // Sequence uint8 3 bytes
1183 0x19,
1184 0x01,
1185 0x00, // UUID: Protocol: L2CAP
1186 0x00,
1187 0xFF // MaximumServiceRecordCount: 256
1188 );
1189
1190 DynamicByteBuffer req(kContinuedRequestStart.size() + sizeof(uint8_t) +
1191 cont_size);
1192
1193 kContinuedRequestStart.Copy(&req);
1194 req.Write(&cont_size, sizeof(uint8_t), kContinuedRequestStart.size());
1195 req.Write(continuation, kContinuedRequestStart.size() + sizeof(uint8_t));
1196
1197 fake_chan()->Receive(req);
1198 }
1199 };
1200
1201 const StaticByteBuffer kL2capSearch(0x02, // SDP_ServiceSearchRequest
1202 0x10,
1203 0xC1, // Transaction ID (0x10C1)
1204 0x00,
1205 0x08, // Parameter length (8 bytes)
1206 // ServiceSearchPattern
1207 0x35,
1208 0x03, // Sequence uint8 3 bytes
1209 0x19,
1210 0x01,
1211 0x00, // UUID: Protocol: L2CAP
1212 0x00,
1213 0xFF, // MaximumServiceRecordCount: 256
1214 0x00 // Continuation State: none
1215 );
1216
1217 fake_chan()->SetSendCallback(send_cb, dispatcher());
1218 fake_chan()->Receive(kL2capSearch);
1219 RunUntilIdle();
1220
1221 EXPECT_GE(received, 1u);
1222 EXPECT_EQ(11u, rsp.service_record_handle_list().size());
1223 }
1224
1225 // Test:
1226 // - Answers ServiceAttributeRequest correctly
1227 // - Continuation state is generated correctly re:
1228 // MaximumAttributeListByteCount
1229 // - Valid Continuation state continues response
TEST_F(ServerTest,ServiceAttributeRequest)1230 TEST_F(ServerTest, ServiceAttributeRequest) {
1231 ServiceRecord record;
1232 record.SetServiceClassUUIDs({profile::kAVRemoteControl});
1233 record.SetAttribute(0xf00d, DataElement(uint32_t{0xfeedbeef}));
1234 record.SetAttribute(0xf000, DataElement(uint32_t{0x01234567}));
1235
1236 std::vector<ServiceRecord> records;
1237 records.emplace_back(std::move(record));
1238 RegistrationHandle handle =
1239 server()->RegisterService(std::move(records), kChannelParams, {});
1240
1241 EXPECT_TRUE(handle);
1242
1243 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
1244 kTestHandle1, l2cap::kSDP, kSdpChannel, 0x0bad));
1245 RunUntilIdle();
1246
1247 const auto kRequestAttr =
1248 StaticByteBuffer(0x04, // SDP_ServiceAttributeRequest
1249 0x10,
1250 0x01, // Transaction ID (0x1001)
1251 0x00,
1252 0x11, // Parameter length (17 bytes)
1253 UINT32_AS_BE_BYTES(handle), // ServiceRecordHandle
1254 0x00,
1255 0x0A, // MaximumAttributeByteCount (10 bytes max)
1256 // AttributeIDList
1257 0x35,
1258 0x08, // Sequence uint8 8 bytes
1259 0x09, // uint16_t, single attribute
1260 0x00,
1261 0x01, // ServiceClassIDList
1262 0x0A, // uint32_t, which is a range (0x3000 - 0xf000)
1263 0x30,
1264 0x00, // low end of range
1265 0xf0,
1266 0x00, // high end of range
1267 0x00 // Continuation State: none
1268 );
1269
1270 size_t received = 0;
1271
1272 ServiceAttributeResponse rsp;
1273
1274 auto send_cb = [this, handle, &rsp, &received](auto cb_packet) {
1275 EXPECT_LE(sizeof(Header), cb_packet->size());
1276 PacketView<sdp::Header> packet(cb_packet.get());
1277 ASSERT_EQ(0x05, packet.header().pdu_id);
1278 uint16_t len = be16toh(packet.header().param_length);
1279 EXPECT_LE(len, 0x11); // 10 + 2 (byte count) + 5 (cont state)
1280 packet.Resize(len);
1281 fit::result<Error<>> result = rsp.Parse(packet.payload_data());
1282 if (received == 0) {
1283 // Server should have split this into more than one response.
1284 EXPECT_EQ(ToResult(HostError::kInProgress), result);
1285 EXPECT_FALSE(rsp.complete());
1286 }
1287 received++;
1288 if (result.is_error() && !result.error_value().is(HostError::kInProgress)) {
1289 // This isn't a valid packet and we shouldn't try to get
1290 // a continuation.
1291 return;
1292 }
1293 if (!rsp.complete()) {
1294 // Repeat the request with the continuation state if it was returned.
1295 auto continuation = rsp.ContinuationState();
1296 uint8_t cont_size = continuation.size();
1297 EXPECT_NE(0u, cont_size);
1298 // Make another request with the continuation data.
1299 size_t param_size = 17 + cont_size;
1300 auto kContinuedRequestAttrStart = StaticByteBuffer(
1301 0x04, // SDP_ServiceAttributeRequest
1302 0x10,
1303 0x01, // Transaction ID (reused)
1304 UpperBits(param_size),
1305 LowerBits(param_size), // Parameter length
1306 UINT32_AS_BE_BYTES(handle), // ServiceRecordHandle
1307 0x00,
1308 0x0A, // MaximumAttributeByteCount (10 bytes max)
1309 // AttributeIDList
1310 0x35,
1311 0x08, // Sequence uint8 8 bytes
1312 0x09, // uint16_t, single attribute
1313 0x00,
1314 0x01, // ServiceClassIDList
1315 0x0A, // uint32_t, which is a range (0x3000 - 0xf000)
1316 0x30,
1317 0x00, // low end of range
1318 0xf0,
1319 0x00 // high end of range
1320 );
1321 DynamicByteBuffer req(kContinuedRequestAttrStart.size() +
1322 sizeof(uint8_t) + cont_size);
1323
1324 kContinuedRequestAttrStart.Copy(&req);
1325 req.Write(&cont_size, sizeof(uint8_t), kContinuedRequestAttrStart.size());
1326 req.Write(continuation,
1327 kContinuedRequestAttrStart.size() + sizeof(uint8_t));
1328
1329 fake_chan()->Receive(req);
1330 }
1331 };
1332
1333 fake_chan()->SetSendCallback(send_cb, dispatcher());
1334 fake_chan()->Receive(kRequestAttr);
1335 RunUntilIdle();
1336
1337 EXPECT_GE(received, 1u);
1338 const auto& attrs = rsp.attributes();
1339 EXPECT_EQ(2u, attrs.size());
1340 EXPECT_NE(attrs.end(), attrs.find(kServiceClassIdList));
1341 EXPECT_NE(attrs.end(), attrs.find(0xf000));
1342
1343 const auto kInvalidRangeOrder =
1344 StaticByteBuffer(0x04, // SDP_ServiceAttributeRequest
1345 0xE0,
1346 0x01, // Transaction ID (0xE001)
1347 0x00,
1348 0x11, // Parameter length (17 bytes)
1349 UINT32_AS_BE_BYTES(handle), // ServiceRecordHandle
1350 0x00,
1351 0x0A, // MaximumAttributeByteCount (10 bytes max)
1352 // AttributeIDList
1353 0x35,
1354 0x08, // Sequence uint8 8 bytes
1355 0x09, // uint16_t, single attribute
1356 0x00,
1357 0x01, // ServiceClassIDList
1358 0x0A, // uint32_t, which is a range (0x3000 - 0xf000)
1359 0xf0,
1360 0x00, // low end of range
1361 0x30,
1362 0x00, // high end of range
1363 0x00 // Continuation State: none
1364 );
1365
1366 const auto kRspErrSyntax =
1367 SDP_ERROR_RSP(0xE001, ErrorCode::kInvalidRequestSyntax);
1368
1369 EXPECT_TRUE(ReceiveAndExpect(kInvalidRangeOrder, kRspErrSyntax));
1370
1371 const auto kInvalidMaxBytes =
1372 StaticByteBuffer(0x04, // SDP_ServiceAttributeRequest
1373 0xE0,
1374 0x02, // Transaction ID (0xE001)
1375 0x00,
1376 0x0C, // Parameter length (12 bytes)
1377 UINT32_AS_BE_BYTES(handle), // ServiceRecordHandle
1378 0x00,
1379 0x05, // MaximumAttributeByteCount (5 bytes max)
1380 // AttributeIDList
1381 0x35,
1382 0x03, // Sequence uint8 3 bytes
1383 0x09, // uint16_t, single attribute
1384 0x00,
1385 0x01, // ServiceClassIDList
1386 0x00 // Continuation State: none
1387 );
1388
1389 const auto kRspErrSyntax2 =
1390 SDP_ERROR_RSP(0xE002, ErrorCode::kInvalidRequestSyntax);
1391
1392 EXPECT_TRUE(ReceiveAndExpect(kInvalidMaxBytes, kRspErrSyntax2));
1393 }
1394
1395 // Test:
1396 // - Answers ServiceSearchAttributeRequest correctly
1397 // - Continuation state is generated correctly re:
1398 // MaximumAttributeListsByteCount
1399 // - Valid Continuation state continues response
TEST_F(ServerTest,SearchAttributeRequest)1400 TEST_F(ServerTest, SearchAttributeRequest) {
1401 ServiceRecord record1;
1402 record1.SetServiceClassUUIDs({profile::kAVRemoteControl});
1403 record1.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
1404 protocol::kL2CAP,
1405 DataElement(uint16_t{500}));
1406 record1.SetAttribute(0xf00d, DataElement(uint32_t{0xfeedbeef}));
1407 record1.SetAttribute(0xf000, DataElement(uint32_t{0x01234567}));
1408
1409 std::vector<ServiceRecord> records1;
1410 records1.emplace_back(std::move(record1));
1411 RegistrationHandle handle1 = server()->RegisterService(
1412 std::move(records1), kChannelParams, NopConnectCallback);
1413
1414 EXPECT_TRUE(handle1);
1415
1416 ServiceRecord record2;
1417 record2.SetServiceClassUUIDs({profile::kAVRemoteControl});
1418 record2.AddProtocolDescriptor(ServiceRecord::kPrimaryProtocolList,
1419 protocol::kL2CAP,
1420 DataElement(uint16_t{501}));
1421
1422 std::vector<ServiceRecord> records2;
1423 records2.emplace_back(std::move(record2));
1424 RegistrationHandle handle2 = server()->RegisterService(
1425 std::move(records2), kChannelParams, NopConnectCallback);
1426
1427 EXPECT_TRUE(handle2);
1428
1429 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
1430 kTestHandle1, l2cap::kSDP, kSdpChannel, 0x0bad));
1431 RunUntilIdle();
1432
1433 const auto kRequestAttr =
1434 StaticByteBuffer(0x06, // SDP_ServiceAttributeRequest
1435 0x10,
1436 0x01, // Transaction ID (0x1001)
1437 0x00,
1438 0x12, // Parameter length (18 bytes)
1439 // ServiceSearchPattern
1440 0x35,
1441 0x03, // Sequence uint8 3 bytes
1442 0x19,
1443 0x01,
1444 0x00, // UUID: Protocol: L2CAP
1445 0x00,
1446 0x0A, // MaximumAttributeByteCount (10 bytes max)
1447 // AttributeIDList
1448 0x35,
1449 0x08, // Sequence uint8 8 bytes
1450 0x09, // uint16_t, single attribute
1451 0x00,
1452 0x00, // ServiceRecordHandle
1453 0x0A, // uint32_t, which is a range (0x3000 - 0xf000)
1454 0x30,
1455 0x00, // low end of range
1456 0xf0,
1457 0x00, // high end of range
1458 0x00 // Continuation State: none
1459 );
1460
1461 size_t received = 0;
1462
1463 ServiceSearchAttributeResponse rsp;
1464
1465 auto send_cb = [this, &rsp, &received](auto cb_packet) {
1466 EXPECT_LE(sizeof(Header), cb_packet->size());
1467 PacketView<sdp::Header> packet(cb_packet.get());
1468 ASSERT_EQ(0x07, packet.header().pdu_id);
1469 uint16_t len = be16toh(packet.header().param_length);
1470 EXPECT_LE(len, 0x11); // 2 (byte count) + 10 (max len) + 5 (cont state)
1471 packet.Resize(len);
1472 fit::result<Error<>> result = rsp.Parse(packet.payload_data());
1473 if (received == 0) {
1474 // Server should have split this into more than one response.
1475 EXPECT_EQ(ToResult(HostError::kInProgress), result);
1476 EXPECT_FALSE(rsp.complete());
1477 }
1478 received++;
1479 if (result.is_error() && !result.error_value().is(HostError::kInProgress)) {
1480 // This isn't a valid packet and we shouldn't try to get
1481 // a continuation.
1482 return;
1483 }
1484 if (!rsp.complete()) {
1485 // Repeat the request with the continuation state if it was returned.
1486 auto continuation = rsp.ContinuationState();
1487 uint8_t cont_size = continuation.size();
1488 EXPECT_NE(0u, cont_size);
1489 // Make another request with the continuation data.
1490 size_t param_size = 18 + cont_size;
1491 auto kContinuedRequestAttrStart = StaticByteBuffer(
1492 0x06, // SDP_ServiceAttributeRequest
1493 0x10,
1494 static_cast<uint8_t>(received + 1), // Transaction ID
1495 UpperBits(param_size),
1496 LowerBits(param_size), // Parameter length
1497 0x35,
1498 0x03, // Sequence uint8 3 bytes
1499 0x19,
1500 0x01,
1501 0x00, // SearchPattern: L2CAP
1502 0x00,
1503 0x0A, // MaximumAttributeByteCount (10 bytes max)
1504 // AttributeIDList
1505 0x35,
1506 0x08, // Sequence uint8 8 bytes
1507 0x09, // uint16_t, single attribute
1508 0x00,
1509 0x00, // ServiceRecordHandle
1510 0x0A, // uint32_t, which is a range (0x3000 - 0xf000)
1511 0x30,
1512 0x00, // low end of range
1513 0xf0,
1514 0x00 // high end of range
1515 );
1516 DynamicByteBuffer req(kContinuedRequestAttrStart.size() +
1517 sizeof(uint8_t) + cont_size);
1518
1519 kContinuedRequestAttrStart.Copy(&req);
1520 req.Write(&cont_size, sizeof(uint8_t), kContinuedRequestAttrStart.size());
1521 req.Write(continuation,
1522 kContinuedRequestAttrStart.size() + sizeof(uint8_t));
1523
1524 fake_chan()->Receive(req);
1525 }
1526 };
1527
1528 fake_chan()->SetSendCallback(send_cb, dispatcher());
1529 fake_chan()->Receive(kRequestAttr);
1530 RunUntilIdle();
1531
1532 EXPECT_GE(received, 1u);
1533 // We should receive both of our entered records.
1534 EXPECT_EQ(2u, rsp.num_attribute_lists());
1535 for (size_t i = 0; i < rsp.num_attribute_lists(); i++) {
1536 const auto& attrs = rsp.attributes(i);
1537 // Every service has a record handle
1538 auto handle_it = attrs.find(kServiceRecordHandle);
1539 EXPECT_NE(attrs.end(), handle_it);
1540 ServiceHandle received_handle = *handle_it->second.Get<uint32_t>();
1541 if (received_handle == handle1) {
1542 // The first service also has another attribute we should find.
1543 EXPECT_EQ(2u, attrs.size());
1544 EXPECT_NE(attrs.end(), attrs.find(0xf000));
1545 }
1546 }
1547
1548 const auto kInvalidRangeOrder =
1549 StaticByteBuffer(0x06, // SDP_ServiceAttributeRequest
1550 0xE0,
1551 0x01, // Transaction ID (0xE001)
1552 0x00,
1553 0x12, // Parameter length (18 bytes)
1554 0x35,
1555 0x03,
1556 0x19,
1557 0x01,
1558 0x00, // SearchPattern: L2CAP
1559 0x00,
1560 0x0A, // MaximumAttributeByteCount (10 bytes max)
1561 // AttributeIDList
1562 0x35,
1563 0x08, // Sequence uint8 8 bytes
1564 0x09, // uint16_t, single attribute
1565 0x00,
1566 0x01, // ServiceClassIDList
1567 0x0A, // uint32_t, which is a range (0x3000 - 0xf000)
1568 0xf0,
1569 0x00, // low end of range
1570 0x30,
1571 0x00, // high end of range
1572 0x00 // Continuation State: none
1573 );
1574
1575 const auto kRspErrSyntax =
1576 SDP_ERROR_RSP(0xE001, ErrorCode::kInvalidRequestSyntax);
1577
1578 EXPECT_TRUE(ReceiveAndExpect(kInvalidRangeOrder, kRspErrSyntax));
1579
1580 const auto kInvalidMaxBytes =
1581 StaticByteBuffer(0x04, // SDP_ServiceAttributeRequest
1582 0xE0,
1583 0x02, // Transaction ID (0xE002)
1584 0x00,
1585 0x0D, // Parameter length (13 bytes)
1586 0x35,
1587 0x03,
1588 0x19,
1589 0x01,
1590 0x00, // SearchPattern: L2CAP
1591 0x00,
1592 0x05, // MaximumAttributeByteCount (5 bytes max)
1593 // AttributeIDList
1594 0x35,
1595 0x03, // Sequence uint8 3 bytes
1596 0x09, // uint16_t, single attribute
1597 0x00,
1598 0x01, // ServiceClassIDList
1599 0x00 // Continuation State: none
1600 );
1601
1602 const auto kRspErrSyntax2 =
1603 SDP_ERROR_RSP(0xE002, ErrorCode::kInvalidRequestSyntax);
1604
1605 EXPECT_TRUE(ReceiveAndExpect(kInvalidMaxBytes, kRspErrSyntax2));
1606 }
1607
TEST_F(ServerTest,ConnectionCallbacks)1608 TEST_F(ServerTest, ConnectionCallbacks) {
1609 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
1610 kTestHandle1, l2cap::kSDP, kSdpChannel, 0x0bad));
1611 RunUntilIdle();
1612
1613 std::vector<l2cap::Channel::WeakPtr> channels;
1614 hci_spec::ConnectionHandle latest_handle;
1615
1616 // Register a service
1617 AddA2DPSink([&channels, &latest_handle](l2cap::Channel::WeakPtr chan,
1618 const auto& protocol) {
1619 bt_log(TRACE, "test", "Got channel for the a2dp sink");
1620 latest_handle = chan->link_handle();
1621 channels.emplace_back(std::move(chan));
1622 });
1623
1624 // Connect to the service
1625 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
1626 kTestHandle1, l2cap::kAVDTP, kSdpChannel + 1, 0x0b00));
1627 RunUntilIdle();
1628
1629 // It should get a callback with a channel
1630 EXPECT_EQ(1u, channels.size());
1631 EXPECT_EQ(kTestHandle1, latest_handle);
1632
1633 // Connect to the same service again with the same PSM (on a different
1634 // connection, it should still work)
1635 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
1636 kTestHandle2, l2cap::kAVDTP, kSdpChannel + 2, 0x0b01));
1637 RunUntilIdle();
1638
1639 ASSERT_EQ(2u, channels.size());
1640 EXPECT_EQ(kTestHandle2, latest_handle);
1641 EXPECT_NE(&channels.front().get(), &channels.back().get());
1642
1643 // Connect to the service again, on the first connection.
1644 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
1645 kTestHandle1, l2cap::kAVDTP, kSdpChannel + 3, 0x0b00));
1646 RunUntilIdle();
1647
1648 // It should get a callback with a channel
1649 EXPECT_EQ(3u, channels.size());
1650 EXPECT_EQ(kTestHandle1, latest_handle);
1651 }
1652
1653 // Browse Group gets set correctly
TEST_F(ServerTest,BrowseGroup)1654 TEST_F(ServerTest, BrowseGroup) {
1655 AddA2DPSink();
1656
1657 EXPECT_TRUE(l2cap()->TriggerInboundL2capChannel(
1658 kTestHandle1, l2cap::kSDP, kSdpChannel, 0x0bad));
1659 RunUntilIdle();
1660
1661 const auto kRequestAttr =
1662 StaticByteBuffer(0x06, // SDP_ServiceAttributeRequest
1663 0x10,
1664 0x01, // Transaction ID (0x1001)
1665 0x00,
1666 0x0D, // Parameter length (12 bytes)
1667 // ServiceSearchPattern
1668 0x35,
1669 0x03, // Sequence uint8 3 bytes
1670 0x19,
1671 0x01,
1672 0x00, // UUID: Protocol: L2CAP
1673 0xFF,
1674 0xFF, // MaximumAttributeByteCount (no max)
1675 // AttributeIDList
1676 0x35,
1677 0x03, // Sequence uint8 3 bytes
1678 0x09, // uint16_t, single attribute
1679 0x00,
1680 0x05, // BrowseGroupList
1681 0x00 // Continuation State: none
1682 );
1683
1684 ServiceSearchAttributeResponse rsp;
1685 auto send_cb = [&rsp](auto cb_packet) {
1686 EXPECT_LE(sizeof(Header), cb_packet->size());
1687 PacketView<sdp::Header> packet(cb_packet.get());
1688 ASSERT_EQ(0x07, packet.header().pdu_id);
1689 uint16_t len = be16toh(packet.header().param_length);
1690 packet.Resize(len);
1691 auto status = rsp.Parse(packet.payload_data());
1692 EXPECT_EQ(fit::ok(), status);
1693 };
1694
1695 fake_chan()->SetSendCallback(send_cb, dispatcher());
1696 fake_chan()->Receive(kRequestAttr);
1697 RunUntilIdle();
1698
1699 EXPECT_EQ(1u, rsp.num_attribute_lists());
1700 auto& attributes = rsp.attributes(0);
1701 auto group_attr_it = attributes.find(kBrowseGroupList);
1702 ASSERT_EQ(DataElement::Type::kSequence, group_attr_it->second.type());
1703 ASSERT_EQ(DataElement::Type::kUuid, group_attr_it->second.At(0)->type());
1704 EXPECT_NE(attributes.end(), group_attr_it);
1705 EXPECT_EQ(kPublicBrowseRootUuid, *group_attr_it->second.At(0)->Get<UUID>());
1706 }
1707
1708 // Channels created for a service registered with channel parameters should be
1709 // configured with that service's channel parameters.
TEST_F(ServerTest,RegisterServiceWithChannelParameters)1710 TEST_F(ServerTest, RegisterServiceWithChannelParameters) {
1711 l2cap::Psm kPsm = l2cap::kAVDTP;
1712
1713 l2cap::ChannelParameters preferred_params;
1714 preferred_params.mode =
1715 l2cap::RetransmissionAndFlowControlMode::kEnhancedRetransmission;
1716 preferred_params.max_rx_sdu_size = l2cap::kMinACLMTU;
1717
1718 std::optional<l2cap::ChannelInfo> params;
1719 size_t chan_cb_count = 0;
1720 ASSERT_TRUE(AddL2capService(
1721 kPsm, preferred_params, [&](auto chan, auto& /*protocol*/) {
1722 chan_cb_count++;
1723 params = chan->info();
1724 }));
1725
1726 EXPECT_TRUE(
1727 l2cap()->TriggerInboundL2capChannel(kTestHandle1, kPsm, 0x40, 0x41));
1728 RunUntilIdle();
1729 EXPECT_EQ(1u, chan_cb_count);
1730 ASSERT_TRUE(params);
1731 EXPECT_EQ(*preferred_params.mode, params->mode);
1732 EXPECT_EQ(*preferred_params.max_rx_sdu_size, params->max_rx_sdu_size);
1733 }
1734
1735 // Test:
1736 // - Creation of ServiceDiscoveryService is valid.
TEST_F(ServerTest,MakeServiceDiscoveryServiceIsValid)1737 TEST_F(ServerTest, MakeServiceDiscoveryServiceIsValid) {
1738 auto sdp_def = server()->MakeServiceDiscoveryService();
1739
1740 const DataElement& version_number_list =
1741 sdp_def.GetAttribute(kSDP_VersionNumberList);
1742 EXPECT_EQ(DataElement::Type::kSequence, version_number_list.type());
1743
1744 auto* it = version_number_list.At(0);
1745 EXPECT_EQ(DataElement::Type::kUnsignedInt, it->type());
1746 EXPECT_EQ(0x0100u, it->Get<uint16_t>());
1747 }
1748
1749 #ifndef NINSPECT
1750 // Test:
1751 // - The inspect hierarchy for the initial server is valid. It should
1752 // only contain the registered PSM for SDP.
TEST_F(ServerTest,InspectHierarchy)1753 TEST_F(ServerTest, InspectHierarchy) {
1754 inspect::Inspector inspector;
1755 server()->AttachInspect(inspector.GetRoot());
1756
1757 auto psm_matcher = AllOf(NodeMatches(
1758 AllOf(NameMatches("psm0x1"),
1759 PropertyList(UnorderedElementsAre(StringIs("psm", "SDP"))))));
1760 auto reg_psm_matcher =
1761 AllOf(NodeMatches(AllOf(NameMatches("registered_psms"))),
1762 ChildrenMatch(UnorderedElementsAre(psm_matcher)));
1763
1764 auto record_matcher = AllOf(
1765 NodeMatches(AllOf(NameMatches("record0x0"),
1766 PropertyList(UnorderedElementsAre(StringIs(
1767 "record",
1768 "Service Class Id List: Sequence { "
1769 "UUID(00001000-0000-1000-8000-00805f9b34fb) }"))))),
1770 ChildrenMatch(UnorderedElementsAre(reg_psm_matcher)));
1771
1772 auto sdp_matcher = AllOf(NodeMatches(AllOf(NameMatches("sdp_server"))),
1773 ChildrenMatch(UnorderedElementsAre(record_matcher)));
1774
1775 auto hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
1776 ASSERT_TRUE(hierarchy);
1777 EXPECT_THAT(hierarchy.take_value(),
1778 AllOf(NodeMatches(NameMatches("root")),
1779 ChildrenMatch(UnorderedElementsAre(sdp_matcher))));
1780 }
1781 #endif // NINSPECT
1782
1783 #ifndef NINSPECT
1784 // Test:
1785 // - The inspect hierarchy is updated correctly after registering another
1786 // service.
1787 // - The inspect hierarchy is updated correctly after unregistering a service.
1788 // Note: None of the matchers test the name of the node. This is because the
1789 // ordering of the std::unordered_map of PSMs is not guaranteed. Asserting on
1790 // the name of the node is not feasible due to the usage of inspect::UniqueName,
1791 // which assigns a new name to a node in every call. The contents of the node
1792 // are verified.
TEST_F(ServerTest,InspectHierarchyAfterUnregisterService)1793 TEST_F(ServerTest, InspectHierarchyAfterUnregisterService) {
1794 inspect::Inspector inspector;
1795 server()->AttachInspect(inspector.GetRoot());
1796
1797 auto handle = AddA2DPSink();
1798
1799 auto sdp_psm_matcher = AllOf(NodeMatches(
1800 AllOf(PropertyList(UnorderedElementsAre(StringIs("psm", "SDP"))))));
1801 auto sdp_matcher =
1802 AllOf(NodeMatches(AllOf(NameMatches("registered_psms"))),
1803 ChildrenMatch(UnorderedElementsAre(sdp_psm_matcher)));
1804
1805 auto a2dp_psm_matcher = AllOf(NodeMatches(
1806 AllOf(PropertyList(UnorderedElementsAre(StringIs("psm", "AVDTP"))))));
1807 auto a2dp_matcher =
1808 AllOf(NodeMatches(AllOf(NameMatches("registered_psms"))),
1809 ChildrenMatch(UnorderedElementsAre(a2dp_psm_matcher)));
1810
1811 auto sdp_record_matcher =
1812 AllOf(NodeMatches(AllOf(PropertyList(UnorderedElementsAre(
1813 StringIs("record",
1814 "Service Class Id List: Sequence { "
1815 "UUID(00001000-0000-1000-8000-00805f9b34fb) }"))))),
1816 ChildrenMatch(UnorderedElementsAre(sdp_matcher)));
1817 auto a2dp_record_matcher =
1818 AllOf(NodeMatches(AllOf(PropertyList(UnorderedElementsAre(
1819 StringIs("record",
1820 "Profile Descriptor: Sequence { Sequence { "
1821 "UUID(0000110d-0000-1000-8000-00805f9b34fb) "
1822 "UnsignedInt:2(259) } }\nService Class "
1823 "Id List: Sequence { "
1824 "UUID(0000110b-0000-1000-8000-00805f9b34fb) }"))))),
1825 ChildrenMatch(UnorderedElementsAre(a2dp_matcher)));
1826
1827 auto sdp_server_matcher =
1828 AllOf(NodeMatches(AllOf(NameMatches("sdp_server"))),
1829 ChildrenMatch(
1830 UnorderedElementsAre(sdp_record_matcher, a2dp_record_matcher)));
1831
1832 // Hierarchy should contain ServiceRecords and PSMs for SDP and A2DP Sink.
1833 auto hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo());
1834 ASSERT_TRUE(hierarchy);
1835 EXPECT_THAT(hierarchy.take_value(),
1836 AllOf(NodeMatches(NameMatches("root")),
1837 ChildrenMatch(UnorderedElementsAre(sdp_server_matcher))));
1838
1839 // Unregister the A2DP Sink service.
1840 EXPECT_TRUE(server()->UnregisterService(handle));
1841
1842 auto sdp_server_matcher2 =
1843 AllOf(NodeMatches(AllOf(NameMatches("sdp_server"))),
1844 ChildrenMatch(UnorderedElementsAre(sdp_record_matcher)));
1845
1846 // The ServiceRecords and PSMs associated with A2DP Sink should be removed
1847 // after the service has been registered. Only SDP's data should still exist.
1848 auto hierarchy2 = inspect::ReadFromVmo(inspector.DuplicateVmo());
1849 ASSERT_TRUE(hierarchy2);
1850 EXPECT_THAT(hierarchy2.take_value(),
1851 AllOf(NodeMatches(NameMatches("root")),
1852 ChildrenMatch(UnorderedElementsAre(sdp_server_matcher2))));
1853 }
1854 #endif // NINSPECT
1855
1856 // Test:
1857 // Server::HandleRequest() provides expected responses when called without
1858 // a corresponding l2cap::channel for both successful requests and errors.
TEST_F(ServerTest,HandleRequestWithoutChannel)1859 TEST_F(ServerTest, HandleRequestWithoutChannel) {
1860 const auto kRspErrSize = SDP_ERROR_RSP(0x1001, ErrorCode::kInvalidSize);
1861 const StaticByteBuffer kTooSmall(0x01, // SDP_ServiceSearchRequest
1862 0x10,
1863 0x01, // Transaction ID (0x1001)
1864 0x00,
1865 0x09 // Parameter length (9 bytes)
1866 );
1867 const auto kRspTooSmall = SDP_ERROR_RSP(0x1001, ErrorCode::kInvalidSize);
1868 auto too_small_rsp = server()->HandleRequest(
1869 std::unique_ptr<ByteBuffer>(new StaticByteBuffer(kTooSmall)),
1870 l2cap::kDefaultMTU);
1871 EXPECT_TRUE(ContainersEqual(*too_small_rsp.value(), kRspTooSmall));
1872
1873 RegistrationHandle spp_handle = AddSPP();
1874 RegistrationHandle a2dp_handle = AddA2DPSink();
1875 const StaticByteBuffer kL2capSearch(
1876 0x02, // SDP_ServiceSearchRequest
1877 0x10,
1878 0x01, // Transaction ID (0x1001)
1879 0x00,
1880 0x08, // Parameter length (8 bytes)
1881 // ServiceSearchPattern
1882 0x35,
1883 0x03, // Sequence uint8 3 bytes
1884 0x19,
1885 0x01,
1886 0x00, // UUID: Protocol: L2CAP
1887 0xFF,
1888 0xFF, // MaximumServiceRecordCount: (none)
1889 0x00 // Continuation State: none
1890 );
1891 const StaticByteBuffer kL2capSearchResponse(
1892 0x03, // SDP_ServicesearchResponse
1893 0x10,
1894 0x01, // Transaction ID (0x1001)
1895 0x00,
1896 0x0D, // Parameter length (13 bytes)
1897 0x00,
1898 0x02, // Total service record count: 2
1899 0x00,
1900 0x02, // Current service record count: 2
1901 UINT32_AS_BE_BYTES(a2dp_handle), // This list isn't specifically ordered
1902 UINT32_AS_BE_BYTES(spp_handle),
1903 0x00 // No continuation state
1904 );
1905 auto search_rsp = server()->HandleRequest(
1906 std::unique_ptr<ByteBuffer>(new StaticByteBuffer(kL2capSearch)),
1907 l2cap::kDefaultMTU);
1908 EXPECT_TRUE(ContainersEqual(*search_rsp.value(), kL2capSearchResponse));
1909 }
1910
1911 #undef SDP_ERROR_RSP
1912 #undef UINT32_AS_LE_BYTES
1913
1914 } // namespace
1915 } // namespace bt::sdp
1916