unmp-center 0.1.2

unmp data center
Documentation
//! 链路层数据收发

use crate::event;
use crate::var;
use log::*;
use spin::Once;
use unmp::id::*;
use unmp::link::{ErrorKind, Link};
use unmp::net;
use unmp::Connection;
use unmp_center_core::{Cmd, Data};
use unmp_protocol_etp::Addr;

const ETP_PORT: u8 = 0x64;
static SEND: Once<SendFun> = Once::new();
static PROTOCOL: Once<Protocol> = Once::new();
static LINK: Once<Link> = Once::new();
static CENTER_ID: Id = UniqueId::new(0, 1).id();
static CENTER_ETP: Addr = Addr::new(UniqueId::new(0, 1).id(), ETP_PORT);

type SendFun = fn(buf: &[u8]);

#[derive(Clone)]
pub enum Protocol {
    Raw,
    Etp(u8),
}
fn solve(data: &Data) {
    match data.cmd() {
        Cmd::GetIdRes {
            device_id,
            private_key,
            public_key,
        } => {
            event::emit_getid(device_id, private_key, public_key);
        }
        Cmd::LoginRes {} => {
            event::emit_login();
        }
        Cmd::HeartRes {} => {}
        Cmd::GetTimestampRes { timestamp } => {
            event::emit_get_timestamp(*timestamp);
        }
        Cmd::SetActualRes { id, k, v } => {
            var::set_actual(id, *k, v);
        }
        Cmd::GetActualRes { id, k, v } => {
            var::set_actual(id, *k, v);
        }
        Cmd::NoticeActual { id, k, v } => {
            var::set_actual(id, *k, v);
        }
        Cmd::SetTargetRes { id, k, v } => {
            var::set_target(id, *k, v);
        }
        Cmd::GetTargetRes { id, k, v } => {
            var::set_target(id, *k, v);
        }
        Cmd::NoticeTarget { id, k, v } => {
            var::set_target(id, *k, v);
        }
        Cmd::EnterBindRes { code } => {
            event::emit_enter_bind(code);
        }
        Cmd::BindRes { id, public_key } => {
            event::emit_bind(id, public_key);
        }
        Cmd::UnbindRes { id } => {
            event::emit_unbind(id);
        }
        Cmd::NoticeBind { id, public_key } => {
            event::emit_bind(id, public_key);
        }
        Cmd::NoticeUnbind { id } => {
            event::emit_unbind(id);
        }
        _ => {
            event::emit_error(data.kind(), data.status());
            info!("{:?}", data);
        }
    }
}
fn etp_listener(_remote: Addr, buf: &[u8]) {
    let data = Data::parse(buf);
    solve(&data);
}
fn raw_listener(_remote: Connection, buf: &[u8]) {
    let data = Data::parse(buf);
    solve(&data);
}
fn sendto(_link: Link, buf: &[u8]) -> Result<(), ErrorKind> {
    if let Some(fun) = SEND.get() {
        fun(buf);
    }
    return Ok(());
}

pub fn set_protocol(protocol: Protocol) {
    match protocol {
        Protocol::Raw => {
            unmp_protocol_raw::init();
            unmp_protocol_raw::set_recv_cb(raw_listener);
        }
        Protocol::Etp(_) => {
            unmp_protocol_etp::init();
            unmp_protocol_etp::listen(ETP_PORT, etp_listener);
        }
    }
    PROTOCOL.call_once(|| protocol);
}
pub fn set_send(fun: SendFun) {
    SEND.call_once(|| fun);
    let link = Link::new(sendto);
    LINK.call_once(|| link);
    net::connect(&ID_PARENT, link);
}
pub(crate) fn send(buf: &[u8]) {
    match PROTOCOL.get().unwrap() {
        Protocol::Raw => {
            unmp_protocol_raw::send(&CENTER_ID, buf);
        }
        Protocol::Etp(retry) => {
            unmp_protocol_etp::send(ETP_PORT, &CENTER_ETP, buf, *retry);
        }
    }
}
pub fn recv(buf: &[u8]) {
    let link = LINK.get().unwrap();
    net::when_recv(*link, buf);
}