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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
//! Common definitions for the execution of system calls
use anyhow::{anyhow, Result};
use byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt};
use enum_primitive::FromPrimitive;
pub const SYSCALL_SOCKET_PATH: &str = "/syscall-a653";
enum_from_primitive! {
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ApexSyscall {
/// P1-5 3.2.2.1 - GET_PARTITION_STATUS
GetPartitionStatus = 6530,
/// P1-5 3.2.2.2 - SET_PARTITION_MODE
SetPartitionMode = 6531,
/////////////////////
//* 10 Free Spaces */
/////////////////////
/// P1-5 3.3.2.1 - GET_PROCESS_ID
GetProcessId = 6542,
/// P1-5 3.3.2.2 - GET_PROCESS_STATUS
GetProcessStatus = 6543,
/// P1-5 3.3.2.3 - CREATE_PROCESS
CreateProcess = 6544,
/// P1-5 3.3.2.4 - SET_PRIORITY
SetPriority = 6545,
/// P1-5 3.3.2.5 - SUSPEND_SELF
SuspendSelf = 6546,
/// P1-5 3.3.2.6 - SUSPEND
Suspend = 6547,
/// P1-5 3.3.2.7 - RESUME
Resume = 6548,
/// P1-5 3.3.2.8 - STOP_SELF
StopSelf = 6549,
/// P1-5 3.3.2.9 - STOP
Stop = 6550,
/// P1-5 3.3.2.10 - START
Start = 6551,
/// P1-5 3.3.2.11 - DELAY_START
DelayStart = 6552,
/// P1-5 3.3.2.12 - LOCK_PREEMPTION
LockPreemption = 6553,
/// P1-5 3.3.2.13 - UNLOCK_PREEMPTION
UnlockPreemption = 6554,
/// P1-5 3.3.2.14 - GET_MY_ID
GetMyId = 6555,
/// P1-5 3.3.2.15 - INITIALIZE_PROCESS_CORE_AFFINITY
InitializeProcessCoreAffinity = 6556,
/// P1-5 3.3.2.16 - GET_MY_PROCESSOR_CORE_ID
GetMyProcessorCoreId = 6557,
/// P1-5 3.3.2.17 - GET_MY_INDEX
GetMyIndex = 6558,
/////////////////////
//* 10 Free Spaces */
/////////////////////
/// P1-5 3.4.2.1 - TIMED_WAIT
TimedWait = 6569,
/// P1-5 3.4.2.2 - PERIODIC_WAIT
PeriodicWait = 6570,
/// P1-5 3.4.2.3 - GET_TIME
GetTime = 6571,
/// P1-5 3.4.2.4 - REPLENISH
Replenish = 6572,
/////////////////////
//* 10 Free Spaces */
/////////////////////
/// P1-5 3.6.2.1.1 - CREATE_SAMPLING_PORT
CreateSamplingPort = 6583,
/// P1-5 3.6.2.1.2 - WRITE_SAMPLING_MESSAGE
WriteSamplingMessage = 6584,
/// P1-5 3.6.2.1.3 - READ_SAMPLING_MESSAGE
ReadSamplingMessage = 6585,
/// P1-5 3.6.2.1.4 - GET_SAMPLING_MESSAGE_PORT_ID
GetSamplingMessagePortId = 6586,
/// P1-5 3.6.2.1.5 - GET_SAMPLING_PORT_STATUS
GetSamplingPortStatus = 6587,
/////////////////////
//* 10 Free Spaces */
/////////////////////
/// P1-5 3.6.2.1.1 - CREATE_QUEUING_PORT
CreateQueuingPort = 6598,
/// P1-5 3.6.2.1.2 - SEND_QUEUING_MESSAGE
SendQueuingMessage = 6599,
/// P1-5 3.6.2.1.3 - RECEIVE_QUEUING_MESSAGE
ReceiveQueuingMessage = 6600,
/// P1-5 3.6.2.1.4 - GET_QUEUING_MESSAGE_PORT_ID
GetQueuingMessagePortId = 6601,
/// P1-5 3.6.2.1.5 - GET_QUEUING_PORT_STATUS
GetQueuingPortStatus = 6602,
/// P1-5 3.6.2.1.6 - CLEAR_QUEUING_PORT
ClearQueuingPort = 6603,
/////////////////////
//* 10 Free Spaces */
/////////////////////
/// P1-5 3.7.2.1.1 - CREATE_BUFFER
CreateBuffer = 6614,
/// P1-5 3.7.2.1.2 - SEND_BUFFER
SendBuffer = 6615,
/// P1-5 3.7.2.1.3 - RECEIVE_BUFFER
ReceiveBuffer = 6616,
/// P1-5 3.7.2.1.4 - GET_BUFFER_ID
GetBufferId = 6617,
/// P1-5 3.7.2.1.5 - GET_BUFFER_STATUS
GetBufferStatus = 6618,
/////////////////////
//* 10 Free Spaces */
/////////////////////
/// P1-5 3.7.2.2.1 - CREATE_BLACKBOARD
CreateBlackboard = 6629,
/// P1-5 3.7.2.2.2 - DISPLAY_BLACKBOARD
DisplayBlackboard = 6630,
/// P1-5 3.7.2.2.3 - READ_BLACKBOARD
ReadBlackboard = 6631,
/// P1-5 3.7.2.2.4 - CLEAR_BLACKBOARD
ClearBlackboard = 6632,
/// P1-5 3.7.2.2.5 - GET_BLACKBOARD_ID
GetBlackboardId = 6633,
/// P1-5 3.7.2.2.6 - GET_BLACKBOARD_STATUS
GetBlackboardStatus = 6634,
/////////////////////
//* 10 Free Spaces */
/////////////////////
/// P1-5 3.7.2.3.1 - CREATE_SEMAPHORE
CreateSemaphore = 6645,
/// P1-5 3.7.2.3.2 - WAIT_SEMAPHORE
WaitSemaphore = 6646,
/// P1-5 3.7.2.3.3 - SIGNAL_SEMAPHORE
SignalSemaphore = 6647,
/// P1-5 3.7.2.3.4 - GET_SEMAPHORE_ID
GetSemaphoreId = 6648,
/// P1-5 3.7.2.3.5 - GET_SEMAPHORE_STATUS
GetSemaphoreStatus = 6649,
/////////////////////
//* 10 Free Spaces */
/////////////////////
/// P1-5 3.7.2.4.1 - CREATE_EVENT
CreateEvent = 6660,
/// P1-5 3.7.2.4.2 - SET_EVENT
SetEvent = 6661,
/// P1-5 3.7.2.4.3 - RESET_EVENT
ResetEvent = 6662,
/// P1-5 3.7.2.4.4 - WAIT_EVENT
WaitEvent = 6663,
/// P1-5 3.7.2.4.5 - GET_EVENT_ID
GetEventId = 6664,
/// P1-5 3.7.2.4.6 - GET_EVENT_STATUS
GetEventStatus = 6665,
/////////////////////
//* 10 Free Spaces */
/////////////////////
/// P1-5 3.7.2.1.1 - CREATE_MUTEX
CreateMutex = 6676,
/// P1-5 3.7.2.1.2 - ACQUIRE_MUTEX
AcquireMutex = 6677,
/// P1-5 3.7.2.1.3 - RELEASE_MUTEX
ReleaseMutex = 6678,
/// P1-5 3.7.2.1.4 - RESET_MUTEX
ResetMutex = 6679,
/// P1-5 3.7.2.1.5 - GET_MUTEX_ID
GetMutexId = 6680,
/// P1-5 3.7.2.1.6 - GET_MUTEX_STATUS
GetMutexStatus = 6681,
/// P1-5 3.7.2.1.7 - GET_PROCIESS_MUTEX_STATE
GetProciessMutexState = 6682,
/////////////////////
//* 10 Free Spaces */
/////////////////////
/// P1-5 3.8.2.1 - REPORT_APPLICATION_MESSAGE
ReportApplicationMessage = 6693,
/// P1-5 3.8.2.2 - CREATE_ERROR_HANDLER
CreateErrorHandler = 6694,
/// P1-5 3.8.2.3 - GET_ERROR_STATUS
GetErrorStatus = 6695,
/// P1-5 3.8.2.4 - RAISE_APPLICATION_ERROR
RaiseApplicationError = 6696,
/// P1-5 3.8.2.5 - CONFIGURE_ERROR_HANDLER
ConfigureErrorHandler = 6697,
}
}
#[derive(Debug, PartialEq)]
pub struct SyscallRequest {
pub id: ApexSyscall,
pub params: Vec<u64>,
}
#[derive(Debug, PartialEq)]
pub struct SyscallResponse {
pub id: ApexSyscall,
pub status: u64,
}
impl SyscallRequest {
/// Serializes a SyscallRequest into its binary representation
///
/// The format for serializing a SyscallRequest is defined as follows:
/// ```text
/// id [u64]
/// nparams [u8]
/// params [u64 * nparams]
/// ```
///
/// All integers are encoded in native endian.
pub fn serialize(&self) -> Result<Vec<u8>> {
let mut serialized: Vec<u8> = Vec::new();
serialized.write_u64::<NativeEndian>(self.id as u64)?;
serialized.write_u8(self.params.len().try_into()?)?;
for ¶m in &self.params {
serialized.write_u64::<NativeEndian>(param)?;
}
Ok(serialized)
}
/// Deserializes a serialized SyscallRequest back into its internal
/// representation
pub fn deserialize(serialized: &Vec<u8>) -> Result<Self> {
let mut serialized: &[u8] = serialized;
let id = ApexSyscall::from_u64(serialized.read_u64::<NativeEndian>()?)
.ok_or(anyhow!("deserialization of ApexSyscall failed"))?;
let nparams = serialized.read_u8()?;
let mut params: Vec<u64> = Vec::with_capacity(nparams as usize);
for _ in 0..nparams {
params.push(serialized.read_u64::<NativeEndian>()?);
}
Ok(SyscallRequest { id, params })
}
}
impl SyscallResponse {
/// Serializes a SyscallResponse into its binary representation
///
/// The format for serializing a SyscallResponse is defined as follows:
/// ```text
/// id [u64]
/// status [u64]
/// ```
///
/// All integers are encoded in native endian.
pub fn serialize(&self) -> Result<Vec<u8>> {
let mut serialized: Vec<u8> = Vec::new();
serialized.write_u64::<NativeEndian>(self.id as u64)?;
serialized.write_u64::<NativeEndian>(self.status)?;
Ok(serialized)
}
/// Deserializes a serialized SyscallResponse back into its internal
/// representation
pub fn deserialize(serialized: &Vec<u8>) -> Result<Self> {
let mut serialized: &[u8] = serialized;
let id = ApexSyscall::from_u64(serialized.read_u64::<NativeEndian>()?)
.ok_or(anyhow!("deserialization of ApexSyscall failed"))?;
let status = serialized.read_u64::<NativeEndian>()?;
Ok(SyscallResponse { id, status })
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_request() {
let request = SyscallRequest {
id: ApexSyscall::Start,
params: vec![1, 2, 3],
};
let serialized = request.serialize().unwrap();
let mut serialized: &[u8] = &serialized;
let id = serialized.read_u64::<NativeEndian>().unwrap();
assert_eq!(id, ApexSyscall::Start as u64);
let nparams = serialized.read_u8().unwrap();
assert_eq!(nparams, 3);
let params = [
serialized.read_u64::<NativeEndian>().unwrap(),
serialized.read_u64::<NativeEndian>().unwrap(),
serialized.read_u64::<NativeEndian>().unwrap(),
];
assert_eq!(params, [1, 2, 3]);
assert!(serialized.is_empty());
}
#[test]
fn test_serialize_response() {
let response = SyscallResponse {
id: ApexSyscall::Start,
status: 42,
};
let serialized = response.serialize().unwrap();
let mut serialized: &[u8] = &serialized;
let id = serialized.read_u64::<NativeEndian>().unwrap();
assert_eq!(id, ApexSyscall::Start as u64);
let status = serialized.read_u64::<NativeEndian>().unwrap();
assert_eq!(status, 42);
assert!(serialized.is_empty());
}
#[test]
fn test_deserialize_request() {
let request = SyscallRequest {
id: ApexSyscall::Start,
params: vec![1, 2, 3],
};
let serialized = request.serialize().unwrap();
let deserialized = SyscallRequest::deserialize(&serialized).unwrap();
assert_eq!(request, deserialized);
assert!(!serialized.is_empty());
}
#[test]
fn test_deserialize_response() {
let response = SyscallResponse {
id: ApexSyscall::Start,
status: 42,
};
let serialized = response.serialize().unwrap();
let deserialized = SyscallResponse::deserialize(&serialized).unwrap();
assert_eq!(response, deserialized);
assert!(!serialized.is_empty());
}
}