1use basic_scheduler::{BasicEvent, Duration, Scheduler};
2use std::sync::mpsc::{channel, Receiver, Sender};
3use BtMacAddress;
4use std::collections::{HashMap, HashSet};
5use errors::*;
6use std::str::FromStr;
7use uuid::Uuid;
8use std::thread;
9
10use bt_manager::SomethingItem;
11use bt_manager::discovery::{discovery_task, DiscoveryData};
12use bt_manager::connection::{connect_task, ConnectionDb};
13use bt_manager::endpoints::{endpoints_task, EndpointsDb};
14use bt_manager::data_poll::{data_poll_task, DataDb};
15use bt_manager::data_write::{data_write_task, DataWDb};
16
17pub struct EasyBluez {
18 scan_interval: Duration,
19 scan_duration: Duration,
20 connect_interval: Duration,
21 endpoint_interval: Duration,
22 poll_interval: Duration,
23 write_interval: Duration,
24}
25
26pub struct EasyBluezHandle {
27 mac_sender: Sender<BtMacAddress>,
28 poll_sender: Sender<(SomethingItem, Sender<Box<[u8]>>)>,
29 write_sender: Sender<(SomethingItem, Receiver<Box<[u8]>>)>,
30 _scheduler: thread::JoinHandle<()>,
31 _data_scheduler: thread::JoinHandle<()>,
32
33 _rx: Receiver<(String, bool)>,
34}
35
36impl EasyBluezHandle {
37 pub fn writeable(
38 &self,
39 mac_s: &str,
40 svc_s: &str,
41 chrc_s: &str,
42 ) -> Result<Sender<Box<[u8]>>> {
43 let (tx, rx) = channel();
44
45 let mac = BtMacAddress::from_str(mac_s)?;
46 let svc = Uuid::from_str(svc_s).chain_err(|| "not a UUID!")?;
47 let chrc = Uuid::from_str(chrc_s).chain_err(|| "not a UUID!")?;
48
49 self.mac_sender.send(mac.clone()).chain_err(|| "")?;
50
51 let si = SomethingItem {
52 mac: mac,
53 svc: svc,
54 chrc: chrc,
55 };
56
57 self.write_sender.send((si, rx)).chain_err(|| "")?;
58
59 Ok(tx)
60 }
61
62 pub fn poll(
63 &self,
64 mac_s: &str,
65 svc_s: &str,
66 chrc_s: &str,
67 ) -> Result<Receiver<Box<[u8]>>> {
68 let (tx, rx) = channel();
69
70 let mac = BtMacAddress::from_str(mac_s)?;
71 let svc = Uuid::from_str(svc_s).chain_err(|| "not a UUID!")?;
72 let chrc = Uuid::from_str(chrc_s).chain_err(|| "not a UUID!")?;
73
74 self.mac_sender.send(mac.clone()).chain_err(|| "")?;
75
76 let si = SomethingItem {
77 mac: mac,
78 svc: svc,
79 chrc: chrc,
80 };
81
82 self.poll_sender.send((si, tx)).chain_err(|| "")?;
83
84 Ok(rx)
85 }
86}
87
88impl EasyBluez {
89 pub fn new() -> Self {
90 EasyBluez {
91 scan_interval: Duration::seconds(10),
92 scan_duration: Duration::milliseconds(1000),
93 connect_interval: Duration::seconds(3),
94 endpoint_interval: Duration::seconds(3),
95 poll_interval: Duration::milliseconds(1000),
96 write_interval: Duration::milliseconds(100),
97 }
98 }
99
100 pub fn scan_interval(mut self, interval: Duration) -> Self {
106 self.scan_interval = interval;
107 self
108 }
109
110 pub fn scan_duration(mut self, duration: Duration) -> Self {
112 self.scan_duration = duration;
113 self
114 }
115
116 pub fn connect_interval(mut self, interval: Duration) -> Self {
118 self.connect_interval = interval;
119 self
120 }
121
122 pub fn endpoint_interval(mut self, interval: Duration) -> Self {
124 self.endpoint_interval = interval;
125 self
126 }
127
128 pub fn poll_interval(mut self, interval: Duration) -> Self {
130 self.poll_interval = interval;
131 self
132 }
133
134 pub fn run(&mut self) -> EasyBluezHandle {
138 self.spawn_events()
139 }
140
141 fn spawn_events(&mut self) -> EasyBluezHandle {
142 let (tx_macs, rx_macs) = channel();
143 let (tx_devs, rx_devs) = channel();
144 let (tx_conn_evs, _rx_conn_evs) = channel();
145 let (tx_poll, rx_poll) = channel();
146 let (tx_write, rx_write) = channel();
147 let (tx_poll_characs, rx_poll_characs) = channel();
148 let (tx_write_characs, rx_write_characs) = channel();
149 let (tx_edpts, rx_edpts) = channel();
150
151 let discover_event = BasicEvent {
152 task: |s: &mut DiscoveryData| discovery_task(s),
153 state: DiscoveryData {
154 db: HashSet::new(),
155 wl: HashSet::new(),
156 receiver: rx_macs,
157 sender_connect: tx_devs,
158 sender_endpoints: tx_edpts,
159 scan_interval: self.scan_interval.clone(),
160 scan_duration: self.scan_duration.clone(),
161 },
162 };
163
164 let connection_event = BasicEvent {
165 task: |s: &mut ConnectionDb| connect_task(s),
166 state: ConnectionDb {
167 connect_interval: self.connect_interval,
168 db: vec![],
169 incoming: rx_devs,
170 outgoing: tx_conn_evs,
171 },
172 };
173
174 let endpoints_event = BasicEvent {
175 task: |s: &mut EndpointsDb| endpoints_task(s),
176 state: EndpointsDb {
177 endpoint_interval: self.endpoint_interval,
178
179 rx_polls: rx_poll,
180 rx_writes: rx_write,
181
182 pending_poll: Vec::new(),
183 pending_write: Vec::new(),
184
185 tx_poll_characs: tx_poll_characs,
186 tx_write_characs: tx_write_characs,
187
188 rx_devs: rx_edpts,
189 devices: HashMap::new(),
190 },
191 };
192
193 let poll_event = BasicEvent {
194 task: |s: &mut DataDb| data_poll_task(s),
195 state: DataDb {
196 poll_interval: self.poll_interval,
197 polls: Vec::new(),
198 poll_rx: rx_poll_characs,
199 },
200 };
201
202 let write_event = BasicEvent {
203 task: |s: &mut DataWDb| data_write_task(s),
204 state: DataWDb {
205 write_interval: self.write_interval,
206 writes: Vec::new(),
207 write_rx: rx_write_characs,
208 },
209 };
210
211 let mut scheduler = Scheduler::new();
212 let hdl = scheduler.add_handle();
213 hdl.send(Box::new(discover_event)).unwrap();
214 hdl.send(Box::new(connection_event)).unwrap();
215 hdl.send(Box::new(endpoints_event)).unwrap();
216
217 let mut data_scheduler = Scheduler::new();
218 let d_hdl = data_scheduler.add_handle();
219
220 d_hdl.send(Box::new(poll_event)).unwrap();
221 d_hdl.send(Box::new(write_event)).unwrap();
222
223 EasyBluezHandle {
224 _scheduler: thread::spawn(move || {
225 scheduler.run();
226 }),
227 _data_scheduler: thread::spawn(move || {
228 data_scheduler.run();
229 }),
230 mac_sender: tx_macs,
231 poll_sender: tx_poll,
232 write_sender: tx_write,
233 _rx: _rx_conn_evs,
234 }
235 }
236}