Skip to main content

tap_sdk/
event_manager.rs

1use btleplug::platform::Peripheral as PlatformPeripheral;
2use uuid::Uuid;
3use crate::types::air_gestures::AirGestures;
4use crate::types::uuid::characteristics::Characteristic;
5use std::sync::Arc;
6use tokio::sync::Mutex;
7use futures::StreamExt;
8use btleplug::api::Peripheral;
9
10#[derive(Clone, Debug)]
11pub struct EventManager {
12    peripheral: Option<Arc<Mutex<PlatformPeripheral>>>,
13}
14
15impl EventManager {
16    pub fn new() -> Self {
17        EventManager { peripheral: None }
18    }
19
20    pub fn set_peripheral(&mut self, peripheral: Arc<Mutex<PlatformPeripheral>>) {
21        self.peripheral = Some(peripheral);
22    }
23
24    async fn subscribe_to_characteristic<F>(&self, characteristic_uuid: Uuid, callback: F) -> Result<(), Box<dyn std::error::Error>>
25    where
26        F: Fn(Uuid, Vec<u8>) + Send + 'static,
27    {
28        if let Some(peripheral_arc) = &self.peripheral {
29            let characteristics = {
30                let peripheral = peripheral_arc.lock().await;
31                peripheral.characteristics().clone()
32            };
33            for characteristic in &characteristics {
34                if characteristic.uuid == characteristic_uuid {
35                    if !characteristic.properties.contains(btleplug::api::CharPropFlags::NOTIFY) {
36                        return Err(format!("Characteristic {:?} does not support notifications", characteristic_uuid).into());
37                    }
38                    {
39                        let peripheral = peripheral_arc.lock().await;
40                        peripheral.subscribe(characteristic).await?;
41                    }
42                    let peripheral_clone = Arc::clone(peripheral_arc);
43                    let char_uuid = characteristic.uuid;
44                    tokio::spawn(async move {
45                        let stream = {
46                            let peripheral = peripheral_clone.lock().await;
47                            peripheral.notifications().await
48                        };
49                        if let Ok(mut stream) = stream {
50                            println!("Successfully subscribed to characteristic {:?}", char_uuid);
51                            while let Some(notification) = stream.next().await {
52                                if notification.uuid == char_uuid {
53                                    callback(char_uuid, notification.value);
54                                }
55                            }
56                        } else {
57                            eprintln!("Failed to get notification stream for characteristic {:?}", char_uuid);
58                        }
59                    });
60                    return Ok(());
61                }
62            }
63            Err(format!("Characteristic {:?} not found", characteristic_uuid).into())
64        } else {
65            Err("No peripheral connected".into())
66        }
67    }
68
69    pub async fn register_air_gesture_events(&self, listener: fn(Uuid, AirGestures)) {
70        let air_gesture_uuid = Uuid::from_u128(Characteristic::AirGestureData.as_uuid());
71        let callback = move |uuid: Uuid, data: Vec<u8>| {
72            if data.len() > 0 {
73                let gesture_value = data[0] as u8;
74                let gesture = AirGestures::from_u8(gesture_value);
75                listener(uuid, gesture);
76            }
77        };
78        if let Err(e) = self.subscribe_to_characteristic(air_gesture_uuid, callback).await {
79            eprintln!("Failed to register air gesture events: {:?}", e);
80        }
81    }
82
83    pub async fn register_tap_events(&self, listener: fn(Uuid, u8)) {
84        let tap_data_uuid = Uuid::from_u128(Characteristic::TapData.as_uuid());
85        let callback = move |uuid: Uuid, data: Vec<u8>| {
86            if data.len() > 0 {
87                let tapcode = data[0];
88                listener(uuid, tapcode);
89            }
90        };
91        if let Err(e) = self.subscribe_to_characteristic(tap_data_uuid, callback).await {
92            eprintln!("Failed to register tap events: {:?}", e);
93        }
94    }
95
96    pub async fn register_raw_data_events(&self, listener: fn(Uuid, Vec<u8>)) {
97        let raw_sensors_uuid = Uuid::from_u128(Characteristic::RawSensors.as_uuid());
98        let callback = move |uuid: Uuid, data: Vec<u8>| {
99            listener(uuid, data);
100        };
101        if let Err(e) = self.subscribe_to_characteristic(raw_sensors_uuid, callback).await {
102            eprintln!("Failed to register raw data events: {:?}", e);
103        }
104    }
105
106    pub async fn register_mouse_events(&self, listener: fn(Uuid, i16, i16, bool)) {
107        let mouse_data_uuid = Uuid::from_u128(Characteristic::MouseData.as_uuid());
108        let callback = move |uuid: Uuid, data: Vec<u8>| {
109            if data.len() >= 4 {
110                let vx = ((data[0] as i16) << 8) | (data[1] as i16);
111                let vy = ((data[2] as i16) << 8) | (data[3] as i16);
112                let proximity = data.len() > 4 && data[4] != 0;
113                listener(uuid, vx, vy, proximity);
114            }
115        };
116        if let Err(e) = self.subscribe_to_characteristic(mouse_data_uuid, callback).await {
117            eprintln!("Failed to register mouse events: {:?}", e);
118        }
119    }
120
121    pub async fn register_air_gesture_state_events(&self, listener: fn(Uuid, bool)) {
122        let air_gesture_uuid = Uuid::from_u128(Characteristic::AirGestureData.as_uuid());
123        let callback = move |uuid: Uuid, data: Vec<u8>| {
124            if data.len() > 0 {
125                let in_air_gesture_state = data[0] == 0x14 && data.len() > 1 && data[1] != 0;
126                listener(uuid, in_air_gesture_state);
127            }
128        };
129        if let Err(e) = self.subscribe_to_characteristic(air_gesture_uuid, callback).await {
130            eprintln!("Failed to register air gesture state events: {:?}", e);
131        }
132    }
133}