Skip to main content

cc_teec/common/
protocol.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (C) 2025-2026 KylinSoft Co., Ltd. <https://www.kylinos.cn/>
3// See LICENSES for license details.
4
5#![allow(dead_code)]
6#![allow(non_camel_case_types)]
7
8use bytemuck::{Pod, Zeroable};
9use serde::{Deserialize, Serialize};
10
11pub const CHUNK_SIZE: u64 = 512; // 512B 分块
12
13/// 数据包类型枚举,定义协议支持的不同操作类型
14#[derive(Debug, PartialEq, Eq, Default)]
15pub enum PacketType {
16    #[default]
17    Unknown = 0,
18    OpenSession = 1,
19    CloseSession = 2,
20    InvokeCommand = 3,
21    RequestCancellation = 4,
22}
23
24impl From<u64> for PacketType {
25    fn from(value: u64) -> Self {
26        match value {
27            0 => PacketType::Unknown,
28            1 => PacketType::OpenSession,
29            2 => PacketType::CloseSession,
30            3 => PacketType::InvokeCommand,
31            4 => PacketType::RequestCancellation,
32            _ => PacketType::Unknown,
33        }
34    }
35}
36
37impl From<PacketType> for u64 {
38    fn from(value: PacketType) -> Self {
39        match value {
40            PacketType::Unknown => 0,
41            PacketType::OpenSession => 1,
42            PacketType::CloseSession => 2,
43            PacketType::InvokeCommand => 3,
44            PacketType::RequestCancellation => 4,
45        }
46    }
47}
48/// 协议头结构,使用 #[repr(C)] 确保内存布局与C兼容
49/// 满足 bytemuck::Pod 要求:所有字段必须为基本类型
50#[repr(C)]
51#[derive(Debug, Copy, Clone, Pod, Zeroable)]
52pub struct PacketHeader {
53    /// 数据包类型标识,对应 PacketType 枚举的数值表示
54    pub data_type: u64,
55    /// 数据包负载大小
56    pub data_size: u64,
57}
58
59impl PacketHeader {
60    /// 协议头结构体的大小
61    pub const SIZE: usize = size_of::<PacketHeader>();
62
63    /// 将协议头序列化为字节切片
64    pub fn as_bytes(&self) -> &[u8] {
65        bytemuck::bytes_of(self)
66    }
67
68    /// 从字节切片反序列化协议头,
69    pub fn from_bytes(buf: &[u8]) -> Self {
70        *bytemuck::from_bytes(buf)
71    }
72}
73
74#[derive(Serialize, Deserialize)]
75pub enum TEE_Request {
76    OpenSession {
77        uuid: String,
78        connection_method: u32,
79        params: TEE_Parameters,
80    },
81    CloseSession {
82        session_id: u32,
83    },
84    InvokeCommand {
85        session_id: u32,
86        cmd_id: u32,
87        params: TEE_Parameters,
88    },
89    RequestCancellation {
90        session_id: u32,
91    },
92}
93
94#[derive(Serialize, Deserialize)]
95pub enum TEE_Response {
96    OpenSession { session_id: u32, result: u32 },
97    CloseSession { result: u32 },
98    InvokeCommand { params: TEE_Parameters, result: u32 },
99    RequestCancellation { result: u32 },
100}
101
102#[derive(Serialize, Deserialize, Default)]
103pub struct TEE_Parameters(
104    pub TEE_Parameter,
105    pub TEE_Parameter,
106    pub TEE_Parameter,
107    pub TEE_Parameter,
108);
109
110#[derive(Serialize, Deserialize, Default)]
111pub struct TEE_Parameter {
112    pub param: TEE_Param,
113    pub param_type: TEE_ParamType,
114}
115
116#[derive(Serialize, Deserialize, Default)]
117pub struct TEE_Param {
118    pub data: Vec<u8>,
119    pub value: TEE_Value,
120}
121
122#[derive(Serialize, Deserialize, Default)]
123pub struct TEE_Value {
124    pub a: u32,
125    pub b: u32,
126}
127
128#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone, Copy)]
129pub enum TEE_ParamType {
130    #[default]
131    None = 0,
132    ValueInput = 1,
133    ValueOutput = 2,
134    ValueInout = 3,
135    MemrefInput = 5,
136    MemrefOutput = 6,
137    MemrefInout = 7,
138}
139
140impl From<u32> for TEE_ParamType {
141    fn from(value: u32) -> Self {
142        match value {
143            0 => TEE_ParamType::None,
144            1 => TEE_ParamType::ValueInput,
145            2 => TEE_ParamType::ValueOutput,
146            3 => TEE_ParamType::ValueInout,
147            5 => TEE_ParamType::MemrefInput,
148            6 => TEE_ParamType::MemrefOutput,
149            7 => TEE_ParamType::MemrefInout,
150            _ => TEE_ParamType::None,
151        }
152    }
153}
154
155#[cfg(test)]
156mod protocol_tests {
157    use super::*;
158
159    #[test]
160    fn test_tee_param_type_from_u32() {
161        // 测试 TEE_ParamType 的 From<u32> 实现 - 覆盖所有分支
162        assert_eq!(TEE_ParamType::from(0), TEE_ParamType::None);
163        assert_eq!(TEE_ParamType::from(1), TEE_ParamType::ValueInput);
164        assert_eq!(TEE_ParamType::from(2), TEE_ParamType::ValueOutput);
165        assert_eq!(TEE_ParamType::from(3), TEE_ParamType::ValueInout);
166        assert_eq!(TEE_ParamType::from(4), TEE_ParamType::None); // 未知值 -> None
167        assert_eq!(TEE_ParamType::from(5), TEE_ParamType::MemrefInput);
168        assert_eq!(TEE_ParamType::from(6), TEE_ParamType::MemrefOutput);
169        assert_eq!(TEE_ParamType::from(7), TEE_ParamType::MemrefInout);
170        assert_eq!(TEE_ParamType::from(8), TEE_ParamType::None); // 未知值 -> None
171        assert_eq!(TEE_ParamType::from(99), TEE_ParamType::None); // 未知值 -> None
172        assert_eq!(TEE_ParamType::from(255), TEE_ParamType::None); // 边界值
173    }
174
175    #[test]
176    fn test_tee_value_default() {
177        // 测试 TEE_Value 的 Default trait
178        let default_val = TEE_Value::default();
179        assert_eq!(default_val.a, 0);
180        assert_eq!(default_val.b, 0);
181    }
182
183    #[test]
184    fn test_tee_parameter_default() {
185        // 测试 TEE_Parameter 的 Default trait
186        let default_param = TEE_Parameter::default();
187        assert_eq!(default_param.param_type, TEE_ParamType::None);
188        assert_eq!(default_param.param.value.a, 0);
189        assert_eq!(default_param.param.value.b, 0);
190        assert!(default_param.param.data.is_empty());
191    }
192
193    #[test]
194    fn test_packet_header_serialization_roundtrip() {
195        // 测试 PacketHeader 序列化/反序列化的往返一致性
196        let original = PacketHeader {
197            data_type: 0x1234_5678_9ABC_DEF0,
198            data_size: 0xFEDC_BA98_7654_3210,
199        };
200
201        let bytes = original.as_bytes();
202        let restored = PacketHeader::from_bytes(bytes);
203
204        assert_eq!(original.data_type, restored.data_type);
205        assert_eq!(original.data_size, restored.data_size);
206    }
207}