add example helper, translate more examples

update to wip servicepoint lib
This commit is contained in:
Vinzenz Schroeter 2025-05-10 14:58:50 +02:00
parent b8a55d0433
commit 4ab5305377
15 changed files with 195 additions and 61 deletions

View file

@ -103,7 +103,7 @@ pub unsafe extern "C" fn sp_cmd_bitvec_set_offset(
pub unsafe extern "C" fn sp_cmd_bitvec_get_operation(
command: NonNull<BitVecCommand>,
) -> BinaryOperation {
unsafe { command.as_ref().operation.clone() } // TODO remove clone
unsafe { command.as_ref().operation }
}
/// Overwrites the [BinaryOperation] of the command.

View file

@ -1,7 +1,5 @@
//! FFI slice helper
use std::ptr::NonNull;
/// Represents a span of memory (`&mut [u8]` ) as a struct.
///
/// # Safety
@ -11,28 +9,39 @@ use std::ptr::NonNull;
/// - accesses to the memory pointed to with `start` is never accessed outside `length`
/// - the lifetime of the `CByteSlice` does not outlive the memory it points to, as described in
/// the function returning this type.
/// - if `start` is NULL or `length` is 0, do not dereference `start`.
///
/// # Examples
///
/// ```c
/// ByteSlice empty = {.start: NULL, .length = 0};
/// ```
#[repr(C)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct ByteSlice {
/// The start address of the memory.
pub start: NonNull<u8>,
pub start: *mut u8,
/// The amount of memory in bytes.
pub length: usize,
}
impl ByteSlice {
pub(crate) const INVALID: ByteSlice = ByteSlice {
start: std::ptr::null_mut(),
length: 0,
};
pub(crate) unsafe fn as_slice(&self) -> &[u8] {
unsafe { std::slice::from_raw_parts(self.start.as_ptr(), self.length) }
unsafe { std::slice::from_raw_parts(self.start, self.length) }
}
pub(crate) unsafe fn as_slice_mut(&mut self) -> &mut [u8] {
unsafe {
std::slice::from_raw_parts_mut(self.start.as_ptr(), self.length)
}
unsafe { std::slice::from_raw_parts_mut(self.start, self.length) }
}
pub(crate) unsafe fn from_slice(slice: &mut [u8]) -> Self {
Self {
start: NonNull::new(slice.as_mut_ptr()).unwrap(),
start: slice.as_mut_ptr(),
length: slice.len(),
}
}

View file

@ -35,10 +35,8 @@ pub mod packet;
/// Functions related to [UdpSocket].
pub mod udp;
use std::time::Duration;
/// Actual hardware limit is around 28-29ms/frame. Rounded up for less dropped packets.
pub const SP_FRAME_PACING_MS: u128 = Duration::from_millis(30).as_millis();
pub const SP_FRAME_PACING_MS: u128 = 30;
/// This is a type only used by cbindgen to have a type for pointers.
pub struct UdpSocket;

View file

@ -20,13 +20,12 @@ pub unsafe extern "C" fn sp_packet_try_load(data: ByteSlice) -> *mut Packet {
#[no_mangle]
pub unsafe extern "C" fn sp_packet_from_parts(
header: Header,
payload: *const ByteSlice,
payload: ByteSlice,
) -> NonNull<Packet> {
let payload = if payload.is_null() {
vec![]
let payload = if payload == ByteSlice::INVALID {
None
} else {
let payload = unsafe { (*payload).as_slice() };
Vec::from(payload)
Some(Vec::from(unsafe { payload.as_slice() }))
};
heap_move_nonnull(Packet { header, payload })
@ -44,12 +43,19 @@ pub unsafe extern "C" fn sp_packet_get_header(
/// Returns a pointer to the current payload of the provided packet.
///
/// Returns an [ByteSlice::INVALID] instance in case the packet does not have any payload.
///
/// The returned memory can be changed and will be valid until a new payload is set.
#[no_mangle]
pub unsafe extern "C" fn sp_packet_get_payload(
packet: NonNull<Packet>,
) -> ByteSlice {
unsafe { ByteSlice::from_slice(&mut (*packet.as_ptr()).payload) }
unsafe {
match &mut (*packet.as_ptr()).payload {
None => ByteSlice::INVALID,
Some(payload) => ByteSlice::from_slice(payload),
}
}
}
/// Sets the payload of the provided packet to the provided data.
@ -60,7 +66,13 @@ pub unsafe extern "C" fn sp_packet_set_payload(
packet: NonNull<Packet>,
data: ByteSlice,
) {
unsafe { (*packet.as_ptr()).payload = data.as_slice().to_vec() }
unsafe {
(*packet.as_ptr()).payload = if data == ByteSlice::INVALID {
None
} else {
Some(data.as_slice().to_vec())
}
}
}
/// Serialize the packet into the provided buffer.

View file

@ -136,7 +136,7 @@ pub unsafe extern "C" fn sp_udp_send_header(
) -> bool {
let packet = Packet {
header,
payload: vec![],
payload: None,
};
unsafe { udp_connection.as_ref() }
.send(&Vec::from(packet))