1 // Copyright 2024 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/fuchsia/host/fidl/helpers.h"
16
17 #include <gmock/gmock.h>
18 #include <pw_async/dispatcher.h>
19
20 #include <algorithm>
21 #include <iterator>
22
23 #include "fuchsia/bluetooth/bredr/cpp/fidl.h"
24 #include "fuchsia/bluetooth/cpp/fidl.h"
25 #include "fuchsia/bluetooth/le/cpp/fidl.h"
26 #include "fuchsia/bluetooth/sys/cpp/fidl.h"
27 #include "fuchsia/media/cpp/fidl.h"
28 #include "lib/fidl/cpp/comparison.h"
29 #include "pw_bluetooth_sapphire/fuchsia/host/fidl/adapter_test_fixture.h"
30 #include "pw_bluetooth_sapphire/fuchsia/host/fidl/fake_adapter_test_fixture.h"
31 #include "pw_bluetooth_sapphire/internal/host/common/advertising_data.h"
32 #include "pw_bluetooth_sapphire/internal/host/common/device_address.h"
33 #include "pw_bluetooth_sapphire/internal/host/common/uuid.h"
34 #include "pw_bluetooth_sapphire/internal/host/gap/gap.h"
35 #include "pw_bluetooth_sapphire/internal/host/iso/iso_common.h"
36 #include "pw_bluetooth_sapphire/internal/host/sco/sco.h"
37 #include "pw_bluetooth_sapphire/internal/host/sdp/data_element.h"
38 #include "pw_bluetooth_sapphire/internal/host/sdp/sdp.h"
39 #include "pw_bluetooth_sapphire/internal/host/sdp/service_record.h"
40 #include "pw_bluetooth_sapphire/internal/host/sm/types.h"
41 #include "pw_bluetooth_sapphire/internal/host/testing/loop_fixture.h"
42 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
43 #include "pw_unit_test/framework.h"
44
45 namespace fble = fuchsia::bluetooth::le;
46 namespace fbt = fuchsia::bluetooth;
47 namespace fsys = fuchsia::bluetooth::sys;
48 namespace fbg = fuchsia::bluetooth::gatt;
49 namespace fbg2 = fuchsia::bluetooth::gatt2;
50 namespace fbredr = fuchsia::bluetooth::bredr;
51 namespace faudio = fuchsia::hardware::audio;
52
53 namespace fuchsia::bluetooth {
54 // Make UUIDs equality comparable for advanced testing matchers. ADL rules
55 // mandate the namespace.
operator ==(const Uuid & a,const Uuid & b)56 bool operator==(const Uuid& a, const Uuid& b) { return fidl::Equals(a, b); }
57 } // namespace fuchsia::bluetooth
58
59 namespace bthost::fidl_helpers {
60 namespace {
61
62 // Constants as BT stack types
63 const bt::UInt128 kTestKeyValue{
64 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
65 const bt::sm::SecurityProperties kTestSecurity(
66 bt::sm::SecurityLevel::kSecureAuthenticated,
67 16,
68 /*secure_connections=*/true);
69 const bt::sm::LTK kTestLtk(kTestSecurity,
70 bt::hci_spec::LinkKey(kTestKeyValue, 0, 0));
71 const bt::sm::Key kTestKey(kTestSecurity, kTestKeyValue);
72
73 // Constants as FIDL types
74 const fbt::Address kPublicAddrFidl =
75 fbt::Address{fbt::AddressType::PUBLIC, {1, 0, 0, 0, 0, 0}};
76 const fbt::Address kRandomAddrFidl =
77 fbt::Address{fbt::AddressType::RANDOM, {2, 0, 0, 0, 0, 0b11000011}};
78 const fbt::Address kRandomAddrResolvableFidl{
79 fbt::AddressType::RANDOM, {0x55, 0x44, 0x33, 0x22, 0x11, 0b01000011}};
80 const fbt::Address kRandomAddrNonResolvableFidl{
81 fbt::AddressType::RANDOM, {0x55, 0x44, 0x33, 0x22, 0x11, 0x00}};
82
83 const bt::DeviceAddress kTestPeerAddr(bt::DeviceAddress::Type::kBREDR,
84 {1, 0, 0, 0, 0, 0});
85 const bt::DeviceAddress kLePublicAddress(bt::DeviceAddress::Type::kLEPublic,
86 {1, 0, 0, 0, 0, 0});
87
88 const fsys::PeerKey kTestKeyFidl{
89 .security =
90 fsys::SecurityProperties{
91 .authenticated = true,
92 .secure_connections = true,
93 .encryption_key_size = 16,
94 },
95 .data = fsys::Key{.value = kTestKeyValue},
96 };
97 const fsys::Ltk kTestLtkFidl{.key = kTestKeyFidl, .ediv = 0, .rand = 0};
98
99 // Minimum values permitted for the CIS_ESTABLISHED unidirectional parameters
100 bt::iso::CisEstablishedParameters::CisUnidirectionalParams kMinUniParams = {
101 .transport_latency = 0x0000ea,
102 .phy = pw::bluetooth::emboss::IsoPhyType::LE_1M,
103 .burst_number = 0x01,
104 .flush_timeout = 0x01,
105 .max_pdu_size = 0x00,
106 };
107
108 // Maximum values permitted for the CIS_ESTABLISHED unidirectional parameters
109 bt::iso::CisEstablishedParameters::CisUnidirectionalParams kMaxUniParams = {
110 .transport_latency = 0x7fffff,
111 .phy = pw::bluetooth::emboss::IsoPhyType::LE_CODED,
112 .burst_number = 0x0f,
113 .flush_timeout = 0xff,
114 .max_pdu_size = 0xfb,
115 };
116
117 class HelpersTestWithLoop : public bt::testing::TestLoopFixture {
118 public:
pw_dispatcher()119 pw::async::Dispatcher& pw_dispatcher() { return pw_dispatcher_; }
120
121 private:
122 pw::async_fuchsia::FuchsiaDispatcher pw_dispatcher_{dispatcher()};
123 };
124
TEST(HelpersTest,HostErrorToFidl)125 TEST(HelpersTest, HostErrorToFidl) {
126 EXPECT_EQ(fsys::Error::FAILED, HostErrorToFidl(bt::HostError::kFailed));
127 EXPECT_EQ(fsys::Error::TIMED_OUT, HostErrorToFidl(bt::HostError::kTimedOut));
128 EXPECT_EQ(fsys::Error::INVALID_ARGUMENTS,
129 HostErrorToFidl(bt::HostError::kInvalidParameters));
130 EXPECT_EQ(fsys::Error::CANCELED, HostErrorToFidl(bt::HostError::kCanceled));
131 EXPECT_EQ(fsys::Error::IN_PROGRESS,
132 HostErrorToFidl(bt::HostError::kInProgress));
133 EXPECT_EQ(fsys::Error::NOT_SUPPORTED,
134 HostErrorToFidl(bt::HostError::kNotSupported));
135 EXPECT_EQ(fsys::Error::PEER_NOT_FOUND,
136 HostErrorToFidl(bt::HostError::kNotFound));
137
138 // All other errors currently map to FAILED.
139 EXPECT_EQ(fsys::Error::FAILED, HostErrorToFidl(bt::HostError::kNotReady));
140 }
141
TEST(HelpersTest,GattErrorToFidl)142 TEST(HelpersTest, GattErrorToFidl) {
143 // Host errors
144 EXPECT_EQ(fbg::Error::INVALID_RESPONSE,
145 GattErrorToFidl(bt::Error(bt::HostError::kPacketMalformed)));
146 EXPECT_EQ(fbg::Error::FAILURE,
147 GattErrorToFidl(bt::Error(bt::HostError::kTimedOut)));
148
149 // Protocol errors
150 EXPECT_EQ(fbg::Error::INSUFFICIENT_AUTHORIZATION,
151 GattErrorToFidl(bt::att::Error(
152 bt::att::ErrorCode::kInsufficientAuthorization)));
153 EXPECT_EQ(fbg::Error::INSUFFICIENT_AUTHENTICATION,
154 GattErrorToFidl(bt::att::Error(
155 bt::att::ErrorCode::kInsufficientAuthentication)));
156 EXPECT_EQ(fbg::Error::INSUFFICIENT_ENCRYPTION_KEY_SIZE,
157 GattErrorToFidl(bt::att::Error(
158 bt::att::ErrorCode::kInsufficientEncryptionKeySize)));
159 EXPECT_EQ(fbg::Error::INSUFFICIENT_ENCRYPTION,
160 GattErrorToFidl(
161 bt::att::Error(bt::att::ErrorCode::kInsufficientEncryption)));
162 EXPECT_EQ(
163 fbg::Error::READ_NOT_PERMITTED,
164 GattErrorToFidl(bt::att::Error(bt::att::ErrorCode::kReadNotPermitted)));
165 EXPECT_EQ(
166 fbg::Error::FAILURE,
167 GattErrorToFidl(bt::att::Error(bt::att::ErrorCode::kUnlikelyError)));
168 }
169
TEST(HelpersTest,AttErrorToGattFidlError)170 TEST(HelpersTest, AttErrorToGattFidlError) {
171 // Host errors
172 EXPECT_EQ(
173 fbg2::Error::INVALID_PDU,
174 AttErrorToGattFidlError(bt::Error(bt::HostError::kPacketMalformed)));
175 EXPECT_EQ(
176 fbg2::Error::INVALID_PARAMETERS,
177 AttErrorToGattFidlError(bt::Error(bt::HostError::kInvalidParameters)));
178 EXPECT_EQ(fbg2::Error::UNLIKELY_ERROR,
179 AttErrorToGattFidlError(bt::Error(bt::HostError::kTimedOut)));
180
181 // Protocol errors
182 EXPECT_EQ(fbg2::Error::INSUFFICIENT_AUTHORIZATION,
183 AttErrorToGattFidlError(bt::att::Error(
184 bt::att::ErrorCode::kInsufficientAuthorization)));
185 EXPECT_EQ(fbg2::Error::INSUFFICIENT_AUTHENTICATION,
186 AttErrorToGattFidlError(bt::att::Error(
187 bt::att::ErrorCode::kInsufficientAuthentication)));
188 EXPECT_EQ(fbg2::Error::INSUFFICIENT_ENCRYPTION_KEY_SIZE,
189 AttErrorToGattFidlError(bt::att::Error(
190 bt::att::ErrorCode::kInsufficientEncryptionKeySize)));
191 EXPECT_EQ(fbg2::Error::INSUFFICIENT_ENCRYPTION,
192 AttErrorToGattFidlError(
193 bt::att::Error(bt::att::ErrorCode::kInsufficientEncryption)));
194 EXPECT_EQ(fbg2::Error::READ_NOT_PERMITTED,
195 AttErrorToGattFidlError(
196 bt::att::Error(bt::att::ErrorCode::kReadNotPermitted)));
197 EXPECT_EQ(fbg2::Error::INVALID_HANDLE,
198 AttErrorToGattFidlError(
199 bt::att::Error(bt::att::ErrorCode::kInvalidHandle)));
200 EXPECT_EQ(fbg2::Error::UNLIKELY_ERROR,
201 AttErrorToGattFidlError(
202 bt::att::Error(bt::att::ErrorCode::kUnlikelyError)));
203 }
204
TEST(HelpersTest,AdvertisingIntervalFromFidl)205 TEST(HelpersTest, AdvertisingIntervalFromFidl) {
206 EXPECT_EQ(bt::gap::AdvertisingInterval::FAST1,
207 AdvertisingIntervalFromFidl(fble::AdvertisingModeHint::VERY_FAST));
208 EXPECT_EQ(bt::gap::AdvertisingInterval::FAST2,
209 AdvertisingIntervalFromFidl(fble::AdvertisingModeHint::FAST));
210 EXPECT_EQ(bt::gap::AdvertisingInterval::SLOW,
211 AdvertisingIntervalFromFidl(fble::AdvertisingModeHint::SLOW));
212 }
213
TEST(HelpersTest,UuidFromFidl)214 TEST(HelpersTest, UuidFromFidl) {
215 // Test HLCPP FIDL bindings with fuchsia::bluetooth::Uuid
216 fbt::Uuid input;
217 input.value = {{0xFB,
218 0x34,
219 0x9B,
220 0x5F,
221 0x80,
222 0x00,
223 0x00,
224 0x80,
225 0x00,
226 0x10,
227 0x00,
228 0x00,
229 0x0d,
230 0x18,
231 0x00,
232 0x00}};
233
234 // We expect the input bytes to be carried over directly.
235 bt::UUID output = UuidFromFidl(input);
236 EXPECT_EQ("0000180d-0000-1000-8000-00805f9b34fb", output.ToString());
237 EXPECT_EQ(2u, output.CompactSize());
238
239 // Test new C++ FIDL bindings with fuchsia_bluetooth::Uuid
240 fuchsia_bluetooth::Uuid input2;
241 input2.value({0xFB,
242 0x34,
243 0x9B,
244 0x5F,
245 0x80,
246 0x00,
247 0x00,
248 0x80,
249 0x00,
250 0x10,
251 0x00,
252 0x00,
253 0x0d,
254 0x18,
255 0x00,
256 0x00});
257
258 // We expect the input bytes to be carried over directly.
259 output = NewUuidFromFidl(input2);
260 EXPECT_EQ("0000180d-0000-1000-8000-00805f9b34fb", output.ToString());
261 EXPECT_EQ(2u, output.CompactSize());
262 }
263
TEST(HelpersTest,FidlToScmsTEnableTest)264 TEST(HelpersTest, FidlToScmsTEnableTest) {
265 bt::StaticPacket<android_emb::A2dpScmsTEnableWriter> result_enable =
266 FidlToScmsTEnable(true);
267 EXPECT_EQ(result_enable.view().enabled().Read(),
268 pw::bluetooth::emboss::GenericEnableParam::ENABLE);
269 EXPECT_EQ(result_enable.view().header().Read(), 0x0);
270
271 bt::StaticPacket<android_emb::A2dpScmsTEnableWriter> result_disable =
272 FidlToScmsTEnable(false);
273 EXPECT_EQ(result_disable.view().enabled().Read(),
274 pw::bluetooth::emboss::GenericEnableParam::DISABLE);
275 EXPECT_EQ(result_disable.view().header().Read(), 0x0);
276 }
277
TEST(HelpersTest,FidlToEncoderSettingsSbcTest)278 TEST(HelpersTest, FidlToEncoderSettingsSbcTest) {
279 std::unique_ptr<fbredr::AudioEncoderSettings> encoder_settings =
280 std::make_unique<fbredr::AudioEncoderSettings>();
281 std::unique_ptr<fuchsia::media::SbcEncoderSettings> value =
282 fuchsia::media::SbcEncoderSettings::New();
283 encoder_settings->set_sbc(*value);
284
285 fbredr::AudioSamplingFrequency sampling_frequency =
286 fbredr::AudioSamplingFrequency::HZ_44100;
287 fbredr::AudioChannelMode channel_mode = fbredr::AudioChannelMode::MONO;
288
289 bt::StaticPacket<android_emb::SbcCodecInformationWriter> result =
290 FidlToEncoderSettingsSbc(
291 *encoder_settings, sampling_frequency, channel_mode);
292
293 EXPECT_EQ(android_emb::SbcAllocationMethod::LOUDNESS,
294 result.view().allocation_method().Read());
295 EXPECT_EQ(android_emb::SbcSubBands::SUBBANDS_8,
296 result.view().subbands().Read());
297 EXPECT_EQ(android_emb::SbcBlockLen::BLOCK_LEN_4,
298 result.view().block_length().Read());
299 EXPECT_EQ(0, result.view().min_bitpool_value().Read());
300 EXPECT_EQ(0, result.view().max_bitpool_value().Read());
301 EXPECT_EQ(android_emb::SbcSamplingFrequency::HZ_44100,
302 result.view().sampling_frequency().Read());
303 EXPECT_EQ(android_emb::SbcChannelMode::MONO,
304 result.view().channel_mode().Read());
305 }
306
TEST(HelpersTest,FidlToEncoderSettingsAacTest)307 TEST(HelpersTest, FidlToEncoderSettingsAacTest) {
308 std::unique_ptr<fbredr::AudioEncoderSettings> encoder_settings =
309 std::make_unique<fbredr::AudioEncoderSettings>();
310 std::unique_ptr<fuchsia::media::AacEncoderSettings> value =
311 fuchsia::media::AacEncoderSettings::New();
312 value->aot = fuchsia::media::AacAudioObjectType::MPEG4_AAC_LC;
313 value->bit_rate.set_variable(::fuchsia::media::AacVariableBitRate::V1);
314 encoder_settings->set_aac(std::move(*value));
315
316 fbredr::AudioSamplingFrequency sampling_frequency =
317 fbredr::AudioSamplingFrequency::HZ_44100;
318 fbredr::AudioChannelMode channel_mode = fbredr::AudioChannelMode::MONO;
319
320 bt::StaticPacket<android_emb::AacCodecInformationWriter> result =
321 FidlToEncoderSettingsAac(
322 *encoder_settings, sampling_frequency, channel_mode);
323
324 EXPECT_EQ(result.view().object_type().Read(), 1);
325 EXPECT_EQ(result.view().variable_bit_rate().Read(),
326 android_emb::AacEnableVariableBitRate::ENABLE);
327 }
328
329 template <typename T>
FidlToDataElementIntegerTest(const std::function<fbredr::DataElement (T &&)> & func,bt::sdp::DataElement::Type type)330 void FidlToDataElementIntegerTest(
331 const std::function<fbredr::DataElement(T&&)>& func,
332 bt::sdp::DataElement::Type type) {
333 fbredr::DataElement data_element = func(std::numeric_limits<T>::max());
334 std::optional<bt::sdp::DataElement> result = FidlToDataElement(data_element);
335 ASSERT_TRUE(result.has_value());
336 EXPECT_EQ(type, result->type());
337 EXPECT_EQ(std::numeric_limits<T>::max(), result->Get<T>());
338
339 // result->size() returns an enum member of DataElement::Size indicating the
340 // number of bytes
341 uint8_t exponent = static_cast<uint8_t>(result->size());
342 EXPECT_EQ(sizeof(T), std::pow(2, exponent));
343 }
344
TEST(HelpersTest,FidlToDataElementInt8Test)345 TEST(HelpersTest, FidlToDataElementInt8Test) {
346 FidlToDataElementIntegerTest(std::function(fbredr::DataElement::WithInt8),
347 bt::sdp::DataElement::Type::kSignedInt);
348 }
349
TEST(HelpersTest,FidlToDataElementInt16Test)350 TEST(HelpersTest, FidlToDataElementInt16Test) {
351 FidlToDataElementIntegerTest(std::function(fbredr::DataElement::WithInt16),
352 bt::sdp::DataElement::Type::kSignedInt);
353 }
354
TEST(HelpersTest,FidlToDataElementInt32Test)355 TEST(HelpersTest, FidlToDataElementInt32Test) {
356 FidlToDataElementIntegerTest(std::function(fbredr::DataElement::WithInt32),
357 bt::sdp::DataElement::Type::kSignedInt);
358 }
359
TEST(HelpersTest,FidlToDataElementInt64Test)360 TEST(HelpersTest, FidlToDataElementInt64Test) {
361 FidlToDataElementIntegerTest(std::function(fbredr::DataElement::WithInt64),
362 bt::sdp::DataElement::Type::kSignedInt);
363 }
364
TEST(HelpersTest,FidlToDataElementUint8Test)365 TEST(HelpersTest, FidlToDataElementUint8Test) {
366 FidlToDataElementIntegerTest(std::function(fbredr::DataElement::WithUint8),
367 bt::sdp::DataElement::Type::kUnsignedInt);
368 }
369
TEST(HelpersTest,FidlToDataElementUint16Test)370 TEST(HelpersTest, FidlToDataElementUint16Test) {
371 FidlToDataElementIntegerTest(std::function(fbredr::DataElement::WithUint16),
372 bt::sdp::DataElement::Type::kUnsignedInt);
373 }
374
TEST(HelpersTest,FidlToDataElementUint32Test)375 TEST(HelpersTest, FidlToDataElementUint32Test) {
376 FidlToDataElementIntegerTest(std::function(fbredr::DataElement::WithUint32),
377 bt::sdp::DataElement::Type::kUnsignedInt);
378 }
379
TEST(HelpersTest,FidlToDataElementUint64Test)380 TEST(HelpersTest, FidlToDataElementUint64Test) {
381 FidlToDataElementIntegerTest(std::function(fbredr::DataElement::WithUint64),
382 bt::sdp::DataElement::Type::kUnsignedInt);
383 }
384
TEST(HelpersTest,FidlToDataElementEmptyStringTest)385 TEST(HelpersTest, FidlToDataElementEmptyStringTest) {
386 std::vector<uint8_t> data;
387 ASSERT_EQ(0u, data.size());
388
389 fbredr::DataElement data_element =
390 fbredr::DataElement::WithStr(std::move(data));
391 std::optional<bt::sdp::DataElement> result = FidlToDataElement(data_element);
392
393 EXPECT_TRUE(result.has_value());
394 EXPECT_EQ(bt::sdp::DataElement::Type::kString, result->type());
395 EXPECT_EQ("", result->Get<std::string>());
396 EXPECT_EQ(bt::sdp::DataElement::Size::kNextOne, result->size());
397 }
398
TEST(HelpersTest,FidlToDataElementStringTest)399 TEST(HelpersTest, FidlToDataElementStringTest) {
400 std::string expected_str = "foobarbaz";
401 std::vector<uint8_t> data(expected_str.size(), 0);
402 std::memcpy(data.data(), expected_str.data(), expected_str.size());
403
404 fbredr::DataElement data_element =
405 fbredr::DataElement::WithStr(std::move(data));
406 std::optional<bt::sdp::DataElement> result = FidlToDataElement(data_element);
407
408 EXPECT_TRUE(result.has_value());
409 EXPECT_EQ(bt::sdp::DataElement::Type::kString, result->type());
410 EXPECT_EQ(expected_str, result->Get<std::string>());
411 EXPECT_EQ(bt::sdp::DataElement::Size::kNextOne, result->size());
412 }
413
TEST(HelpersTest,FidlToDataElementUrlTest)414 TEST(HelpersTest, FidlToDataElementUrlTest) {
415 std::string url = "http://www.google.com";
416 std::string moved = url;
417 fbredr::DataElement data_element =
418 fbredr::DataElement::WithUrl(std::move(moved));
419 std::optional<bt::sdp::DataElement> result = FidlToDataElement(data_element);
420
421 EXPECT_TRUE(result.has_value());
422 EXPECT_EQ(bt::sdp::DataElement::Type::kUrl, result->type());
423 EXPECT_EQ(url, result->GetUrl());
424 EXPECT_EQ(bt::sdp::DataElement::Size::kNextOne, result->size());
425 }
426
TEST(HelpersTest,FidlToDataElementBooleanTest)427 TEST(HelpersTest, FidlToDataElementBooleanTest) {
428 bool expected = true;
429 bool moved = expected;
430 fbredr::DataElement data_element =
431 fbredr::DataElement::WithB(std::move(moved));
432 std::optional<bt::sdp::DataElement> result = FidlToDataElement(data_element);
433
434 EXPECT_TRUE(result.has_value());
435 EXPECT_EQ(bt::sdp::DataElement::Type::kBoolean, result->type());
436 EXPECT_EQ(expected, result->Get<bool>());
437 EXPECT_EQ(bt::sdp::DataElement::Size::kOneByte, result->size());
438 }
439
TEST(HelpersTest,FidlToDataElementUuidTest)440 TEST(HelpersTest, FidlToDataElementUuidTest) {
441 std::unique_ptr<fbt::Uuid> uuid = fbt::Uuid::New();
442 uuid->value.fill(123);
443
444 fbredr::DataElement data_element =
445 fbredr::DataElement::WithUuid(std::move(*uuid));
446 std::optional<bt::sdp::DataElement> result = FidlToDataElement(data_element);
447
448 ASSERT_TRUE(result.has_value());
449 EXPECT_EQ(bt::sdp::DataElement::Type::kUuid, result->type());
450 EXPECT_EQ(bt::sdp::DataElement::Size::kSixteenBytes, result->size());
451
452 bt::DynamicByteBuffer bytes(16);
453 bytes.Fill(123);
454
455 bt::UUID expected;
456 ASSERT_TRUE(bt::UUID::FromBytes(bytes, &expected));
457 EXPECT_EQ(expected, result->Get<bt::UUID>());
458 }
459
TEST(HelpersTest,FidlToDataElementSequenceTest)460 TEST(HelpersTest, FidlToDataElementSequenceTest) {
461 int8_t size = 3;
462 std::vector<std::unique_ptr<fbredr::DataElement>> moved;
463 std::vector<bt::sdp::DataElement> expected;
464
465 for (int16_t i = 0; i < size; i++) {
466 expected.emplace_back(i);
467 moved.push_back(std::make_unique<fbredr::DataElement>(
468 fbredr::DataElement::WithInt16(std::move(i))));
469 }
470
471 fbredr::DataElement data_element =
472 fbredr::DataElement::WithSequence(std::move(moved));
473 std::optional<bt::sdp::DataElement> result = FidlToDataElement(data_element);
474
475 EXPECT_TRUE(result.has_value());
476 EXPECT_EQ(bt::sdp::DataElement::Type::kSequence, result->type());
477 EXPECT_EQ(bt::sdp::DataElement::Size::kNextOne, result->size());
478
479 std::optional<std::vector<bt::sdp::DataElement>> actual =
480 result->Get<std::vector<bt::sdp::DataElement>>();
481 EXPECT_TRUE(actual);
482
483 for (int8_t i = 0; i < size; i++) {
484 EXPECT_EQ(expected[i].Get<int16_t>(), actual.value()[i].Get<int16_t>());
485 }
486 }
487
488 template <typename T>
NewFidlToDataElementIntegerTest(const std::function<fuchsia_bluetooth_bredr::DataElement (T)> & func,bt::sdp::DataElement::Type type)489 void NewFidlToDataElementIntegerTest(
490 const std::function<fuchsia_bluetooth_bredr::DataElement(T)>& func,
491 bt::sdp::DataElement::Type type) {
492 fuchsia_bluetooth_bredr::DataElement data_element =
493 func(std::numeric_limits<T>::max());
494 std::optional<bt::sdp::DataElement> result =
495 NewFidlToDataElement(data_element);
496 ASSERT_TRUE(result.has_value());
497 EXPECT_EQ(type, result->type());
498 EXPECT_EQ(std::numeric_limits<T>::max(), result->Get<T>());
499
500 // result->size() returns an enum member of DataElement::Size indicating the
501 // number of bytes
502 uint8_t exponent = static_cast<uint8_t>(result->size());
503 EXPECT_EQ(sizeof(T), std::pow(2, exponent));
504 }
505
TEST(HelpersTest,NewFidlToDataElementInt8Test)506 TEST(HelpersTest, NewFidlToDataElementInt8Test) {
507 NewFidlToDataElementIntegerTest(
508 std::function(fuchsia_bluetooth_bredr::DataElement::WithInt8),
509 bt::sdp::DataElement::Type::kSignedInt);
510 }
511
TEST(HelpersTest,NewFidlToDataElementInt16Test)512 TEST(HelpersTest, NewFidlToDataElementInt16Test) {
513 NewFidlToDataElementIntegerTest(
514 std::function(fuchsia_bluetooth_bredr::DataElement::WithInt16),
515 bt::sdp::DataElement::Type::kSignedInt);
516 }
517
TEST(HelpersTest,NewFidlToDataElementInt32Test)518 TEST(HelpersTest, NewFidlToDataElementInt32Test) {
519 NewFidlToDataElementIntegerTest(
520 std::function(fuchsia_bluetooth_bredr::DataElement::WithInt32),
521 bt::sdp::DataElement::Type::kSignedInt);
522 }
523
TEST(HelpersTest,NewFidlToDataElementInt64Test)524 TEST(HelpersTest, NewFidlToDataElementInt64Test) {
525 NewFidlToDataElementIntegerTest(
526 std::function(fuchsia_bluetooth_bredr::DataElement::WithInt64),
527 bt::sdp::DataElement::Type::kSignedInt);
528 }
529
TEST(HelpersTest,NewFidlToDataElementUint8Test)530 TEST(HelpersTest, NewFidlToDataElementUint8Test) {
531 NewFidlToDataElementIntegerTest(
532 std::function(fuchsia_bluetooth_bredr::DataElement::WithUint8),
533 bt::sdp::DataElement::Type::kUnsignedInt);
534 }
535
TEST(HelpersTest,NewFidlToDataElementUint16Test)536 TEST(HelpersTest, NewFidlToDataElementUint16Test) {
537 NewFidlToDataElementIntegerTest(
538 std::function(fuchsia_bluetooth_bredr::DataElement::WithUint16),
539 bt::sdp::DataElement::Type::kUnsignedInt);
540 }
541
TEST(HelpersTest,NewFidlToDataElementUint32Test)542 TEST(HelpersTest, NewFidlToDataElementUint32Test) {
543 NewFidlToDataElementIntegerTest(
544 std::function(fuchsia_bluetooth_bredr::DataElement::WithUint32),
545 bt::sdp::DataElement::Type::kUnsignedInt);
546 }
547
TEST(HelpersTest,NewFidlToDataElementUint64Test)548 TEST(HelpersTest, NewFidlToDataElementUint64Test) {
549 NewFidlToDataElementIntegerTest(
550 std::function(fuchsia_bluetooth_bredr::DataElement::WithUint64),
551 bt::sdp::DataElement::Type::kUnsignedInt);
552 }
553
TEST(HelpersTest,NewFidlToDataElementEmptyStringTest)554 TEST(HelpersTest, NewFidlToDataElementEmptyStringTest) {
555 std::vector<uint8_t> data;
556 ASSERT_EQ(0u, data.size());
557
558 fuchsia_bluetooth_bredr::DataElement data_element =
559 fuchsia_bluetooth_bredr::DataElement::WithStr(std::move(data));
560 std::optional<bt::sdp::DataElement> result =
561 NewFidlToDataElement(data_element);
562
563 EXPECT_TRUE(result.has_value());
564 EXPECT_EQ(bt::sdp::DataElement::Type::kString, result->type());
565 EXPECT_EQ("", result->Get<std::string>());
566 EXPECT_EQ(bt::sdp::DataElement::Size::kNextOne, result->size());
567 }
568
TEST(HelpersTest,NewFidlToDataElementStringTest)569 TEST(HelpersTest, NewFidlToDataElementStringTest) {
570 std::string expected_str = "foobarbaz";
571 std::vector<uint8_t> data(expected_str.size(), 0);
572 std::memcpy(data.data(), expected_str.data(), expected_str.size());
573
574 fuchsia_bluetooth_bredr::DataElement data_element =
575 fuchsia_bluetooth_bredr::DataElement::WithStr(std::move(data));
576 std::optional<bt::sdp::DataElement> result =
577 NewFidlToDataElement(data_element);
578
579 EXPECT_TRUE(result.has_value());
580 EXPECT_EQ(bt::sdp::DataElement::Type::kString, result->type());
581 EXPECT_EQ(expected_str, result->Get<std::string>());
582 EXPECT_EQ(bt::sdp::DataElement::Size::kNextOne, result->size());
583 }
584
TEST(HelpersTest,NewFidlToDataElementUrlTest)585 TEST(HelpersTest, NewFidlToDataElementUrlTest) {
586 std::string url = "http://www.google.com";
587 std::string moved = url;
588 fuchsia_bluetooth_bredr::DataElement data_element =
589 fuchsia_bluetooth_bredr::DataElement::WithUrl(std::move(moved));
590 std::optional<bt::sdp::DataElement> result =
591 NewFidlToDataElement(data_element);
592
593 EXPECT_TRUE(result.has_value());
594 EXPECT_EQ(bt::sdp::DataElement::Type::kUrl, result->type());
595 EXPECT_EQ(url, result->GetUrl());
596 EXPECT_EQ(bt::sdp::DataElement::Size::kNextOne, result->size());
597 }
598
TEST(HelpersTest,NewFidlToDataElementBooleanTest)599 TEST(HelpersTest, NewFidlToDataElementBooleanTest) {
600 bool expected = true;
601 bool moved = expected;
602 fuchsia_bluetooth_bredr::DataElement data_element =
603 fuchsia_bluetooth_bredr::DataElement::WithB(std::move(moved));
604 std::optional<bt::sdp::DataElement> result =
605 NewFidlToDataElement(data_element);
606
607 EXPECT_TRUE(result.has_value());
608 EXPECT_EQ(bt::sdp::DataElement::Type::kBoolean, result->type());
609 EXPECT_EQ(expected, result->Get<bool>());
610 EXPECT_EQ(bt::sdp::DataElement::Size::kOneByte, result->size());
611 }
612
TEST(HelpersTest,NewFidlToDataElementUuidTest)613 TEST(HelpersTest, NewFidlToDataElementUuidTest) {
614 fuchsia_bluetooth::Uuid uuid;
615 uuid.value().fill(123);
616
617 fuchsia_bluetooth_bredr::DataElement data_element =
618 fuchsia_bluetooth_bredr::DataElement::WithUuid(std::move(uuid));
619 std::optional<bt::sdp::DataElement> result =
620 NewFidlToDataElement(data_element);
621
622 ASSERT_TRUE(result.has_value());
623 EXPECT_EQ(bt::sdp::DataElement::Type::kUuid, result->type());
624 EXPECT_EQ(bt::sdp::DataElement::Size::kSixteenBytes, result->size());
625
626 bt::DynamicByteBuffer bytes(16);
627 bytes.Fill(123);
628
629 bt::UUID expected;
630 ASSERT_TRUE(bt::UUID::FromBytes(bytes, &expected));
631 EXPECT_EQ(expected, result->Get<bt::UUID>());
632 }
633
TEST(HelpersTest,NewFidlToDataElementSequenceTest)634 TEST(HelpersTest, NewFidlToDataElementSequenceTest) {
635 int8_t size = 3;
636 std::vector<fidl::Box<::fuchsia_bluetooth_bredr::DataElement>> moved;
637 std::vector<bt::sdp::DataElement> expected;
638
639 for (int16_t i = 0; i < size; i++) {
640 expected.emplace_back(i);
641 moved.push_back(std::make_unique<fuchsia_bluetooth_bredr::DataElement>(
642 fuchsia_bluetooth_bredr::DataElement::WithInt16(std::move(i))));
643 }
644
645 fuchsia_bluetooth_bredr::DataElement data_element =
646 fuchsia_bluetooth_bredr::DataElement::WithSequence(std::move(moved));
647 std::optional<bt::sdp::DataElement> result =
648 NewFidlToDataElement(data_element);
649
650 EXPECT_TRUE(result.has_value());
651 EXPECT_EQ(bt::sdp::DataElement::Type::kSequence, result->type());
652 EXPECT_EQ(bt::sdp::DataElement::Size::kNextOne, result->size());
653
654 std::optional<std::vector<bt::sdp::DataElement>> actual =
655 result->Get<std::vector<bt::sdp::DataElement>>();
656 EXPECT_TRUE(actual);
657
658 for (int8_t i = 0; i < size; i++) {
659 EXPECT_EQ(expected[i].Get<int16_t>(), actual.value()[i].Get<int16_t>());
660 }
661 }
662
TEST(HelpersTest,AdvertisingDataFromFidlEmpty)663 TEST(HelpersTest, AdvertisingDataFromFidlEmpty) {
664 fble::AdvertisingData input;
665 ASSERT_TRUE(input.IsEmpty());
666
667 std::optional<bt::AdvertisingData> maybe_data =
668 AdvertisingDataFromFidl(input);
669 ASSERT_TRUE(maybe_data.has_value());
670 auto output = std::move(*maybe_data);
671
672 EXPECT_TRUE(output.service_uuids().empty());
673 EXPECT_TRUE(output.service_data_uuids().empty());
674 EXPECT_TRUE(output.manufacturer_data_ids().empty());
675 EXPECT_TRUE(output.uris().empty());
676 EXPECT_FALSE(output.appearance());
677 EXPECT_FALSE(output.tx_power());
678 EXPECT_FALSE(output.local_name());
679 }
680
TEST(HelpersTest,AdvertisingDataFromFidlName)681 TEST(HelpersTest, AdvertisingDataFromFidlName) {
682 constexpr char kTestName[] = "";
683 fble::AdvertisingData input;
684 input.set_name(kTestName);
685
686 std::optional<bt::AdvertisingData> maybe_data =
687 AdvertisingDataFromFidl(input);
688 ASSERT_TRUE(maybe_data.has_value());
689 auto output = std::move(*maybe_data);
690 EXPECT_TRUE(output.local_name());
691 EXPECT_EQ(kTestName, output.local_name()->name);
692 }
693
TEST(HelpersTest,AdvertisingDataFromFidlAppearance)694 TEST(HelpersTest, AdvertisingDataFromFidlAppearance) {
695 fble::AdvertisingData input;
696 input.set_appearance(fuchsia::bluetooth::Appearance::HID_DIGITIZER_TABLET);
697
698 std::optional<bt::AdvertisingData> maybe_data =
699 AdvertisingDataFromFidl(input);
700 ASSERT_TRUE(maybe_data.has_value());
701 auto output = std::move(*maybe_data);
702
703 EXPECT_TRUE(output.appearance());
704
705 // Value comes from the standard Bluetooth "assigned numbers" document.
706 EXPECT_EQ(0x03C5, *output.appearance());
707 }
708
TEST(HelpersTest,AdvertisingDataFromFidlTxPower)709 TEST(HelpersTest, AdvertisingDataFromFidlTxPower) {
710 constexpr int8_t kTxPower = -50;
711 fble::AdvertisingData input;
712 input.set_tx_power_level(kTxPower);
713
714 std::optional<bt::AdvertisingData> maybe_data =
715 AdvertisingDataFromFidl(input);
716 ASSERT_TRUE(maybe_data.has_value());
717 auto output = std::move(*maybe_data);
718
719 EXPECT_TRUE(output.tx_power());
720 EXPECT_EQ(kTxPower, *output.tx_power());
721 }
722
TEST(HelpersTest,AdvertisingDataFromFidlUuids)723 TEST(HelpersTest, AdvertisingDataFromFidlUuids) {
724 // The first two entries are duplicated. The resulting structure should
725 // contain no duplicates.
726 const fbt::Uuid kUuid1{
727 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
728 const fbt::Uuid kUuid2{
729 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
730 const fbt::Uuid kUuid3{
731 {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}};
732 fble::AdvertisingData input;
733 input.set_service_uuids({{kUuid1, kUuid2, kUuid3}});
734
735 std::optional<bt::AdvertisingData> maybe_data =
736 AdvertisingDataFromFidl(input);
737 ASSERT_TRUE(maybe_data.has_value());
738 auto output = std::move(*maybe_data);
739
740 EXPECT_EQ(2u, output.service_uuids().size());
741 EXPECT_EQ(1u, output.service_uuids().count(bt::UUID(kUuid1.value)));
742 EXPECT_EQ(1u, output.service_uuids().count(bt::UUID(kUuid2.value)));
743 }
744
TEST(HelpersTest,AdvertisingDataFromFidlServiceData)745 TEST(HelpersTest, AdvertisingDataFromFidlServiceData) {
746 const fbt::Uuid kUuid1{
747 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
748 const fbt::Uuid kUuid2{
749 {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}};
750 const std::vector<uint8_t> kData1{{'h', 'e', 'l', 'l', 'o'}};
751 const std::vector<uint8_t> kData2{{'b', 'y', 'e'}};
752
753 fble::AdvertisingData input;
754 input.set_service_data({{{kUuid1, kData1}, {kUuid2, kData2}}});
755
756 std::optional<bt::AdvertisingData> maybe_data =
757 AdvertisingDataFromFidl(input);
758 ASSERT_TRUE(maybe_data.has_value());
759 auto output = std::move(*maybe_data);
760 EXPECT_EQ(2u, output.service_data_uuids().size());
761 EXPECT_TRUE(ContainersEqual(bt::BufferView(kData1),
762 output.service_data(bt::UUID(kUuid1.value))));
763 EXPECT_TRUE(ContainersEqual(bt::BufferView(kData2),
764 output.service_data(bt::UUID(kUuid2.value))));
765 }
766
TEST(HelpersTest,AdvertisingDataFromFidlManufacturerData)767 TEST(HelpersTest, AdvertisingDataFromFidlManufacturerData) {
768 constexpr uint16_t kCompanyId1 = 1;
769 constexpr uint16_t kCompanyId2 = 2;
770 const std::vector<uint8_t> kData1{{'h', 'e', 'l', 'l', 'o'}};
771 const std::vector<uint8_t> kData2{{'b', 'y', 'e'}};
772
773 fble::AdvertisingData input;
774 input.set_manufacturer_data({{{kCompanyId1, kData1}, {kCompanyId2, kData2}}});
775
776 std::optional<bt::AdvertisingData> maybe_data =
777 AdvertisingDataFromFidl(input);
778 ASSERT_TRUE(maybe_data.has_value());
779 auto output = std::move(*maybe_data);
780 EXPECT_EQ(2u, output.manufacturer_data_ids().size());
781 EXPECT_TRUE(ContainersEqual(bt::BufferView(kData1),
782 output.manufacturer_data(kCompanyId1)));
783 EXPECT_TRUE(ContainersEqual(bt::BufferView(kData2),
784 output.manufacturer_data(kCompanyId2)));
785 }
786
UuidToString(fbt::Uuid uuid)787 std::string UuidToString(fbt::Uuid uuid) {
788 std::string s;
789 for (uint8_t byte : uuid.value) {
790 s += std::to_string(static_cast<uint16_t>(byte)) + ", ";
791 }
792 return s;
793 }
794 // Each field for this test first attempts to perform the too-long conversion,
795 // and then verifies that the bounds are where expected by performing a
796 // successful conversion with a field that just fits in the encoded version.
797 // This also enables using the same `input` throughout the test.
TEST(HelpersTest,AdvertisingDataFromFidlWithFieldsTooLong)798 TEST(HelpersTest, AdvertisingDataFromFidlWithFieldsTooLong) {
799 fble::AdvertisingData input;
800 // The length of the AD name field must be <= 248 bytes per v5.2, Vol 4, Part
801 // E, 7.3.11 and Vol 3, Part C, 12.1.`
802 {
803 std::string name_that_fits(bt::kMaxNameLength, 'a');
804 std::string too_long_name(bt::kMaxNameLength + 1, 'b');
805 input.set_name(too_long_name);
806 EXPECT_FALSE(AdvertisingDataFromFidl(input).has_value());
807 input.set_name(name_that_fits);
808 EXPECT_TRUE(AdvertisingDataFromFidl(input).has_value());
809 }
810 {
811 // This is the longest encoding scheme known to Fuchsia BT, so this
812 // represents the longest string allowed (and subsequently, too long to be
813 // allowed) by both FIDL and internal invariants.
814 std::string uri = "ms-settings-cloudstorage:";
815 uri += std::string(fble::MAX_URI_LENGTH - uri.size(), '.');
816 input.set_uris({uri});
817 EXPECT_FALSE(AdvertisingDataFromFidl(input).has_value());
818 // This string should fit when it is one character shorter.
819 uri.pop_back();
820 input.set_uris({uri});
821 EXPECT_TRUE(AdvertisingDataFromFidl(input).has_value());
822 }
823 // Ensure encoded service data that is too long is rejected.
824 {
825 const fbt::Uuid kUuid1{
826 .value = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
827 // |kUuid1| = 16 bytes, i.e. 14 bytes longer than the shortest possible
828 // encoded UUID (2 bytes).
829 std::vector too_long_data(fble::MAX_SERVICE_DATA_LENGTH - 13,
830 uint8_t{0xAB});
831 input.set_service_data(std::vector(
832 {fble::ServiceData{.uuid = kUuid1, .data = too_long_data}}));
833 EXPECT_FALSE(AdvertisingDataFromFidl(input).has_value());
834 // A vector that is 1 byte shorter than too_long_data should convert
835 // successfully
836 std::vector data_that_fits(too_long_data.size() - 1, too_long_data[0]);
837 input.set_service_data(std::vector(
838 {fble::ServiceData{.uuid = kUuid1, .data = data_that_fits}}));
839 EXPECT_TRUE(AdvertisingDataFromFidl(input).has_value());
840 }
841 // Ensure encoded manufacturer data that is too long is rejected.
842 {
843 uint16_t company_id = 0x1212;
844 std::vector too_long_data(fble::MAX_MANUFACTURER_DATA_LENGTH + 1,
845 uint8_t{0xAB});
846 input.set_manufacturer_data(std::vector({fble::ManufacturerData{
847 .company_id = company_id, .data = too_long_data}}));
848 EXPECT_FALSE(AdvertisingDataFromFidl(input).has_value());
849 // A vector that is 1 byte shorter than too_long_data should convert
850 // successfully
851 std::vector data_that_fits(too_long_data.size() - 1, too_long_data[0]);
852 input.set_manufacturer_data(std::vector({fble::ManufacturerData{
853 .company_id = company_id, .data = data_that_fits}}));
854 EXPECT_TRUE(AdvertisingDataFromFidl(input).has_value());
855 }
856 // Ensure input with too many service UUIDs is truncated (NOT rejected).
857 {
858 std::vector<fbt::Uuid> fbt_uuids;
859 fbt::Uuid kBaseUuid{
860 .value = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}};
861 for (int i = 0; i < bt::kMax128BitUuids; ++i) {
862 fbt::Uuid next_uuid = kBaseUuid;
863 next_uuid.value[0] += i;
864 fbt_uuids.push_back(next_uuid);
865 }
866 input.set_service_uuids(fbt_uuids);
867 auto ad = AdvertisingDataFromFidl(input);
868 EXPECT_TRUE(ad.has_value());
869 std::unordered_set<bt::UUID> converted_uuids = ad->service_uuids();
870 for (auto& fbt_uuid : fbt_uuids) {
871 SCOPED_TRACE(UuidToString(fbt_uuid));
872 EXPECT_TRUE(converted_uuids.find(bt::UUID(fbt_uuid.value)) !=
873 converted_uuids.end());
874 }
875 fbt::Uuid excessive_uuid = kBaseUuid;
876 excessive_uuid.value[0] += bt::kMax128BitUuids + 1;
877 fbt_uuids.push_back(excessive_uuid);
878 input.set_service_uuids(fbt_uuids);
879 ad = AdvertisingDataFromFidl(input);
880 EXPECT_TRUE(ad.has_value());
881 converted_uuids = ad->service_uuids();
882 EXPECT_TRUE(converted_uuids.find(bt::UUID(excessive_uuid.value)) ==
883 converted_uuids.end());
884 }
885 }
886
TEST(HelpersTest,AdvertisingDataToFidlDeprecatedEmpty)887 TEST(HelpersTest, AdvertisingDataToFidlDeprecatedEmpty) {
888 bt::AdvertisingData input;
889 auto output = AdvertisingDataToFidlDeprecated(input);
890
891 // All fields in |input| are not set. Therefore, output should have no set
892 // fields as well.
893 EXPECT_FALSE(output.name);
894 EXPECT_FALSE(output.tx_power_level);
895 EXPECT_FALSE(output.appearance);
896 EXPECT_FALSE(output.service_uuids);
897 EXPECT_FALSE(output.service_data);
898 EXPECT_FALSE(output.manufacturer_specific_data);
899 EXPECT_FALSE(output.solicited_service_uuids);
900 EXPECT_FALSE(output.uris);
901 }
902
TEST(HelpersTest,AdvertisingDataToFidlDeprecated)903 TEST(HelpersTest, AdvertisingDataToFidlDeprecated) {
904 bt::AdvertisingData input;
905 EXPECT_TRUE(input.SetLocalName("fuchsia"));
906 input.SetTxPower(4);
907 input.SetAppearance(0x1234);
908
909 const uint16_t id = 0x5678;
910 const bt::UUID test_uuid = bt::UUID(id);
911 bt::StaticByteBuffer service_bytes(0x01, 0x02);
912 EXPECT_TRUE(input.AddServiceUuid(test_uuid));
913 EXPECT_TRUE(input.SetServiceData(test_uuid, service_bytes.view()));
914
915 uint16_t company_id = 0x98;
916 bt::StaticByteBuffer manufacturer_bytes(0x04, 0x03);
917 EXPECT_TRUE(input.SetManufacturerData(company_id, manufacturer_bytes.view()));
918
919 auto uri = "http://fuchsia.cl";
920 EXPECT_TRUE(input.AddUri(uri));
921
922 auto output = AdvertisingDataToFidlDeprecated(input);
923
924 EXPECT_EQ("fuchsia", output.name);
925
926 auto expected_power_level = std::make_unique<fbt::Int8>();
927 expected_power_level->value = 4;
928 EXPECT_EQ(expected_power_level->value, output.tx_power_level->value);
929
930 auto expected_appearance = std::make_unique<fbt::UInt16>();
931 expected_appearance->value = 0x1234;
932 EXPECT_EQ(expected_appearance->value, output.appearance->value);
933
934 EXPECT_EQ(1u, output.service_uuids->size());
935 EXPECT_EQ(test_uuid.ToString(), output.service_uuids->front());
936
937 EXPECT_EQ(1u, output.service_data->size());
938 auto service_data = output.service_data->front();
939 EXPECT_EQ(test_uuid.ToString(), service_data.uuid);
940 EXPECT_TRUE(
941 ContainersEqual(bt::BufferView(service_bytes), service_data.data));
942
943 EXPECT_EQ(1u, output.manufacturer_specific_data->size());
944 auto manufacturer_data = output.manufacturer_specific_data->front();
945 EXPECT_EQ(company_id, manufacturer_data.company_id);
946 EXPECT_TRUE(ContainersEqual(bt::BufferView(manufacturer_bytes),
947 manufacturer_data.data));
948
949 EXPECT_EQ(1u, output.uris->size());
950 EXPECT_EQ(uri, output.uris->front());
951 }
952
TEST(HelpersTest,AdvertisingDataToFidlEmpty)953 TEST(HelpersTest, AdvertisingDataToFidlEmpty) {
954 bt::AdvertisingData input;
955 auto output = AdvertisingDataToFidl(input);
956
957 // All fields in |input| are not set. Therefore, output should have no set
958 // fields as well.
959 EXPECT_FALSE(output.has_name());
960 EXPECT_FALSE(output.has_tx_power_level());
961 EXPECT_FALSE(output.has_appearance());
962 EXPECT_FALSE(output.has_service_uuids());
963 EXPECT_FALSE(output.has_service_data());
964 EXPECT_FALSE(output.has_manufacturer_data());
965 EXPECT_FALSE(output.has_uris());
966 }
967
TEST(HelpersTest,AdvertisingDataToFidl)968 TEST(HelpersTest, AdvertisingDataToFidl) {
969 bt::AdvertisingData input;
970 EXPECT_TRUE(input.SetLocalName("fuchsia"));
971 input.SetTxPower(4);
972 const uint16_t kAppearance = 193u; // WATCH_SPORTS
973 input.SetAppearance(kAppearance);
974
975 const uint16_t id = 0x5678;
976 const bt::UUID test_uuid = bt::UUID(id);
977 bt::StaticByteBuffer service_bytes(0x01, 0x02);
978 EXPECT_TRUE(input.AddServiceUuid(test_uuid));
979 EXPECT_TRUE(input.SetServiceData(test_uuid, service_bytes.view()));
980
981 uint16_t company_id = 0x98;
982 bt::StaticByteBuffer manufacturer_bytes(0x04, 0x03);
983 EXPECT_TRUE(input.SetManufacturerData(company_id, manufacturer_bytes.view()));
984
985 auto uri = "http://fuchsia.cl/461435";
986 EXPECT_TRUE(input.AddUri(uri));
987
988 auto output = AdvertisingDataToFidl(input);
989
990 EXPECT_EQ("fuchsia", output.name());
991
992 auto expected_power_level = std::make_unique<fbt::Int8>();
993 expected_power_level->value = 4;
994 EXPECT_EQ(expected_power_level->value, output.tx_power_level());
995
996 EXPECT_EQ(fbt::Appearance{kAppearance}, output.appearance());
997
998 EXPECT_EQ(1u, output.service_uuids().size());
999 EXPECT_EQ(test_uuid, UuidFromFidl(output.service_uuids().front()));
1000
1001 EXPECT_EQ(1u, output.service_data().size());
1002 auto service_data = output.service_data().front();
1003 EXPECT_EQ(test_uuid, UuidFromFidl(service_data.uuid));
1004 EXPECT_TRUE(
1005 ContainersEqual(bt::BufferView(service_bytes), service_data.data));
1006
1007 EXPECT_EQ(1u, output.manufacturer_data().size());
1008 auto manufacturer_data = output.manufacturer_data().front();
1009 EXPECT_EQ(company_id, manufacturer_data.company_id);
1010 EXPECT_TRUE(ContainersEqual(bt::BufferView(manufacturer_bytes),
1011 manufacturer_data.data));
1012
1013 EXPECT_THAT(output.uris(), ::testing::ElementsAre(uri));
1014 }
1015
TEST(HelpersTest,AdvertisingDataToFidlOmitsNonEnumeratedAppearance)1016 TEST(HelpersTest, AdvertisingDataToFidlOmitsNonEnumeratedAppearance) {
1017 // There is an "unknown" appearance, which is why this isn't named that.
1018 const uint16_t kNonEnumeratedAppearance = 0xFFFFu;
1019 bt::AdvertisingData input;
1020 input.SetAppearance(kNonEnumeratedAppearance);
1021
1022 EXPECT_FALSE(AdvertisingDataToFidl(input).has_appearance());
1023
1024 const uint16_t kKnownAppearance = 832u; // HEART_RATE_SENSOR
1025 input.SetAppearance(kKnownAppearance);
1026
1027 EXPECT_TRUE(AdvertisingDataToFidl(input).has_appearance());
1028 }
1029
TEST(HelpersTest,BrEdrSecurityModeFromFidl)1030 TEST(HelpersTest, BrEdrSecurityModeFromFidl) {
1031 EXPECT_EQ(bt::gap::BrEdrSecurityMode::Mode4,
1032 BrEdrSecurityModeFromFidl(fsys::BrEdrSecurityMode::MODE_4));
1033 EXPECT_EQ(bt::gap::BrEdrSecurityMode::SecureConnectionsOnly,
1034 BrEdrSecurityModeFromFidl(
1035 fsys::BrEdrSecurityMode::SECURE_CONNECTIONS_ONLY));
1036 auto nonexistent_security_mode = static_cast<fsys::BrEdrSecurityMode>(0xFF);
1037 EXPECT_EQ(std::nullopt, BrEdrSecurityModeFromFidl(nonexistent_security_mode));
1038 }
1039
TEST(HelpersTest,LeSecurityModeFromFidl)1040 TEST(HelpersTest, LeSecurityModeFromFidl) {
1041 EXPECT_EQ(bt::gap::LESecurityMode::Mode1,
1042 LeSecurityModeFromFidl(fsys::LeSecurityMode::MODE_1));
1043 EXPECT_EQ(
1044 bt::gap::LESecurityMode::SecureConnectionsOnly,
1045 LeSecurityModeFromFidl(fsys::LeSecurityMode::SECURE_CONNECTIONS_ONLY));
1046 auto nonexistent_security_mode = static_cast<fsys::LeSecurityMode>(0xFF);
1047 EXPECT_EQ(bt::gap::LESecurityMode::SecureConnectionsOnly,
1048 LeSecurityModeFromFidl(nonexistent_security_mode));
1049 }
1050
TEST(HelpersTest,TechnologyTypeToFidl)1051 TEST(HelpersTest, TechnologyTypeToFidl) {
1052 EXPECT_EQ(fsys::TechnologyType::LOW_ENERGY,
1053 TechnologyTypeToFidl(bt::gap::TechnologyType::kLowEnergy));
1054 EXPECT_EQ(fsys::TechnologyType::CLASSIC,
1055 TechnologyTypeToFidl(bt::gap::TechnologyType::kClassic));
1056 EXPECT_EQ(fsys::TechnologyType::DUAL_MODE,
1057 TechnologyTypeToFidl(bt::gap::TechnologyType::kDualMode));
1058 }
1059
TEST(HelpersTest,SecurityLevelFromFidl)1060 TEST(HelpersTest, SecurityLevelFromFidl) {
1061 const fsys::PairingSecurityLevel level =
1062 fsys::PairingSecurityLevel::AUTHENTICATED;
1063 EXPECT_EQ(bt::sm::SecurityLevel::kAuthenticated,
1064 SecurityLevelFromFidl(level));
1065 }
1066
TEST(HelpersTest,SecurityLevelFromBadFidlFails)1067 TEST(HelpersTest, SecurityLevelFromBadFidlFails) {
1068 int nonexistant_security_level = 500000;
1069 auto level =
1070 static_cast<fsys::PairingSecurityLevel>(nonexistant_security_level);
1071 EXPECT_EQ(std::nullopt, SecurityLevelFromFidl(level));
1072 }
1073
TEST(HelpersTest,PeerToFidlMandatoryFields)1074 TEST(HelpersTest, PeerToFidlMandatoryFields) {
1075 // Required by PeerCache expiry functions.
1076 async::TestLoop test_loop;
1077 pw::async_fuchsia::FuchsiaDispatcher pw_dispatcher(test_loop.dispatcher());
1078
1079 bt::gap::PeerCache cache(pw_dispatcher);
1080 bt::DeviceAddress addr(bt::DeviceAddress::Type::kLEPublic,
1081 {0, 1, 2, 3, 4, 5});
1082 auto* peer = cache.NewPeer(addr, /*connectable=*/true);
1083 auto fidl = PeerToFidl(*peer);
1084 ASSERT_TRUE(fidl.has_id());
1085 EXPECT_EQ(peer->identifier().value(), fidl.id().value);
1086 ASSERT_TRUE(fidl.has_address());
1087 EXPECT_TRUE(
1088 fidl::Equals(fbt::Address{fbt::AddressType::PUBLIC, {{0, 1, 2, 3, 4, 5}}},
1089 fidl.address()));
1090 ASSERT_TRUE(fidl.has_technology());
1091 EXPECT_EQ(fsys::TechnologyType::LOW_ENERGY, fidl.technology());
1092 ASSERT_TRUE(fidl.has_connected());
1093 EXPECT_FALSE(fidl.connected());
1094 ASSERT_TRUE(fidl.has_bonded());
1095 EXPECT_FALSE(fidl.bonded());
1096
1097 EXPECT_FALSE(fidl.has_name());
1098 EXPECT_FALSE(fidl.has_appearance());
1099 EXPECT_FALSE(fidl.has_rssi());
1100 EXPECT_FALSE(fidl.has_tx_power());
1101 EXPECT_FALSE(fidl.has_device_class());
1102 EXPECT_FALSE(fidl.has_services());
1103 EXPECT_FALSE(fidl.has_le_services());
1104 EXPECT_FALSE(fidl.has_bredr_services());
1105 }
1106
TEST(HelpersTest,PeerToFidlOptionalFields)1107 TEST(HelpersTest, PeerToFidlOptionalFields) {
1108 // Required by PeerCache expiry functions.
1109 async::TestLoop test_loop;
1110 pw::async_fuchsia::FuchsiaDispatcher pw_dispatcher(test_loop.dispatcher());
1111
1112 const int8_t kRssi = 5;
1113 const int8_t kTxPower = 6;
1114 const auto kAdv = bt::StaticByteBuffer(0x02,
1115 0x01,
1116 0x01, // Flags: General Discoverable
1117 0x03,
1118 0x19,
1119 192,
1120 0, // Appearance: Watch
1121 0x02,
1122 0x0A,
1123 0x06, // Tx-Power: 5
1124 0x05,
1125 0x09,
1126 't',
1127 'e',
1128 's',
1129 't' // Complete Local Name: "test"
1130 );
1131 const std::vector kBrEdrServices = {bt::UUID(uint16_t{0x110a}),
1132 bt::UUID(uint16_t{0x110b})};
1133
1134 bt::gap::PeerCache cache(pw_dispatcher);
1135 bt::DeviceAddress addr(bt::DeviceAddress::Type::kLEPublic,
1136 {0, 1, 2, 3, 4, 5});
1137 auto* peer = cache.NewPeer(addr, /*connectable=*/true);
1138 peer->MutLe().SetAdvertisingData(
1139 kRssi, kAdv, pw::chrono::SystemClock::time_point());
1140 bt::StaticPacket<pw::bluetooth::emboss::InquiryResultWriter> inquiry_result;
1141 auto view = inquiry_result.view();
1142 view.bd_addr().CopyFrom(bt::DeviceAddressBytes{{0, 1, 2, 3, 4, 5}}.view());
1143 view.page_scan_repetition_mode().Write(
1144 pw::bluetooth::emboss::PageScanRepetitionMode::R0_);
1145 view.class_of_device().major_device_class().Write(
1146 pw::bluetooth::emboss::MajorDeviceClass::PERIPHERAL);
1147 peer->MutBrEdr().SetInquiryData(inquiry_result.view());
1148 for (auto& service : kBrEdrServices) {
1149 peer->MutBrEdr().AddService(service);
1150 }
1151
1152 auto fidl = PeerToFidl(*peer);
1153 ASSERT_TRUE(fidl.has_name());
1154 EXPECT_EQ("test", fidl.name());
1155 ASSERT_TRUE(fidl.has_appearance());
1156 EXPECT_EQ(fbt::Appearance::WATCH, fidl.appearance());
1157 ASSERT_TRUE(fidl.has_rssi());
1158 EXPECT_EQ(kRssi, fidl.rssi());
1159 ASSERT_TRUE(fidl.has_tx_power());
1160 EXPECT_EQ(kTxPower, fidl.tx_power());
1161 ASSERT_TRUE(fidl.has_device_class());
1162 EXPECT_EQ(fbt::MAJOR_DEVICE_CLASS_PERIPHERAL, fidl.device_class().value);
1163
1164 // Deprecated and never implemented (see https://fxbug.dev/42135180).
1165 EXPECT_FALSE(fidl.has_services());
1166
1167 // TODO(fxbug.dev/42135180): Add a test when this field gets populated.
1168 EXPECT_FALSE(fidl.has_le_services());
1169
1170 ASSERT_TRUE(fidl.has_bredr_services());
1171 std::vector<fbt::Uuid> expected_uuids;
1172 std::transform(kBrEdrServices.begin(),
1173 kBrEdrServices.end(),
1174 std::back_inserter(expected_uuids),
1175 UuidToFidl);
1176 EXPECT_THAT(fidl.bredr_services(),
1177 ::testing::UnorderedElementsAreArray(expected_uuids));
1178 }
1179
TEST(HelpersTest,ReliableModeFromFidl)1180 TEST(HelpersTest, ReliableModeFromFidl) {
1181 using WriteOptions = fuchsia::bluetooth::gatt::WriteOptions;
1182 using ReliableMode = fuchsia::bluetooth::gatt::ReliableMode;
1183 WriteOptions options;
1184
1185 // No options set, so this should default to disabled.
1186 EXPECT_EQ(bt::gatt::ReliableMode::kDisabled, ReliableModeFromFidl(options));
1187
1188 options.set_reliable_mode(ReliableMode::ENABLED);
1189 EXPECT_EQ(bt::gatt::ReliableMode::kEnabled, ReliableModeFromFidl(options));
1190
1191 options.set_reliable_mode(ReliableMode::DISABLED);
1192 EXPECT_EQ(bt::gatt::ReliableMode::kDisabled, ReliableModeFromFidl(options));
1193 }
1194
TEST(HelpersTest,InvalidServiceDefinitionToServiceRecordIsError)1195 TEST(HelpersTest, InvalidServiceDefinitionToServiceRecordIsError) {
1196 fuchsia::bluetooth::bredr::ServiceDefinition def_should_fail;
1197 // Should fail to convert without service class UUIDs.
1198 auto rec_no_uuids = ServiceDefinitionToServiceRecord(def_should_fail);
1199 EXPECT_FALSE(rec_no_uuids.is_ok());
1200 // Should fail to convert when information set without language.
1201 def_should_fail.mutable_service_class_uuids()->emplace_back(
1202 fidl_helpers::UuidToFidl(bt::sdp::profile::kAudioSink));
1203 fuchsia::bluetooth::bredr::Information info_no_language;
1204 def_should_fail.mutable_information()->emplace_back(
1205 std::move(info_no_language));
1206 auto rec_no_language = ServiceDefinitionToServiceRecord(def_should_fail);
1207 EXPECT_FALSE(rec_no_language.is_ok());
1208 }
1209
1210 // - make sure the expected attributes are set and have the correct type
1211 // - make sure the profile descriptor sets the right attributes
TEST(HelpersTest,ServiceDefinitionToServiceRecordRoundtrip)1212 TEST(HelpersTest, ServiceDefinitionToServiceRecordRoundtrip) {
1213 fuchsia::bluetooth::bredr::ServiceDefinition def;
1214 def.mutable_service_class_uuids()->emplace_back(
1215 fidl_helpers::UuidToFidl(bt::sdp::profile::kAudioSink));
1216 fuchsia::bluetooth::bredr::Information info;
1217 info.set_language("en");
1218 info.set_name("TEST");
1219 def.mutable_information()->emplace_back(std::move(info));
1220 fuchsia::bluetooth::bredr::ProtocolDescriptor l2cap_proto;
1221 l2cap_proto.set_protocol(
1222 fuchsia::bluetooth::bredr::ProtocolIdentifier::L2CAP);
1223 fuchsia::bluetooth::bredr::DataElement l2cap_data_el;
1224 l2cap_data_el.set_uint16(fuchsia::bluetooth::bredr::PSM_SDP);
1225 std::vector<fuchsia::bluetooth::bredr::DataElement> l2cap_params;
1226 l2cap_params.emplace_back(std::move(l2cap_data_el));
1227 l2cap_proto.set_params(std::move(l2cap_params));
1228 def.mutable_protocol_descriptor_list()->emplace_back(std::move(l2cap_proto));
1229 fuchsia::bluetooth::bredr::ProtocolDescriptor avdtp_proto;
1230 avdtp_proto.set_protocol(
1231 fuchsia::bluetooth::bredr::ProtocolIdentifier::AVDTP);
1232 fuchsia::bluetooth::bredr::DataElement avdtp_data_el;
1233 avdtp_data_el.set_uint16(0x0103); // Version 1
1234 std::vector<fuchsia::bluetooth::bredr::DataElement> avdtp_params;
1235 avdtp_params.emplace_back(std::move(avdtp_data_el));
1236 avdtp_proto.set_params(std::move(avdtp_params));
1237 def.mutable_protocol_descriptor_list()->emplace_back(std::move(avdtp_proto));
1238 fuchsia::bluetooth::bredr::ProfileDescriptor prof_desc;
1239 prof_desc.set_profile_id(
1240 fuchsia::bluetooth::bredr::ServiceClassProfileIdentifier::
1241 ADVANCED_AUDIO_DISTRIBUTION);
1242 prof_desc.set_major_version(1);
1243 prof_desc.set_minor_version(3);
1244 def.mutable_profile_descriptors()->emplace_back(std::move(prof_desc));
1245 bt::sdp::AttributeId valid_att_id = 0x1111;
1246 fuchsia::bluetooth::bredr::Attribute valid_attribute;
1247 valid_attribute.set_element(
1248 ::fuchsia::bluetooth::bredr::DataElement::WithUint8(0x01));
1249 valid_attribute.set_id(valid_att_id);
1250 def.mutable_additional_attributes()->emplace_back(std::move(valid_attribute));
1251 // Add a URL attribute.
1252 bt::sdp::AttributeId url_attr_id = 0x1112; // Random ID
1253 fuchsia::bluetooth::bredr::Attribute url_attribute;
1254 url_attribute.set_element(
1255 ::fuchsia::bluetooth::bredr::DataElement::WithUrl("foobar.dev"));
1256 url_attribute.set_id(url_attr_id);
1257 def.mutable_additional_attributes()->emplace_back(std::move(url_attribute));
1258
1259 // Confirm converted ServiceRecord fields match ServiceDefinition
1260 auto rec = ServiceDefinitionToServiceRecord(def);
1261 EXPECT_TRUE(rec.is_ok());
1262
1263 // Confirm UUIDs match
1264 std::unordered_set<bt::UUID> attribute_uuid = {bt::sdp::profile::kAudioSink};
1265 EXPECT_TRUE(rec.value().FindUUID(attribute_uuid));
1266
1267 // Confirm information fields match
1268 EXPECT_TRUE(rec.value().HasAttribute(bt::sdp::kLanguageBaseAttributeIdList));
1269 const bt::sdp::DataElement& lang_val =
1270 rec.value().GetAttribute(bt::sdp::kLanguageBaseAttributeIdList);
1271 auto triplets = lang_val.Get<std::vector<bt::sdp::DataElement>>();
1272 EXPECT_TRUE(triplets);
1273 EXPECT_TRUE(triplets->size() % 3 == 0);
1274 EXPECT_EQ(bt::sdp::DataElement::Type::kUnsignedInt, triplets->at(0).type());
1275 EXPECT_EQ(bt::sdp::DataElement::Type::kUnsignedInt, triplets->at(1).type());
1276 EXPECT_EQ(bt::sdp::DataElement::Type::kUnsignedInt, triplets->at(2).type());
1277 auto lang = triplets->at(0).Get<uint16_t>();
1278 EXPECT_TRUE(lang);
1279 EXPECT_EQ(0x656e, *lang); // should be 'en' in ascii (but big-endian)
1280 auto encoding = triplets->at(1).Get<uint16_t>();
1281 EXPECT_TRUE(encoding);
1282 EXPECT_EQ(106, *encoding); // should always be UTF-8
1283 auto base_attrid = triplets->at(2).Get<uint16_t>();
1284 EXPECT_TRUE(base_attrid);
1285 EXPECT_EQ(0x0100, *base_attrid); // The primary language must be at 0x0100.
1286 EXPECT_TRUE(
1287 rec.value().HasAttribute(*base_attrid + bt::sdp::kServiceNameOffset));
1288 const bt::sdp::DataElement& name_elem =
1289 rec.value().GetAttribute(*base_attrid + bt::sdp::kServiceNameOffset);
1290 auto name = name_elem.Get<std::string>();
1291 EXPECT_TRUE(name);
1292 EXPECT_EQ("TEST", *name);
1293
1294 // Confirm protocol + descriptor list
1295 EXPECT_TRUE(rec.value().HasAttribute(bt::sdp::kProtocolDescriptorList));
1296 const bt::sdp::DataElement& protocol_val =
1297 rec.value().GetAttribute(bt::sdp::kProtocolDescriptorList);
1298 bt::DynamicByteBuffer protocol_block(protocol_val.WriteSize());
1299 protocol_val.Write(&protocol_block);
1300 auto expected_protocol_list =
1301 bt::StaticByteBuffer(0x35,
1302 0x10, // Data Element Sequence (10 bytes)
1303 0x35,
1304 0x06, // Data Element Sequence (6 bytes)
1305 0x19, // UUID (16 bits)
1306 0x01,
1307 0x00, // L2CAP Profile UUID
1308 0x09, // uint16_t
1309 0x00,
1310 0x01, // PSM = SDP
1311 0x35,
1312 0x06, // Data Element Sequence (6 bytes)
1313 0x19, // UUID
1314 0x00,
1315 0x19, // AVTDP Profile UUID
1316 0x09, // uint16_t
1317 0x01,
1318 0x03 // PSM_AVDTP
1319 );
1320 EXPECT_EQ(expected_protocol_list.size(), protocol_block.size());
1321 EXPECT_TRUE(ContainersEqual(expected_protocol_list, protocol_block));
1322
1323 // Confirm profile descriptor list
1324 EXPECT_TRUE(
1325 rec.value().HasAttribute(bt::sdp::kBluetoothProfileDescriptorList));
1326 const bt::sdp::DataElement& profile_val =
1327 rec.value().GetAttribute(bt::sdp::kBluetoothProfileDescriptorList);
1328 bt::DynamicByteBuffer profile_block(profile_val.WriteSize());
1329 profile_val.Write(&profile_block);
1330 auto expected_profile_list =
1331 bt::StaticByteBuffer(0x35,
1332 0x08, // Data Element Sequence (8 bytes)
1333 0x35,
1334 0x06, // Data Element Sequence (6 bytes)
1335 0x19, // UUID
1336 0x11,
1337 0x0d, // Advanced Audio Identifier
1338 0x09, // uint16_t
1339 0x01,
1340 0x03 // Major and minor version
1341 );
1342 EXPECT_EQ(expected_profile_list.size(), profile_block.size());
1343 EXPECT_TRUE(ContainersEqual(expected_profile_list, profile_block));
1344
1345 // Confirm additional attributes
1346 EXPECT_TRUE(rec.value().HasAttribute(valid_att_id));
1347 EXPECT_TRUE(rec.value().HasAttribute(url_attr_id));
1348 EXPECT_EQ(*rec.value().GetAttribute(url_attr_id).GetUrl(), "foobar.dev");
1349
1350 // Can go back to the original FIDL service definition.
1351 auto fidl_def = ServiceRecordToServiceDefinition(rec.value());
1352 ASSERT_TRUE(fidl_def.is_ok());
1353 ASSERT_TRUE(::fidl::Equals(fidl_def.value(), def));
1354 }
1355
TEST(HelpersTest,ObexServiceDefinitionToServiceRecordRoundtrip)1356 TEST(HelpersTest, ObexServiceDefinitionToServiceRecordRoundtrip) {
1357 // Create an OBEX definition for a successful conversion. MAP MSE uses both
1358 // L2CAP and RFCOMM.
1359 fuchsia::bluetooth::bredr::ServiceDefinition def;
1360 def.mutable_service_class_uuids()->emplace_back(
1361 fidl_helpers::UuidToFidl(bt::sdp::profile::kMessageAccessServer));
1362
1363 // The primary protocol contains L2CAP, RFCOMM, & OBEX.
1364 fuchsia::bluetooth::bredr::ProtocolDescriptor l2cap_proto;
1365 l2cap_proto.set_protocol(
1366 fuchsia::bluetooth::bredr::ProtocolIdentifier::L2CAP);
1367 l2cap_proto.set_params({});
1368 def.mutable_protocol_descriptor_list()->emplace_back(std::move(l2cap_proto));
1369
1370 fuchsia::bluetooth::bredr::ProtocolDescriptor rfcomm_proto;
1371 rfcomm_proto.set_protocol(
1372 fuchsia::bluetooth::bredr::ProtocolIdentifier::RFCOMM);
1373 fuchsia::bluetooth::bredr::DataElement rfcomm_data_el;
1374 rfcomm_data_el.set_uint8(10); // Random ServerChannel number
1375 std::vector<fuchsia::bluetooth::bredr::DataElement> rfcomm_params;
1376 rfcomm_params.emplace_back(std::move(rfcomm_data_el));
1377 rfcomm_proto.set_params(std::move(rfcomm_params));
1378 def.mutable_protocol_descriptor_list()->emplace_back(std::move(rfcomm_proto));
1379
1380 fuchsia::bluetooth::bredr::ProtocolDescriptor obex_proto;
1381 obex_proto.set_protocol(fuchsia::bluetooth::bredr::ProtocolIdentifier::OBEX);
1382 obex_proto.set_params({});
1383 def.mutable_protocol_descriptor_list()->emplace_back(std::move(obex_proto));
1384
1385 // Profile version = 1.4.
1386 fuchsia::bluetooth::bredr::ProfileDescriptor prof_desc;
1387 prof_desc.set_profile_id(
1388 fuchsia::bluetooth::bredr::ServiceClassProfileIdentifier::
1389 MESSAGE_ACCESS_PROFILE);
1390 prof_desc.set_major_version(1);
1391 prof_desc.set_minor_version(4);
1392 def.mutable_profile_descriptors()->emplace_back(std::move(prof_desc));
1393
1394 // ServiceName = "MAP MAS"
1395 fuchsia::bluetooth::bredr::Information info;
1396 info.set_language("en");
1397 info.set_name("MAP MAS");
1398 def.mutable_information()->emplace_back(std::move(info));
1399
1400 // GoepL2capPsm Attribute with a dynamic PSM.
1401 fuchsia::bluetooth::bredr::Attribute goep_l2cap_psm_attribute;
1402 goep_l2cap_psm_attribute.set_id(bt::sdp::kGoepL2capPsm);
1403 fuchsia::bluetooth::bredr::DataElement geop_psm;
1404 geop_psm.set_uint16(fuchsia::bluetooth::bredr::PSM_DYNAMIC);
1405 goep_l2cap_psm_attribute.set_element(std::move(geop_psm));
1406 def.mutable_additional_attributes()->emplace_back(
1407 std::move(goep_l2cap_psm_attribute));
1408
1409 // Add MASInstanceID Attribute = 1
1410 fuchsia::bluetooth::bredr::Attribute instance_id_attribute;
1411 instance_id_attribute.set_id(0x0315);
1412 instance_id_attribute.set_element(
1413 fuchsia::bluetooth::bredr::DataElement::WithUint16(1));
1414 def.mutable_additional_attributes()->emplace_back(
1415 std::move(instance_id_attribute));
1416 // Add SupportedMessagesTypes Attribute = Email (0)
1417 fuchsia::bluetooth::bredr::Attribute message_types_attribute;
1418 message_types_attribute.set_id(0x0316);
1419 message_types_attribute.set_element(
1420 fuchsia::bluetooth::bredr::DataElement::WithUint16(0));
1421 def.mutable_additional_attributes()->emplace_back(
1422 std::move(message_types_attribute));
1423 // Add MapSupportedFeatures Attribute = Notification Registration only (1)
1424 fuchsia::bluetooth::bredr::Attribute features_attribute;
1425 features_attribute.set_id(0x0317);
1426 features_attribute.set_element(
1427 fuchsia::bluetooth::bredr::DataElement::WithUint16(1));
1428 def.mutable_additional_attributes()->emplace_back(
1429 std::move(features_attribute));
1430
1431 // Confirm converted ServiceRecord fields match ServiceDefinition
1432 const auto rec = ServiceDefinitionToServiceRecord(def);
1433 ASSERT_TRUE(rec.is_ok());
1434
1435 // Confirm UUIDs match
1436 std::unordered_set<bt::UUID> attribute_uuid = {
1437 bt::sdp::profile::kMessageAccessServer};
1438 EXPECT_TRUE(rec.value().FindUUID(attribute_uuid));
1439
1440 // Confirm information fields match
1441 EXPECT_TRUE(rec.value().HasAttribute(bt::sdp::kLanguageBaseAttributeIdList));
1442 const bt::sdp::DataElement& lang_val =
1443 rec.value().GetAttribute(bt::sdp::kLanguageBaseAttributeIdList);
1444 auto triplets = lang_val.Get<std::vector<bt::sdp::DataElement>>();
1445 EXPECT_TRUE(triplets);
1446 EXPECT_TRUE(triplets->size() % 3 == 0);
1447 EXPECT_EQ(bt::sdp::DataElement::Type::kUnsignedInt, triplets->at(0).type());
1448 EXPECT_EQ(bt::sdp::DataElement::Type::kUnsignedInt, triplets->at(1).type());
1449 EXPECT_EQ(bt::sdp::DataElement::Type::kUnsignedInt, triplets->at(2).type());
1450 auto lang = triplets->at(0).Get<uint16_t>();
1451 EXPECT_TRUE(lang);
1452 EXPECT_EQ(0x656e, *lang); // should be 'en' in ascii (but big-endian)
1453 auto encoding = triplets->at(1).Get<uint16_t>();
1454 EXPECT_TRUE(encoding);
1455 EXPECT_EQ(106, *encoding); // should always be UTF-8
1456 auto base_attrid = triplets->at(2).Get<uint16_t>();
1457 EXPECT_TRUE(base_attrid);
1458 EXPECT_EQ(0x0100, *base_attrid); // The primary language must be at 0x0100.
1459 EXPECT_TRUE(
1460 rec.value().HasAttribute(*base_attrid + bt::sdp::kServiceNameOffset));
1461 const bt::sdp::DataElement& name_elem =
1462 rec.value().GetAttribute(*base_attrid + bt::sdp::kServiceNameOffset);
1463 auto name = name_elem.Get<std::string>();
1464 EXPECT_TRUE(name);
1465 EXPECT_EQ("MAP MAS", *name);
1466
1467 // Confirm protocol + descriptor list
1468 EXPECT_TRUE(rec.value().HasAttribute(bt::sdp::kProtocolDescriptorList));
1469 const bt::sdp::DataElement& protocol_val =
1470 rec.value().GetAttribute(bt::sdp::kProtocolDescriptorList);
1471 bt::DynamicByteBuffer protocol_block(protocol_val.WriteSize());
1472 protocol_val.Write(&protocol_block);
1473 auto expected_protocol_list =
1474 bt::StaticByteBuffer(0x35,
1475 0x11, // Data Element Sequence (11 bytes)
1476 0x35,
1477 0x03, // Data Element Sequence (3 bytes)
1478 0x19, // UUID (16 bits)
1479 0x01,
1480 0x00, // L2CAP Profile UUID
1481 0x35,
1482 0x05, // Data Element Sequence (5 bytes)
1483 0x19, // UUID
1484 0x00,
1485 0x03, // RFCOMM Profile UUID
1486 0x08, // uint8_t
1487 0x0a, // ServerChannel = 10
1488 0x35,
1489 0x03, // Data Element Sequence (3 bytes)
1490 0x19, // UUID
1491 0x00,
1492 0x08 // OBEX Profile UUID
1493 );
1494 EXPECT_EQ(expected_protocol_list.size(), protocol_block.size());
1495 EXPECT_TRUE(ContainersEqual(expected_protocol_list, protocol_block));
1496
1497 // Confirm profile descriptor list
1498 EXPECT_TRUE(
1499 rec.value().HasAttribute(bt::sdp::kBluetoothProfileDescriptorList));
1500 const bt::sdp::DataElement& profile_val =
1501 rec.value().GetAttribute(bt::sdp::kBluetoothProfileDescriptorList);
1502 bt::DynamicByteBuffer profile_block(profile_val.WriteSize());
1503 profile_val.Write(&profile_block);
1504 auto expected_profile_list =
1505 bt::StaticByteBuffer(0x35,
1506 0x08, // Data Element Sequence (8 bytes)
1507 0x35,
1508 0x06, // Data Element Sequence (6 bytes)
1509 0x19, // UUID
1510 0x11,
1511 0x34, // Message Access Profile ID
1512 0x09, // uint16_t
1513 0x01,
1514 0x04 // Major and minor version
1515 );
1516 EXPECT_EQ(expected_profile_list.size(), profile_block.size());
1517 EXPECT_TRUE(ContainersEqual(expected_profile_list, profile_block));
1518
1519 // Confirm additional attributes
1520 EXPECT_TRUE(rec.value().HasAttribute(0x0315));
1521 EXPECT_TRUE(rec.value().HasAttribute(0x0316));
1522 EXPECT_TRUE(rec.value().HasAttribute(0x0317));
1523 // The GoepL2capPsm value should be saved.
1524 EXPECT_EQ(*rec.value().GetAttribute(bt::sdp::kGoepL2capPsm).Get<uint16_t>(),
1525 fuchsia::bluetooth::bredr::PSM_DYNAMIC);
1526
1527 // Can go back to the original FIDL service definition.
1528 auto fidl_def = ServiceRecordToServiceDefinition(rec.value());
1529 ASSERT_TRUE(fidl_def.is_ok());
1530 ASSERT_TRUE(::fidl::Equals(fidl_def.value(), def));
1531 }
1532
TEST(HelpersTest,MinimalServiceRecordToServiceDefinition)1533 TEST(HelpersTest, MinimalServiceRecordToServiceDefinition) {
1534 // Minimal record has only service UUIDs. Everything else is optional.
1535 bt::sdp::ServiceRecord minimal;
1536 const std::vector<bt::UUID> uuids = {bt::sdp::profile::kSerialPort};
1537 minimal.SetServiceClassUUIDs(uuids);
1538 auto minimal_rec = ServiceRecordToServiceDefinition(minimal);
1539 EXPECT_TRUE(minimal_rec.is_ok());
1540 }
1541
TEST(HelpersTest,InvalidServiceRecordToServiceDefinitionIsError)1542 TEST(HelpersTest, InvalidServiceRecordToServiceDefinitionIsError) {
1543 const bt::sdp::ServiceRecord empty_record;
1544 // Should fail to convert without service class UUIDs.
1545 auto rec_no_uuids = ServiceRecordToServiceDefinition(empty_record);
1546 EXPECT_FALSE(rec_no_uuids.is_ok());
1547
1548 bt::sdp::ServiceRecord invalid_record;
1549 const std::vector<bt::UUID> uuids = {bt::sdp::profile::kAudioSink};
1550 invalid_record.SetServiceClassUUIDs(uuids);
1551 // Invalid profile descriptor
1552 bt::sdp::DataElement invalid_profile_descriptors;
1553 invalid_record.SetAttribute(bt::sdp::kBluetoothProfileDescriptorList,
1554 std::move(invalid_profile_descriptors));
1555 auto invalid_profile_rec = ServiceRecordToServiceDefinition(invalid_record);
1556 EXPECT_FALSE(invalid_profile_rec.is_ok());
1557 invalid_record.RemoveAttribute(bt::sdp::kBluetoothProfileDescriptorList);
1558
1559 // Invalid protocol descriptor
1560 bt::sdp::DataElement invalid_protocol_descriptor;
1561 invalid_record.SetAttribute(bt::sdp::kProtocolDescriptorList,
1562 std::move(invalid_protocol_descriptor));
1563 auto invalid_protocol_rec = ServiceRecordToServiceDefinition(invalid_record);
1564 EXPECT_FALSE(invalid_protocol_rec.is_ok());
1565 }
1566
TEST(HelpersTest,FidlToBrEdrSecurityRequirements)1567 TEST(HelpersTest, FidlToBrEdrSecurityRequirements) {
1568 fbt::ChannelParameters params;
1569 EXPECT_EQ(FidlToBrEdrSecurityRequirements(params),
1570 (bt::gap::BrEdrSecurityRequirements{.authentication = false,
1571 .secure_connections = false}));
1572
1573 params.set_security_requirements(fbt::SecurityRequirements());
1574 EXPECT_EQ(FidlToBrEdrSecurityRequirements(params),
1575 (bt::gap::BrEdrSecurityRequirements{.authentication = false,
1576 .secure_connections = false}));
1577
1578 params.mutable_security_requirements()->set_secure_connections_required(
1579 false);
1580 EXPECT_EQ(FidlToBrEdrSecurityRequirements(params),
1581 (bt::gap::BrEdrSecurityRequirements{.authentication = false,
1582 .secure_connections = false}));
1583 params.mutable_security_requirements()->clear_secure_connections_required();
1584
1585 params.mutable_security_requirements()->set_authentication_required(false);
1586 EXPECT_EQ(FidlToBrEdrSecurityRequirements(params),
1587 (bt::gap::BrEdrSecurityRequirements{.authentication = false,
1588 .secure_connections = false}));
1589
1590 params.mutable_security_requirements()->set_secure_connections_required(
1591 false);
1592 EXPECT_EQ(FidlToBrEdrSecurityRequirements(params),
1593 (bt::gap::BrEdrSecurityRequirements{.authentication = false,
1594 .secure_connections = false}));
1595
1596 params.mutable_security_requirements()->set_authentication_required(true);
1597 EXPECT_EQ(FidlToBrEdrSecurityRequirements(params),
1598 (bt::gap::BrEdrSecurityRequirements{.authentication = true,
1599 .secure_connections = false}));
1600
1601 params.mutable_security_requirements()->set_secure_connections_required(true);
1602 EXPECT_EQ(FidlToBrEdrSecurityRequirements(params),
1603 (bt::gap::BrEdrSecurityRequirements{.authentication = true,
1604 .secure_connections = true}));
1605 }
1606
TEST(HelpersTest,AddressFromFidlBondingDataRandomAddressRejectedIfBredr)1607 TEST(HelpersTest, AddressFromFidlBondingDataRandomAddressRejectedIfBredr) {
1608 fsys::BondingData bond;
1609 bond.set_address(kRandomAddrFidl);
1610 bond.set_bredr_bond(fsys::BredrBondData());
1611
1612 EXPECT_EQ(std::nullopt, AddressFromFidlBondingData(bond));
1613 }
1614
TEST(HelpersTest,AddressFromFidlBondingDataBredr)1615 TEST(HelpersTest, AddressFromFidlBondingDataBredr) {
1616 fsys::BondingData bond;
1617 bond.set_address(kPublicAddrFidl);
1618 bond.set_bredr_bond(fsys::BredrBondData());
1619
1620 auto addr = AddressFromFidlBondingData(bond);
1621 ASSERT_TRUE(addr);
1622 EXPECT_EQ(addr->type(), bt::DeviceAddress::Type::kBREDR);
1623 }
1624
TEST(HelpersTest,AddressFromFidlBondingDataDualMode)1625 TEST(HelpersTest, AddressFromFidlBondingDataDualMode) {
1626 fsys::BondingData bond;
1627 bond.set_address(kPublicAddrFidl);
1628 bond.set_bredr_bond(fsys::BredrBondData());
1629 bond.set_le_bond(fsys::LeBondData());
1630
1631 auto addr = AddressFromFidlBondingData(bond);
1632 ASSERT_TRUE(addr);
1633 EXPECT_EQ(addr->type(), bt::DeviceAddress::Type::kBREDR);
1634 }
1635
TEST(HelpersTest,AddressFromFidlBondingDataLePublic)1636 TEST(HelpersTest, AddressFromFidlBondingDataLePublic) {
1637 fsys::BondingData bond;
1638 bond.set_address(kPublicAddrFidl);
1639 bond.set_le_bond(fsys::LeBondData());
1640
1641 auto addr = AddressFromFidlBondingData(bond);
1642 ASSERT_TRUE(addr);
1643 EXPECT_EQ(addr->type(), bt::DeviceAddress::Type::kLEPublic);
1644 }
1645
TEST(HelpersTest,AddressFromFidlBondingDataLeRandom)1646 TEST(HelpersTest, AddressFromFidlBondingDataLeRandom) {
1647 fsys::BondingData bond;
1648 bond.set_address(kRandomAddrFidl);
1649 bond.set_le_bond(fsys::LeBondData());
1650
1651 auto addr = AddressFromFidlBondingData(bond);
1652 ASSERT_TRUE(addr);
1653 EXPECT_EQ(addr->type(), bt::DeviceAddress::Type::kLERandom);
1654 }
1655
TEST(HelpersTest,AddressFromFidlBondingDataLeRandomResolvable)1656 TEST(HelpersTest, AddressFromFidlBondingDataLeRandomResolvable) {
1657 fsys::BondingData bond;
1658 bond.set_address(kRandomAddrResolvableFidl);
1659 bond.set_le_bond(fsys::LeBondData());
1660
1661 auto addr = AddressFromFidlBondingData(bond);
1662 EXPECT_FALSE(addr);
1663 }
1664
TEST(HelpersTest,AddressFromFidlBondingDataLeRandomNonResolvable)1665 TEST(HelpersTest, AddressFromFidlBondingDataLeRandomNonResolvable) {
1666 fsys::BondingData bond;
1667 bond.set_address(kRandomAddrNonResolvableFidl);
1668 bond.set_le_bond(fsys::LeBondData());
1669
1670 auto addr = AddressFromFidlBondingData(bond);
1671 EXPECT_FALSE(addr);
1672 }
1673
TEST(HelpersTest,LePairingDataFromFidlEmpty)1674 TEST(HelpersTest, LePairingDataFromFidlEmpty) {
1675 bt::sm::PairingData result =
1676 LePairingDataFromFidl(kLePublicAddress, fsys::LeBondData());
1677 EXPECT_FALSE(result.identity_address);
1678 EXPECT_FALSE(result.local_ltk);
1679 EXPECT_FALSE(result.peer_ltk);
1680 EXPECT_FALSE(result.irk);
1681 EXPECT_FALSE(result.csrk);
1682 }
1683
TEST(HelpersTest,LePairingDataFromFidl)1684 TEST(HelpersTest, LePairingDataFromFidl) {
1685 fsys::LeBondData le;
1686 le.set_local_ltk(kTestLtkFidl);
1687 le.set_peer_ltk(kTestLtkFidl);
1688 le.set_irk(kTestKeyFidl);
1689 le.set_csrk(kTestKeyFidl);
1690
1691 bt::sm::PairingData result =
1692 LePairingDataFromFidl(kLePublicAddress, std::move(le));
1693 ASSERT_TRUE(result.local_ltk);
1694 ASSERT_TRUE(result.peer_ltk);
1695 ASSERT_TRUE(result.irk);
1696 ASSERT_TRUE(result.identity_address);
1697 ASSERT_TRUE(result.csrk);
1698
1699 EXPECT_EQ(kTestLtk, *result.local_ltk);
1700 EXPECT_EQ(kTestLtk, *result.peer_ltk);
1701 EXPECT_EQ(kTestKey, *result.irk);
1702 EXPECT_EQ(kLePublicAddress, *result.identity_address);
1703 EXPECT_EQ(kTestKey, *result.csrk);
1704 }
1705
TEST(HelpersTest,BredrKeyFromFidlEmpty)1706 TEST(HelpersTest, BredrKeyFromFidlEmpty) {
1707 EXPECT_FALSE(BredrKeyFromFidl(fsys::BredrBondData()));
1708 }
1709
TEST(HelpersTest,BredrKeyFromFidl)1710 TEST(HelpersTest, BredrKeyFromFidl) {
1711 const bt::sm::SecurityProperties kTestSecurity(
1712 bt::sm::SecurityLevel::kSecureAuthenticated,
1713 16,
1714 /*secure_connections=*/true);
1715 const bt::sm::LTK kTestLtk(kTestSecurity,
1716 bt::hci_spec::LinkKey(kTestKeyValue, 0, 0));
1717
1718 fsys::BredrBondData bredr;
1719 bredr.set_link_key(kTestKeyFidl);
1720 std::optional<bt::sm::LTK> result = BredrKeyFromFidl(bredr);
1721 ASSERT_TRUE(result);
1722 EXPECT_EQ(kTestLtk, *result);
1723 }
1724
TEST(HelpersTest,BredrServicesFromFidlEmpty)1725 TEST(HelpersTest, BredrServicesFromFidlEmpty) {
1726 EXPECT_TRUE(BredrServicesFromFidl(fsys::BredrBondData()).empty());
1727 }
1728
TEST(HelpersTest,BredrServicesFromFidl)1729 TEST(HelpersTest, BredrServicesFromFidl) {
1730 fsys::BredrBondData bredr;
1731 bredr.mutable_services()->push_back(UuidToFidl(bt::sdp::profile::kAudioSink));
1732 bredr.mutable_services()->push_back(
1733 UuidToFidl(bt::sdp::profile::kAudioSource));
1734 auto bredr_services = BredrServicesFromFidl(bredr);
1735 EXPECT_THAT(bredr_services,
1736 ::testing::UnorderedElementsAre(bt::sdp::profile::kAudioSource,
1737 bt::sdp::profile::kAudioSink));
1738 }
1739
1740 class HelpersAdapterTest : public bthost::testing::AdapterTestFixture {};
1741
TEST_F(HelpersAdapterTest,PeerToFidlBondingData_NoTransportData)1742 TEST_F(HelpersAdapterTest, PeerToFidlBondingData_NoTransportData) {
1743 auto* peer =
1744 adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
1745 fsys::BondingData data = PeerToFidlBondingData(adapter().get(), *peer);
1746 ASSERT_TRUE(data.has_identifier());
1747 ASSERT_TRUE(data.has_local_address());
1748 ASSERT_TRUE(data.has_address());
1749 EXPECT_FALSE(data.has_name());
1750 EXPECT_FALSE(data.has_le_bond());
1751 EXPECT_FALSE(data.has_bredr_bond());
1752
1753 EXPECT_EQ(peer->identifier().value(), data.identifier().value);
1754 EXPECT_TRUE(fidl::Equals(
1755 (fbt::Address{fbt::AddressType::PUBLIC, std::array<uint8_t, 6>{0}}),
1756 data.local_address()));
1757 EXPECT_TRUE(fidl::Equals(kPublicAddrFidl, data.address()));
1758 }
1759
TEST_F(HelpersAdapterTest,PeerToFidlBondingData_BothTransportsPresentButNotBonded)1760 TEST_F(HelpersAdapterTest,
1761 PeerToFidlBondingData_BothTransportsPresentButNotBonded) {
1762 auto* peer =
1763 adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
1764 peer->MutLe();
1765 peer->MutBrEdr();
1766
1767 fsys::BondingData data = PeerToFidlBondingData(adapter().get(), *peer);
1768 ASSERT_TRUE(data.has_identifier());
1769 ASSERT_TRUE(data.has_local_address());
1770 ASSERT_TRUE(data.has_address());
1771 EXPECT_FALSE(data.has_le_bond());
1772 EXPECT_FALSE(data.has_bredr_bond());
1773
1774 EXPECT_EQ(peer->identifier().value(), data.identifier().value);
1775 EXPECT_TRUE(fidl::Equals(
1776 (fbt::Address{fbt::AddressType::PUBLIC, std::array<uint8_t, 6>{0}}),
1777 data.local_address()));
1778 EXPECT_TRUE(fidl::Equals(kPublicAddrFidl, data.address()));
1779 }
1780
TEST_F(HelpersAdapterTest,PeerToFidlBondingData_BredrServicesDiscoveredNotBonded)1781 TEST_F(HelpersAdapterTest,
1782 PeerToFidlBondingData_BredrServicesDiscoveredNotBonded) {
1783 auto* peer =
1784 adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
1785 peer->MutBrEdr().AddService(bt::UUID(uint16_t{0x1234}));
1786
1787 fsys::BondingData data = PeerToFidlBondingData(adapter().get(), *peer);
1788 EXPECT_FALSE(data.has_bredr_bond());
1789 }
1790
TEST_F(HelpersAdapterTest,PeerToFidlBondingData_EmptyLeData)1791 TEST_F(HelpersAdapterTest, PeerToFidlBondingData_EmptyLeData) {
1792 auto* peer =
1793 adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
1794 peer->MutLe().SetBondData(bt::sm::PairingData());
1795
1796 fsys::BondingData data = PeerToFidlBondingData(adapter().get(), *peer);
1797 EXPECT_FALSE(data.has_bredr_bond());
1798 ASSERT_TRUE(data.has_le_bond());
1799 EXPECT_FALSE(data.le_bond().has_local_ltk());
1800 EXPECT_FALSE(data.le_bond().has_peer_ltk());
1801 EXPECT_FALSE(data.le_bond().has_irk());
1802 EXPECT_FALSE(data.le_bond().has_csrk());
1803 }
1804
TEST_F(HelpersAdapterTest,PeerToFidlBondingData_LeData)1805 TEST_F(HelpersAdapterTest, PeerToFidlBondingData_LeData) {
1806 auto* peer =
1807 adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
1808 peer->MutLe().SetBondData(bt::sm::PairingData{
1809 .local_ltk = {kTestLtk},
1810 .peer_ltk = {kTestLtk},
1811 .irk = {kTestKey},
1812 .csrk = {kTestKey},
1813 });
1814
1815 fsys::BondingData data = PeerToFidlBondingData(adapter().get(), *peer);
1816 EXPECT_FALSE(data.has_bredr_bond());
1817 ASSERT_TRUE(data.has_le_bond());
1818 ASSERT_TRUE(data.le_bond().has_local_ltk());
1819 ASSERT_TRUE(data.le_bond().has_peer_ltk());
1820 ASSERT_TRUE(data.le_bond().has_irk());
1821 ASSERT_TRUE(data.le_bond().has_csrk());
1822
1823 EXPECT_TRUE(fidl::Equals(kTestLtkFidl, data.le_bond().local_ltk()));
1824 EXPECT_TRUE(fidl::Equals(kTestLtkFidl, data.le_bond().peer_ltk()));
1825 EXPECT_TRUE(fidl::Equals(kTestKeyFidl, data.le_bond().irk()));
1826 EXPECT_TRUE(fidl::Equals(kTestKeyFidl, data.le_bond().csrk()));
1827 }
1828
TEST_F(HelpersAdapterTest,PeerToFidlBondingData_BredrData)1829 TEST_F(HelpersAdapterTest, PeerToFidlBondingData_BredrData) {
1830 auto* peer =
1831 adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
1832 peer->MutBrEdr().SetBondData(kTestLtk);
1833
1834 fsys::BondingData data = PeerToFidlBondingData(adapter().get(), *peer);
1835 EXPECT_FALSE(data.has_le_bond());
1836 ASSERT_TRUE(data.has_bredr_bond());
1837 ASSERT_TRUE(data.bredr_bond().has_link_key());
1838 EXPECT_TRUE(fidl::Equals(kTestKeyFidl, data.bredr_bond().link_key()));
1839 }
1840
TEST_F(HelpersAdapterTest,PeerToFidlBondingData_IncludesBredrServices)1841 TEST_F(HelpersAdapterTest, PeerToFidlBondingData_IncludesBredrServices) {
1842 auto* peer =
1843 adapter()->peer_cache()->NewPeer(kTestPeerAddr, /*connectable=*/true);
1844 peer->MutBrEdr().SetBondData(kTestLtk);
1845 peer->MutBrEdr().AddService(bt::sdp::profile::kAudioSink);
1846 peer->MutBrEdr().AddService(bt::sdp::profile::kAudioSource);
1847
1848 fsys::BondingData data = PeerToFidlBondingData(adapter().get(), *peer);
1849 ASSERT_TRUE(data.has_bredr_bond());
1850 ASSERT_TRUE(data.bredr_bond().has_services());
1851
1852 EXPECT_THAT(data.bredr_bond().services(),
1853 ::testing::UnorderedElementsAre(
1854 UuidToFidl(bt::sdp::profile::kAudioSink),
1855 UuidToFidl(bt::sdp::profile::kAudioSource)));
1856 }
1857
1858 // Returns a copy to avoid forming references to misaligned fields, which is UB.
1859 template <typename T>
copy(T t)1860 T copy(T t) {
1861 return t;
1862 }
1863
TEST_F(HelpersAdapterTest,FidlToScoParameters)1864 TEST_F(HelpersAdapterTest, FidlToScoParameters) {
1865 fbredr::ScoConnectionParameters params;
1866 EXPECT_TRUE(FidlToScoParameters(params).is_error());
1867 params.set_parameter_set(fbredr::HfpParameterSet::T2);
1868 EXPECT_TRUE(FidlToScoParameters(params).is_error());
1869 params.set_air_coding_format(fbt::AssignedCodingFormat::MSBC);
1870 EXPECT_TRUE(FidlToScoParameters(params).is_error());
1871 params.set_air_frame_size(8u);
1872 EXPECT_TRUE(FidlToScoParameters(params).is_error());
1873 params.set_io_bandwidth(32000);
1874 EXPECT_TRUE(FidlToScoParameters(params).is_error());
1875 params.set_io_coding_format(fbt::AssignedCodingFormat::LINEAR_PCM);
1876 EXPECT_TRUE(FidlToScoParameters(params).is_error());
1877 params.set_io_frame_size(16u);
1878 EXPECT_TRUE(FidlToScoParameters(params).is_error());
1879 params.set_io_pcm_data_format(faudio::SampleFormat::PCM_SIGNED);
1880 EXPECT_TRUE(FidlToScoParameters(params).is_error());
1881 params.set_io_pcm_sample_payload_msb_position(3u);
1882 EXPECT_TRUE(FidlToScoParameters(params).is_error());
1883 params.set_path(fbredr::DataPath::OFFLOAD);
1884 ASSERT_TRUE(FidlToScoParameters(params).is_ok());
1885
1886 bt::StaticPacket<pw::bluetooth::emboss::SynchronousConnectionParametersWriter>
1887 out = FidlToScoParameters(params).take_value();
1888 auto view = out.view();
1889 EXPECT_EQ(view.transmit_bandwidth().Read(), 8000u);
1890 EXPECT_EQ(view.receive_bandwidth().Read(), 8000u);
1891
1892 EXPECT_EQ(view.transmit_coding_format().coding_format().Read(),
1893 pw::bluetooth::emboss::CodingFormat::MSBC);
1894 EXPECT_EQ(view.transmit_coding_format().company_id().Read(), 0u);
1895 EXPECT_EQ(view.transmit_coding_format().vendor_codec_id().Read(), 0u);
1896
1897 EXPECT_EQ(view.receive_coding_format().coding_format().Read(),
1898 pw::bluetooth::emboss::CodingFormat::MSBC);
1899 EXPECT_EQ(view.receive_coding_format().company_id().Read(), 0u);
1900 EXPECT_EQ(view.receive_coding_format().vendor_codec_id().Read(), 0u);
1901
1902 EXPECT_EQ(view.transmit_codec_frame_size_bytes().Read(), 8u);
1903 EXPECT_EQ(view.receive_codec_frame_size_bytes().Read(), 8u);
1904
1905 EXPECT_EQ(view.input_bandwidth().Read(), 32000u);
1906 EXPECT_EQ(view.output_bandwidth().Read(), 32000u);
1907
1908 EXPECT_EQ(view.input_coding_format().coding_format().Read(),
1909 pw::bluetooth::emboss::CodingFormat::LINEAR_PCM);
1910 EXPECT_EQ(view.input_coding_format().company_id().Read(), 0u);
1911 EXPECT_EQ(view.input_coding_format().vendor_codec_id().Read(), 0u);
1912
1913 EXPECT_EQ(view.output_coding_format().coding_format().Read(),
1914 pw::bluetooth::emboss::CodingFormat::LINEAR_PCM);
1915 EXPECT_EQ(view.output_coding_format().company_id().Read(), 0u);
1916 EXPECT_EQ(view.output_coding_format().vendor_codec_id().Read(), 0u);
1917
1918 EXPECT_EQ(view.input_coded_data_size_bits().Read(), 16u);
1919 EXPECT_EQ(view.output_coded_data_size_bits().Read(), 16u);
1920
1921 EXPECT_EQ(view.input_pcm_data_format().Read(),
1922 pw::bluetooth::emboss::PcmDataFormat::TWOS_COMPLEMENT);
1923 EXPECT_EQ(view.output_pcm_data_format().Read(),
1924 pw::bluetooth::emboss::PcmDataFormat::TWOS_COMPLEMENT);
1925
1926 EXPECT_EQ(view.input_pcm_sample_payload_msb_position().Read(), 3u);
1927 EXPECT_EQ(view.output_pcm_sample_payload_msb_position().Read(), 3u);
1928
1929 EXPECT_EQ(view.input_data_path().Read(),
1930 static_cast<pw::bluetooth::emboss::ScoDataPath>(6));
1931 EXPECT_EQ(view.output_data_path().Read(),
1932 static_cast<pw::bluetooth::emboss::ScoDataPath>(6));
1933
1934 EXPECT_EQ(view.input_transport_unit_size_bits().Read(), 0u);
1935 EXPECT_EQ(view.output_transport_unit_size_bits().Read(), 0u);
1936
1937 EXPECT_EQ(view.max_latency_ms().Read(),
1938 bt::sco::kParameterSetT2.max_latency_ms);
1939 EXPECT_EQ(view.packet_types().BackingStorage().ReadUInt(),
1940 bt::sco::kParameterSetT2.packet_types);
1941 EXPECT_EQ(view.retransmission_effort().Read(),
1942 static_cast<pw::bluetooth::emboss::SynchronousConnectionParameters::
1943 ScoRetransmissionEffort>(
1944 bt::sco::kParameterSetT2.retransmission_effort));
1945
1946 // When the IO coding format is Linear PCM, the PCM data format is required.
1947 params.clear_io_pcm_data_format();
1948 EXPECT_TRUE(FidlToScoParameters(params).is_error());
1949
1950 // PCM_FLOAT is not a supported PCM format.
1951 params.set_io_pcm_data_format(faudio::SampleFormat::PCM_FLOAT);
1952 EXPECT_TRUE(FidlToScoParameters(params).is_error());
1953
1954 // PCM format for non-PCM IO coding formats is kNotApplicable and MSB is 0.
1955 params.set_io_coding_format(fbt::AssignedCodingFormat::TRANSPARENT);
1956 ASSERT_TRUE(FidlToScoParameters(params).is_ok());
1957 out = FidlToScoParameters(params).value();
1958 EXPECT_EQ(view.input_pcm_data_format().Read(),
1959 pw::bluetooth::emboss::PcmDataFormat::NOT_APPLICABLE);
1960 EXPECT_EQ(view.input_pcm_sample_payload_msb_position().Read(), 0u);
1961 }
1962
1963 class HelpersTestFakeAdapter
1964 : public bt::fidl::testing::FakeAdapterTestFixture {
1965 public:
1966 HelpersTestFakeAdapter() = default;
1967 ~HelpersTestFakeAdapter() override = default;
1968
SetUp()1969 void SetUp() override { FakeAdapterTestFixture::SetUp(); }
1970
TearDown()1971 void TearDown() override { FakeAdapterTestFixture::TearDown(); }
1972
1973 private:
1974 BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(HelpersTestFakeAdapter);
1975 };
1976
TEST_F(HelpersTestFakeAdapter,HostInfoToFidl)1977 TEST_F(HelpersTestFakeAdapter, HostInfoToFidl) {
1978 // Verify that the default parameters are populated as expected.
1979 auto host_info = HostInfoToFidl(*adapter());
1980 ASSERT_TRUE(host_info.has_id());
1981 ASSERT_TRUE(host_info.has_technology());
1982 ASSERT_TRUE(host_info.has_local_name());
1983 ASSERT_TRUE(host_info.has_discoverable());
1984 ASSERT_TRUE(host_info.has_discovering());
1985 ASSERT_TRUE(host_info.has_addresses());
1986
1987 EXPECT_EQ(adapter()->identifier().value(), host_info.id().value);
1988 EXPECT_EQ(fsys::TechnologyType::DUAL_MODE, host_info.technology());
1989 EXPECT_EQ("", host_info.local_name());
1990 EXPECT_TRUE(host_info.discoverable());
1991 EXPECT_TRUE(host_info.discovering());
1992 // Since privacy is not enabled by default, only the public address should be
1993 // reported.
1994 ASSERT_EQ(host_info.addresses().size(), 1u);
1995 EXPECT_EQ(fbt::AddressType::PUBLIC, host_info.addresses()[0].type);
1996 EXPECT_TRUE(ContainersEqual(adapter()->state().controller_address.bytes(),
1997 host_info.addresses()[0].bytes));
1998 }
1999
TEST_F(HelpersTestFakeAdapter,HostInfoWithLEAddressToFidl)2000 TEST_F(HelpersTestFakeAdapter, HostInfoWithLEAddressToFidl) {
2001 // Enabling privacy does not result in the LE random address being set
2002 // immediately. Therefore, only the public address should be reported.
2003 adapter()->fake_le()->EnablePrivacy(/*enabled=*/true);
2004 auto host_info = HostInfoToFidl(*adapter());
2005 EXPECT_EQ(adapter()->identifier().value(), host_info.id().value);
2006 EXPECT_EQ(fsys::TechnologyType::DUAL_MODE, host_info.technology());
2007 EXPECT_EQ("", host_info.local_name());
2008 EXPECT_TRUE(host_info.discoverable());
2009 EXPECT_TRUE(host_info.discovering());
2010 ASSERT_EQ(host_info.addresses().size(), 1u);
2011 EXPECT_EQ(fbt::AddressType::PUBLIC, host_info.addresses()[0].type);
2012 EXPECT_TRUE(ContainersEqual(adapter()->state().controller_address.bytes(),
2013 host_info.addresses()[0].bytes));
2014
2015 // Setting a RPA should result in the LE random address being reported.
2016 auto resolvable_address = bt::DeviceAddress(
2017 bt::DeviceAddress::Type::kLERandom, {0x55, 0x44, 0x33, 0x22, 0x11, 0x43});
2018 adapter()->fake_le()->UpdateRandomAddress(resolvable_address);
2019 host_info = HostInfoToFidl(*adapter());
2020 ASSERT_EQ(host_info.addresses().size(), 2u);
2021 EXPECT_EQ(fbt::AddressType::PUBLIC, host_info.addresses()[0].type);
2022 EXPECT_TRUE(ContainersEqual(adapter()->state().controller_address.bytes(),
2023 host_info.addresses()[0].bytes));
2024 EXPECT_EQ(fbt::AddressType::RANDOM, host_info.addresses()[1].type);
2025 EXPECT_TRUE(ContainersEqual(adapter()->le()->CurrentAddress().value().bytes(),
2026 host_info.addresses()[1].bytes));
2027
2028 // Setting a static address should result in the LE random address being
2029 // reported.
2030 auto static_address = bt::DeviceAddress(bt::DeviceAddress::Type::kLERandom,
2031 {0x55, 0x44, 0x33, 0x22, 0x11, 0x43});
2032 adapter()->fake_le()->UpdateRandomAddress(static_address);
2033 host_info = HostInfoToFidl(*adapter());
2034 ASSERT_EQ(host_info.addresses().size(), 2u);
2035 EXPECT_EQ(fbt::AddressType::RANDOM, host_info.addresses()[1].type);
2036 EXPECT_TRUE(ContainersEqual(adapter()->le()->CurrentAddress().value().bytes(),
2037 host_info.addresses()[1].bytes));
2038 }
2039
TEST(HelpersTest,DiscoveryFilterFromEmptyFidlFilter)2040 TEST(HelpersTest, DiscoveryFilterFromEmptyFidlFilter) {
2041 bt::gap::DiscoveryFilter filter = DiscoveryFilterFromFidl(fble::Filter());
2042 EXPECT_TRUE(filter.service_uuids().empty());
2043 EXPECT_TRUE(filter.service_data_uuids().empty());
2044 EXPECT_FALSE(filter.manufacturer_code().has_value());
2045 EXPECT_FALSE(filter.connectable().has_value());
2046 EXPECT_TRUE(filter.name_substring().empty());
2047 EXPECT_FALSE(filter.pathloss().has_value());
2048 }
2049
TEST(HelpersTest,DiscoveryFilterFromFidlFilter)2050 TEST(HelpersTest, DiscoveryFilterFromFidlFilter) {
2051 fble::Filter fidl_filter;
2052 fuchsia::bluetooth::Uuid service_uuid;
2053 service_uuid.value[0] = 1;
2054 fuchsia::bluetooth::Uuid service_data_uuid;
2055 service_uuid.value[0] = 2;
2056 fidl_filter.set_service_uuid(service_uuid);
2057 fidl_filter.set_service_data_uuid(service_data_uuid);
2058 fidl_filter.set_manufacturer_id(2);
2059 fidl_filter.set_connectable(true);
2060 fidl_filter.set_name("name");
2061 fidl_filter.set_max_path_loss(3);
2062 bt::gap::DiscoveryFilter filter = DiscoveryFilterFromFidl(fidl_filter);
2063 EXPECT_THAT(filter.service_uuids(),
2064 ::testing::ElementsAre(service_uuid.value));
2065 EXPECT_THAT(filter.service_data_uuids(),
2066 ::testing::ElementsAre(service_data_uuid.value));
2067 ASSERT_TRUE(filter.manufacturer_code().has_value());
2068 EXPECT_EQ(filter.manufacturer_code().value(), 2u);
2069 ASSERT_TRUE(filter.connectable().has_value());
2070 EXPECT_EQ(filter.connectable().value(), true);
2071 EXPECT_EQ(filter.name_substring(), "name");
2072 ASSERT_TRUE(filter.pathloss().has_value());
2073 ASSERT_EQ(filter.pathloss().value(), 3);
2074 }
2075
TEST(HelpersTest,EmptyAdvertisingDataToFidlScanData)2076 TEST(HelpersTest, EmptyAdvertisingDataToFidlScanData) {
2077 bt::AdvertisingData input;
2078 fble::ScanData output = AdvertisingDataToFidlScanData(
2079 input, pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(1)));
2080 EXPECT_FALSE(output.has_tx_power());
2081 EXPECT_FALSE(output.has_appearance());
2082 EXPECT_FALSE(output.has_service_uuids());
2083 EXPECT_FALSE(output.has_service_data());
2084 EXPECT_FALSE(output.has_manufacturer_data());
2085 EXPECT_FALSE(output.has_uris());
2086 ASSERT_TRUE(output.has_timestamp());
2087 EXPECT_EQ(output.timestamp(), zx::time(1).get());
2088 }
2089
TEST(HelpersTest,AdvertisingDataToFidlScanData)2090 TEST(HelpersTest, AdvertisingDataToFidlScanData) {
2091 bt::AdvertisingData input;
2092 input.SetTxPower(4);
2093 const uint16_t kAppearance = 193u; // WATCH_SPORTS
2094 input.SetAppearance(kAppearance);
2095
2096 const uint16_t id = 0x5678;
2097 const bt::UUID kServiceUuid = bt::UUID(id);
2098 auto service_bytes = bt::StaticByteBuffer(0x01, 0x02);
2099 EXPECT_TRUE(input.AddServiceUuid(kServiceUuid));
2100 EXPECT_TRUE(input.SetServiceData(kServiceUuid, service_bytes.view()));
2101
2102 const uint16_t kManufacturer = 0x98;
2103 auto manufacturer_bytes = bt::StaticByteBuffer(0x04, 0x03);
2104 EXPECT_TRUE(
2105 input.SetManufacturerData(kManufacturer, manufacturer_bytes.view()));
2106
2107 const char* const kUri = "http://fuchsia.cl/461435";
2108 EXPECT_TRUE(input.AddUri(kUri));
2109
2110 fble::ScanData output = AdvertisingDataToFidlScanData(
2111 input, pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(1)));
2112 EXPECT_EQ(4, output.tx_power());
2113 EXPECT_EQ(fbt::Appearance{kAppearance}, output.appearance());
2114 ASSERT_EQ(1u, output.service_uuids().size());
2115 EXPECT_EQ(kServiceUuid, UuidFromFidl(output.service_uuids().front()));
2116 ASSERT_EQ(1u, output.service_data().size());
2117 ASSERT_TRUE(output.has_timestamp());
2118 EXPECT_EQ(output.timestamp(), zx::time(1).get());
2119 auto service_data = output.service_data().front();
2120 EXPECT_EQ(kServiceUuid, UuidFromFidl(service_data.uuid));
2121 EXPECT_TRUE(
2122 ContainersEqual(bt::BufferView(service_bytes), service_data.data));
2123 EXPECT_EQ(1u, output.manufacturer_data().size());
2124 auto manufacturer_data = output.manufacturer_data().front();
2125 EXPECT_EQ(kManufacturer, manufacturer_data.company_id);
2126 EXPECT_TRUE(ContainersEqual(bt::BufferView(manufacturer_bytes),
2127 manufacturer_data.data));
2128 EXPECT_THAT(output.uris(), ::testing::ElementsAre(kUri));
2129 }
2130
TEST(HelpersTest,AdvertisingDataToFidlScanDataOmitsNonEnumeratedAppearance)2131 TEST(HelpersTest, AdvertisingDataToFidlScanDataOmitsNonEnumeratedAppearance) {
2132 // There is an "unknown" appearance, which is why this isn't named that.
2133 const uint16_t kNonEnumeratedAppearance = 0xFFFFu;
2134 bt::AdvertisingData input;
2135 input.SetAppearance(kNonEnumeratedAppearance);
2136
2137 EXPECT_FALSE(AdvertisingDataToFidlScanData(
2138 input, pw::chrono::SystemClock::time_point())
2139 .has_appearance());
2140
2141 const uint16_t kKnownAppearance = 832u; // HEART_RATE_SENSOR
2142 input.SetAppearance(kKnownAppearance);
2143
2144 EXPECT_TRUE(AdvertisingDataToFidlScanData(
2145 input, pw::chrono::SystemClock::time_point())
2146 .has_appearance());
2147 }
2148
TEST_F(HelpersTestWithLoop,PeerToFidlLeWithAllFields)2149 TEST_F(HelpersTestWithLoop, PeerToFidlLeWithAllFields) {
2150 RunLoopFor(zx::duration(2));
2151
2152 const bt::PeerId kPeerId(1);
2153 const bt::DeviceAddress kAddr(bt::DeviceAddress::Type::kLEPublic,
2154 {1, 0, 0, 0, 0, 0});
2155 bt::gap::PeerMetrics metrics;
2156 bt::gap::Peer peer([](auto&, auto) {},
2157 [](auto&) {},
2158 [](auto&) {},
2159 [](auto&) { return false; },
2160 kPeerId,
2161 kAddr,
2162 /*connectable=*/true,
2163 &metrics,
2164 pw_dispatcher());
2165 peer.RegisterName("name");
2166 const int8_t kRssi = 1;
2167 auto adv_bytes = bt::StaticByteBuffer(
2168 // Uri: "https://abc.xyz"
2169 0x0B,
2170 bt::DataType::kURI,
2171 0x17,
2172 '/',
2173 '/',
2174 'a',
2175 'b',
2176 'c',
2177 '.',
2178 'x',
2179 'y',
2180 'z');
2181 peer.MutLe().SetAdvertisingData(
2182 kRssi,
2183 adv_bytes,
2184 pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(1)));
2185
2186 fble::Peer fidl_peer = PeerToFidlLe(peer);
2187 ASSERT_TRUE(fidl_peer.has_id());
2188 EXPECT_EQ(fidl_peer.id().value, kPeerId.value());
2189 ASSERT_TRUE(fidl_peer.has_bonded());
2190 EXPECT_FALSE(fidl_peer.bonded());
2191 ASSERT_TRUE(fidl_peer.has_name());
2192 EXPECT_EQ(fidl_peer.name(), "name");
2193 ASSERT_TRUE(fidl_peer.has_rssi());
2194 EXPECT_EQ(fidl_peer.rssi(), kRssi);
2195 ASSERT_TRUE(fidl_peer.has_data());
2196 EXPECT_THAT(fidl_peer.data().uris(),
2197 ::testing::ElementsAre("https://abc.xyz"));
2198 ASSERT_TRUE(fidl_peer.has_last_updated());
2199 EXPECT_EQ(fidl_peer.last_updated(), 2);
2200 ASSERT_TRUE(fidl_peer.data().has_timestamp());
2201 EXPECT_EQ(fidl_peer.data().timestamp(), 1);
2202 }
2203
TEST_F(HelpersTestWithLoop,PeerToFidlLeWithoutAdvertisingData)2204 TEST_F(HelpersTestWithLoop, PeerToFidlLeWithoutAdvertisingData) {
2205 const bt::PeerId kPeerId(1);
2206 const bt::DeviceAddress kAddr(bt::DeviceAddress::Type::kLEPublic,
2207 {1, 0, 0, 0, 0, 0});
2208 bt::gap::PeerMetrics metrics;
2209 bt::gap::Peer peer([](auto&, auto) {},
2210 [](auto&) {},
2211 [](auto&) {},
2212 [](auto&) { return false; },
2213 kPeerId,
2214 kAddr,
2215 /*connectable=*/true,
2216 &metrics,
2217 pw_dispatcher());
2218
2219 fble::Peer fidl_peer = PeerToFidlLe(peer);
2220 ASSERT_TRUE(fidl_peer.has_id());
2221 EXPECT_EQ(fidl_peer.id().value, kPeerId.value());
2222 ASSERT_TRUE(fidl_peer.has_bonded());
2223 EXPECT_FALSE(fidl_peer.bonded());
2224 EXPECT_FALSE(fidl_peer.has_name());
2225 EXPECT_FALSE(fidl_peer.has_rssi());
2226 EXPECT_FALSE(fidl_peer.has_data());
2227 ASSERT_TRUE(fidl_peer.has_last_updated());
2228 EXPECT_EQ(fidl_peer.last_updated(), 0);
2229 }
2230
TEST(HelpersTest,PeerIdFromString)2231 TEST(HelpersTest, PeerIdFromString) {
2232 EXPECT_FALSE(PeerIdFromString(std::string()));
2233 EXPECT_FALSE(PeerIdFromString("-1"));
2234 EXPECT_FALSE(PeerIdFromString("g"));
2235 EXPECT_EQ(PeerIdFromString("0"), std::optional(bt::PeerId(0)));
2236 EXPECT_EQ(PeerIdFromString("FFFFFFFFFFFFFFFF"),
2237 std::optional(bt::PeerId(std::numeric_limits<uint64_t>::max())));
2238 // ID is 1 more than max.
2239 EXPECT_FALSE(PeerIdFromString("10000000000000000"));
2240 EXPECT_EQ(PeerIdFromString("0123456789"),
2241 std::optional(bt::PeerId(0x123456789)));
2242 EXPECT_EQ(PeerIdFromString("abcdef"), std::optional(bt::PeerId(0xabcdef)));
2243 EXPECT_EQ(PeerIdFromString("ABCDEF"), std::optional(bt::PeerId(0xabcdef)));
2244 }
2245
TEST(HelpersTest,ScoPacketStatusToFidl)2246 TEST(HelpersTest, ScoPacketStatusToFidl) {
2247 EXPECT_EQ(
2248 ScoPacketStatusToFidl(
2249 bt::hci_spec::SynchronousDataPacketStatusFlag::kCorrectlyReceived),
2250 fuchsia::bluetooth::bredr::RxPacketStatus::CORRECTLY_RECEIVED_DATA);
2251 EXPECT_EQ(
2252 ScoPacketStatusToFidl(
2253 bt::hci_spec::SynchronousDataPacketStatusFlag::kPossiblyInvalid),
2254 fuchsia::bluetooth::bredr::RxPacketStatus::POSSIBLY_INVALID_DATA);
2255 EXPECT_EQ(ScoPacketStatusToFidl(
2256 bt::hci_spec::SynchronousDataPacketStatusFlag::kNoDataReceived),
2257 fuchsia::bluetooth::bredr::RxPacketStatus::NO_DATA_RECEIVED);
2258 EXPECT_EQ(
2259 ScoPacketStatusToFidl(
2260 bt::hci_spec::SynchronousDataPacketStatusFlag::kDataPartiallyLost),
2261 fuchsia::bluetooth::bredr::RxPacketStatus::DATA_PARTIALLY_LOST);
2262 }
2263
TEST(HelpersTest,Gatt2DescriptorFromFidlNoPermissions)2264 TEST(HelpersTest, Gatt2DescriptorFromFidlNoPermissions) {
2265 fbg2::Descriptor desc;
2266 fbt::Uuid fidl_uuid{{}};
2267 desc.set_type(fidl_uuid);
2268 desc.set_handle(fbg2::Handle{3});
2269 EXPECT_EQ(Gatt2DescriptorFromFidl(desc), nullptr);
2270 }
2271
TEST(HelpersTest,Gatt2DescriptorFromFidlNoType)2272 TEST(HelpersTest, Gatt2DescriptorFromFidlNoType) {
2273 fbg2::Descriptor desc;
2274 fbg2::AttributePermissions permissions;
2275 desc.set_permissions(std::move(permissions));
2276 desc.set_handle(fbg2::Handle{3});
2277 EXPECT_EQ(Gatt2DescriptorFromFidl(desc), nullptr);
2278 }
2279
TEST(HelpersTest,Gatt2DescriptorFromFidlNoHandle)2280 TEST(HelpersTest, Gatt2DescriptorFromFidlNoHandle) {
2281 fbg2::Descriptor desc;
2282 fbg2::AttributePermissions permissions;
2283 desc.set_permissions(std::move(permissions));
2284 fbt::Uuid fidl_uuid{{}};
2285 desc.set_type(fidl_uuid);
2286 EXPECT_EQ(Gatt2DescriptorFromFidl(desc), nullptr);
2287 }
2288
TEST(HelpersTest,Gatt2DescriptorFromFidlSuccessWithEmptyPermissions)2289 TEST(HelpersTest, Gatt2DescriptorFromFidlSuccessWithEmptyPermissions) {
2290 bt::UInt128 type = {2};
2291
2292 fbg2::Descriptor desc;
2293 fbg2::AttributePermissions permissions;
2294 desc.set_permissions(std::move(permissions));
2295 fbt::Uuid fidl_uuid{type};
2296 desc.set_type(fidl_uuid);
2297 desc.set_handle(fbg2::Handle{3});
2298
2299 std::unique_ptr<bt::gatt::Descriptor> out = Gatt2DescriptorFromFidl(desc);
2300 ASSERT_TRUE(out);
2301 EXPECT_EQ(out->id(), 3u);
2302 EXPECT_EQ(out->type(), bt::UUID(type));
2303 EXPECT_FALSE(out->read_permissions().allowed());
2304 EXPECT_FALSE(out->write_permissions().allowed());
2305 }
2306
TEST(HelpersTest,Gatt2DescriptorFromFidlSuccessWithEmptyReadWritePermissions)2307 TEST(HelpersTest, Gatt2DescriptorFromFidlSuccessWithEmptyReadWritePermissions) {
2308 fbg2::Descriptor desc;
2309 fbg2::AttributePermissions permissions;
2310 permissions.set_read(fbg2::SecurityRequirements());
2311 permissions.set_write(fbg2::SecurityRequirements());
2312 desc.set_permissions(std::move(permissions));
2313 fbt::Uuid fidl_uuid{{}};
2314 desc.set_type(fidl_uuid);
2315 desc.set_handle(fbg2::Handle{3});
2316
2317 std::unique_ptr<bt::gatt::Descriptor> out = Gatt2DescriptorFromFidl(desc);
2318 ASSERT_TRUE(out);
2319 EXPECT_TRUE(out->read_permissions().allowed_without_security());
2320 EXPECT_TRUE(out->write_permissions().allowed_without_security());
2321 }
2322
TEST(HelpersTest,Gatt2DescriptorFromFidlSuccessWithReadPermissions)2323 TEST(HelpersTest, Gatt2DescriptorFromFidlSuccessWithReadPermissions) {
2324 fbg2::Descriptor desc;
2325 fbg2::AttributePermissions permissions;
2326 fbg2::SecurityRequirements read_reqs;
2327 read_reqs.set_authentication_required(true);
2328 read_reqs.set_authorization_required(true);
2329 read_reqs.set_encryption_required(true);
2330 permissions.set_read(std::move(read_reqs));
2331 desc.set_permissions(std::move(permissions));
2332 desc.set_type({{}});
2333 desc.set_handle(fbg2::Handle{3});
2334
2335 std::unique_ptr<bt::gatt::Descriptor> out = Gatt2DescriptorFromFidl(desc);
2336 ASSERT_TRUE(out);
2337 EXPECT_TRUE(out->read_permissions().encryption_required());
2338 EXPECT_TRUE(out->read_permissions().authentication_required());
2339 EXPECT_TRUE(out->read_permissions().authorization_required());
2340 EXPECT_FALSE(out->write_permissions().allowed());
2341 }
2342
TEST(HelpersTest,Gatt2DescriptorFromFidlSuccessWithWritePermissions)2343 TEST(HelpersTest, Gatt2DescriptorFromFidlSuccessWithWritePermissions) {
2344 fbg2::Descriptor desc;
2345 fbg2::AttributePermissions permissions;
2346 fbg2::SecurityRequirements write_reqs;
2347 write_reqs.set_authentication_required(true);
2348 write_reqs.set_authorization_required(true);
2349 write_reqs.set_encryption_required(true);
2350 permissions.set_write(std::move(write_reqs));
2351 desc.set_permissions(std::move(permissions));
2352 desc.set_type({{}});
2353 desc.set_handle(fbg2::Handle{3});
2354
2355 std::unique_ptr<bt::gatt::Descriptor> out = Gatt2DescriptorFromFidl(desc);
2356 ASSERT_TRUE(out);
2357 EXPECT_FALSE(out->read_permissions().allowed());
2358 EXPECT_TRUE(out->write_permissions().encryption_required());
2359 EXPECT_TRUE(out->write_permissions().authentication_required());
2360 EXPECT_TRUE(out->write_permissions().authorization_required());
2361 }
2362
TEST(HelpersTest,Gatt2CharacteristicFromFidlNoProperties)2363 TEST(HelpersTest, Gatt2CharacteristicFromFidlNoProperties) {
2364 fbg2::Characteristic chrc;
2365 chrc.set_permissions(fbg2::AttributePermissions());
2366 chrc.set_type(fbt::Uuid{{}});
2367 chrc.set_handle(fbg2::Handle{3});
2368 EXPECT_FALSE(Gatt2CharacteristicFromFidl(chrc));
2369 }
2370
TEST(HelpersTest,Gatt2CharacteristicFromFidlNoPermissions)2371 TEST(HelpersTest, Gatt2CharacteristicFromFidlNoPermissions) {
2372 fbg2::Characteristic chrc;
2373 chrc.mutable_properties();
2374 chrc.set_type(fbt::Uuid{{}});
2375 chrc.set_handle(fbg2::Handle{3});
2376 EXPECT_FALSE(Gatt2CharacteristicFromFidl(chrc));
2377 }
2378
TEST(HelpersTest,Gatt2CharacteristicFromFidlSuccessWithPropertiesAndEmptyPermissions)2379 TEST(HelpersTest,
2380 Gatt2CharacteristicFromFidlSuccessWithPropertiesAndEmptyPermissions) {
2381 fbg2::Characteristic chrc;
2382 chrc.set_properties(fbg2::CharacteristicPropertyBits::WRITE |
2383 fbg2::CharacteristicPropertyBits::RELIABLE_WRITE);
2384 chrc.set_permissions(fbg2::AttributePermissions());
2385 bt::UInt128 type = {2};
2386 chrc.set_type(fbt::Uuid{type});
2387 chrc.set_handle(fbg2::Handle{3});
2388 std::unique_ptr<bt::gatt::Characteristic> out =
2389 Gatt2CharacteristicFromFidl(chrc);
2390 ASSERT_TRUE(out);
2391 EXPECT_EQ(
2392 out->properties(),
2393 bt::gatt::Property::kWrite | bt::gatt::Property::kExtendedProperties);
2394 EXPECT_EQ(out->extended_properties(),
2395 bt::gatt::ExtendedProperty::kReliableWrite);
2396 EXPECT_FALSE(out->write_permissions().allowed());
2397 EXPECT_FALSE(out->read_permissions().allowed());
2398 EXPECT_FALSE(out->update_permissions().allowed());
2399 EXPECT_EQ(out->type(), bt::UUID(type));
2400 EXPECT_EQ(out->id(), 3u);
2401 }
2402
TEST(HelpersTest,Gatt2CharacteristicFromFidlSupportsNotifyButDoesNotHavePermission)2403 TEST(HelpersTest,
2404 Gatt2CharacteristicFromFidlSupportsNotifyButDoesNotHavePermission) {
2405 fbg2::Characteristic chrc;
2406 chrc.set_properties(fbg2::CharacteristicPropertyBits::NOTIFY);
2407 chrc.set_permissions(fbg2::AttributePermissions());
2408 bt::UInt128 type = {2};
2409 chrc.set_type(fbt::Uuid{type});
2410 chrc.set_handle(fbg2::Handle{3});
2411 std::unique_ptr<bt::gatt::Characteristic> out =
2412 Gatt2CharacteristicFromFidl(chrc);
2413 ASSERT_FALSE(out);
2414 }
2415
TEST(HelpersTest,Gatt2CharacteristicFromFidlDoesNotSupportNotifyButDoesHaveUpdatePermission)2416 TEST(
2417 HelpersTest,
2418 Gatt2CharacteristicFromFidlDoesNotSupportNotifyButDoesHaveUpdatePermission) {
2419 fbg2::Characteristic chrc;
2420 chrc.mutable_properties();
2421 fbg2::AttributePermissions permissions;
2422 permissions.set_update(fbg2::SecurityRequirements());
2423 chrc.set_permissions(std::move(permissions));
2424 bt::UInt128 type = {2};
2425 chrc.set_type(fbt::Uuid{type});
2426 chrc.set_handle(fbg2::Handle{3});
2427 std::unique_ptr<bt::gatt::Characteristic> out =
2428 Gatt2CharacteristicFromFidl(chrc);
2429 ASSERT_FALSE(out);
2430 }
2431
TEST(HelpersTest,Gatt2CharacteristicFromFidlSuccessWithEmptySecurityRequirements)2432 TEST(HelpersTest,
2433 Gatt2CharacteristicFromFidlSuccessWithEmptySecurityRequirements) {
2434 fbg2::Characteristic chrc;
2435 chrc.set_properties(fbg2::CharacteristicPropertyBits::NOTIFY);
2436 fbg2::AttributePermissions permissions;
2437 permissions.set_read(fbg2::SecurityRequirements());
2438 permissions.set_write(fbg2::SecurityRequirements());
2439 permissions.set_update(fbg2::SecurityRequirements());
2440 chrc.set_permissions(std::move(permissions));
2441 bt::UInt128 type = {2};
2442 chrc.set_type(fbt::Uuid{type});
2443 chrc.set_handle(fbg2::Handle{3});
2444 std::unique_ptr<bt::gatt::Characteristic> out =
2445 Gatt2CharacteristicFromFidl(chrc);
2446 ASSERT_TRUE(out);
2447 EXPECT_TRUE(out->write_permissions().allowed_without_security());
2448 EXPECT_TRUE(out->read_permissions().allowed_without_security());
2449 EXPECT_TRUE(out->update_permissions().allowed_without_security());
2450 }
2451
TEST(HelpersTest,Gatt2CharacteristicFromFidlSuccessWithAllSecurityRequirements)2452 TEST(HelpersTest,
2453 Gatt2CharacteristicFromFidlSuccessWithAllSecurityRequirements) {
2454 fbg2::Characteristic chrc;
2455 chrc.set_properties(fbg2::CharacteristicPropertyBits::NOTIFY);
2456 fbg2::AttributePermissions permissions;
2457 fbg2::SecurityRequirements read_reqs;
2458 read_reqs.set_authentication_required(true);
2459 read_reqs.set_authorization_required(true);
2460 read_reqs.set_encryption_required(true);
2461 permissions.set_read(std::move(read_reqs));
2462 fbg2::SecurityRequirements write_reqs;
2463 write_reqs.set_authentication_required(true);
2464 write_reqs.set_authorization_required(true);
2465 write_reqs.set_encryption_required(true);
2466 permissions.set_write(std::move(write_reqs));
2467 fbg2::SecurityRequirements update_reqs;
2468 update_reqs.set_authentication_required(true);
2469 update_reqs.set_authorization_required(true);
2470 update_reqs.set_encryption_required(true);
2471 permissions.set_update(std::move(update_reqs));
2472 chrc.set_permissions(std::move(permissions));
2473 bt::UInt128 type = {2};
2474 chrc.set_type(fbt::Uuid{type});
2475 chrc.set_handle(fbg2::Handle{3});
2476 std::unique_ptr<bt::gatt::Characteristic> out =
2477 Gatt2CharacteristicFromFidl(chrc);
2478 ASSERT_TRUE(out);
2479 EXPECT_TRUE(out->write_permissions().authentication_required());
2480 EXPECT_TRUE(out->write_permissions().authorization_required());
2481 EXPECT_TRUE(out->write_permissions().encryption_required());
2482 EXPECT_TRUE(out->read_permissions().authentication_required());
2483 EXPECT_TRUE(out->read_permissions().authorization_required());
2484 EXPECT_TRUE(out->read_permissions().encryption_required());
2485 EXPECT_TRUE(out->update_permissions().authentication_required());
2486 EXPECT_TRUE(out->update_permissions().authorization_required());
2487 EXPECT_TRUE(out->update_permissions().encryption_required());
2488 }
2489
TEST(HelpersTest,Gatt2CharacteristicFromFidlWithInvalidDescriptor)2490 TEST(HelpersTest, Gatt2CharacteristicFromFidlWithInvalidDescriptor) {
2491 fbg2::Characteristic chrc;
2492 chrc.mutable_properties();
2493 chrc.set_permissions(fbg2::AttributePermissions());
2494 bt::UInt128 type = {2};
2495 chrc.set_type(fbt::Uuid{type});
2496 chrc.set_handle(fbg2::Handle{3});
2497 std::vector<fbg2::Descriptor> descriptors;
2498 descriptors.emplace_back(fbg2::Descriptor());
2499 chrc.set_descriptors(std::move(descriptors));
2500 std::unique_ptr<bt::gatt::Characteristic> out =
2501 Gatt2CharacteristicFromFidl(chrc);
2502 ASSERT_FALSE(out);
2503 }
2504
TEST(HelpersTest,Gatt2CharacteristicFromFidlWith2Descriptors)2505 TEST(HelpersTest, Gatt2CharacteristicFromFidlWith2Descriptors) {
2506 fbg2::Characteristic chrc;
2507 chrc.mutable_properties();
2508 chrc.set_permissions(fbg2::AttributePermissions());
2509 bt::UInt128 chrc_type = {2};
2510 chrc.set_type(fbt::Uuid{chrc_type});
2511 chrc.set_handle(fbg2::Handle{3});
2512
2513 std::vector<fbg2::Descriptor> descriptors;
2514
2515 fbg2::Descriptor desc_0;
2516 desc_0.set_permissions(fbg2::AttributePermissions());
2517 bt::UInt128 desc_type_0 = {4};
2518 desc_0.set_type(fbt::Uuid{desc_type_0});
2519 desc_0.set_handle(fbg2::Handle{5});
2520 descriptors.push_back(std::move(desc_0));
2521
2522 fbg2::Descriptor desc_1;
2523 desc_1.set_permissions(fbg2::AttributePermissions());
2524 bt::UInt128 desc_type_1 = {6};
2525 desc_1.set_type(fbt::Uuid{desc_type_1});
2526 desc_1.set_handle(fbg2::Handle{7});
2527 descriptors.push_back(std::move(desc_1));
2528
2529 chrc.set_descriptors(std::move(descriptors));
2530
2531 std::unique_ptr<bt::gatt::Characteristic> out =
2532 Gatt2CharacteristicFromFidl(chrc);
2533 ASSERT_TRUE(out);
2534 ASSERT_EQ(out->descriptors().size(), 2u);
2535 EXPECT_EQ(out->descriptors()[0]->id(), 5u);
2536 EXPECT_EQ(out->descriptors()[0]->type(), bt::UUID(desc_type_0));
2537 EXPECT_FALSE(out->descriptors()[0]->read_permissions().allowed());
2538 EXPECT_FALSE(out->descriptors()[0]->write_permissions().allowed());
2539 EXPECT_EQ(out->descriptors()[1]->id(), 7u);
2540 EXPECT_EQ(out->descriptors()[1]->type(), bt::UUID(desc_type_1));
2541 EXPECT_FALSE(out->descriptors()[1]->read_permissions().allowed());
2542 EXPECT_FALSE(out->descriptors()[1]->write_permissions().allowed());
2543 }
2544
TEST(HelpersTest,DataPathDirectionFromFidl)2545 TEST(HelpersTest, DataPathDirectionFromFidl) {
2546 EXPECT_EQ(DataPathDirectionFromFidl(fuchsia::bluetooth::DataDirection::INPUT),
2547 pw::bluetooth::emboss::DataPathDirection::INPUT);
2548 EXPECT_EQ(
2549 DataPathDirectionFromFidl(fuchsia::bluetooth::DataDirection::OUTPUT),
2550 pw::bluetooth::emboss::DataPathDirection::OUTPUT);
2551 }
2552
TEST(HelpersTest,CodingFormatFromFidl)2553 TEST(HelpersTest, CodingFormatFromFidl) {
2554 EXPECT_EQ(
2555 CodingFormatFromFidl(fuchsia::bluetooth::AssignedCodingFormat::U_LAW_LOG),
2556 pw::bluetooth::emboss::CodingFormat::U_LAW);
2557 EXPECT_EQ(
2558 CodingFormatFromFidl(fuchsia::bluetooth::AssignedCodingFormat::A_LAW_LOG),
2559 pw::bluetooth::emboss::CodingFormat::A_LAW);
2560 EXPECT_EQ(
2561 CodingFormatFromFidl(fuchsia::bluetooth::AssignedCodingFormat::CVSD),
2562 pw::bluetooth::emboss::CodingFormat::CVSD);
2563 EXPECT_EQ(CodingFormatFromFidl(
2564 fuchsia::bluetooth::AssignedCodingFormat::TRANSPARENT),
2565 pw::bluetooth::emboss::CodingFormat::TRANSPARENT);
2566 EXPECT_EQ(CodingFormatFromFidl(
2567 fuchsia::bluetooth::AssignedCodingFormat::LINEAR_PCM),
2568 pw::bluetooth::emboss::CodingFormat::LINEAR_PCM);
2569 EXPECT_EQ(
2570 CodingFormatFromFidl(fuchsia::bluetooth::AssignedCodingFormat::MSBC),
2571 pw::bluetooth::emboss::CodingFormat::MSBC);
2572 EXPECT_EQ(CodingFormatFromFidl(fuchsia::bluetooth::AssignedCodingFormat::LC3),
2573 pw::bluetooth::emboss::CodingFormat::LC3);
2574 EXPECT_EQ(
2575 CodingFormatFromFidl(fuchsia::bluetooth::AssignedCodingFormat::G_729A),
2576 pw::bluetooth::emboss::CodingFormat::G729A);
2577 }
2578
TEST(HelpersTest,AssignedCodecIdFromFidl)2579 TEST(HelpersTest, AssignedCodecIdFromFidl) {
2580 // Assigned format
2581 fuchsia::bluetooth::CodecId fidl_codec_id;
2582 fidl_codec_id.set_assigned_format(
2583 fuchsia::bluetooth::AssignedCodingFormat::LC3);
2584 auto codec_id = CodecIdFromFidl(fidl_codec_id);
2585 auto view = codec_id.view();
2586 EXPECT_EQ(view.coding_format().Read(),
2587 pw::bluetooth::emboss::CodingFormat::LC3);
2588 }
2589
TEST(HelpersTest,VendorCodecIdFromFidl)2590 TEST(HelpersTest, VendorCodecIdFromFidl) {
2591 // Vendor-specific format
2592 uint16_t kCompanyId = 0x1234;
2593 uint16_t kVendorId = 0xfedc;
2594 fuchsia::bluetooth::CodecId fidl_codec_id;
2595 fuchsia::bluetooth::VendorCodingFormat vendor_format;
2596 vendor_format.set_company_id(kCompanyId);
2597 vendor_format.set_vendor_id(kVendorId);
2598 fidl_codec_id.set_vendor_format(std::move(vendor_format));
2599 auto codec_id = CodecIdFromFidl(fidl_codec_id);
2600 auto view = codec_id.view();
2601 EXPECT_EQ(view.coding_format().Read(),
2602 pw::bluetooth::emboss::CodingFormat::VENDOR_SPECIFIC);
2603 EXPECT_EQ(view.company_id().Read(), kCompanyId);
2604 EXPECT_EQ(view.vendor_codec_id().Read(), kVendorId);
2605 }
2606
TEST(HelpersTest,LogicalTransportTypeFromFidl)2607 TEST(HelpersTest, LogicalTransportTypeFromFidl) {
2608 EXPECT_EQ(LogicalTransportTypeFromFidl(
2609 fuchsia::bluetooth::LogicalTransportType::LE_CIS),
2610 pw::bluetooth::emboss::LogicalTransportType::LE_CIS);
2611 EXPECT_EQ(LogicalTransportTypeFromFidl(
2612 fuchsia::bluetooth::LogicalTransportType::LE_BIS),
2613 pw::bluetooth::emboss::LogicalTransportType::LE_BIS);
2614 }
2615
ValidateCisEstablishedUnidirectionalParams(const fuchsia::bluetooth::le::CisUnidirectionalParams & fidl_params,const bt::iso::CisEstablishedParameters::CisUnidirectionalParams & iso_params)2616 static void ValidateCisEstablishedUnidirectionalParams(
2617 const fuchsia::bluetooth::le::CisUnidirectionalParams& fidl_params,
2618 const bt::iso::CisEstablishedParameters::CisUnidirectionalParams&
2619 iso_params) {
2620 zx::duration transport_latency = zx::usec(iso_params.transport_latency);
2621 EXPECT_EQ(fidl_params.transport_latency(), transport_latency.get());
2622 // phy is not included in FIDL output
2623 EXPECT_EQ(fidl_params.burst_number(), iso_params.burst_number);
2624 EXPECT_EQ(fidl_params.flush_timeout(), iso_params.flush_timeout);
2625 // max_pdu_size is not included in FIDL output
2626 }
2627
2628 // Helper function to validate a single set of test values
ValidateCisEstablishedConversion(const bt::iso::CisEstablishedParameters & params_in)2629 static void ValidateCisEstablishedConversion(
2630 const bt::iso::CisEstablishedParameters& params_in) {
2631 auto params_out = CisEstablishedParametersToFidl(params_in);
2632
2633 zx::duration cig_sync_delay(params_out.cig_sync_delay());
2634 EXPECT_EQ(cig_sync_delay, zx::usec(params_in.cig_sync_delay));
2635
2636 zx::duration cis_sync_delay(params_out.cis_sync_delay());
2637 EXPECT_EQ(cis_sync_delay, zx::usec(params_in.cis_sync_delay));
2638
2639 EXPECT_EQ(params_out.max_subevents(), params_in.max_subevents);
2640
2641 zx::duration iso_interval(params_out.iso_interval());
2642 EXPECT_EQ(
2643 iso_interval,
2644 zx::usec(params_in.iso_interval *
2645 bt::iso::CisEstablishedParameters::kIsoIntervalToMicroseconds));
2646
2647 if (params_in.c_to_p_params.burst_number > 0) {
2648 ValidateCisEstablishedUnidirectionalParams(
2649 params_out.central_to_peripheral_params(), params_in.c_to_p_params);
2650 } else {
2651 EXPECT_FALSE(params_out.has_central_to_peripheral_params());
2652 }
2653
2654 if (params_in.p_to_c_params.burst_number > 0) {
2655 ValidateCisEstablishedUnidirectionalParams(
2656 params_out.peripheral_to_central_params(), params_in.p_to_c_params);
2657 } else {
2658 EXPECT_FALSE(params_out.has_peripheral_to_central_params());
2659 }
2660 }
2661
TEST(HelpersTest,CisEstablishedParametersToFidl)2662 TEST(HelpersTest, CisEstablishedParametersToFidl) {
2663 // Min values for all bidirectional params
2664 bt::iso::CisEstablishedParameters params1 = {
2665 .cig_sync_delay = 0x0000ea,
2666 .cis_sync_delay = 0x0000ea,
2667 .max_subevents = 0x01,
2668 .iso_interval = 0x0004,
2669 .c_to_p_params = kMinUniParams,
2670 .p_to_c_params = kMaxUniParams,
2671 };
2672 ValidateCisEstablishedConversion(params1);
2673
2674 // Values somewhere between min and max
2675 bt::iso::CisEstablishedParameters params2 = {
2676 .cig_sync_delay = 0x001234,
2677 .cis_sync_delay = 0x005678,
2678 .max_subevents = 0x10,
2679 .iso_interval = 0x246,
2680 .c_to_p_params =
2681 {
2682 .transport_latency = 0x55aa55,
2683 .phy = pw::bluetooth::emboss::IsoPhyType::LE_2M,
2684 .burst_number = 0x02,
2685 .flush_timeout = 0x42,
2686 .max_pdu_size = 0xa3,
2687 },
2688 .p_to_c_params =
2689 {
2690 .transport_latency = 0xabc123,
2691 .phy = pw::bluetooth::emboss::IsoPhyType::LE_CODED,
2692 .burst_number = 0x0F,
2693 .flush_timeout = 0x53,
2694 .max_pdu_size = 0x37,
2695 },
2696 };
2697 ValidateCisEstablishedConversion(params2);
2698
2699 // Max values for all bidirectional params
2700 bt::iso::CisEstablishedParameters params3 = {
2701 .cig_sync_delay = 0x7fffff,
2702 .cis_sync_delay = 0x7fffff,
2703 .max_subevents = 0x1f,
2704 .iso_interval = 0x0c80,
2705 .c_to_p_params = kMaxUniParams,
2706 .p_to_c_params = kMinUniParams,
2707 };
2708 ValidateCisEstablishedConversion(params3);
2709
2710 // Parameters where the burst_number is zero, indicating that this direction
2711 // is not configured. All other values should be ignored and the corresponding
2712 // FIDL unidirectional parameters should not be instantiated.
2713 bt::iso::CisEstablishedParameters::CisUnidirectionalParams
2714 unconfigured_params = {
2715 .transport_latency = 0,
2716 .phy = pw::bluetooth::emboss::IsoPhyType::LE_1M,
2717 .burst_number = 0x00,
2718 .flush_timeout = 0x00,
2719 .max_pdu_size = 0x00,
2720 };
2721
2722 // Unconfigured central => peripheral
2723 bt::iso::CisEstablishedParameters params4 = params2;
2724 params4.c_to_p_params = unconfigured_params;
2725 ValidateCisEstablishedConversion(params4);
2726
2727 // Unconfigured peripheral => central
2728 params4 = params2;
2729 params4.p_to_c_params = unconfigured_params;
2730 ValidateCisEstablishedConversion(params4);
2731 }
2732
2733 } // namespace
2734 } // namespace bthost::fidl_helpers
2735