mirror of
https://github.com/jkcoxson/idevice.git
synced 2026-03-02 14:36:16 +01:00
Implement adapter bindings
This commit is contained in:
192
ffi/src/adapter.rs
Normal file
192
ffi/src/adapter.rs
Normal file
@@ -0,0 +1,192 @@
|
||||
// Jackson Coxson
|
||||
|
||||
use std::ffi::{CString, c_char};
|
||||
|
||||
use crate::core_device_proxy::AdapterHandle;
|
||||
use crate::{IdeviceErrorCode, RUNTIME};
|
||||
|
||||
/// Connects the adapter to a specific port
|
||||
///
|
||||
/// # Arguments
|
||||
/// * [`handle`] - The adapter handle
|
||||
/// * [`port`] - The port to connect to
|
||||
///
|
||||
/// # Returns
|
||||
/// An error code indicating success or failure
|
||||
///
|
||||
/// # Safety
|
||||
/// `handle` must be a valid pointer to a handle allocated by this library
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn adapter_connect(
|
||||
handle: *mut AdapterHandle,
|
||||
port: u16,
|
||||
) -> IdeviceErrorCode {
|
||||
if handle.is_null() {
|
||||
return IdeviceErrorCode::InvalidArg;
|
||||
}
|
||||
|
||||
let adapter = unsafe { &mut (*handle).0 };
|
||||
let res = RUNTIME.block_on(async move { adapter.connect(port).await });
|
||||
|
||||
match res {
|
||||
Ok(_) => IdeviceErrorCode::IdeviceSuccess,
|
||||
Err(e) => {
|
||||
log::error!("Adapter connect failed: {}", e);
|
||||
IdeviceErrorCode::AdapterIOFailed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Enables PCAP logging for the adapter
|
||||
///
|
||||
/// # Arguments
|
||||
/// * [`handle`] - The adapter handle
|
||||
/// * [`path`] - The path to save the PCAP file (null-terminated string)
|
||||
///
|
||||
/// # Returns
|
||||
/// An error code indicating success or failure
|
||||
///
|
||||
/// # Safety
|
||||
/// `handle` must be a valid pointer to a handle allocated by this library
|
||||
/// `path` must be a valid null-terminated string
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn adapter_pcap(
|
||||
handle: *mut AdapterHandle,
|
||||
path: *const c_char,
|
||||
) -> IdeviceErrorCode {
|
||||
if handle.is_null() || path.is_null() {
|
||||
return IdeviceErrorCode::InvalidArg;
|
||||
}
|
||||
|
||||
let adapter = unsafe { &mut (*handle).0 };
|
||||
let c_str = unsafe { CString::from_raw(path as *mut c_char) };
|
||||
let path_str = match c_str.to_str() {
|
||||
Ok(s) => s,
|
||||
Err(_) => return IdeviceErrorCode::InvalidArg,
|
||||
};
|
||||
|
||||
let res = RUNTIME.block_on(async move { adapter.pcap(path_str).await });
|
||||
|
||||
match res {
|
||||
Ok(_) => IdeviceErrorCode::IdeviceSuccess,
|
||||
Err(e) => {
|
||||
log::error!("Adapter pcap failed: {}", e);
|
||||
IdeviceErrorCode::AdapterIOFailed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Closes the adapter connection
|
||||
///
|
||||
/// # Arguments
|
||||
/// * [`handle`] - The adapter handle
|
||||
///
|
||||
/// # Returns
|
||||
/// An error code indicating success or failure
|
||||
///
|
||||
/// # Safety
|
||||
/// `handle` must be a valid pointer to a handle allocated by this library
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn adapter_close(handle: *mut AdapterHandle) -> IdeviceErrorCode {
|
||||
if handle.is_null() {
|
||||
return IdeviceErrorCode::InvalidArg;
|
||||
}
|
||||
|
||||
let adapter = unsafe { &mut (*handle).0 };
|
||||
let res = RUNTIME.block_on(async move { adapter.close().await });
|
||||
|
||||
match res {
|
||||
Ok(_) => IdeviceErrorCode::IdeviceSuccess,
|
||||
Err(e) => {
|
||||
log::error!("Adapter close failed: {}", e);
|
||||
IdeviceErrorCode::AdapterIOFailed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sends data through the adapter
|
||||
///
|
||||
/// # Arguments
|
||||
/// * [`handle`] - The adapter handle
|
||||
/// * [`data`] - The data to send
|
||||
/// * [`length`] - The length of the data
|
||||
///
|
||||
/// # Returns
|
||||
/// An error code indicating success or failure
|
||||
///
|
||||
/// # Safety
|
||||
/// `handle` must be a valid pointer to a handle allocated by this library
|
||||
/// `data` must be a valid pointer to at least `length` bytes
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn adapter_send(
|
||||
handle: *mut AdapterHandle,
|
||||
data: *const u8,
|
||||
length: usize,
|
||||
) -> IdeviceErrorCode {
|
||||
if handle.is_null() || data.is_null() {
|
||||
return IdeviceErrorCode::InvalidArg;
|
||||
}
|
||||
|
||||
let adapter = unsafe { &mut (*handle).0 };
|
||||
let data_slice = unsafe { std::slice::from_raw_parts(data, length) };
|
||||
|
||||
let res = RUNTIME.block_on(async move { adapter.psh(data_slice).await });
|
||||
|
||||
match res {
|
||||
Ok(_) => IdeviceErrorCode::IdeviceSuccess,
|
||||
Err(e) => {
|
||||
log::error!("Adapter send failed: {}", e);
|
||||
IdeviceErrorCode::AdapterIOFailed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Receives data from the adapter
|
||||
///
|
||||
/// # Arguments
|
||||
/// * [`handle`] - The adapter handle
|
||||
/// * [`data`] - Pointer to a buffer where the received data will be stored
|
||||
/// * [`length`] - Pointer to store the actual length of received data
|
||||
/// * [`max_length`] - Maximum number of bytes that can be stored in `data`
|
||||
///
|
||||
/// # Returns
|
||||
/// An error code indicating success or failure
|
||||
///
|
||||
/// # Safety
|
||||
/// `handle` must be a valid pointer to a handle allocated by this library
|
||||
/// `data` must be a valid pointer to at least `max_length` bytes
|
||||
/// `length` must be a valid pointer to a usize
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn adapter_recv(
|
||||
handle: *mut AdapterHandle,
|
||||
data: *mut u8,
|
||||
length: *mut usize,
|
||||
max_length: usize,
|
||||
) -> IdeviceErrorCode {
|
||||
if handle.is_null() || data.is_null() || length.is_null() {
|
||||
return IdeviceErrorCode::InvalidArg;
|
||||
}
|
||||
|
||||
let adapter = unsafe { &mut (*handle).0 };
|
||||
let res = RUNTIME.block_on(async move { adapter.recv().await });
|
||||
|
||||
match res {
|
||||
Ok(received_data) => {
|
||||
let received_len = received_data.len();
|
||||
if received_len > max_length {
|
||||
return IdeviceErrorCode::BufferTooSmall;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
std::ptr::copy_nonoverlapping(received_data.as_ptr(), data, received_len);
|
||||
*length = received_len;
|
||||
}
|
||||
|
||||
IdeviceErrorCode::IdeviceSuccess
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Adapter recv failed: {}", e);
|
||||
IdeviceErrorCode::AdapterIOFailed
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user