1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 use alloc::alloc::AllocError; 18 use alloc::collections::TryReserveError; 19 use core::num::TryFromIntError; 20 use trusty_std::ffi::TryNewError; 21 use trusty_sys::{c_long, Error}; 22 23 /// A specialized [`Result`] type for IPC operations. 24 /// 25 /// This type is used throughout the [`tipc`](crate) crate as a shorthand for result 26 /// return values. Users outside the current crate should generally use this 27 /// type as `tipc::Result` rather than shadowing the standard `Result` type. 28 pub type Result<T> = core::result::Result<T, TipcError>; 29 30 /// Errors that an IPC connection may encounter. 31 #[derive(Clone, Debug, Eq, PartialEq)] 32 pub enum TipcError { 33 /// The handle ID provided or returned by the kernel was invalid. 34 InvalidHandle, 35 36 /// The provided port was invalid. 37 InvalidPort, 38 39 /// Failed to allocate, probably out of memory. 40 AllocError, 41 42 /// An integer did not fit into the required size. 43 OutOfBounds, 44 45 /// Could not write the entire message. Contains the number of bytes that 46 /// were successfully written. 47 IncompleteWrite { num_bytes_written: usize }, 48 49 /// The provided buffer was not large enough to receive the entire message. 50 NotEnoughBuffer, 51 52 /// Some other error occurred. 53 UnknownError, 54 55 /// Internal data was not valid 56 InvalidData, 57 58 /// Message could not be sent because connection was busy. 59 Busy, 60 61 /// The channel was closed before the operation could be completed. 62 ChannelClosed, 63 64 /// Some other system error 65 SystemError(Error), 66 } 67 68 /// The result type for an `on_connect` operation. 69 /// 70 /// If the connection is accepted, contains created connection object for this connection. 71 #[derive(Clone, Copy, Debug)] 72 pub enum ConnectResult<C> { 73 Accept(C), 74 CloseConnection, 75 } 76 77 /// The result type for an `on_message` operation. 78 /// 79 /// Its value tells the `ServiceManager` what to do after handling the message. 80 #[derive(Clone, Copy, Debug)] 81 pub enum MessageResult { 82 MaintainConnection, 83 CloseConnection, 84 } 85 86 impl TipcError { from_uapi(rc: c_long) -> Self87 pub fn from_uapi(rc: c_long) -> Self { 88 let sys_err: Error = rc.into(); 89 match sys_err { 90 Error::BadHandle => TipcError::InvalidHandle, 91 e => TipcError::SystemError(e), 92 } 93 } 94 } 95 96 impl<T> ConnectResult<T> { 97 /// Maps a `ConnectResult<T>` to a `ConnectResult<U>` by applying a function to the contained connection. map<U, F: FnOnce(T) -> U>(self, f: F) -> ConnectResult<U>98 pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> ConnectResult<U> { 99 match self { 100 Self::Accept(c) => ConnectResult::Accept(f(c)), 101 Self::CloseConnection => ConnectResult::CloseConnection, 102 } 103 } 104 } 105 106 impl From<TryNewError> for TipcError { from(err: TryNewError) -> Self107 fn from(err: TryNewError) -> Self { 108 match err { 109 TryNewError::NulError(..) => Self::InvalidPort, 110 TryNewError::AllocError => Self::AllocError, 111 } 112 } 113 } 114 115 impl From<TryReserveError> for TipcError { from(_err: TryReserveError) -> Self116 fn from(_err: TryReserveError) -> Self { 117 TipcError::AllocError 118 } 119 } 120 121 impl From<TryFromIntError> for TipcError { from(_err: TryFromIntError) -> Self122 fn from(_err: TryFromIntError) -> Self { 123 TipcError::OutOfBounds 124 } 125 } 126 127 impl From<AllocError> for TipcError { from(_err: AllocError) -> Self128 fn from(_err: AllocError) -> Self { 129 TipcError::AllocError 130 } 131 } 132