br-ble 0.2.0

This is an Bluetooth
Documentation
mod until;
use std::collections::HashMap;
use std::sync::Mutex;
use std::sync::mpsc::Receiver;
use std::time::{Duration, Instant};
use lazy_static::lazy_static;
use log::{debug, error, info, warn};
use uuid::Uuid;
use windows::Devices::Enumeration::{DeviceInformation, DeviceInformationPairing};
use crate::Handler;
use crate::device::{Characteristic, Device};
use crate::win::central::{CentralEvent, CentralManager, ManagerState};
pub mod central;

pub struct Win {
    central: CentralManager,
    receiver: Receiver<CentralEvent>,
    service_count: HashMap<String, usize>,
    connect_device: Vec<String>,
}
// 用来存储上次接收到的值和时间戳
lazy_static! {
    static ref DATA_CACHE: Mutex<HashMap<String, (Vec<u8>, Instant)>> = Mutex::new(HashMap::new());
}
impl Win {
    pub fn new() -> Self {
        let (central, receiver) = CentralManager::new();
        Self {
            central,
            receiver,
            service_count: HashMap::new(),
            connect_device: vec![],
        }
    }

    fn event<F>(&mut self, event: CentralEvent, factory: F)
    where
        F: Fn() -> Box<dyn Handler>,
    {
        match event {
            CentralEvent::ManagerStateChanged { new_state } => {
                match new_state {
                    ManagerState::PoweredOff => {
                        self.central.stop_threads();
                        factory().on_adapter_close();
                    }
                    ManagerState::PoweredOn => {
                        factory().on_adapter_open();
                        self.central.scan();
                        self.central.connected();
                    }
                    _ => {
                        error!("未知错误: {:?}",new_state);
                    }
                }
            }
            CentralEvent::ConnectedPeripheral { connected_device } => {
                self.connect_device = connected_device.clone();
                factory().listen_connected(self.connect_device.clone())
            }
            CentralEvent::PeripheralDiscovered { peripheral, advertisement_data, rssi } => {
                let name = advertisement_data.name.clone();
                let id = peripheral.DeviceId().unwrap().to_string().split("-").last().unwrap().to_string();
                let device_info: DeviceInformation = DeviceInformation::CreateFromIdAsync(&peripheral.DeviceId().unwrap()).unwrap().get().unwrap();
                let pairing_info: DeviceInformationPairing = device_info.Pairing().unwrap();
                if !pairing_info.IsPaired().unwrap() {
                    let t = Device::new(id, name, rssi as i32, self.central.clone(), peripheral.clone(), advertisement_data.clone());
                    factory().on_discover(t.clone());
                }
            }
            CentralEvent::PeripheralUnConnected { peripheral } => {
                let id = peripheral.DeviceId().unwrap().to_string().split("-").last().unwrap().to_string();
                info!("准备连接设备: {}", id);
                factory().on_unconnect(id.clone());
                self.central.discover_services(peripheral.clone());
            }
            // 已连接
            CentralEvent::PeripheralConnected { peripheral } => {
                let id = peripheral.DeviceId().unwrap().to_string().split("-").last().unwrap().to_string();
                debug!("已连接设备: {}", id);
                factory().on_connect(id.clone());
            }
            // 外围设备已断开连接
            CentralEvent::PeripheralDisconnected { peripheral } => {
                let id = peripheral.DeviceId().unwrap().to_string().split("-").last().unwrap().to_string();
                factory().on_disconnect(id.clone());
                warn!("设备断开: {}", id);
            }
            CentralEvent::ServicesDiscovered { peripheral, services } => {
                for service in services.iter() {
                    let service_uuid = service.Uuid().unwrap().to_u128().to_string();
                    self.central.discover_characteristics(peripheral.clone(), service.clone());
                    self.service_count.entry(service_uuid.clone()).or_insert(0usize);
                    let service_count = *self.service_count.get(&service_uuid.clone()).unwrap();
                    self.service_count.insert(service_uuid.clone(), service_count + 1);
                }
            }
            CentralEvent::CharacteristicsDiscovered { peripheral, service, characteristics } => {
                let id = peripheral.DeviceId().unwrap().to_string().split("-").last().unwrap().to_string();
                let service_uuid = service.Uuid().unwrap().to_u128().to_string();
                for characteristic in characteristics.iter() {
                    let props = characteristic.CharacteristicProperties().unwrap();
                    let characteristic_uuid = Uuid::from_u128(characteristic.Uuid().unwrap().to_u128().to_string().parse().unwrap()).to_string();
                    let t = Characteristic::default(characteristic_uuid.clone(), props, characteristic.clone());
                    factory().on_characteristics(id.clone(), t);
                }
                let service_count = *self.service_count.get(&service_uuid.clone()).unwrap();
                self.service_count.insert(service_uuid.clone(), service_count - 1usize);

                let service_count = *self.service_count.get(&service_uuid).unwrap();
                if service_count == 0 {
                    self.service_count.remove(&service_uuid);
                }
                if self.service_count.is_empty() {
                    factory().listen(id.clone())
                }
            }
            CentralEvent::SubscriptionChangeResult { peripheral, characteristic } => {
                self.central.get_value(peripheral, characteristic)
            }
            // 接收监听
            CentralEvent::CharacteristicValue { peripheral, characteristic, value } => {
                match value {
                    Ok(data) => {
                        let id = peripheral.DeviceId().unwrap().to_string().split("-").last().unwrap().to_string();
                        if should_process_data(&id, &characteristic.uuid, &data) {
                            factory().on_data(id, characteristic.uuid, data);
                        }
                    }
                    Err(e) => {
                        error!("接收失败: {} {} {}",peripheral.DeviceId().unwrap().to_string(), characteristic.uuid,e);
                    }
                }
            }
            // 连接失败
            CentralEvent::PeripheralConnectFailed { peripheral } => {
                let id = peripheral.DeviceId().unwrap().to_string().split("-").last().unwrap().to_string();
                error!("连接失败: {}",id);
                factory().on_disconnect(id.clone());
            }
        }
        return;
    }
    /// 运行
    pub fn run<F>(&mut self, factory: F)
    where
        F: Fn() -> Box<dyn Handler>,
    {
        while let Ok(event) = self.receiver.recv() {
            self.event(event, &factory);
        }
    }
}
// 检查数据是否在一秒内重复出现
fn should_process_data(device_id: &str, characteristic_uuid: &str, data: &Vec<u8>) -> bool {
    let mut cache = DATA_CACHE.lock().unwrap();
    let key = format!("{}-{}", device_id, characteristic_uuid);

    // 获取当前时间
    let now = Instant::now();

    // 检查缓存中是否存在该数据
    if let Some((cached_data, timestamp)) = cache.get(&key) {
        if cached_data == data && now.duration_since(*timestamp) < Duration::from_millis(500) {
            // 如果数据相同且时间间隔小于500毫秒,过滤掉
            return false;
        }
    }

    // 更新缓存数据和时间戳
    cache.insert(key, (data.clone(), now));
    true
}