blob: a8f6795de448870464bb4a651570d6ae2e9128bb [file] [log] [blame]
use crate::callback::CallbackSubscription;
use crate::callback::SubscribableCallback;
use crate::syscalls;
use core::slice;
const DRIVER_NUMBER: usize = 0x10000;
mod ipc_commands {
pub const REGISTER_SERVICE: usize = 0;
pub const NOTIFY_CLIENT: usize = 1;
}
pub struct IpcServerCallback<CB> {
callback: CB,
}
impl<CB> IpcServerCallback<CB> {
pub fn new(callback: CB) -> Self {
IpcServerCallback { callback }
}
}
impl<CB: FnMut(usize, usize, &mut [u8])> SubscribableCallback for IpcServerCallback<CB> {
fn call_rust(&mut self, arg0: usize, arg1: usize, arg2: usize) {
// FIXME: This is unsafe because IpcServerCallback can be subscribed on any driver
let mut v = unsafe { slice::from_raw_parts_mut(arg2 as *mut u8, arg1) };
(self.callback)(arg0, arg1, &mut v);
}
}
pub fn notify_client(pid: usize) {
unsafe { syscalls::command(DRIVER_NUMBER, pid, ipc_commands::NOTIFY_CLIENT, 0) };
}
pub struct IpcServerDriver;
impl IpcServerDriver {
pub fn start<CB>(callback: &mut IpcServerCallback<CB>) -> Result<CallbackSubscription, isize>
where
IpcServerCallback<CB>: SubscribableCallback,
{
syscalls::subscribe(DRIVER_NUMBER, ipc_commands::REGISTER_SERVICE, callback)
}
}