1use crate::ConversionError;
2
3use crate::hci::adapter;
4use crate::le::advertisement::StaticAdvBuffer;
5use crate::le::report::ReportInfo;
6use core::convert::TryFrom;
7use futures_util::future::LocalBoxFuture;
8use futures_util::stream::LocalBoxStream;
9
10#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
11pub enum ScanningFilterPolicy {
12 All = 0x00,
13 Whitelisted = 0x01,
14 DirectedAll = 0x02,
15 DirectedWhitelisted = 0x03,
16}
17impl From<ScanningFilterPolicy> for u8 {
18 fn from(p: ScanningFilterPolicy) -> Self {
19 p as u8
20 }
21}
22impl TryFrom<u8> for ScanningFilterPolicy {
23 type Error = ConversionError;
24
25 fn try_from(value: u8) -> Result<Self, Self::Error> {
26 match value {
27 0 => Ok(ScanningFilterPolicy::All),
28 1 => Ok(ScanningFilterPolicy::Whitelisted),
29 2 => Ok(ScanningFilterPolicy::DirectedAll),
30 3 => Ok(ScanningFilterPolicy::DirectedWhitelisted),
31 _ => Err(ConversionError(())),
32 }
33 }
34}
35const INTERVAL_MIN: u16 = 0x0004;
36const INTERVAL_MAX: u16 = 0x4000;
37#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
42pub struct ScanInterval(u16);
43impl ScanInterval {
44 pub const MIN: ScanInterval = ScanInterval(INTERVAL_MIN);
45 pub const MAX: ScanInterval = ScanInterval(INTERVAL_MAX);
46 pub const BYTE_LEN: usize = 2;
47 pub const DEFAULT: ScanInterval = ScanInterval(0x0010);
48 pub fn new(interval: u16) -> ScanInterval {
49 assert!(
50 interval >= INTERVAL_MIN && interval <= INTERVAL_MAX,
51 "interval '{}' is out of range"
52 );
53 ScanInterval(interval)
54 }
55 pub fn as_microseconds(self) -> u32 {
56 u32::from(u16::from(self)) * 625
57 }
58}
59impl From<ScanInterval> for u16 {
60 fn from(i: ScanInterval) -> u16 {
61 i.0
62 }
63}
64impl Default for ScanInterval {
65 fn default() -> Self {
66 Self::DEFAULT
67 }
68}
69#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
70pub struct ScanWindow(u16);
71impl ScanWindow {
72 pub const MIN: ScanWindow = ScanWindow(INTERVAL_MIN);
73 pub const MAX: ScanWindow = ScanWindow(INTERVAL_MAX);
74 pub const BYTE_LEN: usize = 2;
75 pub const DEFAULT: ScanWindow = ScanWindow(0x0010);
76 pub fn new(window: u16) -> ScanWindow {
77 assert!(
78 window >= INTERVAL_MIN && window <= INTERVAL_MAX,
79 "window '{}' is out of range"
80 );
81 ScanWindow(window)
82 }
83 pub fn as_microseconds(self) -> u32 {
84 u32::from(u16::from(self)) * 625
85 }
86}
87impl From<ScanWindow> for u16 {
88 fn from(w: ScanWindow) -> u16 {
89 w.0
90 }
91}
92impl Default for ScanWindow {
93 fn default() -> Self {
94 Self::DEFAULT
95 }
96}
97
98#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
99pub enum OwnAddressType {
100 Public = 0x00,
101 Random = 0x01,
102 PrivateOrPublic = 0x02,
103 PrivateOrRandom = 0x03,
104}
105
106impl From<OwnAddressType> for u8 {
107 fn from(s: OwnAddressType) -> Self {
108 s as u8
109 }
110}
111impl TryFrom<u8> for OwnAddressType {
112 type Error = ConversionError;
113
114 fn try_from(value: u8) -> Result<Self, Self::Error> {
115 match value {
116 0 => Ok(OwnAddressType::Public),
117 1 => Ok(OwnAddressType::Random),
118 2 => Ok(OwnAddressType::PrivateOrPublic),
119 3 => Ok(OwnAddressType::PrivateOrRandom),
120 _ => Err(ConversionError(())),
121 }
122 }
123}
124#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
126pub enum ScanType {
127 Passive = 0x00,
128 Active = 0x01,
129}
130impl From<ScanType> for u8 {
131 fn from(s: ScanType) -> Self {
132 s as u8
133 }
134}
135impl TryFrom<u8> for ScanType {
136 type Error = ConversionError;
137
138 fn try_from(value: u8) -> Result<Self, Self::Error> {
139 match value {
140 0 => Ok(ScanType::Passive),
141 1 => Ok(ScanType::Active),
142 _ => Err(ConversionError(())),
143 }
144 }
145}
146#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)]
147pub struct ScanParameters {
148 pub scan_type: ScanType,
149 pub scan_interval: ScanInterval,
150 pub scan_window: ScanWindow,
151 pub own_address_type: OwnAddressType,
152 pub scanning_filter_policy: ScanningFilterPolicy,
153}
154impl ScanParameters {
155 pub const DEFAULT: ScanParameters = ScanParameters {
156 scan_type: ScanType::Passive,
157 scan_interval: ScanInterval::DEFAULT,
158 scan_window: ScanWindow::DEFAULT,
159 own_address_type: OwnAddressType::Public,
160 scanning_filter_policy: ScanningFilterPolicy::All,
161 };
162}
163impl Default for ScanParameters {
164 fn default() -> Self {
165 Self::DEFAULT
166 }
167}
168#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
169pub enum ObserverError {
170 AdapterError(adapter::Error),
171}
172impl crate::error::Error for ObserverError {}
173pub trait Observer {
174 fn set_scan_parameters<'a>(
175 &'a mut self,
176 scan_parameters: ScanParameters,
177 ) -> LocalBoxFuture<'a, Result<(), adapter::Error>>;
178 fn set_scan_enable<'a>(
179 &'a mut self,
180 is_enabled: bool,
181 filter_duplicates: bool,
182 ) -> LocalBoxFuture<'a, Result<(), adapter::Error>>;
183 fn advertisement_stream<'a>(
184 &'a mut self,
185 ) -> LocalBoxFuture<
186 'a,
187 Result<
188 LocalBoxStream<'a, Result<ReportInfo<StaticAdvBuffer>, adapter::Error>>,
189 adapter::Error,
190 >,
191 >;
192 fn advertisement_stream_without_mask<'a>(
198 &'a mut self,
199 ) -> LocalBoxFuture<
200 'a,
201 Result<
202 LocalBoxStream<'a, Result<ReportInfo<StaticAdvBuffer>, adapter::Error>>,
203 adapter::Error,
204 >,
205 > {
206 self.advertisement_stream()
207 }
208}