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());
}
}