optee_utee/net/
socket.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use optee_utee_sys as raw;
19
20use super::SocketError;
21use core::time::Duration;
22
23/// A trait designed to accommodate various implementations of GP TEE Sockets
24/// API.
25///
26/// An implementation of this trait is responsible for handling all
27/// protocol-related tasks, including but not limited to:
28/// * Defining its own Setup type and using it to establish a new connection;
29/// * Sending and receiving data over the connection, while managing protocol
30///   errors (such as permitting certain warnings but raising others).
31pub trait SocketAdapter: Sized {
32    type Setup;
33    type Handle;
34
35    fn open(setup: Self::Setup) -> Result<Self::Handle, SocketError>;
36    fn send(handle: &mut Self::Handle, buf: &[u8], timeout: u32) -> Result<usize, SocketError>;
37    fn recv(handle: &mut Self::Handle, buf: &mut [u8], timeout: u32) -> Result<usize, SocketError>;
38}
39
40/// A struct used for socket operations.
41pub struct Socket<T: SocketAdapter> {
42    handle: T::Handle,
43    recv_timeout: u32,
44    send_timeout: u32,
45}
46
47impl<T: SocketAdapter> Socket<T> {
48    /// create a new connection, and then sending and receiving data over it.
49    pub fn open(setup: T::Setup) -> Result<Self, SocketError> {
50        let handle = T::open(setup)?;
51        Ok(Self {
52            handle,
53            recv_timeout: raw::TEE_TIMEOUT_INFINITE,
54            send_timeout: raw::TEE_TIMEOUT_INFINITE,
55        })
56    }
57    /// set timeout of recv operation.
58    pub fn set_recv_timeout_in_milli(&mut self, milliseconds: u32) {
59        self.recv_timeout = milliseconds;
60    }
61    /// set timeout of send operation.
62    pub fn set_send_timeout_in_milli(&mut self, milliseconds: u32) {
63        self.send_timeout = milliseconds;
64    }
65    /// a wrapper of `set_recv_timeout_in_milli`, similar to `set_read_timeout`
66    /// in std::net::TcpStream, it will set timeout to `TEE_TIMEOUT_INFINITE`
67    /// if `Option::None` is provided.
68    pub fn set_recv_timeout(&mut self, dur: Option<Duration>) -> crate::Result<()> {
69        let milliseconds = convert_duration_option_to_timeout(dur)?;
70        self.set_recv_timeout_in_milli(milliseconds);
71        Ok(())
72    }
73    /// a wrapper of `set_send_timeout_in_milli`, similar to
74    /// `set_write_timeout` in std::net::TcpStream, it will set timeout to
75    /// `TEE_TIMEOUT_INFINITE` if `Option::None` is provided.
76    pub fn set_send_timeout(&mut self, dur: Option<Duration>) -> crate::Result<()> {
77        let milliseconds = convert_duration_option_to_timeout(dur)?;
78        self.set_send_timeout_in_milli(milliseconds);
79        Ok(())
80    }
81    /// send data, similar to `write` in `io::Write`
82    pub fn send(&mut self, buf: &[u8]) -> Result<usize, SocketError> {
83        T::send(&mut self.handle, buf, self.send_timeout)
84    }
85    /// recv data, similar to `read` in `io::Read`
86    pub fn recv(&mut self, buf: &mut [u8]) -> Result<usize, SocketError> {
87        T::recv(&mut self.handle, buf, self.recv_timeout)
88    }
89}
90
91fn convert_duration_option_to_timeout(dur: Option<Duration>) -> crate::Result<u32> {
92    match dur {
93        None => Ok(raw::TEE_TIMEOUT_INFINITE),
94        Some(v) => {
95            let milliseconds = v.as_millis();
96            if milliseconds > (u32::MAX as u128) {
97                return Err(crate::ErrorKind::BadParameters.into());
98            }
99            Ok(milliseconds as u32)
100        }
101    }
102}