use core::marker::PhantomData;
use std::sync::atomic::{AtomicBool, Ordering};
use wolfhsm_sys::{wc_CryptoInfo, wh_Client_CryptoCb};
use crate::client::Client;
use crate::error::Error;
pub const DEV_ID: i32 = 0x5748534Du32 as i32;
unsafe extern "C" {
fn wc_CryptoCb_RegisterDevice(
dev_id: core::ffi::c_int,
cb: Option<
unsafe extern "C" fn(
dev_id: core::ffi::c_int,
info: *mut wc_CryptoInfo,
ctx: *mut core::ffi::c_void,
) -> core::ffi::c_int,
>,
ctx: *mut core::ffi::c_void,
) -> core::ffi::c_int;
fn wc_CryptoCb_UnRegisterDevice(devId: core::ffi::c_int);
}
static REGISTERED: AtomicBool = AtomicBool::new(false);
pub struct CryptoCbGuard<'a>(PhantomData<&'a mut Client>);
impl Client {
pub fn register_cryptocb(&mut self) -> Result<CryptoCbGuard<'_>, Error> {
REGISTERED
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
.map_err(|_| Error::AlreadyRegistered)?;
let rc = unsafe {
wc_CryptoCb_RegisterDevice(DEV_ID, Some(wh_Client_CryptoCb), self.ctx_ptr().cast())
};
if rc != 0 {
REGISTERED.store(false, Ordering::SeqCst);
return Err(Error::Ffi {
code: rc,
func: "wc_CryptoCb_RegisterDevice",
});
}
Ok(CryptoCbGuard(PhantomData))
}
}
impl Drop for CryptoCbGuard<'_> {
fn drop(&mut self) {
unsafe { wc_CryptoCb_UnRegisterDevice(DEV_ID) };
REGISTERED.store(false, Ordering::SeqCst);
}
}