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