br-ble 0.2.0

This is an Bluetooth
Documentation
#![allow(warnings)]
use std::collections::HashMap;
use std::process::exit;
use std::thread;
use std::thread::sleep;
use std::time::Duration;
use log::{debug, error, warn};
use static_assertions::{assert_impl_all, assert_not_impl_any};
use crate::Handler;
use crate::device::{Device, Characteristic};
use crate::mac::central::{CentralEvent, CentralManager};
use crate::mac::error::{ErrorKind};
use crate::mac::sync::Receiver;

#[macro_use]
pub mod macros;
pub mod platform;
pub mod central;
pub mod sync;
pub mod uuid;
pub mod error;


pub struct Mac {
    central: CentralManager,
    receiver: Receiver<CentralEvent>,
    service_count: HashMap<String, usize>,
    connect_device: Vec<String>,
}
impl Default for Mac {
    fn default() -> Self {
        Self::new()
    }
}

impl Mac {
    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::Unsupported => {
                        eprintln!("Bluetooth is not supported on this system");
                        exit(1);
                    }
                    ManagerState::Unauthorized => {
                        eprintln!("The app is not authorized to use Bluetooth on this system");
                        exit(1);
                    }
                    ManagerState::PoweredOff => {
                        factory().on_adapter_close();
                    }
                    ManagerState::PoweredOn => {
                        factory().on_adapter_open();
                        self.central.scan();
                    }
                    _ => {}
                }
            }
            // 发现设备
            CentralEvent::PeripheralDiscovered { peripheral, advertisement_data, rssi } => {
                let name = advertisement_data.local_name().unwrap_or("").to_string();
                if advertisement_data.is_connectable() != Some(false) {
                    let uuid = peripheral.peripheral.id().to_string();
                    let t = Device::new(uuid, name, rssi, self.central.clone(), peripheral.clone(), advertisement_data);
                    factory().on_discover(t.clone());
                }
            }
            // 外围设备已断开连接
            CentralEvent::PeripheralDisconnected { peripheral, error } => {
                factory().on_disconnect(peripheral.id().to_string().clone());
                if error.is_none() {
                    warn!("设备正常断开: {}", peripheral.id().to_string());
                    return;
                }
                match error.clone().unwrap().kind() {
                    ErrorKind::PeripheralDisconnected => {
                        warn!("设备断开: {}", peripheral.id().to_string());
                    }
                    ErrorKind::ConnectionTimeout => {
                        warn!("设备离线: {}", peripheral.id().to_string());
                    }
                    _ => {
                        warn!("未知设备离线: {} {:?}", peripheral.id().to_string(),error.clone().unwrap());
                    }
                }
            }
            // 已连接
            CentralEvent::PeripheralConnected { peripheral } => {
                debug!("已连接设备: {}", peripheral.id().to_string());
                peripheral.discover_services_with_uuids(&[]);
                factory().on_connect(peripheral.id().to_string());
            }
            // 发现的服务
            CentralEvent::ServicesDiscovered { peripheral, services, } => {
                match services {
                    Ok(services) => {
                        for service in services.iter() {
                            peripheral.discover_characteristics_with_uuids(service, &[]);
                            self.service_count.entry(service.id().to_string().clone()).or_insert(0usize);
                            let service_count = *self.service_count.get(&service.id().to_string().clone()).unwrap();
                            self.service_count.insert(service.id().to_string().clone(), service_count + 1);
                        }
                    }
                    Err(_) => {
                        error!("未发现服务: {}",peripheral.id().to_string());
                    }
                }
            }
            // 发现特征
            CentralEvent::CharacteristicsDiscovered { peripheral, service, characteristics } => {
                match characteristics {
                    Ok(chars) => {
                        for char in chars {
                            let characteristic = Characteristic::default(char);
                            factory().on_characteristics(peripheral.id().to_string(), characteristic);
                        }
                        let service_count = *self.service_count.get(&service.id().to_string()).unwrap();
                        self.service_count.insert(service.id().to_string(), service_count - 1usize);
                    }
                    Err(err) => {
                        let service_count = *self.service_count.get(&service.id().to_string()).unwrap();
                        self.service_count.insert(service.id().to_string(), service_count - 1usize);
                        error!("特征发现失败: {} {}", peripheral.id(), err)
                    }
                }
                let service_count = *self.service_count.get(&service.id().to_string()).unwrap();
                if service_count == 0 {
                    self.service_count.remove(&service.id().to_string());
                    factory().listen(peripheral.id().to_string());
                }
            }
            // 订阅返回
            CentralEvent::SubscriptionChangeResult { peripheral, characteristic, result } => {
                match result {
                    Ok(_) => {}
                    Err(e) => {
                        error!("订阅失败: {} {} {}",peripheral.id(),characteristic.id(),e);
                    }
                }
            }
            // 接收监听
            CentralEvent::CharacteristicValue { peripheral, characteristic, value } => {
                match value {
                    Ok(data) => {
                        factory().on_data(peripheral.id().to_string(), characteristic.id().to_string(), data);
                    }
                    Err(e) => {
                        error!("接收失败: {} {} {}",peripheral.id(),characteristic.id(),e);
                    }
                }
            }
            CentralEvent::PeripheralConnectFailed { peripheral, error } => {
                error!("连接失败: {} {:?}",peripheral.id(),error);
                factory().on_disconnect(peripheral.id().to_string().clone());
            }
            CentralEvent::PeripheralNameChanged { peripheral, new_name } => {
                warn!("外围设备名称更改: {} {:?}",peripheral.id(),new_name);
            }
            _ => {
                warn!("未知: {:?}", event);
            }
        }
    }

    /// 运行
    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);
        }
    }
}
/// Arbitrary data to associate with asynchronous API call.
pub type Tag = Box<dyn std::any::Any + Send>;

assert_impl_all!(Tag: Send);
assert_not_impl_any!(Tag: Sync);

/// The possible states of a Core Bluetooth manager.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[non_exhaustive]
pub enum ManagerState {
    /// The manager’s state is unknown.
    Unknown = 0,

    /// A state that indicates the connection with the system service was momentarily lost.
    Resetting = 1,

    /// A state that indicates this device doesn’t support the Bluetooth low energy central or client role.
    Unsupported = 2,

    /// A state that indicates the application isn’t authorized to use the Bluetooth low energy role.
    Unauthorized = 3,

    /// A state that indicates Bluetooth is currently powered off.
    PoweredOff = 4,

    /// A state that indicates Bluetooth is currently powered on and available to use.
    PoweredOn = 5,
}

impl ManagerState {
    fn from_u8(v: u8) -> Option<Self> {
        Some(match v {
            0 => Self::Unknown,
            1 => Self::Resetting,
            2 => Self::Unsupported,
            3 => Self::Unauthorized,
            4 => Self::PoweredOff,
            5 => Self::PoweredOn,
            _ => return None,
        })
    }
}