• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Shim to provide more structured access to sysprops from Rust.
2 
3 use std::ffi::CString;
4 
5 use crate::bindings::root as bindings;
6 use crate::utils::LTCheckedPtr;
7 
8 /// List of properties accessible to Rust. Add new ones here as they become
9 /// necessary.
10 pub enum PropertyI32 {
11     // bluetooth.core.le
12     LeInquiryScanInterval,
13     LeInquiryScanWindow,
14     LeAdvMonScanInterval,
15     LeAdvMonScanWindow,
16 
17     // bluetooth.device_id
18     ProductId,
19     ProductVersion,
20     VendorId,
21     VendorIdSource,
22 }
23 
24 impl Into<(CString, i32)> for PropertyI32 {
25     /// Convert the property into the property key name and a default value.
into(self) -> (CString, i32)26     fn into(self) -> (CString, i32) {
27         let (key, default_value) = match self {
28             // Inquiry scan interval = N * 0.625 ms; value of 36 = 22.5ms
29             PropertyI32::LeInquiryScanInterval => ("bluetooth.core.le.inquiry_scan_interval", 36),
30 
31             //Inquiry scan window = N * 0.625 ms; value of 18 = 11.25ms
32             PropertyI32::LeInquiryScanWindow => ("bluetooth.core.le.inquiry_scan_window", 18),
33 
34             // Adv Mon scan interval = N * 0.625 ms; value of 40 = 25ms
35             PropertyI32::LeAdvMonScanInterval => ("bluetooth.core.le.adv_mon_scan_interval", 40),
36 
37             // Adv Mon scan window = N * 0.625 ms; value of 20 = 12.5ms
38             PropertyI32::LeAdvMonScanWindow => ("bluetooth.core.le.adv_mon_scan_window", 20),
39 
40             PropertyI32::ProductId => ("bluetooth.device_id.product_id", 0),
41             PropertyI32::ProductVersion => ("bluetooth.device_id.product_version", 0),
42 
43             // Vendor ID defaults to Google (0xE0)
44             PropertyI32::VendorId => ("bluetooth.device_id.vendor_id", 0xE0),
45 
46             // Vendor ID source defaults to Bluetooth Sig (0x1)
47             PropertyI32::VendorIdSource => ("bluetooth.device_id.vendor_id_source", 0x1),
48         };
49 
50         (CString::new(key).expect("CString::new failed on sysprop key"), default_value)
51     }
52 }
53 
54 /// Get the i32 value for a system property.
get_i32(prop: PropertyI32) -> i3255 pub fn get_i32(prop: PropertyI32) -> i32 {
56     let (key, default_value): (CString, i32) = prop.into();
57     let key_cptr = LTCheckedPtr::from(&key);
58 
59     // SAFETY: Calling C++ function with compatible types (null terminated string and i32) is safe.
60     unsafe { bindings::osi_property_get_int32(key_cptr.into(), default_value) }
61 }
62 
63 /// List of properties accessible to Rust. Add new ones here as they become
64 /// necessary.
65 pub enum PropertyBool {
66     // bluetooth.core.le
67     LeAdvMonRtlQuirk,
68     LeAdvMonQcaQuirk,
69 
70     // bluetooth.core.gap
71     LePrivacyEnabled,
72     LePrivacyOwnAddressTypeEnabled,
73 
74     // bluetooth.le_audio
75     LeAudioEnableLeAudioOnly,
76 }
77 
78 impl Into<(CString, bool)> for PropertyBool {
79     /// Convert the property into the property key name and a default value.
into(self) -> (CString, bool)80     fn into(self) -> (CString, bool) {
81         let (key, default_value) = match self {
82             PropertyBool::LeAdvMonRtlQuirk => ("bluetooth.core.le.adv_mon_rtl_quirk", false),
83             PropertyBool::LeAdvMonQcaQuirk => ("bluetooth.core.le.adv_mon_qca_quirk", false),
84             PropertyBool::LeAudioEnableLeAudioOnly => {
85                 ("bluetooth.le_audio.enable_le_audio_only", false)
86             }
87             PropertyBool::LePrivacyEnabled => ("bluetooth.core.gap.le.privacy.enabled", false),
88             PropertyBool::LePrivacyOwnAddressTypeEnabled => {
89                 ("bluetooth.core.gap.le.privacy.own_address_type.enabled", false)
90             }
91         };
92 
93         (CString::new(key).expect("CString::new failed on sysprop key"), default_value)
94     }
95 }
96 
97 /// Get the boolean value for a system property.
get_bool(prop: PropertyBool) -> bool98 pub fn get_bool(prop: PropertyBool) -> bool {
99     let (key, default_value): (CString, bool) = prop.into();
100     let key_cptr = LTCheckedPtr::from(&key);
101 
102     // SAFETY: Calling C++ function with compatible types (null terminated string and bool) is safe.
103     unsafe { bindings::osi_property_get_bool(key_cptr.into(), default_value) }
104 }
105