1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//! 透传协议

#![no_std]
extern crate alloc;

use alloc::boxed::Box;
use alloc::sync::Arc;
use spin::Mutex;
use unmp::net::{Id, NET};

/// 协议ID
pub const PROTOCOL_ID: u8 = 0;

/// 接收到数据的回调函数格式
pub type RecvCallback = dyn Fn(&Id, &[u8]) + Send + Sync + 'static;
/// 透传协议的回调函数列表
#[derive(Default)]
struct CallbackContext {
    on_recv: Option<Box<RecvCallback>>,
}

/// 透传协议
#[derive(Clone)]
pub struct ProtocolRaw {
    /// 回调函数列表
    cbctx: Arc<Mutex<CallbackContext>>,
}
impl ProtocolRaw {
    /// 创建一个透传协议实例
    pub fn new() -> Self {
        let protocol = ProtocolRaw {
            cbctx: Arc::new(Mutex::new(CallbackContext::default())),
        };
        let protocol_tmp = protocol.clone();
        NET.register_protocol(
            PROTOCOL_ID,
            Box::new(move |remote: &Id, data: &[u8]| {
                protocol_tmp.recv_handle(remote, data);
            }),
        );
        return protocol;
    }
    /// 设置接收到数据后的回调函数
    pub fn set_recv_cb(&self, cb: Box<RecvCallback>) {
        let mut cbctx = self.cbctx.lock();
        cbctx.on_recv = Some(cb);
    }
    /// 接收网络层数据包
    pub fn recv_handle(&self, remote: &Id, data: &[u8]) {
        let mut cbctx = self.cbctx.lock();
        if let Some(ref mut cb) = cbctx.on_recv {
            cb(remote, data);
        } else {
            // W:("unmp_protocol_raw has not recv callback.");
        }
    }
    /// 发送数据到指定设备
    pub fn send(&self, id: &Id, buf: &[u8]) {
        NET.send(PROTOCOL_ID, &buf, Some(id), None);
    }
}