• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_bluetooth_sapphire/internal/host/gap/android_vendor_capabilities.h"
16 
17 #include "pw_bluetooth_sapphire/internal/host/transport/control_packets.h"
18 #include "pw_unit_test/framework.h"
19 
20 namespace bt::gap {
21 namespace {
22 
23 namespace android_emb = pw::bluetooth::vendor::android_hci;
24 namespace pwemb = pw::bluetooth::emboss;
25 
26 using android_emb::Capability;
27 
TEST(AndroidVendorCapabilitiesTest,NonSuccess)28 TEST(AndroidVendorCapabilitiesTest, NonSuccess) {
29   auto params = hci::EventPacket::New<
30       android_emb::LEGetVendorCapabilitiesCommandCompleteEventWriter>(
31       hci_spec::kCommandCompleteEventCode,
32       android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
33           version_0_55_size());
34 
35   auto view = params.unchecked_view_t();
36   view.status().Write(pw::bluetooth::emboss::StatusCode::UNKNOWN_COMMAND);
37 
38   view.max_advt_instances().Write(1);
39   view.offloaded_resolution_of_private_address().Write(Capability::CAPABLE);
40   view.total_scan_results_storage().Write(2);
41   view.max_irk_list_sz().Write(3);
42   view.filtering_support().Write(Capability::CAPABLE);
43   view.max_filter().Write(4);
44   view.activity_energy_info_support().Write(Capability::CAPABLE);
45 
46   AndroidVendorCapabilities capabilities = AndroidVendorCapabilities::New(view);
47   EXPECT_EQ(0u, capabilities.max_simultaneous_advertisements());
48   EXPECT_EQ(false, capabilities.supports_offloaded_rpa());
49   EXPECT_EQ(0u, capabilities.scan_results_storage_bytes());
50   EXPECT_EQ(0u, capabilities.irk_list_size());
51   EXPECT_EQ(false, capabilities.supports_filtering());
52   EXPECT_EQ(0u, capabilities.max_filters());
53   EXPECT_EQ(false, capabilities.supports_activity_energy_info());
54   EXPECT_EQ(0u, capabilities.version_major());
55   EXPECT_EQ(0u, capabilities.version_minor());
56   EXPECT_EQ(0u, capabilities.max_advertisers_tracked());
57   EXPECT_EQ(false, capabilities.supports_extended_scan());
58   EXPECT_EQ(false, capabilities.supports_debug_logging());
59   EXPECT_EQ(false, capabilities.supports_offloading_le_address_generation());
60   EXPECT_EQ(0u, capabilities.a2dp_source_offload_capability_mask());
61   EXPECT_EQ(false, capabilities.supports_bluetooth_quality_report());
62   EXPECT_EQ(0u, capabilities.supports_dynamic_audio_buffer());
63   EXPECT_EQ(false, capabilities.supports_a2dp_offload_v2());
64 }
65 
TEST(AndroidVendorCapabilitiesTest,Version055)66 TEST(AndroidVendorCapabilitiesTest, Version055) {
67   auto params = hci::EventPacket::New<
68       android_emb::LEGetVendorCapabilitiesCommandCompleteEventWriter>(
69       hci_spec::kCommandCompleteEventCode,
70       android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
71           version_0_55_size());
72 
73   auto view = params.unchecked_view_t();
74   view.status().Write(pwemb::StatusCode::SUCCESS);
75 
76   view.max_advt_instances().Write(1);
77   view.offloaded_resolution_of_private_address().Write(Capability::CAPABLE);
78   view.total_scan_results_storage().Write(2);
79   view.max_irk_list_sz().Write(3);
80   view.filtering_support().Write(Capability::CAPABLE);
81   view.max_filter().Write(4);
82   view.activity_energy_info_support().Write(Capability::CAPABLE);
83 
84   AndroidVendorCapabilities capabilities = AndroidVendorCapabilities::New(view);
85   EXPECT_EQ(1u, capabilities.max_simultaneous_advertisements());
86   EXPECT_EQ(true, capabilities.supports_offloaded_rpa());
87   EXPECT_EQ(2u, capabilities.scan_results_storage_bytes());
88   EXPECT_EQ(3u, capabilities.irk_list_size());
89   EXPECT_EQ(true, capabilities.supports_filtering());
90   EXPECT_EQ(4u, capabilities.max_filters());
91   EXPECT_EQ(true, capabilities.supports_activity_energy_info());
92   EXPECT_EQ(0u, capabilities.version_major());
93   EXPECT_EQ(55u, capabilities.version_minor());
94   EXPECT_EQ(0u, capabilities.max_advertisers_tracked());
95   EXPECT_EQ(false, capabilities.supports_extended_scan());
96   EXPECT_EQ(false, capabilities.supports_debug_logging());
97   EXPECT_EQ(false, capabilities.supports_offloading_le_address_generation());
98   EXPECT_EQ(0u, capabilities.a2dp_source_offload_capability_mask());
99   EXPECT_EQ(false, capabilities.supports_bluetooth_quality_report());
100   EXPECT_EQ(0u, capabilities.supports_dynamic_audio_buffer());
101   EXPECT_EQ(false, capabilities.supports_a2dp_offload_v2());
102 }
103 
TEST(AndroidVendorCapabilitiesTest,Version095)104 TEST(AndroidVendorCapabilitiesTest, Version095) {
105   auto params = hci::EventPacket::New<
106       android_emb::LEGetVendorCapabilitiesCommandCompleteEventWriter>(
107       hci_spec::kCommandCompleteEventCode,
108       android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
109           version_0_95_size());
110 
111   auto view = params.unchecked_view_t();
112   view.status().Write(pwemb::StatusCode::SUCCESS);
113 
114   view.max_advt_instances().Write(1);
115   view.offloaded_resolution_of_private_address().Write(Capability::CAPABLE);
116   view.total_scan_results_storage().Write(2);
117   view.max_irk_list_sz().Write(3);
118   view.filtering_support().Write(Capability::CAPABLE);
119   view.max_filter().Write(4);
120   view.activity_energy_info_support().Write(Capability::CAPABLE);
121   view.version_supported().major_number().Write(0);
122   view.version_supported().minor_number().Write(95);
123 
124   ASSERT_TRUE(view.has_total_num_of_advt_tracked().ValueOr(false));
125   view.total_num_of_advt_tracked().UncheckedWrite(5u);
126 
127   ASSERT_TRUE(view.has_extended_scan_support().ValueOr(false));
128   view.extended_scan_support().UncheckedWrite(Capability::CAPABLE);
129 
130   ASSERT_TRUE(view.has_debug_logging_supported().ValueOr(false));
131   view.debug_logging_supported().UncheckedWrite(Capability::CAPABLE);
132 
133   AndroidVendorCapabilities capabilities = AndroidVendorCapabilities::New(view);
134   EXPECT_EQ(1u, capabilities.max_simultaneous_advertisements());
135   EXPECT_EQ(true, capabilities.supports_offloaded_rpa());
136   EXPECT_EQ(2u, capabilities.scan_results_storage_bytes());
137   EXPECT_EQ(3u, capabilities.irk_list_size());
138   EXPECT_EQ(true, capabilities.supports_filtering());
139   EXPECT_EQ(4u, capabilities.max_filters());
140   EXPECT_EQ(true, capabilities.supports_activity_energy_info());
141   EXPECT_EQ(0u, capabilities.version_major());
142   EXPECT_EQ(95u, capabilities.version_minor());
143   EXPECT_EQ(5u, capabilities.max_advertisers_tracked());
144   EXPECT_EQ(true, capabilities.supports_extended_scan());
145   EXPECT_EQ(true, capabilities.supports_debug_logging());
146   EXPECT_EQ(false, capabilities.supports_offloading_le_address_generation());
147   EXPECT_EQ(0u, capabilities.a2dp_source_offload_capability_mask());
148   EXPECT_EQ(false, capabilities.supports_bluetooth_quality_report());
149   EXPECT_EQ(0u, capabilities.supports_dynamic_audio_buffer());
150   EXPECT_EQ(false, capabilities.supports_a2dp_offload_v2());
151 }
152 
TEST(AndroidVendorCapabilitiesTest,Version096)153 TEST(AndroidVendorCapabilitiesTest, Version096) {
154   auto params = hci::EventPacket::New<
155       android_emb::LEGetVendorCapabilitiesCommandCompleteEventWriter>(
156       hci_spec::kCommandCompleteEventCode,
157       android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
158           version_0_96_size());
159 
160   auto view = params.unchecked_view_t();
161   view.status().Write(pwemb::StatusCode::SUCCESS);
162 
163   view.max_advt_instances().Write(1);
164   view.offloaded_resolution_of_private_address().Write(Capability::CAPABLE);
165   view.total_scan_results_storage().Write(2);
166   view.max_irk_list_sz().Write(3);
167   view.filtering_support().Write(Capability::CAPABLE);
168   view.max_filter().Write(4);
169   view.activity_energy_info_support().Write(Capability::CAPABLE);
170   view.version_supported().major_number().Write(0);
171   view.version_supported().minor_number().Write(96);
172 
173   ASSERT_TRUE(view.has_total_num_of_advt_tracked().ValueOr(false));
174   view.total_num_of_advt_tracked().UncheckedWrite(5u);
175 
176   ASSERT_TRUE(view.has_extended_scan_support().ValueOr(false));
177   view.extended_scan_support().UncheckedWrite(Capability::CAPABLE);
178 
179   ASSERT_TRUE(view.has_debug_logging_supported().ValueOr(false));
180   view.debug_logging_supported().UncheckedWrite(Capability::CAPABLE);
181 
182   ASSERT_TRUE(
183       view.has_le_address_generation_offloading_support().ValueOr(false));
184   view.le_address_generation_offloading_support().Write(Capability::CAPABLE);
185 
186   AndroidVendorCapabilities capabilities = AndroidVendorCapabilities::New(view);
187   EXPECT_EQ(1u, capabilities.max_simultaneous_advertisements());
188   EXPECT_EQ(true, capabilities.supports_offloaded_rpa());
189   EXPECT_EQ(2u, capabilities.scan_results_storage_bytes());
190   EXPECT_EQ(3u, capabilities.irk_list_size());
191   EXPECT_EQ(true, capabilities.supports_filtering());
192   EXPECT_EQ(4u, capabilities.max_filters());
193   EXPECT_EQ(true, capabilities.supports_activity_energy_info());
194   EXPECT_EQ(0u, capabilities.version_major());
195   EXPECT_EQ(96u, capabilities.version_minor());
196   EXPECT_EQ(5u, capabilities.max_advertisers_tracked());
197   EXPECT_EQ(true, capabilities.supports_extended_scan());
198   EXPECT_EQ(true, capabilities.supports_debug_logging());
199   EXPECT_EQ(true, capabilities.supports_offloading_le_address_generation());
200   EXPECT_EQ(0u, capabilities.a2dp_source_offload_capability_mask());
201   EXPECT_EQ(false, capabilities.supports_bluetooth_quality_report());
202   EXPECT_EQ(0u, capabilities.supports_dynamic_audio_buffer());
203   EXPECT_EQ(false, capabilities.supports_a2dp_offload_v2());
204 }
205 
TEST(AndroidVendorCapabilitiesTest,Version098)206 TEST(AndroidVendorCapabilitiesTest, Version098) {
207   auto params = hci::EventPacket::New<
208       android_emb::LEGetVendorCapabilitiesCommandCompleteEventWriter>(
209       hci_spec::kCommandCompleteEventCode,
210       android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
211           version_0_98_size());
212 
213   auto view = params.unchecked_view_t();
214   view.status().Write(pwemb::StatusCode::SUCCESS);
215 
216   view.max_advt_instances().Write(1);
217   view.offloaded_resolution_of_private_address().Write(Capability::CAPABLE);
218   view.total_scan_results_storage().Write(2);
219   view.max_irk_list_sz().Write(3);
220   view.filtering_support().Write(Capability::CAPABLE);
221   view.max_filter().Write(4);
222   view.activity_energy_info_support().Write(Capability::CAPABLE);
223   view.version_supported().major_number().Write(0);
224   view.version_supported().minor_number().Write(98);
225 
226   ASSERT_TRUE(view.has_total_num_of_advt_tracked().ValueOr(false));
227   view.total_num_of_advt_tracked().UncheckedWrite(5u);
228 
229   ASSERT_TRUE(view.has_extended_scan_support().ValueOr(false));
230   view.extended_scan_support().UncheckedWrite(Capability::CAPABLE);
231 
232   ASSERT_TRUE(view.has_debug_logging_supported().ValueOr(false));
233   view.debug_logging_supported().UncheckedWrite(Capability::CAPABLE);
234 
235   ASSERT_TRUE(
236       view.has_le_address_generation_offloading_support().ValueOr(false));
237   view.le_address_generation_offloading_support().Write(Capability::CAPABLE);
238 
239   ASSERT_TRUE(view.has_a2dp_source_offload_capability_mask().ValueOr(false));
240   view.a2dp_source_offload_capability_mask().BackingStorage().WriteUInt(6);
241 
242   ASSERT_TRUE(view.has_bluetooth_quality_report_support().ValueOr(false));
243   view.bluetooth_quality_report_support().Write(Capability::CAPABLE);
244 
245   AndroidVendorCapabilities capabilities = AndroidVendorCapabilities::New(view);
246   EXPECT_EQ(1u, capabilities.max_simultaneous_advertisements());
247   EXPECT_EQ(true, capabilities.supports_offloaded_rpa());
248   EXPECT_EQ(2u, capabilities.scan_results_storage_bytes());
249   EXPECT_EQ(3u, capabilities.irk_list_size());
250   EXPECT_EQ(true, capabilities.supports_filtering());
251   EXPECT_EQ(4u, capabilities.max_filters());
252   EXPECT_EQ(true, capabilities.supports_activity_energy_info());
253   EXPECT_EQ(0u, capabilities.version_major());
254   EXPECT_EQ(98u, capabilities.version_minor());
255   EXPECT_EQ(5u, capabilities.max_advertisers_tracked());
256   EXPECT_EQ(true, capabilities.supports_extended_scan());
257   EXPECT_EQ(true, capabilities.supports_debug_logging());
258   EXPECT_EQ(true, capabilities.supports_offloading_le_address_generation());
259   EXPECT_EQ(6u, capabilities.a2dp_source_offload_capability_mask());
260   EXPECT_EQ(true, capabilities.supports_bluetooth_quality_report());
261   EXPECT_EQ(0u, capabilities.supports_dynamic_audio_buffer());
262   EXPECT_EQ(false, capabilities.supports_a2dp_offload_v2());
263 }
264 
TEST(AndroidVendorCapabilitiesTest,Version103)265 TEST(AndroidVendorCapabilitiesTest, Version103) {
266   auto params = hci::EventPacket::New<
267       android_emb::LEGetVendorCapabilitiesCommandCompleteEventWriter>(
268       hci_spec::kCommandCompleteEventCode,
269       android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
270           version_1_03_size());
271 
272   auto view = params.unchecked_view_t();
273   view.status().Write(pwemb::StatusCode::SUCCESS);
274 
275   view.max_advt_instances().Write(1);
276   view.offloaded_resolution_of_private_address().Write(Capability::CAPABLE);
277   view.total_scan_results_storage().Write(2);
278   view.max_irk_list_sz().Write(3);
279   view.filtering_support().Write(Capability::CAPABLE);
280   view.max_filter().Write(4);
281   view.activity_energy_info_support().Write(Capability::CAPABLE);
282   view.version_supported().major_number().Write(1);
283   view.version_supported().minor_number().Write(03);
284 
285   ASSERT_TRUE(view.has_total_num_of_advt_tracked().ValueOr(false));
286   view.total_num_of_advt_tracked().UncheckedWrite(5u);
287 
288   ASSERT_TRUE(view.has_extended_scan_support().ValueOr(false));
289   view.extended_scan_support().UncheckedWrite(Capability::CAPABLE);
290 
291   ASSERT_TRUE(view.has_debug_logging_supported().ValueOr(false));
292   view.debug_logging_supported().UncheckedWrite(Capability::CAPABLE);
293 
294   ASSERT_TRUE(
295       view.has_le_address_generation_offloading_support().ValueOr(false));
296   view.le_address_generation_offloading_support().Write(Capability::CAPABLE);
297 
298   ASSERT_TRUE(view.has_a2dp_source_offload_capability_mask().ValueOr(false));
299   view.a2dp_source_offload_capability_mask().BackingStorage().WriteUInt(6);
300 
301   ASSERT_TRUE(view.has_bluetooth_quality_report_support().ValueOr(false));
302   view.bluetooth_quality_report_support().Write(Capability::CAPABLE);
303 
304   ASSERT_TRUE(view.has_dynamic_audio_buffer_support().ValueOr(false));
305   view.dynamic_audio_buffer_support().sbc().Write(true);
306   view.dynamic_audio_buffer_support().aac().Write(true);
307   view.dynamic_audio_buffer_support().aptx().Write(true);
308 
309   AndroidVendorCapabilities capabilities = AndroidVendorCapabilities::New(view);
310   EXPECT_EQ(1u, capabilities.max_simultaneous_advertisements());
311   EXPECT_EQ(true, capabilities.supports_offloaded_rpa());
312   EXPECT_EQ(2u, capabilities.scan_results_storage_bytes());
313   EXPECT_EQ(3u, capabilities.irk_list_size());
314   EXPECT_EQ(true, capabilities.supports_filtering());
315   EXPECT_EQ(4u, capabilities.max_filters());
316   EXPECT_EQ(true, capabilities.supports_activity_energy_info());
317   EXPECT_EQ(1u, capabilities.version_major());
318   EXPECT_EQ(03u, capabilities.version_minor());
319   EXPECT_EQ(5u, capabilities.max_advertisers_tracked());
320   EXPECT_EQ(true, capabilities.supports_extended_scan());
321   EXPECT_EQ(true, capabilities.supports_debug_logging());
322   EXPECT_EQ(true, capabilities.supports_offloading_le_address_generation());
323   EXPECT_EQ(6u, capabilities.a2dp_source_offload_capability_mask());
324   EXPECT_EQ(true, capabilities.supports_bluetooth_quality_report());
325   EXPECT_EQ(7u, capabilities.supports_dynamic_audio_buffer());
326   EXPECT_EQ(false, capabilities.supports_a2dp_offload_v2());
327 }
328 
TEST(AndroidVendorCapabilitiesTest,Version104)329 TEST(AndroidVendorCapabilitiesTest, Version104) {
330   auto params = hci::EventPacket::New<
331       android_emb::LEGetVendorCapabilitiesCommandCompleteEventWriter>(
332       hci_spec::kCommandCompleteEventCode,
333       android_emb::LEGetVendorCapabilitiesCommandCompleteEvent::
334           version_1_04_size());
335 
336   auto view = params.unchecked_view_t();
337   view.status().Write(pwemb::StatusCode::SUCCESS);
338 
339   view.max_advt_instances().Write(1);
340   view.offloaded_resolution_of_private_address().Write(Capability::CAPABLE);
341   view.total_scan_results_storage().Write(2);
342   view.max_irk_list_sz().Write(3);
343   view.filtering_support().Write(Capability::CAPABLE);
344   view.max_filter().Write(4);
345   view.activity_energy_info_support().Write(Capability::CAPABLE);
346   view.version_supported().major_number().Write(1);
347   view.version_supported().minor_number().Write(04);
348 
349   ASSERT_TRUE(view.has_total_num_of_advt_tracked().ValueOr(false));
350   view.total_num_of_advt_tracked().UncheckedWrite(5u);
351 
352   ASSERT_TRUE(view.has_extended_scan_support().ValueOr(false));
353   view.extended_scan_support().UncheckedWrite(Capability::CAPABLE);
354 
355   ASSERT_TRUE(view.has_debug_logging_supported().ValueOr(false));
356   view.debug_logging_supported().UncheckedWrite(Capability::CAPABLE);
357 
358   ASSERT_TRUE(
359       view.has_le_address_generation_offloading_support().ValueOr(false));
360   view.le_address_generation_offloading_support().Write(Capability::CAPABLE);
361 
362   ASSERT_TRUE(view.has_a2dp_source_offload_capability_mask().ValueOr(false));
363   view.a2dp_source_offload_capability_mask().BackingStorage().WriteUInt(6);
364 
365   ASSERT_TRUE(view.has_bluetooth_quality_report_support().ValueOr(false));
366   view.bluetooth_quality_report_support().Write(Capability::CAPABLE);
367 
368   ASSERT_TRUE(view.has_dynamic_audio_buffer_support().ValueOr(false));
369   view.dynamic_audio_buffer_support().sbc().Write(true);
370   view.dynamic_audio_buffer_support().aac().Write(true);
371   view.dynamic_audio_buffer_support().aptx().Write(true);
372 
373   ASSERT_TRUE(view.has_a2dp_offload_v2_support().ValueOr(false));
374   view.a2dp_offload_v2_support().Write(Capability::CAPABLE);
375 
376   AndroidVendorCapabilities capabilities = AndroidVendorCapabilities::New(view);
377   EXPECT_EQ(1u, capabilities.max_simultaneous_advertisements());
378   EXPECT_EQ(true, capabilities.supports_offloaded_rpa());
379   EXPECT_EQ(2u, capabilities.scan_results_storage_bytes());
380   EXPECT_EQ(3u, capabilities.irk_list_size());
381   EXPECT_EQ(true, capabilities.supports_filtering());
382   EXPECT_EQ(4u, capabilities.max_filters());
383   EXPECT_EQ(true, capabilities.supports_activity_energy_info());
384   EXPECT_EQ(1u, capabilities.version_major());
385   EXPECT_EQ(04u, capabilities.version_minor());
386   EXPECT_EQ(5u, capabilities.max_advertisers_tracked());
387   EXPECT_EQ(true, capabilities.supports_extended_scan());
388   EXPECT_EQ(true, capabilities.supports_debug_logging());
389   EXPECT_EQ(true, capabilities.supports_offloading_le_address_generation());
390   EXPECT_EQ(6u, capabilities.a2dp_source_offload_capability_mask());
391   EXPECT_EQ(true, capabilities.supports_bluetooth_quality_report());
392   EXPECT_EQ(7u, capabilities.supports_dynamic_audio_buffer());
393   EXPECT_EQ(true, capabilities.supports_a2dp_offload_v2());
394 }
395 
396 }  // namespace
397 }  // namespace bt::gap
398