1 //! Controller shim
2 
3 use bt_hci::ControllerExports;
4 use bt_packets::hci::OpCode;
5 use paste::paste;
6 use std::ops::Deref;
7 use std::sync::Arc;
8 
9 #[derive(Clone)]
10 pub struct Controller(pub Arc<ControllerExports>);
11 impl Deref for Controller {
12     type Target = Arc<ControllerExports>;
deref(&self) -> &Self::Target13     fn deref(&self) -> &Self::Target {
14         &self.0
15     }
16 }
17 
18 macro_rules! feature_getters {
19     ($($id:ident),*) => {
20         paste! {
21             $(
22                 pub fn [<controller_supports_ $id>](c: &Controller) -> bool {
23                     c.features.$id
24                 }
25             )*
26         }
27     }
28 }
29 
30 feature_getters! {
31     simple_pairing,
32     secure_connections,
33     simultaneous_le_bredr,
34     interlaced_inquiry_scan,
35     rssi_with_inquiry_results,
36     extended_inquiry_response,
37     role_switch,
38     three_slot_packets,
39     five_slot_packets,
40     classic_2m_phy,
41     classic_3m_phy,
42     three_slot_edr_packets,
43     five_slot_edr_packets,
44     sco,
45     hv2_packets,
46     hv3_packets,
47     ev3_packets,
48     ev4_packets,
49     ev5_packets,
50     esco_2m_phy,
51     esco_3m_phy,
52     three_slot_esco_edr_packets,
53     hold_mode,
54     sniff_mode,
55     park_mode,
56     non_flushable_pb,
57     sniff_subrating,
58     encryption_pause,
59     ble
60 }
61 
62 macro_rules! le_feature_getters {
63     ($($id:ident),*) => {
64         paste! {
65             $(
66                 pub fn [<controller_supports_ $id>](c: &Controller) -> bool {
67                     c.le_features.$id
68                 }
69             )*
70         }
71     }
72 }
73 
74 le_feature_getters! {
75     privacy,
76     packet_extension,
77     connection_parameters_request,
78     ble_2m_phy,
79     ble_coded_phy,
80     extended_advertising,
81     periodic_advertising,
82     peripheral_initiated_feature_exchange,
83     connection_parameter_request,
84     periodic_advertising_sync_transfer_sender,
85     periodic_advertising_sync_transfer_recipient,
86     connected_iso_stream_central,
87     connected_iso_stream_peripheral,
88     iso_broadcaster,
89     synchronized_receiver
90 }
91 
92 macro_rules! opcode_getters {
93     ($($id:ident => $opcode:path),*) => {
94         paste! {
95             $(
96                 pub fn [<controller_supports_ $id>](c: &Controller) -> bool {
97                     c.commands.is_supported($opcode)
98                 }
99             )*
100         }
101     }
102 }
103 
104 opcode_getters! {
105     reading_remote_extended_features => OpCode::ReadRemoteSupportedFeatures,
106     enhanced_setup_synchronous_connection => OpCode::EnhancedSetupSynchronousConnection,
107     enhanced_accept_synchronous_connection => OpCode::EnhancedAcceptSynchronousConnection,
108     ble_set_privacy_mode => OpCode::LeSetPrivacyMode
109 }
110 
111 macro_rules! field_getters {
112     ($($id:ident : $type:ty),*) => {
113         paste! {
114             $(
115                 pub fn [<controller_get_ $id>](c: &Controller) -> $type {
116                     c.$id
117                 }
118             )*
119         }
120     }
121 }
122 
123 field_getters! {
124     acl_buffer_length: u16,
125     le_buffer_length: u16,
126     iso_buffer_length: u16,
127     le_suggested_default_data_length: u16,
128     le_max_advertising_data_length: u16,
129     le_supported_advertising_sets: u8,
130     le_periodic_advertiser_list_size: u8,
131     acl_buffers: u16,
132     le_buffers: u8,
133     iso_buffers: u8,
134     le_connect_list_size: u8,
135     le_resolving_list_size: u8,
136     le_supported_states: u64
137 }
138 
controller_get_le_maximum_tx_data_length(c: &Controller) -> u16139 pub fn controller_get_le_maximum_tx_data_length(c: &Controller) -> u16 {
140     c.le_max_data_length.supported_max_tx_octets
141 }
142 
controller_get_le_maximum_tx_time(c: &Controller) -> u16143 pub fn controller_get_le_maximum_tx_time(c: &Controller) -> u16 {
144     c.le_max_data_length.supported_max_tx_time
145 }
146 
controller_get_address(c: &Controller) -> String147 pub fn controller_get_address(c: &Controller) -> String {
148     c.address.to_string()
149 }
150