xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/fuchsia/host/fidl/helpers_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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