Skip to main content

strate_net_silo/
ipc.rs

1use core::str;
2
3use strat9_syscall::data::{
4    IPC_FILE_FLAG_CHUNK_READ, IPC_FILE_FLAG_CHUNK_WRITE, IPC_FILE_FLAG_PIPE,
5};
6use strate_net::IpcMessage;
7
8pub(crate) const HANDLE_FLAG_INFO: u32 = IPC_FILE_FLAG_CHUNK_READ;
9pub(crate) const HANDLE_FLAG_CONTROL: u32 = 0;
10pub(crate) const HANDLE_FLAG_STREAM: u32 =
11    IPC_FILE_FLAG_PIPE | IPC_FILE_FLAG_CHUNK_READ | IPC_FILE_FLAG_CHUNK_WRITE;
12pub(crate) const HANDLE_FLAG_DATAGRAM: u32 = IPC_FILE_FLAG_CHUNK_READ;
13
14pub(crate) fn reply_open(sender: u64, file_id: u64, size: u64, flags: u32) -> IpcMessage {
15    let mut msg = IpcMessage::new(0x80);
16    msg.sender = sender;
17    msg.payload[0..4].copy_from_slice(&0u32.to_le_bytes());
18    msg.payload[4..12].copy_from_slice(&file_id.to_le_bytes());
19    msg.payload[12..20].copy_from_slice(&size.to_le_bytes());
20    msg.payload[20..24].copy_from_slice(&flags.to_le_bytes());
21    msg
22}
23
24pub(crate) fn reply_read(sender: u64, data: &[u8]) -> IpcMessage {
25    let mut msg = IpcMessage::new(0x80);
26    msg.sender = sender;
27    msg.payload[0..4].copy_from_slice(&0u32.to_le_bytes());
28    let n = data.len().min(IpcMessage::READ_INLINE_CAPACITY);
29    msg.payload[4..8].copy_from_slice(&(n as u32).to_le_bytes());
30    msg.payload[8..8 + n].copy_from_slice(&data[..n]);
31    msg
32}
33
34pub(crate) fn reply_write(sender: u64, n: usize) -> IpcMessage {
35    let mut msg = IpcMessage::new(0x80);
36    msg.sender = sender;
37    msg.payload[0..4].copy_from_slice(&0u32.to_le_bytes());
38    msg.payload[4..8].copy_from_slice(&(n as u32).to_le_bytes());
39    msg
40}
41
42pub(crate) fn reply_write_data_len(sender: u64, msg: &IpcMessage) -> IpcMessage {
43    let data_len = u16::from_le_bytes([msg.payload[16], msg.payload[17]]) as usize;
44    reply_write(sender, data_len)
45}
46
47pub(crate) fn reply_ok(sender: u64) -> IpcMessage {
48    let mut msg = IpcMessage::new(0x80);
49    msg.sender = sender;
50    msg.payload[0..4].copy_from_slice(&0u32.to_le_bytes());
51    msg
52}
53
54pub(crate) fn open_path(msg: &IpcMessage) -> Result<&str, i32> {
55    let path_len = u16::from_le_bytes([msg.payload[4], msg.payload[5]]) as usize;
56    if path_len > IpcMessage::OPEN_INLINE_CAPACITY {
57        return Err(-22);
58    }
59    let path_bytes = &msg.payload[6..6 + path_len];
60    let path = str::from_utf8(path_bytes).map_err(|_| -22)?;
61    Ok(path.trim_start_matches('/'))
62}
63
64pub(crate) fn message_file_id(msg: &IpcMessage) -> u64 {
65    u64::from_le_bytes(msg.payload[0..8].try_into().unwrap_or([0u8; 8]))
66}
67
68pub(crate) fn read_request(msg: &IpcMessage) -> (u64, u64, usize) {
69    let file_id = message_file_id(msg);
70    let offset = u64::from_le_bytes(msg.payload[8..16].try_into().unwrap_or([0u8; 8]));
71    let requested = u32::from_le_bytes(msg.payload[16..20].try_into().unwrap_or([0u8; 4]));
72    (file_id, offset, requested as usize)
73}
74
75pub(crate) fn write_data_len(msg: &IpcMessage) -> usize {
76    let data_len = u16::from_le_bytes([msg.payload[16], msg.payload[17]]) as usize;
77    core::cmp::min(data_len, msg.payload.len().saturating_sub(18))
78}
79
80pub(crate) fn write_data(msg: &IpcMessage) -> &[u8] {
81    let data_len = write_data_len(msg);
82    &msg.payload[18..18 + data_len]
83}