1 // Bluetooth Core, Vol 2, Part C, 4.3.4
2
3 use num_traits::ToPrimitive;
4
5 use crate::packets::lmp;
6 use crate::procedure::Context;
7
initiate(ctx: &impl Context, features_page: u8) -> u648 pub async fn initiate(ctx: &impl Context, features_page: u8) -> u64 {
9 ctx.send_lmp_packet(
10 lmp::FeaturesReqExtBuilder {
11 transaction_id: 0,
12 features_page,
13 max_supported_page: 1,
14 extended_features: ctx.extended_features(features_page).to_le_bytes(),
15 }
16 .build(),
17 );
18
19 u64::from_le_bytes(
20 *ctx.receive_lmp_packet::<lmp::FeaturesResExtPacket>().await.get_extended_features(),
21 )
22 }
23
respond(ctx: &impl Context)24 pub async fn respond(ctx: &impl Context) {
25 let req = ctx.receive_lmp_packet::<lmp::FeaturesReqExtPacket>().await;
26 let features_page = req.get_features_page();
27
28 ctx.send_lmp_packet(
29 lmp::FeaturesResExtBuilder {
30 transaction_id: 0,
31 features_page,
32 max_supported_page: 1,
33 extended_features: ctx.extended_features(features_page).to_le_bytes(),
34 }
35 .build(),
36 );
37 }
38
supported_on_both_page(ctx: &impl Context, page_number: u8, feature_mask: u64) -> bool39 async fn supported_on_both_page(ctx: &impl Context, page_number: u8, feature_mask: u64) -> bool {
40 let local_supported = ctx.extended_features(page_number) & feature_mask != 0;
41 // Lazy peer features
42 let peer_supported = async move {
43 let page = if let Some(page) = ctx.peer_extended_features(page_number) {
44 page
45 } else {
46 crate::procedure::features::initiate(ctx, page_number).await
47 };
48 page & feature_mask != 0
49 };
50 local_supported && peer_supported.await
51 }
52
supported_on_both_page1( ctx: &impl Context, feature: crate::packets::hci::LMPFeaturesPage1Bits, ) -> bool53 pub async fn supported_on_both_page1(
54 ctx: &impl Context,
55 feature: crate::packets::hci::LMPFeaturesPage1Bits,
56 ) -> bool {
57 supported_on_both_page(ctx, 1, feature.to_u64().unwrap()).await
58 }
59
supported_on_both_page2( ctx: &impl Context, feature: crate::packets::hci::LMPFeaturesPage2Bits, ) -> bool60 pub async fn supported_on_both_page2(
61 ctx: &impl Context,
62 feature: crate::packets::hci::LMPFeaturesPage2Bits,
63 ) -> bool {
64 supported_on_both_page(ctx, 2, feature.to_u64().unwrap()).await
65 }
66