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