1use crate::setup::{self, RUNTIME};
2use crate::{block_on, spawn, BleAddress, BleDevice};
3use crate::{handler::BleHandler, BleError};
4use futures::{Future, StreamExt};
5use once_cell::sync::OnceCell;
6use tokio::sync::{mpsc, Mutex};
7use uuid::Uuid;
8
9static HANDLER: OnceCell<Mutex<BleHandler>> = OnceCell::new();
10
11pub fn init() -> Result<(), BleError> {
14 setup::create_runtime()?;
16 let rt = RUNTIME.get().ok_or(BleError::RuntimeNotInitialized)?;
17 HANDLER
18 .set(Mutex::new(rt.block_on(BleHandler::new())?))
19 .map_err(|_| BleError::HandlerAlreadyInitialized)?;
20 rt.spawn(event_loop());
22 Ok(())
23}
24
25async fn event_loop() -> Result<(), BleError> {
26 let handler = get_handler();
27 let mut events = handler.lock().await.get_event_stream().await?;
28 while let Some(event) = events.next().await {
29 handler.lock().await.handle_event(event).await?;
30 }
31 Ok(())
32}
33
34fn get_handler() -> &'static Mutex<BleHandler> {
35 let handler = HANDLER
36 .get()
37 .ok_or(BleError::HandlerNotInitialized)
38 .unwrap();
39 handler
40}
41
42async fn run_on_runtime<F, O>(f: F) -> Result<O, BleError>
43where
44 F: Future<Output = Result<O, BleError>> + Send + 'static,
45 O: Send + 'static,
46{
47 let rt = RUNTIME.get().ok_or(BleError::RuntimeNotInitialized)?;
48 rt.spawn(f).await.map_err(|e| BleError::JoinError(e))?
49}
50
51pub async fn connect(
52 addr: BleAddress,
53 service: Uuid,
54 characs: Vec<Uuid>,
55 on_disconnect: Option<impl Fn() + Send + 'static>,
56) -> Result<(), BleError> {
57 run_on_runtime(async move {
58 let mut handler = get_handler().lock().await;
59 handler.connect(addr, service, characs, on_disconnect).await
60 })
61 .await
62}
63
64pub async fn disconnect() -> Result<(), BleError> {
65 run_on_runtime(async move {
66 let mut handler = get_handler().lock().await;
67 handler.disconnect().await
68 })
69 .await
70}
71
72pub fn discover(sink: mpsc::Sender<Vec<BleDevice>>, timeout: u64) -> Result<(), BleError> {
73 spawn(async move {
74 let mut handler = get_handler().lock().await;
75 handler.discover(Some(sink), timeout).await
76 })
77}
78
79pub async fn discover_async(timeout: u64) -> Result<Vec<BleDevice>, BleError> {
80 let discovered = run_on_runtime(async move {
81 let mut handler = get_handler().lock().await;
82 handler.discover(None, timeout).await
83 })
84 .await?;
85 Ok(discovered)
86}
87
88pub fn discover_blocking(timeout: u64) -> Result<Vec<BleDevice>, BleError> {
89 let discovered = block_on(async move {
90 let mut handler = get_handler().lock().await;
91 handler.discover(None, timeout).await
92 })??;
93 Ok(discovered)
94}
95
96pub async fn send_data(charac: Uuid, data: Vec<u8>) -> Result<(), BleError> {
97 run_on_runtime(async move {
98 let mut handler = get_handler().lock().await;
99 handler.send_data(charac, &data).await
100 })
101 .await
102}
103
104pub async fn recv_data(charac: Uuid) -> Result<Vec<u8>, BleError> {
105 run_on_runtime(async move {
106 let mut handler = get_handler().lock().await;
107 handler.recv_data(charac).await
108 })
109 .await
110}
111
112pub async fn is_connected() -> Result<bool, BleError> {
113 run_on_runtime(async move {
114 let handler = get_handler().lock().await;
115 handler.check_connected().await
116 })
117 .await
118}
119
120pub async fn connected_device() -> Result<BleDevice, BleError> {
121 run_on_runtime(async move {
122 let handler = get_handler().lock().await;
123 handler.connected_device().await
124 })
125 .await
126}
127
128pub async fn subscribe(
129 charac: Uuid,
130 callback: impl Fn(&[u8]) + Send + Sync + 'static,
131) -> Result<(), BleError> {
132 run_on_runtime(async move {
133 let mut handler = get_handler().lock().await;
134 handler.subscribe(charac, callback).await
135 })
136 .await
137}