use std::{ffi::c_void, ptr};
use futures_channel::oneshot;
use open62541_sys::{
UA_Client, UA_Client_MonitoredItems_delete_async, UA_DeleteMonitoredItemsResponse, UA_UInt32,
};
use crate::{CallbackOnce, DataType as _, Error, Result, ua};
type CbResponse =
CallbackOnce<std::result::Result<ua::DeleteMonitoredItemsResponse, ua::StatusCode>>;
pub(super) async fn call(
client: &ua::Client,
request: &ua::DeleteMonitoredItemsRequest,
) -> Result<ua::DeleteMonitoredItemsResponse> {
let (tx, rx) = oneshot::channel::<Result<ua::DeleteMonitoredItemsResponse>>();
let status_code = ua::StatusCode::new({
let request = unsafe { ua::DeleteMonitoredItemsRequest::to_raw_copy(request) };
let response_callback =
move |result: std::result::Result<ua::DeleteMonitoredItemsResponse, _>| {
let _unused = tx.send(result.map_err(Error::new));
};
log::debug!("Calling MonitoredItems_delete_async()");
unsafe {
UA_Client_MonitoredItems_delete_async(
client.as_ptr().cast_mut(),
request,
Some(callback_execute_response_c),
CbResponse::prepare(response_callback),
ptr::null_mut(),
)
}
});
Error::verify_good(&status_code)?;
rx.await
.unwrap_or(Err(Error::internal("callback should send result")))
}
unsafe extern "C" fn callback_execute_response_c(
_client: *mut UA_Client,
userdata: *mut c_void,
_request_id: UA_UInt32,
response: *mut c_void,
) {
log::debug!("MonitoredItems_delete_async() completed");
let response = response.cast::<UA_DeleteMonitoredItemsResponse>();
let response = unsafe { response.as_ref() }.expect("response should be set");
let status_code = ua::StatusCode::new(response.responseHeader.serviceResult);
let result = if status_code.is_good() {
Ok(ua::DeleteMonitoredItemsResponse::clone_raw(response))
} else {
Err(status_code)
};
unsafe {
CbResponse::execute(userdata, result);
}
}
pub(super) fn send_request(
client: &ua::Client,
request: &ua::DeleteMonitoredItemsRequest,
) -> Result<()> {
let status_code = ua::StatusCode::new({
let request = unsafe { ua::DeleteMonitoredItemsRequest::to_raw_copy(request) };
log::debug!("Calling MonitoredItems_delete_async()");
unsafe {
UA_Client_MonitoredItems_delete_async(
client.as_ptr().cast_mut(),
request,
Some(callback_log_response_c),
ptr::null_mut(),
ptr::null_mut(),
)
}
});
Error::verify_good(&status_code)?;
Ok(())
}
unsafe extern "C" fn callback_log_response_c(
_client: *mut UA_Client,
_userdata: *mut c_void,
_request_id: UA_UInt32,
response: *mut c_void,
) {
log::debug!("MonitoredItems_delete_async() completed");
let response = response.cast::<UA_DeleteMonitoredItemsResponse>();
let response = unsafe { response.as_ref() }.expect("response should be set");
let status_code = ua::StatusCode::new(response.responseHeader.serviceResult);
if let Err(error) = Error::verify_good(&status_code) {
log::warn!("Error in response when deleting monitored items: {error}");
}
}